Keys, limits and conventions
How requests are authenticated, which mode they act in, and the conventions every endpoint shares: versions, request ids, rate limits, safe retries, paging and metadata.
API keys
Every request carries a secret key in the Authorization header. Create keys in the Developers console.
curl https://api.vindexgrid.com/v1/me \
-H "Authorization: Bearer vdx_test_..."
# or, with curl's -u (the key as the user name, no password)
curl https://api.vindexgrid.com/v1/me -u vdx_test_...:vdx_test_ or vdx_live_, then 38 letters and digits. The last six are a checksum, so a mistyped key is refused straight away and secret scanners can recognise a leaked one.verifications:read, verifications:write, screenings:read, screenings:write, events:read and balance:read. A call outside the key's permissions returns 403 insufficient_scope.403 ip_not_allowed.Never use a key in a browser or app
Keys are secrets for your server. A request that comes from a web page on another site is refused with 403 secret_key_in_browser, and Vindex never sends browsers CORS permission to call the API. If a key leaks, revoke it in the console.
Test and live mode
The key decides the mode: a test key acts in test mode, a live key in live mode. The two never mix.
403 live_mode_not_enabled.livemode so you can tell them apart.Versions and request ids
The API is /v1. Every response carries Vindex-Version: 2026-11-05, the date of the version that answered. Vindex adds fields and endpoints without warning, so ignore fields you don't know. Anything that would break an integration ships as a new dated version, announced in advance.
Every response also carries a Request-Id (req_…). Error bodies repeat it as request_id. Log it, and quote it to Vindex support: it finds the exact request in your request log. Responses are sent with Cache-Control: no-store because they can contain customer data.
Rate limits
Limits are per minute, per account and mode, shared by all your keys.
| Requests | Live, per minute | Test, per minute |
|---|---|---|
| ReadGET requests | 600 | 300 |
| WritePOST requests, except screenings | 120 | 60 |
| ScreeningPOST /screenings and /screening_batches | 60 | 60 |
Every response says where you stand, in the IETF RateLimit header fields. Over the limit you get 429 rate_limited with Retry-After: wait that many seconds, then retry. Need more? Ask Vindex.
RateLimit-Policy: "write";q=120;w=60
RateLimit: "write";r=97;t=23
HTTP/1.1 429 Too Many Requests
Retry-After: 23Idempotent retries
Networks fail. Send an Idempotency-Key header on every POST (a UUID is ideal) and you can retry safely: Vindex does the work once and charges once.
Idempotent-Replayed: true.422 idempotency_key_reused. Use a new key for a new request.409 idempotency_key_in_use with Retry-After: 1. Wait a second and retry.402), fix the cause and retry with the same key.Lists and pagination
Lists come newest first, as { "object": "list", "data": [...], "has_more": true }. Ask for up to 100 at a time with limit (default 10). For the next page, send starting_after with the id of the last item you received, while has_more is true.
curl -G https://api.vindexgrid.com/v1/verifications \
-H "Authorization: Bearer $VINDEX_API_KEY" \
-d limit=100 \
-d starting_after=ver_0vZ3kq9XfJ1mB7c2Lr8sTyVerifications can also be filtered by status, external_reference, created_gte and created_lt; events by type (a group works too, such as verification.*) and object_id.
Metadata
Verifications, screenings and batches take metadata: up to 50 keys of your own, each key up to 40 characters (no [ or ]) and each value a string of up to 500. Vindex stores it and returns it, nothing more. Use external_reference (up to 255 characters, searchable) for your own id.
No personal data in metadata
Metadata and references appear in logs, events and the console. Put ids there, never names, emails, dates of birth or document numbers.
Something missing or unclear? Signed-in users can tell us from Feedback in the app.
