Platform · API

One endpoint. One decision.

If the order already passes through a pipeline you run, skip the interface. POST the order, read the score, the factors, the reasoning, and the recommendation off the response.

POST/api/{org}/order-verification
curl -X POST \
  https://verify-ai.tdcapps.com/api/your_org_slug/order-verification \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "1042",
    "orderAmount": 2480,
    "currency": "USD",
    "customerName": "D. Whitfield",
    "customerEmail": "d.whitfield@example.com",
    "isFirstTimeCustomer": true,
    "shippingAddress": { "street": "8400 NW 25th St", "city": "Miami",
      "state": "FL", "postalCode": "33122", "country": "United States" },
    "billingAddress": { "street": "14 Elm Row", "city": "Leeds",
      "state": "West Yorkshire", "postalCode": "LS8 2AA",
      "country": "United Kingdom" },
    "ipAddress": "203.0.113.24"
  }'
200 OK
{
  "success": true,
  "data": {
    "riskScore": 78,
    "riskLevel": "high",
    "riskFactors": [
      {
        "factor": "Shipping address is a freight forwarder",
        "severity": "high",
        "category": "address",
        "description": "8400 NW 25th St is a package consolidation
          and reshipping facility, not a residence."
      }
    ],
    "reasoning": "A first order at nine times the category average…",
    "recommendations": ["Verify identity before fulfilment"]
  }
}
Surface

What is exposed

Deliberately small. There is one thing to ask and one answer to read, and an API that grew past that would be growth for its own sake.

Organizations
GET the organizations a key can reach, so a client can resolve its own slug rather than having one hardcoded.
Order verification
POST an order, receive a score, the risk factors, the reasoning, and the recommendations. Synchronous: the response is the result.
Authentication
An API key on every request, as either an x-api-key header or an Authorization bearer token. Both are accepted; pick one and be consistent.
Rate limits
Configurable per key, with limit, remaining, and reset returned as response headers so a client can back off before it gets a 429 rather than after.
Wiring it up

Branch on the band, read the factors

Most integrations are this: three cases, and the factor list passed through to whoever reviews the order.

verify-order.ts
const res = await fetch(endpoint, { method: 'POST', headers, body })
const result = await res.json()

if (!result.success) throw new Error(result.message)

switch (result.data.riskLevel) {
  case 'critical':
    return { action: 'reject' }
  case 'high':
  case 'medium':
    return { action: 'review', factors: result.data.riskFactors }
  default:
    return { action: 'approve' }
}

Branch on riskLevel rather than on riskScore. The bands are fixed, so a rule written against them keeps meaning what you meant, while a hardcoded threshold of 65 is a decision you will have forgotten in a year.

Conventions

What to expect

Keys, not sessions

Scoped to an organization, with a configurable rate limit and usage tracked per key. Rotate without touching anyone’s login.

Synchronous by design

The analysis takes 15 to 30 seconds and the response carries the result. No job ID, no polling, no webhook to register and secure.

Predictable envelopes

A consistent success and error shape, and standard status codes. Check success before reading data.

Rate headers on every response

Limit, remaining, and reset, so a client can slow down before it gets a 429 rather than after.

Costs still metered

Verifications started with a key consume the same credits and respect the same balance. Nothing runs that the organization cannot pay for.

Same log, same record

A verification run from a key writes the same row to the organization’s log as one run from the dashboard.
API

Developer questions

How do we authenticate?
An API key, sent as either an x-api-key header or an Authorization bearer token. Keys are scoped to an organization, carry their own rate limit, and are individually revocable, so rotating one does not touch anybody’s login.
Is it synchronous?
Yes. The POST returns the finished assessment rather than a job ID, so there is nothing to poll and no webhook to register. Budget 15 to 30 seconds for the request, and call it from a queue or a background job rather than from a request the customer is waiting on.
Where should we call it from?
After the order is created, not during checkout. Blocking a buyer for 30 seconds to run a fraud check costs more in abandoned carts than the fraud does, and there is nothing about the analysis that needs to happen before the order exists.
What are the rate limits?
Configurable per key, defaulting to 1,000 requests a minute. Limit, remaining, and reset come back as headers on every response. A 429 means that key hit its own ceiling rather than the platform hitting one.
Is there an SDK?
Not yet. It is one endpoint with a JSON body, so a typed client is a short file rather than a dependency. If an official SDK would change your decision, tell sales, because that is how the roadmap gets ordered.
What does a failed verification cost?
A validation error costs nothing, because no analysis runs. An analysis that runs and then fails downstream still consumed the tokens, and the credit ledger shows it.

Create a key and POST one order.

The free credits cover a real integration test rather than a hello-world. Start there and decide.

5 credits on signup · no card required