Docs

Book a waiting visitor in for another time

Preview· P9
POST
/visits/{visit_id}/reschedule

Books the visitor in for another time and closes this visit, for a visitor who can't be seen today.

With expected_at, Agoo makes a new invitation for the same visitor and visit type, for whoever this visit is for unless you name hosts or a team, and sends their pass. With booking_id, a booking you already made for them replaces the visit instead.

This visit becomes cancelled, with rescheduled_to naming what replaced it, and its pass stops working. Only a visit that is expected or awaiting_approval can be booked in again. Fires visit.created for the new visit and visit.cancelled for this one; the new visit's hosts are told.

Scope: visits:write · Plan: Pro and Enterprise in live mode; every plan in test mode.

Authorization

headerAuthorizationBearer <token>

Send Authorization: Bearer <token> on every request. The token is one of:

PrefixWhat it isWhere it may be used
agoo_sk_live_Secret key, live modeYour servers only
agoo_sk_test_Secret key, test modeYour servers only
agoo_pk_live_Publishable key, live modeBrowsers and apps: create pre-registrations and bookings, read public booking types (with their intake questions) and their free slots, read the visit types open for pre-registration with their public forms. Never lists people.
agoo_pk_test_Publishable key, test modeAs above, in test mode

Admins create keys in Console → Developers → API keys and choose each key's scopes. A key is shown once. Never put a secret key in a URL, a browser or a mobile app.

Scope: visits:write

Path Parameters

visit_id*string

The visit's ID.

Match^visit_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"visit_01m4k5z4j0fxbte6sn6e8tpgza"

Header Parameters

Idempotency-Key*string

A UUID you generate for this operation. If you retry with the same key within 24 hours, Agoo returns the original response instead of acting twice. While the first request is still running, a retry returns conflict. Reusing a key with a different request returns idempotency_key_reused. Responses with rate_limited, internal_error or unavailable aren't stored, so retry those with the same key.

Formatuuid

Request Body

application/json
  1. body

When the visitor will come instead (expected_at), or the booking you made for them (booking_id): one of them.

expected_at?string

When the visitor will come instead. A new invitation is made for them.

Formatdate-time
expected_until?string

When their new pass stops working. Must be after expected_at. Defaults to the end of that day at the site.

Formatdate-time
host_id?PersonId

Who they'll see. Left out with host_ids and team_id: whoever this visit is for now.

Match^person_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"person_01kjsesxm0e4zbyvkr7bcfxbfg"
host_ids?array<>
Itemsitems <= 10
team_id?TeamId

A team ID (TypeID with the team prefix).

Match^team_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"team_01m4r6y616e1b973vj50h0643y"
purpose?string
Lengthlength <= 300
send_pass?boolean

Send the visitor their pass for the new time.

Defaulttrue
pass_channels?array<>
Items1 <= items
booking_id?string

Instead of expected_at: a pending or confirmed booking you made for them, which replaces this visit.

Match^booking_[0-7][0-9a-hjkmnp-tv-z]{25}$
note?string

Why, for the record.

Lengthlength <= 500

Response Body

The visit you closed, with rescheduled_to.

application/json
  1. response

One visit by one visitor to one site.

id*VisitId

A visit ID (TypeID with the visit prefix).

Match^visit_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"visit_01m4k5z4j0fxbte6sn6e8tpgza"
status*VisitStatus

Where the visit is. A visit usually goes expected → checked_in → checked_out, passing through awaiting_approval when a host must approve. A pre-registration that needs approval starts as awaiting_approval and, once the host approves, becomes expected with decision.outcome: approved. It can also end as denied, cancelled or no_show.

Value in"expected""awaiting_approval""checked_in""checked_out""denied""cancelled""no_show"
type*VisitType

A visit type's key. Every organisation has six built-in visit types, meeting, interview, delivery, contractor, event and other, and can add its own in the console, such as parent_pickup or vendor. Each type has its own visit form, badge and rules. A key is lowercase letters, digits and underscores, starts with a letter and is at most 40 characters. It never changes, even when the type is renamed, and it's the same in live and test mode. List your organisation's types with GET /visit-types.

A key your organisation doesn't have returns validation_failed, and so does a type that is turned off when you create a visit or change a visit's type.

Match^[a-z][a-z0-9_]{0,39}$
Example"meeting"
Example"contractor"
Example"parent_pickup"
source*VisitSource

How the visit started: invitation (a host, the console or a secret key), pre_registration (the visitor, or a publishable key), walk_in (at the kiosk or front desk) or booking (an in-person booking).

Value in"invitation""pre_registration""walk_in""booking"
site_id*SiteId

A site ID (TypeID with the site prefix).

Match^site_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"site_01kjpt3yw0fz0v414608h9x65s"
gate_id*|

The gate the visitor came in through, once known.

Match^gate_[0-7][0-9a-hjkmnp-tv-z]{25}$
host_id*|

The lead host. null while a visit for a team or for no one in particular hasn't been taken by anyone.

Match^person_[0-7][0-9a-hjkmnp-tv-z]{25}$
Example"person_01kjsesxm0e4zbyvkr7bcfxbfg"
audience*string

Who the visit is for: one person, several people (a lead host and others), a team, or desk (no one in particular, which your reception receives).

Value in"person""people""team""desk"
hosts*array<>

Everyone the visit is for, the lead first, and anyone reception asked to see the visitor, with their answer. Empty while nobody has taken a visit for a team or for no one in particular.

team*|

The team the visit is with: the one the visitor came to see, or the one receiving a visitor with no one in particular to see.

asked_for*|

The person a walk-in asked for, when that person's visitors go through their office.

needs_someone*boolean

The visitor is waiting and nobody has taken the visit yet.

visitor*

The visitor's details as stored on their visitor record.

purpose*|
Lengthlength <= 300
Example"Quarterly treasury review"
vehicle_plate?|

The plate of the vehicle the visitor comes in, as given; the gate recognises it. Left out when there's none.

Lengthlength <= 16
Example"GR 4521-24"
expected_at*|

When the visitor is expected. null for walk-ins.

Formatdate-time
expected_until*|

When the visitor's pass stops working. null for walk-ins.

Formatdate-time
checked_in_at*|
Formatdate-time
checked_out_at*|
Formatdate-time
cancelled_at*|
Formatdate-time
decision*|

The host's decision, for visits that needed approval.

booking_id*|

The booking this visit came from, if any.

Match^booking_[0-7][0-9a-hjkmnp-tv-z]{25}$
rescheduled_to*|

For a visit closed because the visitor was booked in for another time: what replaced it. null otherwise.

pass*

The visitor's QR pass: where and when it was last sent, and when and where it admits.

custom_fields*

Answers to your organisation's custom fields, keyed by field key. The keys and allowed values come from the JSON Schema of the matching form (GET /forms). Keys that aren't in the form are rejected. Questions the form marks as required aren't enforced through the API; they're asked when the visitor checks in or completes their pre-registration. Answers to fields an admin marked sensitive or masked are never included for API keys or connected apps, nor in events and webhooks: they stay inside Agoo, seen only by the roles the admin chose.

Example
{  "vehicle_plate": "GR 4521-24",  "bringing_laptop": true}
created_at*string
Formatdate-time
updated_at*string
Formatdate-time
curl -X POST 'https://api.agoo.ardent.africa/v1/visits/visit_01m4k5z4j0fxbte6sn6e8tpgza/reschedule' \  -H 'Idempotency-Key: 3f6b2a1e-8c4d-4f7a-9b2e-5d1c0a7e9f64' \  -H 'Content-Type: application/json' \  -d '{  "expected_at": "2026-10-16T10:00:00Z",  "note": "Asked to come back on Friday."}'
{  "id": "visit_01m4k5z4j0fxbte6sn6e8tpgza",  "status": "expected",  "type": "meeting",  "source": "invitation",  "site_id": "site_01kjpt3yw0fz0v414608h9x65s",  "gate_id": "string",  "host_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg",  "audience": "person",  "hosts": [    {      "id": "person_01kjsesxm0e4zbyvkr7bcfxbfg",      "name": "Kwame Mensah",      "role": "lead",      "state": "addressed",      "answer": "see",      "answer_minutes": 1,      "asked_at": "2019-08-24T14:15:22Z",      "answered_at": "2019-08-24T14:15:22Z"    }  ],  "team": {    "id": "team_01m4r6y616e1b973vj50h0643y",    "name": "Finance"  },  "asked_for": {    "id": "person_01kjsesxm0e4zbyvkr7bcfxbfg",    "name": "Kwame Mensah"  },  "needs_someone": true,  "visitor": {    "id": "visitor_01krdtb870fxj8t6ntdtcxwdk5",    "name": "Ama Owusu",    "phone": "+233241234567",    "email": "ama@coastline.example",    "company": "Coastline Consult"  },  "purpose": "Quarterly treasury review",  "vehicle_plate": "GR 4521-24",  "expected_at": "2019-08-24T14:15:22Z",  "expected_until": "2019-08-24T14:15:22Z",  "checked_in_at": "2019-08-24T14:15:22Z",  "checked_out_at": "2019-08-24T14:15:22Z",  "cancelled_at": "2019-08-24T14:15:22Z",  "decision": {    "outcome": "approved",    "decided_at": "2019-08-24T14:15:22Z",    "decided_by": "string",    "reason": "string"  },  "booking_id": "string",  "rescheduled_to": {    "visit_id": "string",    "booking_id": "string",    "at": "2019-08-24T14:15:22Z"  },  "pass": {    "channels": [      "whatsapp"    ],    "last_sent_at": "2019-08-24T14:15:22Z",    "rules": {      "daily": {        "from": "08:00",        "until": "17:00"      },      "window": {        "before": 0,        "after": 0      },      "single_use": true,      "gate_ids": [        "gate_01kjpt7m20fpf9vcsaexsxgqr3"      ]    },    "for_visit_id": "string"  },  "custom_fields": {    "vehicle_plate": "GR 4521-24",    "bringing_laptop": true  },  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}