VisitorFlow
Build · REST API

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.