Docs menu
API reference

POST /api/v1/siteverify

Redeem a check token. The browser script and the backend token check. Generated from the OpenAPI file.

Last updated

Overview

POST https://api.inlineshield.io/api/v1/siteverify

Your backend sends the token that inlineshield.js put in the form, with the email the player submitted, and gets the decision recorded by /check. A token works once, for 10 minutes, for the same email (compared without case or surrounding spaces), and only with a secret key of the same account.

Token problems are answered with HTTP 200 and success: false. QUOTA_EXCEEDED means the token is missing because the account is over its quota (/check issued none). Nothing here counts against the quota.

Limited per API key to the key's own per-minute limit (1,200 for a live key, 300 for a test key, as created).

Authentication

Send your secret API key in the X-Api-Key header.

Your secret API key (bs_live_… or bs_test_…), from the console under Settings › Keys. Never put it in a browser or an app. The header name X-ApiKey is also accepted (deprecated).

Request body

JSON (Content-Type: application/json), required.

FieldTypeRequiredDescription
tokenstringnoThe token from /check (inlineshield.js puts it in the form).
emailstringyesThe email the player submitted. Must be the one that was checked.at least 1 character

Request examples

{
  "token": "bst_q3Jm0b8vN2kXo7rT5wYz1cE4hL6pA9sD0fG2jK8uV3i",
  "email": "allow@test.inlineshield.io"
}

The first example as a cURL command:

cURL
curl -X POST https://api.inlineshield.io/api/v1/siteverify \
  -H "X-Api-Key: $INLINESHIELD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "token": "bst_q3Jm0b8vN2kXo7rT5wYz1cE4hL6pA9sD0fG2jK8uV3i",
  "email": "allow@test.inlineshield.io"
}'

Responses

200 OK

success: true with the decision (a live hold also has reviewId), or success: false with the reason.

Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

One of 2 shapes:

SiteverifySuccess

FieldTypeRequiredDescription
successtrueyes
decisionstringyesALLOWED: let the player in. QUARANTINED: hold for review. BLOCKED: refuse.Values: ALLOWED, QUARANTINED, BLOCKED
riskScorenumberyes0 (lowest risk) to 100.0 to 100
reasonsarray of stringyesPlain-language reasons for the result.
requestIdstringyesThe screening's id. Use it for feedback and support.matches ^AUD-
actionstringyesWhat to do with the sign-up: ALLOWED → allow, QUARANTINED → hold, BLOCKED → block.Values: allow, hold, block
recommendedActionstringyesAdvice next to action: allow, allow without a sign-up bonus, review, block, or ask for KYC before paying out.Values: allow, allow_no_bonus, review, block, require_kyc
reviewIdstringnoLive holds only.matches ^rev_

SiteverifyFailure

FieldTypeRequiredDescription
successfalseyes
errorstringyesNO_TOKEN: no token was sent. INVALID_TOKEN: not a token of this account. EXPIRED_TOKEN: older than 10 minutes. TOKEN_ALREADY_USED: redeemed before. EMAIL_MISMATCH: issued for another email. QUOTA_EXCEEDED: no token was sent and the account is over its quota.Values: NO_TOKEN, INVALID_TOKEN, EXPIRED_TOKEN, TOKEN_ALREADY_USED, EMAIL_MISMATCH, QUOTA_EXCEEDED
{
  "success": true,
  "decision": "ALLOWED",
  "riskScore": 0,
  "reasons": [
    "Test mode: allow@test.inlineshield.io always gives ALLOWED / allow."
  ],
  "requestId": "AUD-MHH3K2QZ-4F1C9B2E7D10",
  "action": "allow",
  "recommendedAction": "allow"
}

400 Bad Request

No email, or (without the rate-limit headers) a body that is not valid JSON.

Headers: X-RateLimit-Limit (optional), X-RateLimit-Remaining (optional), X-RateLimit-Reset (optional).

FieldTypeRequiredDescription
errorstringyesValues: BAD_REQUEST
messagestringyes

401 Unauthorized

No X-Api-Key header, or an unknown, revoked or expired key.

FieldTypeRequiredDescription
errorstringyesValues: UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY, ORGANIZATION_NOT_FOUND
messagestringyes
{
  "error": "UNAUTHORIZED",
  "message": "Access denied: Missing required X-Api-Key header."
}

403 Forbidden

The account is suspended.

FieldTypeRequiredDescription
errorstringyesValues: TENANT_SUSPENDED
messagestringyes

429 Too Many Requests

The per-minute limit of this key.

Headers: Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

FieldTypeRequiredDescription
errorstringyesValues: RATE_LIMIT_EXCEEDED
messagestringyes
rateLimit
{
  "error": "RATE_LIMIT_EXCEEDED",
  "message": "Siteverify rate limit of 1200 req/min exceeded. Try again in 12 seconds."
}

500 Internal Server Error

Internal error.

FieldTypeRequiredDescription
errorstringyesValues: VERIFICATION_ERROR, AUTH_ERROR
messagestringyes

503 Service Unavailable

The key could not be checked right now. Try again.

FieldTypeRequiredDescription
errorstringyesValues: DATABASE_ERROR
messagestringyes

Errors

Errors are JSON, { "error": "CODE", "message": "…" }. Branch on error, never on message.

HTTP statuserrorWhen
400BAD_REQUESTNo email, or (without the rate-limit headers) a body that is not valid JSON.
401UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY, ORGANIZATION_NOT_FOUNDNo X-Api-Key header, or an unknown, revoked or expired key.
403TENANT_SUSPENDEDThe account is suspended.
429RATE_LIMIT_EXCEEDEDThe per-minute limit of this key.
500VERIFICATION_ERROR, AUTH_ERRORInternal error.
503DATABASE_ERRORThe key could not be checked right now. Try again.

See all errors for every endpoint.

Headers and limits

Response headerMeaning
X-RateLimit-LimitRequests allowed in the current one-minute window.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetSeconds until the current window ends.
Retry-AfterSeconds to wait before trying again.

The limits per endpoint and plan are on Rate limits and quotas.