Overview
The VerifyGuard Developer API is a server-to-server REST API. All requests and responses are JSON, sent over HTTPS. Every endpoint is scoped to the organization that owns the API key — you can only read and write your own products and codes.
The base URL for all endpoints is:
https://verifyguardafrica.com/api/v1We protect your brand intelligence: verification returns a clear verdict and an opaque risk band only. Internal risk scores, device fingerprints, and the detection logic are never exposed over the API.
Authentication
Authenticate every request with a secret API key in the Authorization header using the Bearer scheme. Keys look like vg_live_….
Authorization: Bearer vg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxCreate and revoke keys in Dashboard → Settings → Developer API. The full secret is shown only once at creation — store it securely (we keep only a hash and can never show it again). Treat it like a password: never embed it in client-side code, mobile apps, or public repositories. If a key leaks, revoke it and mint a new one.
Access & approval
The API is available to approved organizations. Register an account, get approved, and top up a credit balance before generating codes. Requests from an organization that is not yet approved are rejected with 403 org_not_approved.
Scopes
Each key carries one or more scopes. Grant a key only the scopes it needs (least privilege). A request using a scope the key lacks returns 403 insufficient_scope.
| Scope | Grants |
|---|---|
generate | Generate batches of codes (billable). |
verify | Verify a token's authenticity. |
read | Read credit balance and usage. |
manage | Reserved for upcoming product-management endpoints. |
Credits & billing
Billing is prepaid and pay-as-you-go. 1 credit = 1 generated code. Generating a batch of N codes deducts N credits in the same atomic transaction that creates the batch — so a failed request never charges you, and a partially generated batch is automatically refunded.
- Verification (
/verify) and usage (/usage) calls are free. - If your balance is lower than the requested quantity, the call fails with
402 insufficient_creditsand nothing is minted or charged. - Check your balance any time with GET /usage or in the dashboard.
Need more credits? Contact info@verifyguardafrica.com to top up your balance.
Rate limits
Each API key is limited to 60 requests per minute. Exceeding it returns 429 rate_limited with a Retry-After header (seconds) indicating when to retry. Generate large volumes in batches rather than many small calls.
Idempotency
POST /batches is the only billable, state-changing call, so it supports idempotency. Send a unique Idempotency-Key header (e.g. a UUID) with each generate request. If a network error makes you retry, the same key replays the original response instead of minting and charging a second time.
- Replays include an
Idempotent-Replay: trueresponse header. - If the original request is still in flight, the retry returns
409 request_in_progress— wait and retry. - Use a fresh key for every distinct batch you intend to create.
Errors
Errors use standard HTTP status codes and a consistent JSON body with a machine-readable code and a human-readable message.
{
"error": {
"code": "insufficient_credits",
"message": "Insufficient credits: balance 12, required 500. Top up to continue."
}
}| Status | code | Meaning |
|---|---|---|
| 400 | invalid_body | Body was not valid JSON. |
| 400 | invalid_request | A field failed validation. |
| 400 | missing_token | No token supplied to /verify. |
| 401 | unauthorized | Missing or invalid API key. |
| 403 | org_not_approved | Your organization is not approved yet. |
| 403 | insufficient_scope | Key lacks the required scope. |
| 402 | insufficient_credits | Balance too low; nothing charged. |
| 404 | product_not_found | No such product in your org. |
| 409 | request_in_progress | Same Idempotency-Key still processing. |
| 429 | rate_limited | Too many requests; see Retry-After. |
| 500 | generation_failed | Generation failed; credits refunded. |
Generate codes
/api/v1/batchesscope: generateMints a batch of signed QR codes for one of your products and deducts quantity credits. Smaller batches return the codes inline (201); large batches generate asynchronously (202) — detect this via async: true in the response.
curl -X POST https://verifyguardafrica.com/api/v1/batches \
-H "Authorization: Bearer vg_live_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f9619ff-8b86-d011-b42d-00cf4fc964ff" \
-d '{
"productId": "clt0prod123",
"quantity": 500,
"prefix": "EXP24",
"expectedRegion": "Kenya"
}'Response · 201 Created
{
"batchId": "clt0batch456",
"generated": 500,
"charged": 500,
"codes": [
{
"serial": "EXP24-000001",
"token": "Xa9…opaque…token",
"verifyUrl": "https://verifyguardafrica.com/v/Xa9…opaque…token"
}
]
}Response · 202 Accepted (large batches)
{
"batchId": "clt0batch789",
"queued": 20000,
"charged": 20000,
"async": true
}Verify a token
/api/v1/verifyscope: verifyChecks a token's cryptographic signature and current state without recording a consumer scan. An unknown, tampered, or out-of-scope token returns status: counterfeit with HTTP 200 (it is a valid verdict, not an error).
curl -X POST https://verifyguardafrica.com/api/v1/verify \
-H "Authorization: Bearer vg_live_…" \
-H "Content-Type: application/json" \
-d '{ "token": "Xa9…opaque…token" }'Response · 200 OK (genuine)
{
"valid": true,
"status": "genuine",
"token": "Xa9…opaque…token",
"product": "Premium Cooking Oil 5L",
"org": "Acme Foods Ltd",
"serial": "EXP24-000001",
"qrStatus": "ACTIVE",
"scanCount": 3,
"firstScannedAt": "2026-05-02T10:14:00.000Z",
"riskLevel": "green"
}Response · 200 OK (counterfeit)
{
"valid": false,
"status": "counterfeit",
"token": "not-a-real-token"
}Usage & balance
/api/v1/usagescope: readReturns your remaining credit balance and codes generated so far this calendar month (UTC).
curl https://verifyguardafrica.com/api/v1/usage \
-H "Authorization: Bearer vg_live_…"Response · 200 OK
{
"creditBalance": 14500,
"period": { "since": "2026-06-01T00:00:00.000Z" },
"usage": { "codesGenerated": 5500 }
}Versioning & support
The API is versioned in the path (/api/v1). We add new endpoints and optional fields without bumping the version; breaking changes ship under a new version with advance notice.
Import the full OpenAPI 3.1 spec into Postman or Insomnia, or use it to generate a client SDK. Questions? Email info@verifyguardafrica.com.