Developers

The Verdikt API

A single REST endpoint returns a complete fraud decision in under 50ms. Send what you know about an order; get back a verdict, a calibrated risk score and the reasons behind it. Production base URL: https://verdiktt.com/api/v1

Introduction

The Verdikt API is organised around REST. It has predictable, resource-oriented URLs, accepts JSON request bodies, returns JSON responses, and uses standard HTTP verbs and status codes. Every request is scored in real time by our AI decisioning engine: a transaction foundation model, a graph network and risk models running in parallel.

This documentation is live. Every example below runs against a real sandbox served from this environment at /api/v1. Jump to the playground to send a real request and inspect the response.

Authentication

Authenticate with your secret API key in the Authorization header as a bearer token. Keys are environment-scoped: test keys are prefixed vk_test_ and live keys vk_live_. Live keys are billable and eligible for the chargeback guarantee; test keys always run in sandbox. Never expose a live secret key in client-side code.

EnvironmentKey prefixBehaviour
Sandboxvk_test_Deterministic scoring, no billing, no guarantee.
Productionvk_live_Full model, billed per decision, guarantee-eligible.

Sandbox scoring is deterministic. Use the reserved emails approve@verdikt.test, review@verdikt.test and decline@verdikt.test to force each verdict while integrating.

Making requests

All requests must be made over HTTPS and send a JSON body with Content-Type: application/json. The API recognises these headers:

HeaderPurpose
Authorization requiredBearer token with your secret API key.
Content-Type requiredMust be application/json for write calls.
Idempotency-KeySafely retry a decision without scoring it twice.

Every response includes X-Request-Id, X-RateLimit-Limit and X-RateLimit-Remaining headers.

Idempotency

To safely retry requests without accidentally scoring the same order twice, pass a unique Idempotency-Key header (your order_id is a good choice). The first request is processed and the result stored against the key; subsequent requests with the same key return the original decision without re-scoring. Keys are retained for 24 hours.

The Decision object

A decision represents a single risk evaluation. These are the fields it returns:

FieldTypeDescription
idstringUnique identifier, prefixed dec_.
verdictstringOne of approve, review, decline.
scorenumberCalibrated fraud probability from 0.00 to 1.00.
guaranteedbooleanWhether the order is covered by the chargeback guarantee.
reasonsarrayHuman-readable signal codes driving the verdict.
latency_msnumberServer-side decisioning time in milliseconds.
livemodebooleantrue for live keys, false in sandbox.
creatednumberUnix timestamp of creation.

Create a decision

POST/v1/decisions

Submit a transaction and receive a real-time verdict. Request body fields:

FieldTypeDescription
order_id requiredstringYour unique identifier for the order.
amount requirednumberOrder total in major units (e.g. 249.00).
currency requiredstringISO 4217 currency code, e.g. USD.
customer requiredobjectemail, ip, device_id, phone.
product_typestringdigital_goods, marketplace, physical, subscription.
paymentobjectTokenised instrument: bin, last4, method.
sessionobjectBehavioural signals from the Verdikt.js browser SDK.
metadataobjectAny key-value pairs echoed back on webhooks.

Request

curl https://verdiktt.com/api/v1/decisions \
  -H "Authorization: Bearer vk_live_4f9c20a1d8e3" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ord_8842" \
  -d '{
    "order_id": "ord_8842",
    "amount": 249.00,
    "currency": "USD",
    "product_type": "physical",
    "customer": {
      "email": "buyer@example.com",
      "ip": "81.2.69.142",
      "device_id": "dvc_a91f"
    }
  }'

Response

200 OK · application/json
{
  "id": "dec_9f3a21c7c4e0",
  "object": "decision",
  "created": 1781827200,
  "livemode": true,
  "order_id": "ord_8842",
  "amount": 249.0,
  "currency": "USD",
  "product_type": "physical",
  "verdict": "approve",
  "score": 0.07,
  "guaranteed": true,
  "reasons": [
    "email_reputation_ok",
    "established_device",
    "shipping_billing_match",
    "graph_no_fraud_link"
  ],
  "latency_ms": 43
}

Retrieve a decision

GET/v1/decisions/{id}

Fetch a previously created decision by its id.

curl https://verdiktt.com/api/v1/decisions/dec_9f3a21c7c4e0 \
  -H "Authorization: Bearer vk_live_4f9c20a1d8e3"

List decisions

GET/v1/decisions

Returns a list of decisions, most recent first. Accepts an optional limit query parameter (default 10, max 100).

curl "https://verdiktt.com/api/v1/decisions?limit=10" \
  -H "Authorization: Bearer vk_live_4f9c20a1d8e3"

Response

200 OK · application/json
{
  "object": "list",
  "url": "/v1/decisions",
  "has_more": false,
  "data": [
    { "id": "dec_9f3a21c7c4e0", "verdict": "approve", "score": 0.07, "...": "..." },
    { "id": "dec_61b0a4e2f199", "verdict": "review",  "score": 0.54, "...": "..." }
  ]
}

Live playground

Send a real request to the sandbox engine running in this environment. Edit the body or pick a preset, then send. Try the reserved test emails to force each verdict, or a disposable-email domain to watch the score climb.

POST /api/v1/decisions
// Click “Send request” to score this transaction
// against the live sandbox engine.

Verdicts & scores

The score is a calibrated fraud probability. The verdict applies your configured thresholds (defaults shown):

VerdictDefault rangeSuggested action
approvescore < 0.35Fulfil immediately. Guarantee-eligible.
review0.35 to 0.70Hold for manual review or step-up auth.
declinescore ≥ 0.70Block the order.

Errors

Verdikt uses conventional HTTP status codes and returns a machine-readable error object.

StatusMeaning
200Decision returned successfully.
400Invalid or missing request parameters.
401Missing or invalid API key.
404Resource not found.
429Rate limit exceeded; back off and retry.
503Decisioning temporarily unavailable.
400 Bad Request
{
  "error": {
    "type": "invalid_request_error",
    "message": "customer.email is required.",
    "fields": ["customer.email is required."]
  }
}

Rate limits

Production accounts are limited to 1,000 req/s by default, burstable on request. When you exceed the limit the API returns 429. Inspect X-RateLimit-Remaining and implement exponential backoff. Decisioning calls are designed to fail fast, so a safe default is to fail open (approve) or closed (review) per your risk appetite if a call times out.

Webhooks

Verdikt sends signed webhook events when an asynchronous outcome occurs: a held order resolves, a guarantee is confirmed, or a chargeback is reported by the network. Verify the Verdikt-Signature header against your endpoint secret.

EventFires when
decision.updatedA review order is resolved.
guarantee.confirmedAn approved order is covered by the guarantee.
chargeback.receivedThe network reports a chargeback.
chargeback.reimbursedA guaranteed loss is reimbursed to you.
POST https://your-app.com/webhooks/verdikt
{
  "id": "evt_2c8f10a4",
  "type": "chargeback.received",
  "created": 1781913600,
  "data": {
    "decision_id": "dec_9f3a21c7c4e0",
    "order_id": "ord_8842",
    "amount": 249.0,
    "currency": "USD",
    "reason_code": "10.4",
    "guaranteed": true
  }
}

Libraries

Official, typed SDKs wrap the REST API for every major stack:

LanguageInstall
Node / TypeScriptnpm install @verdikt/node
Pythonpip install verdikt
Rubygem install verdikt
Gogo get github.com/verdikt/verdikt-go
PHPcomposer require verdikt/verdikt-php
Get your API keys