API reference
Roadmap — not yet available. The public REST API and SDKs are planned, not shipped. The reference below documents the intended shape so you can plan integrations; the api.visitorflow.com host and API keys are not live yet. Today, integrate via signed webhooks or talk to us about your use case.Once released, every VisitorFlow entity will be reachable via the REST API at https://api.visitorflow.com/v1 — authenticated, JSON in, JSON out, and rate-limited per tenant.
Authentication
Generate an API key from Settings → API & webhooks → New key. Keys are scoped: vfp_live_* for production, vfp_test_* for the sandbox. Pass the key as a Bearer token on every request.
curl https://api.visitorflow.com/v1/visits \
-H "Authorization: Bearer vfp_live_..."Kiosk endpoints under /v1/kiosk/* use a separate device token issued by the pairing flow — those tokens carry the tenant + location implicitly so the body cannot inject a different tenant.
Rate limits
Default budgets per tenant: 600 read req/min, 120 write req/min. Burst is allowed up to 2× for 10 seconds. Hitting the limit returns 429 Too Many Requests with retry-after in seconds. Enterprise plans get custom budgets.
Versioning
The URL prefix carries the major version (/v1/). Additive changes (new fields, new optional params) ship without a version bump. Breaking changes get a new prefix and a 12-month overlap.
Create a visitor visit
POST /v1/visits
{
"type": "visitor",
"host_id": "h_98412",
"visitor": {
"name": "Marisol Cruz",
"email": "marisol@acme.com",
"company": "Acme Co"
},
"location_id": "loc_mty_01"
}
201 Created
{
"id": "vis_2YZ4...",
"checked_in_at": "2026-04-30T14:21:09Z",
"host_notified": true
}Create a driver visit
POST /v1/visits
{
"type": "driver",
"driver": { "name": "J. Pérez", "license_number": "LIC-1234" },
"shipment": { "bol_ref": "BOL-88412", "type": "delivery", "hazmat": false },
"vehicle": { "tractor_plate": "ABC-1234", "trailer_plate": "TR-998" },
"location_id": "loc_mty_01"
}Pre-register a visitor
POST /v1/pre-registrations
{
"host_id": "h_98412",
"visitor": { "name": "Andrés López", "email": "andres@acme.com" },
"scheduled_at": "2026-05-02T15:00:00Z",
"window_minutes": 60
}VisitorFlow emails the visitor a signed QR; the kiosk decodes it and skips straight to photo + NDA. The QR PNG is also reachable at GET /v1/prereg/qr/{id}.png if you want to embed it in your own emails.
List visits
GET /v1/visits?location_id=loc_mty_01&status=onsite
200 OK
{
"data": [{ "id": "vis_2YZ4...", ... }],
"next_cursor": "eyJsYXN0SUQiOi..."
}Check out a visit
PATCH /v1/visits/vis_2YZ4
{ "status": "checked_out" }List incidents
GET /v1/incidents?status=open
200 OK
[
{
"id": "inc_xy12",
"severity": "low",
"type": "tailgating",
"summary": "Visitor entered without badge scan",
"status": "open"
}
]Errors
Errors follow the JSON:API problem shape. 4xx means you sent something invalid; 5xx means we did. Every response includes an x-request-id header — quote it when contacting support.
401 Unauthorized
{ "error": "Bearer token missing or expired" }
400 Bad Request
{
"error": "Invalid payload",
"issues": {
"fieldErrors": { "visitor.email": ["Invalid email"] }
}
}Webhooks
Subscribe to events instead of polling. Every delivery is signed with x-vf-signature: sha256=... and replays with exponential backoff up to a 24h cap. See the webhooks guide.
Looking for SDKs? TypeScript and Python SDKs ship the same week as the public beta. For the canonical schema, fetch the OpenAPI 3.1 document.