Docs

Create a visit

Preview· P9
POST/visits

Creates an expected visit: an invitation from a host when you use a secret key or OAuth token, or a pre-registration when you use a publishable key. Agoo links the visit to an existing visitor record when the phone number (or, without a phone, the email address) matches one, and creates a visitor record otherwise.

  • With send_pass (the default), Agoo sends the visitor a QR pass on the channels in pass_channels, trying them in order and falling back to the next if one fails. Leave pass_channels out to use your organisation's default order. Each message counts towards your SMS and WhatsApp allowance.
  • Fires visit.created, then pass.sent once the pass is sent.
  • The visitor is checked against your watchlist straight away. On a match the visit is held for security (awaiting_approval): no pass is sent, no host is asked, watchlist.matched fires and your security team is alerted. The response shows only the status.
  • type is one of your organisation's visit type keys (see GET /visit-types) and defaults to meeting. A key your organisation doesn't have, or a type that is turned off, returns validation_failed.
  • custom_fields are checked against the visit form for the visit's type (see GET /forms).
  • Pre-registrations made with a publishable key have source: pre_registration. If the site requires host approval for pre-registrations, the visit starts as awaiting_approval, the host is asked, and the pass is sent once the host approves (the visit is then expected again).
  • Each visitor new this month counts towards your plan's visitors a month. A new visitor beyond it returns plan_required; visitors already counted this month can always be invited again.
  • An unknown site_id, or a host_id that isn't an active person who can host, returns validation_failed.
  • With a publishable key, type must be open for pre-registration (pre_registration: true in GET /visit-types); any other type, including the default meeting when it isn't open, returns validation_failed at body.type. custom_fields may contain only the fields in that type's public_form; a field your staff fill in returns validation_failed at body.custom_fields.<key>. Publishable keys can't list or search people, so your page must already know the host_id; to let visitors search for their host, use the hosted pre-registration page (the embed script).
  • In test mode, messages go to the console's test outbox instead of the visitor.

Scope: visits:write · Plan: Pro and Enterprise in live mode; every plan in test mode. Publishable keys: allowed, for visit types open for pre-registration.

Authorization

AuthorizationBearer <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.

In: header

Scope: visits:write

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

TypeScript Definitions

Use the request body type in TypeScript.

A new expected visit.

Response Body

application/json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

curl -X POST "https://example.com/visits" \  -H "Idempotency-Key: 3f6b2a1e-8c4d-4f7a-9b2e-5d1c0a7e9f64" \  -H "Content-Type: application/json" \  -d '{    "site_id": "site_01kjpt3yw0fz0v414608h9x65s",    "host_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg",    "type": "meeting",    "visitor": {      "name": "Ama Owusu",      "phone": "+233241234567",      "email": "ama@coastline.example",      "company": "Coastline Consult"    },    "purpose": "Quarterly treasury review",    "expected_at": "2026-10-14T09:30:00Z",    "expected_until": "2026-10-14T11:30:00Z",    "send_pass": true,    "pass_channels": [      "whatsapp",      "sms"    ],    "custom_fields": {      "vehicle_plate": "GR 4521-24",      "bringing_laptop": true    }  }'
{  "id": "visit_01m4k5z4j0fxbte6sn6e8tpgza",  "status": "expected",  "type": "meeting",  "source": "invitation",  "site_id": "site_01kjpt3yw0fz0v414608h9x65s",  "gate_id": null,  "host_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg",  "visitor": {    "id": "visitor_01krdtb870fxj8t6ntdtcxwdk5",    "name": "Ama Owusu",    "phone": "+233241234567",    "email": "ama@coastline.example",    "company": "Coastline Consult"  },  "purpose": "Quarterly treasury review",  "expected_at": "2026-10-14T09:30:00Z",  "expected_until": "2026-10-14T11:30:00Z",  "checked_in_at": null,  "checked_out_at": null,  "cancelled_at": null,  "decision": null,  "booking_id": null,  "pass": {    "channels": [      "whatsapp"    ],    "last_sent_at": "2026-10-10T15:12:44Z"  },  "custom_fields": {    "vehicle_plate": "GR 4521-24",    "bringing_laptop": true  },  "created_at": "2026-10-10T15:12:40Z",  "updated_at": "2026-10-10T15:12:44Z"}