Ask someone to see a waiting visitor
Reception asks a person to see a visitor who is waiting, or passes the visit to a team. Send person_id or team_id,
one of them.
A person is told on their own channels and answers with answer-visit: see them, ask them to wait, not today, or decline. A yes makes them the visit's host. A team's members are all told, and the first to take the visit becomes its host. Whoever receives the visit may ask: reception, security and admins at its site, and the person or the team it waits with.
Scope: visits:write · Plan: Pro and Enterprise in live mode; every plan in test mode.
AuthorizationBearer <token>Send Authorization: Bearer <token> on every request. The token is one of:
| Prefix | What it is | Where it may be used |
|---|---|---|
agoo_sk_live_ | Secret key, live mode | Your servers only |
agoo_sk_test_ | Secret key, test mode | Your servers only |
agoo_pk_live_ | Publishable key, live mode | Browsers 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 mode | As 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
visit_id*stringThe visit's ID.
^visit_[0-7][0-9a-hjkmnp-tv-z]{25}$"visit_01m4k5z4j0fxbte6sn6e8tpgza"Idempotency-Key*stringA 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.
uuidapplication/json- body
Who to ask: a person or a team, one of them.
person_id?PersonIdAsk this person to see the visitor.
^person_[0-7][0-9a-hjkmnp-tv-z]{25}$"person_01kjsesxm0e4zbyvkr7bcfxbfg"team_id?TeamIdOr pass the visit to this team: its members are told, and the first to take it becomes the host.
^team_[0-7][0-9a-hjkmnp-tv-z]{25}$"team_01m4r6y616e1b973vj50h0643y"note?stringA line for the visit's timeline, such as why they came.
length <= 300The visit, as it is now.
application/json- response
One visit by one visitor to one site.
id*VisitIdA visit ID (TypeID with the visit prefix).
^visit_[0-7][0-9a-hjkmnp-tv-z]{25}$"visit_01m4k5z4j0fxbte6sn6e8tpgza"status*VisitStatusWhere 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.
"expected""awaiting_approval""checked_in""checked_out""denied""cancelled""no_show"type*VisitTypeA 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.
^[a-z][a-z0-9_]{0,39}$"meeting""contractor""parent_pickup"source*VisitSourceHow 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).
"invitation""pre_registration""walk_in""booking"site_id*SiteIdA site ID (TypeID with the site prefix).
^site_[0-7][0-9a-hjkmnp-tv-z]{25}$"site_01kjpt3yw0fz0v414608h9x65s"gate_id*|The gate the visitor came in through, once known.
^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.
^person_[0-7][0-9a-hjkmnp-tv-z]{25}$"person_01kjsesxm0e4zbyvkr7bcfxbfg"audience*stringWho 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).
"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*booleanThe visitor is waiting and nobody has taken the visit yet.
visitor*The visitor's details as stored on their visitor record.
purpose*|length <= 300"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.
length <= 16"GR 4521-24"expected_at*|When the visitor is expected. null for walk-ins.
date-timeexpected_until*|When the visitor's pass stops working. null for walk-ins.
date-timechecked_in_at*|date-timechecked_out_at*|date-timecancelled_at*|date-timedecision*|The host's decision, for visits that needed approval.
booking_id*|The booking this visit came from, if any.
^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.
{ "vehicle_plate": "GR 4521-24", "bringing_laptop": true}created_at*stringdate-timeupdated_at*stringdate-timecurl -X POST 'https://api.agoo.ardent.africa/v1/visits/visit_01m4k5z4j0fxbte6sn6e8tpgza/ask' \ -H 'Idempotency-Key: 3f6b2a1e-8c4d-4f7a-9b2e-5d1c0a7e9f64' \ -H 'Content-Type: application/json' \ -d '{ "person_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg", "note": "Says it is about the tender."}'{ "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"}Remove a host from a visit DELETE
Takes a person off a visit. The lead host can be removed only when nobody else is on the visit and the visit is for a team or for no one in particular: it then waits to be taken again. Otherwise make someone else the lead first (add-visit-host with `lead: true`); a visit for one person always keeps a host. Fires `visit.host_changed`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.
Answer about a visitor POST
A host's answer about a visitor: - `see`: they'll see the visitor. A visit that is `awaiting_approval` is approved, as approve-visit does. - `wait`: they ask the visitor to wait, with `minutes` if they say how long. - `not_today`: not today. The visit keeps waiting, and reception can book the visitor in for another time. - `decline`: they won't see the visitor. Anyone on the visit may answer and the first answer counts, unless the visit type says only the lead host decides; the others are told. A yes from someone reception asked, or from a member of the team that has the visit, makes them its host. Their no goes back to reception and the visit keeps waiting; a `decline` from the visit's own host denies it, as deny-visit does. With `person_id`, reception (or your integration) records the answer of someone they reached another way, such as by phone. The visit's timeline and the audit trail keep both: whose answer it is, and who wrote it down. A secret key has no person of its own, so it always sends `person_id`. **Scope:** `visits:write` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.