Customers

A customer is the account that owns your VerifyAI data. Every API key acts on behalf of exactly one customer, and that customer_id is what scopes everything else: the verifications you can read, the policies your keys can run, and the webhook endpoints you register all belong to a single customer.

If you run VerifyAI for one organization, you have one customer and rarely touch these endpoints — your key already resolves to it. If you're a platform reselling VerifyAI to your own users, customers are how you keep each tenant's data isolated.

How customer_id flows through the API

customer_id is the spine of account isolation:

  • API keys resolve to a customer_id at authentication time. A key can only read and write data for its own customer.
  • Policies are either system policies (customer_id = null, like the built-in scooter_parking) or custom policies owned by one customer.
  • Verifications are written under the authenticating key's customer_id, and list/retrieve only ever return that customer's rows.
  • Inspection sessions and webhook deliveries carry the customer_id so you can route them per tenant — the inspection.submitted webhook payload includes it directly.
You usually don't pass customer_id

Because the key already resolves to a customer, the verify and verifications endpoints never ask you for a customer_id — they infer it from the key. These customer endpoints exist for reading your own account record and, for platform integrations, provisioning sub-accounts.

The customer object

json
{
  "id": "cus_forest1",
  "name": "Forest (HumanForest)",
  "status": "active",
  "created_at": "2026-01-08T09:00:00Z",
  "metadata": {
    "region": "london",
    "external_account_id": "acct_8821"
  }
}

Fields

FieldTypeDescription
idstringStable customer identifier, prefix cus_. This is the customer_id on keys/policies.
namestringDisplay name for the account.
statusstringactive, paused, or cancelled. A non-active customer's keys return 403.
created_atISO 8601When the customer was created.
metadataobject?Free-form key/value data you attach (e.g. your own account ID, region).

Authentication

HeaderRequiredValue
X-API-KeyYesYour vai_… key. See Authentication.
Availability

Most accounts manage their customer record from Dashboard → Settings, and platform sub-account provisioning is enabled per integration. If a call below returns 404, the programmatic surface isn't enabled for your account yet — the request and response shapes match what ships. Contact support to turn on multi-customer provisioning.

Retrieve the current customer

text
GET /api/v1/customers/me

Returns the customer the authenticating key belongs to. This is the call to make when you want to confirm which account a key resolves to, or read your own status.

curl https://verify.switchlabs.dev/api/v1/customers/me \
-H "X-API-Key: vai_your_api_key"
json
{
  "id": "cus_forest1",
  "name": "Forest (HumanForest)",
  "status": "active",
  "created_at": "2026-01-08T09:00:00Z",
  "metadata": { "region": "london" }
}

List customers

text
GET /api/v1/customers

For platform integrations only. Returns the sub-accounts you've provisioned, newest first. A single-tenant account sees just its own record.

Query parameters

ParameterTypeDefaultDescription
limitnumber20Page size. Clamped to a maximum of 100.
cursorstringPagination cursor. Pass next_cursor from the prior page.
statusstringFilter by active, paused, or cancelled.
curl "https://verify.switchlabs.dev/api/v1/customers?limit=20&status=active" \
-H "X-API-Key: vai_your_api_key"
json
{
  "data": [
    {
      "id": "cus_forest1",
      "name": "Forest (HumanForest)",
      "status": "active",
      "created_at": "2026-01-08T09:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Pagination follows the same cursor contract as Verifications: pass next_cursor back as cursor until has_more is false.

Create a customer

text
POST /api/v1/customers

For platform integrations. Provisions a new sub-account under your organization. Issue that customer a key via the API keys endpoint to let it submit verifications independently.

Body parameters

ParameterTypeRequiredDescription
namestringYesDisplay name for the new customer.
metadataobjectNoFree-form data to attach (your own account ID, region, plan, etc.).
curl -X POST https://verify.switchlabs.dev/api/v1/customers \
-H "X-API-Key: vai_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Mobility", "metadata": { "external_account_id": "acct_991" } }'
json
{
  "id": "cus_9q2v8m",
  "name": "Acme Mobility",
  "status": "active",
  "created_at": "2026-06-01T12:00:00Z",
  "metadata": { "external_account_id": "acct_991" }
}

Errors

StatusReason
400Missing name, or invalid metadata.
401Missing or invalid API key.
403Key not valid for VerifyAI, not linked to a customer, or lacks platform provisioning.
404No customer with that id, or it belongs to a different organization.
429Rate limit — check the Retry-After header.
503Authentication service unavailable. Retry.

What's next

Get in Touch

Questions about pricing, integrations, or custom deployments? We'd love to hear from you.