Truform Captcha

API reference

Truform HTTP endpoints on api.syndaq.com.

All Truform API endpoints are served from https://api.syndaq.com/v1/truform/. The widget loader and static assets are hosted at https://syndaq.com/truform/.

When you subscribe to a Truform plan, Syndaq creates a service in your client area. Each site key on that service has a public and secret key. Use the public key in your pages. Keep the secret on your server only.

An OpenAPI description is available at openapi.yaml.

Endpoints overview

MethodPathAuthPurpose
GET/v1/truform/challengePublic key (sitekey query)Fetch a new puzzle challenge
POST/v1/truform/managedPublic key (body)Managed verification with puzzle fallback
POST/v1/truform/verifyPublic key (body)Verify a puzzle solution in the browser
POST/v1/truform/siteverifySecret key (body)Server side token validation
GET/v1/truform/statusPublic or secret keyKey health and quota snapshot
GET/v1/truform/usageSecret keyUsage stats for the subscription

Browser routes answer OPTIONS preflight when the Origin host matches the site key domain allowlist.

Key prefixes

KeyPrefixUsed where
Publictf_pub_Browser widget (data-sitekey, challenge, verify, status)
Secrettf_sec_Server siteverify and usage only

Both keys are tied to your plan (rate limits and monthly quota). The API checks that the key exists and is active.

Security checks

Every authenticated request passes through the following checks when applicable:

CheckApplies toWhen enforced
Valid keyAll endpointsAlways
Domain allowlistchallenge, verify, managed, and successful siteverify hostnamePer site key domain configuration
IP allowlistAll endpointsOnly when IP restrictions are enabled for that site key
Rate limitAll endpointsPer site key (per minute)
Monthly quotaAll endpointsPer subscription (shared across all site keys on the service)
Single use tokensiteverifyEach response token works once

Domain and IP rules are configured per site key in the Syndaq client area. See Site keys and security.

Response headers

Successful and error responses may include:

HeaderDescription
X-Request-IdUnique ID for support and log correlation
X-RateLimit-LimitPlan requests per minute for this site key
X-RateLimit-RemainingRequests left in the current minute window
X-RateLimit-ResetUnix timestamp when the minute window resets
X-Quota-LimitMonthly quota for the subscription
X-Quota-RemainingRequests left this calendar month (UTC)
X-Quota-PeriodCurrent quota month (YYYY-MM)
Retry-AfterSeconds to wait after HTTP 429
Access-Control-Allow-OriginReflected origin when the browser Origin matches the site key allowlist

GET /v1/truform/challenge

Used by the widget loader to fetch a puzzle. The loader calls this automatically. You rarely need to invoke it directly.

Query parameters:

ParameterRequiredDescription
sitekeyYesYour tf_pub_ key
puzzle_typeNoPuzzle style or random
hostnameNoPage hostname (sent automatically by the widget)

The request must come from a browser context on an allowed domain for the site key.

POST /v1/truform/managed

Used by the widget in Managed mode. Evaluates browser telemetry and IP risk signals. Returns a response token when the visitor passes without a puzzle, or interactive_required when a puzzle is needed.

Requires Managed mode to be enabled on the site key in the client area and data-mode="managed" on the widget (or mode: 'managed' in truform.render). Existing Interactive embeds do not call this endpoint.

Request body (JSON):

{
  "sitekey": "tf_pub_your_public_key",
  "hostname": "example.com",
  "action": "login",
  "telemetry": {}
}

Success response includes proof (the token for siteverify), mode (managed), plus risk_score and risk_level.

When a puzzle is required, the API returns HTTP 422 with interactive_required: true. The widget then loads the standard challenge flow.

Counts toward your monthly verification quota the same way as verify.

POST /v1/truform/verify

Called by the widget after the user completes a puzzle. Returns a response token on success.

Request body (JSON):

{
  "sitekey": "tf_pub_your_public_key",
  "hostname": "example.com",
  "token": "…",
  "action": "login",
  "trace": [],
  "telemetry": {}
}

Optional action labels the verification (for example login or signup). The same value can be sent to siteverify and is echoed on success.

The widget sends hostname automatically. The page must be served from a domain allowed for the site key.

On success the response includes proof (the token for siteverify), plus risk_score (0 to 100, lower is safer) and risk_level (low, medium, or high).

POST /v1/truform/siteverify

Server side validation. See Server verification for examples. Send your tf_sec_ secret in the request body.

Recommended body fields:

FieldRequiredDescription
secretYesYour tf_sec_ key
responseYesValue from the truform-response field
remoteipNoEnd user IP (recommended)
actionNoMust match the action used at verify time when provided

If IP restrictions are enabled for the site key, the request must come from an allowed IPv4 or IPv6 address.

Each response token is valid for one successful siteverify call. Reuse returns HTTP 400 with token_already_used.

GET /v1/truform/status

Lightweight health check for monitoring or CI. Pass the public site key as sitekey.

Example response:

{
  "success": true,
  "status": "active",
  "product": "truform",
  "plan": "starter",
  "domains_configured": true,
  "domain_count": 2,
  "ip_restrictions": false,
  "rate_limit_per_minute": 60,
  "monthly_quota": 10000,
  "quota_remaining": 8420,
  "quota_period": "2026-05",
  "request_id": "…"
}

GET /v1/truform/usage

Returns usage for the subscription linked to the secret key (aggregated across all site keys on the service). Authenticate with the secret key in the JSON body, query string, or Authorization: Bearer tf_sec_… header.

Widget loader globals

The script at https://syndaq.com/truform/api.js configures these defaults internally:

SettingValue
API basehttps://api.syndaq.com
Challenge URL/v1/truform/challenge
Verify URL/v1/truform/verify
Response fieldtruform-response

Errors

Failed requests return JSON with success: false, error, error_code, and request_id.

HTTPerror_codeTypical cause
400token_already_usedResponse token was already consumed by siteverify
401missing_credentialsNo site key or secret provided
401invalid_api_keyUnknown or inactive key
401wrong_key_typePublic key used on siteverify or secret on browser endpoints
403domain_not_allowedPage hostname is not allowed for this site key
403domain_requiredBrowser request missing a valid page domain
403domain_not_configuredSite key has no domain allowlist configured
403ip_not_allowedCaller IP is not on the allowlist while IP restrictions are enabled
429rate_limit_exceededToo many requests per minute for the site key
429quota_exceededMonthly subscription quota exhausted
500server_errorTemporary API error — retry with backoff

Common operational causes:

  • Invalid or expired response token
  • Secret key mismatch on siteverify
  • Widget embedded on a domain that does not match the site key
  • siteverify blocked after enabling IP restrictions without adding your server egress IP

Always handle non 200 responses and failed verification gracefully in your application.

See Webhooks for quota alert notifications.