The VerifyDoc.ai API
The API is a REST interface that speaks JSON over HTTPS. You authenticate with a workspace API key, call an endpoint, and receive a predictable response envelope. All successful responses include "ok": true; failures return "ok": false with an error object (see Errors).
- HTTPS only. Plaintext HTTP requests are rejected.
- Workspace-scoped. A key acts only within its issuing workspace; records, seats, and audit events stay bound to that tenant.
- Narrow surface. Four live endpoints cover validation, issuance, provisioning, and signing.
Bearer key or x-api-key
Generate workspace API keys in Dashboard → Settings → API. Only workspace admins can create or revoke keys, and the plaintext value is shown once at creation — store it immediately in your secrets manager.
Pass the key on every request using either header form:
# Option A — Bearer token
Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx
# Option B — API key header
x-api-key: vd_live_xxxxxxxxxxxxxxxxxKeys are prefixed vd_live_ for production. Treat a key like a password: never embed it in client-side code, mobile apps, or public repositories.
Request & response shape
Send JSON bodies with Content-Type: application/json and request JSON back with Accept: application/json. Every response is a JSON object carrying an ok boolean.
{
"ok": true,
"...": "resource fields"
}{
"ok": false,
"error": {
"code": "invalid_request",
"message": "Human-readable detail"
}
}Errors & status codes
The API uses conventional HTTP status codes. A 2xx indicates success; 4xx indicates a problem with your request; 5xx indicates a server-side error.
| Status | Meaning | When it happens |
|---|---|---|
200 / 201 | OK / Created | Request succeeded. |
400 | Bad request | Malformed JSON or missing required fields. |
401 | Unauthorized | Missing, malformed, or revoked API key. |
403 | Forbidden | Key valid but lacks permission, or seat limit reached. |
404 | Not found | Resource or endpoint does not exist. |
409 | Conflict | Idempotency key reused with a different payload. |
422 | Unprocessable | Validation failed on otherwise well-formed input. |
429 | Too many requests | Rate limit exceeded — back off and retry. |
5xx | Server error | Transient issue on our side — retry with backoff. |
Error codes
| Code | Description |
|---|---|
invalid_request | The request body was malformed or missing required fields. |
unauthorized | The API key was missing, invalid, or revoked. |
forbidden | The key is not permitted to perform this action. |
seat_limit_reached | Adding a teammate would exceed the plan’s seat allowance. |
validation_failed | One or more fields failed validation. |
rate_limited | Too many requests in the current window. |
Rate limits
Requests are rate limited per workspace key. When you exceed the limit you receive a 429 with a Retry-After header indicating how many seconds to wait. Build retry-with-backoff into any high-volume issuance loop.
RateLimit-Limit: 120
RateLimit-Remaining: 0
Retry-After: 30Need higher throughput for bulk issuance? Contact support to discuss workspace limits.
Idempotency
Issuance is a write that creates a permanent record, so retries must not produce duplicates. Send an Idempotency-Key header (a unique value you generate, such as a UUID) on POST requests. If a request with the same key is replayed, the original result is returned instead of creating a second record.
curl -X POST "https://verifydoc.ai/api/developer/verification-links" \
-H "Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9f1c4e2a-7b3d-4c9a-bf21-1d0e8a6f7c55" \
-d '{ "issuerName": "Pryme Financial", "documentTitle": "..." }'Reusing a key with a different body returns 409 Conflict.
Integrate in three moves
- Generate a production key in Settings → API and store it in your secrets manager.
- Call /api/developer/me on startup to confirm the workspace context.
- Issue verification or signature records inside your document flow; sync teammates only when your upstream system is the source of truth.
curl -X GET "https://verifydoc.ai/api/developer/me" \
-H "Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx" \
-H "Accept: application/json"const res = await fetch("https://verifydoc.ai/api/developer/me", {
headers: {
Authorization: `Bearer ${process.env.VERIFYDOC_KEY}`,
Accept: "application/json"
}
});
const data = await res.json();import os, requests
res = requests.get(
"https://verifydoc.ai/api/developer/me",
headers={"Authorization": f"Bearer {os.environ['VERIFYDOC_KEY']}"}
)
data = res.json()Validate the key & read workspace context
Call this first. It confirms the API key, returns the issuing workspace profile, and lets your system bind to the right tenant before doing anything else.
curl -X GET "https://verifydoc.ai/api/developer/me" \
-H "Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx"const res = await fetch("https://verifydoc.ai/api/developer/me", {
headers: { Authorization: `Bearer ${key}` }
});res = requests.get(
"https://verifydoc.ai/api/developer/me",
headers={"Authorization": f"Bearer {key}"}
){
"ok": true,
"workspace": {
"id": "workspace:123",
"companyName": "Pryme Financial",
"supportEmail": "hello@verifydoc.ai",
"countryCode": "NG",
"industryId": "financial-institutions"
},
"apiKey": {
"id": "4d3f25b8aa0f",
"name": "Production key",
"preview": "vd_live_4d3f25b8••••d2x9",
"lastUsedAt": "2026-04-12T00:28:00.000Z"
}
}Issue a verification record & return a QR asset
Submit document metadata and receive the hosted verification URL, QR image data URL, reference code, and a certificate-ready summary in one response.
Body parameters
| Field | Type | Description | |
|---|---|---|---|
issuerName | string | required | Name shown as the document’s issuer. |
documentTitle | string | required | Title of the document being verified. |
recipientName | string | optional | Recipient label shown on the verification page. |
recipientEmail | string | optional | Recipient email for record-keeping. |
issuedAt | string (ISO 8601) | optional | Issue timestamp; defaults to the time of the call. |
brandedMessage | string | optional | Short message displayed with the record. |
curl -X POST "https://verifydoc.ai/api/developer/verification-links" \
-H "Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"issuerName": "Pryme Financial",
"recipientName": "Customer segment",
"recipientEmail": "ops@example.com",
"documentTitle": "Core banking migration notice",
"issuedAt": "2026-04-12T10:30:25.000Z",
"brandedMessage": "Managed notice issued from the core banking platform."
}'const res = await fetch("https://verifydoc.ai/api/developer/verification-links", {
method: "POST",
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
issuerName: "Pryme Financial",
documentTitle: "Core banking migration notice",
recipientName: "Customer segment"
})
});res = requests.post(
"https://verifydoc.ai/api/developer/verification-links",
headers={"Authorization": f"Bearer {key}"},
json={
"issuerName": "Pryme Financial",
"documentTitle": "Core banking migration notice",
"recipientName": "Customer segment"
}
){
"ok": true,
"referenceCode": "VD-D9C-HDP",
"verificationUrl": "https://verifydoc.ai/v/<token>",
"qrCodeDataUrl": "data:image/png;base64,...",
"documentSummary": {
"title": "Core banking migration notice",
"issuer": "Pryme Financial",
"recipient": "Customer segment",
"documentId": "26041210302512345678"
}
}Add teammates from an external system
Provision workspace teammates from your HRIS or admin system. Seat limits are enforced at the API edge, and VerifyDoc.ai sends the invite email.
Body parameters
| Field | Type | Description | |
|---|---|---|---|
fullName | string | required | Teammate’s full name. |
email | string | required | Email that receives the workspace invite. |
department | string | optional | Department label for organisation. |
curl -X POST "https://verifydoc.ai/api/developer/team-members" \
-H "Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"fullName": "Ada Okonkwo",
"email": "ada@example.com",
"department": "Operations"
}'await fetch("https://verifydoc.ai/api/developer/team-members", {
method: "POST",
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
body: JSON.stringify({ fullName: "Ada Okonkwo", email: "ada@example.com" })
});requests.post(
"https://verifydoc.ai/api/developer/team-members",
headers={"Authorization": f"Bearer {key}"},
json={"fullName": "Ada Okonkwo", "email": "ada@example.com"}
){
"ok": true,
"member": {
"id": "member:0fd13...",
"fullName": "Ada Okonkwo",
"email": "ada@example.com",
"department": "Operations",
"membership": "Member"
}
}Create a managed verification workflow with signing
Register signers, page assignments, and invite delivery while still returning the hosted verification URL and QR in the same call.
Body parameters
| Field | Type | Description | |
|---|---|---|---|
issuerName | string | required | Issuer shown on the workflow. |
documentTitle | string | required | Title of the document to be signed. |
signers | array | required | Ordered list of signer objects (see below). |
recipientName | string | optional | Recipient label for the record. |
issuedAt | string (ISO 8601) | optional | Issue timestamp; defaults to now. |
Signer object
| Field | Type | Description | |
|---|---|---|---|
fullName | string | required | Signer’s name. |
email | string | required | Where the signing invite is sent. |
pages | number[] | optional | Pages assigned to this signer. |
color | string (hex) | optional | Highlight colour for the signer’s fields. |
curl -X POST "https://verifydoc.ai/api/verifications" \
-H "Authorization: Bearer vd_live_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"issuerName": "Pryme Financial",
"recipientName": "Treasury counterparty",
"documentTitle": "Facility confirmation letter",
"issuedAt": "2026-04-12T10:30:25.000Z",
"signers": [
{ "fullName": "Legal reviewer", "email": "legal@example.com", "pages": [1, 2], "color": "#0f766e" },
{ "fullName": "Treasury approver", "email": "treasury@example.com", "pages": [2] }
]
}'await fetch("https://verifydoc.ai/api/verifications", {
method: "POST",
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
body: JSON.stringify({
issuerName: "Pryme Financial",
documentTitle: "Facility confirmation letter",
signers: [{ fullName: "Legal reviewer", email: "legal@example.com", pages: [1, 2] }]
})
});requests.post(
"https://verifydoc.ai/api/verifications",
headers={"Authorization": f"Bearer {key}"},
json={
"issuerName": "Pryme Financial",
"documentTitle": "Facility confirmation letter",
"signers": [{"fullName": "Legal reviewer", "email": "legal@example.com", "pages": [1, 2]}]
}
){
"ok": true,
"workflowId": "signature:loan-offer-april",
"verificationId": "envelope:c0a80154-7f66-45a3-8dfa-508f2337f2c1",
"referenceCode": "VD-FR6-MQA",
"verificationUrl": "https://verifydoc.ai/v/<token>",
"qrCodeDataUrl": "data:image/png;base64,...",
"signers": [
{
"id": "signer:01",
"fullName": "Legal reviewer",
"email": "legal@example.com",
"pages": [1, 2],
"status": "sent"
}
]
}Everything needed to stamp & track a record
- Use the returned qrCodeDataUrl directly in HTML, PDF, image, or document pipelines.
- Pair the QR with verificationUrl and referenceCode as a visible fallback lookup.
- Issued records remain visible in the workspace dashboard, analytics, and audit surfaces.
- Key usage updates automatically through the API key ledger in Settings.
Production checklist
- Use one production key per service or environment so revocation stays surgical.
- Validate with /api/developer/me before issuing live records.
- Store keys in a secrets manager — plaintext is shown only once.
- Send an Idempotency-Key on every issuance call.
- Implement retry-with-backoff on 429 and 5xx.
- Use teammate provisioning only where your upstream system is the source of truth.
Versioning & stability
The current surface is v1. We add fields and endpoints in a backwards-compatible way; your integration should ignore unknown response fields rather than fail on them. Breaking changes, if ever required, will be introduced under a new version with advance notice to workspace admins.
Need an implementation review?
For rollout questions, API design help, higher rate limits, or an implementation review, contact hello@verifydoc.ai. Manage keys anytime in Settings → API.
↑ Back to top