Docs

API reference / Account

Evaluate Automation Policies

POST/v1/policies/evaluate

API key requiredSupports Idempotency-Key

Evaluates your project’s automation rules for an operation (limits, blocked countries, maturation delay…) and returns the decision (allow, review or block), the rules that matched and any effects (conversion, sweep). The decision is logged in the Hub. Nothing is executed: your application must apply the decision. When user_id is provided, daily/monthly totals and the date of the last deposit are read from the user’s history. Accepts Idempotency-Key.

Authentication#

Send a secret API key as Authorization: Bearer <key>. Both tp_test_… and tp_live_… keys work; the key decides which environment you read and write. See Authentication.

Parameters#

Headers

Header parameters
NameTypeDescription
Idempotency-KeystringIdempotency key (1 to 255 characters, UUID v4 recommended). Responses are replayed for 24 h.

See Idempotency.

Request body#

  • user_idstring

    User concerned (from your project and the key’s environment).

    pattern: ^\d{1,9}$

    Example "4821"

  • operationstringrequired

    Operation being considered.

    One ofdepositwithdrawalpaymenttransfer

    Example "withdrawal"

  • amountnumberrequired

    Amount in the given currency.

    max: 1000000000000 · > 0

    Example 250

  • currencystringrequired

    Currency (EUR, USD… or USDC).

    max length: 4

    Example "USD"

  • countrystring

    Country of the user or of the counterparty (ISO 3166-1 alpha-2).

    pattern: ^[A-Za-z]{2}$

    Example "FR"

  • balance_usdnumber

    USDC balance of the user after the operation (sweep rules).

    min: 0

    Example 1200

Example request body
{
  "user_id": "4821",
  "operation": "withdrawal",
  "amount": 250,
  "currency": "USD",
  "country": "FR"
}

Responses#

200Decision.

Headers

  • X-Request-Id Request identifier.
  • X-RateLimit-Limit Quota of the current window.
  • X-RateLimit-Remaining Requests remaining in the window.
  • X-RateLimit-Reset Seconds before the quota renews.

Body

  • decisionstringrequired

    Decision.

    One ofallowreviewblock

    Example "allow"

  • matched_rulesarray of objectrequired

    Rules that matched, in evaluation order.

    • rule_idstringrequired

      Rule identifier.

    • typestringrequired

      Rule type.

    • actionstringrequired

      Action of the rule.

      One ofblockreview

    • reasonstringrequired

      Human-readable explanation (English).

  • effectsarray of objectrequired

    Effects your application must apply (none when block).

    • rule_idstringrequired

      Rule that produced the effect.

    • typestringrequired

      Effect type.

      One ofconvert_to_usdcsweep_to_company_account

    • detailsobjectrequired

      Details of the effect.

Example 200 response
{
  "decision": "allow",
  "matched_rules": [
    {
      "rule_id": "string",
      "type": "string",
      "action": "block",
      "reason": "string"
    }
  ],
  "effects": [
    {
      "rule_id": "string",
      "type": "convert_to_usdc",
      "details": {}
    }
  ]
}
400Invalid request (malformed JSON, unknown cursor, invalid Idempotency-Key header).

Example: invalid_cursor

Example 400 response
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_cursor",
    "message": "starting_after: unknown cursor",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
401Missing, invalid or revoked API key.

Example: missing_api_key

Example 401 response
{
  "error": {
    "type": "authentication_error",
    "code": "missing_api_key",
    "message": "Provide your API key as \"Authorization: Bearer <key>\"",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}

Example: invalid_api_key

Example 401 response
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The API key is invalid",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}

Example: api_key_revoked

Example 401 response
{
  "error": {
    "type": "authentication_error",
    "code": "api_key_revoked",
    "message": "This API key has been revoked",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
403Organization suspended, live access not enabled, or sandbox-only route.

Example: organization_suspended

Example 403 response
{
  "error": {
    "type": "permission_error",
    "code": "organization_suspended",
    "message": "Your organization is suspended. Contact Tilt Pay support.",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}

Example: live_not_enabled

Example 403 response
{
  "error": {
    "type": "permission_error",
    "code": "live_not_enabled",
    "message": "Live access has not been enabled for your organization yet",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}

Example: sandbox_only

Example 403 response
{
  "error": {
    "type": "permission_error",
    "code": "sandbox_only",
    "message": "This route is only available with a sandbox API key",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
404Resource not found (or belonging to another project or environment).

Example: user_not_found

Example 404 response
{
  "error": {
    "type": "invalid_request_error",
    "code": "user_not_found",
    "message": "User not found",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
409Conflict with the state of the resource, or the original idempotent request is still in progress.

Example: user_already_exists

Example 409 response
{
  "error": {
    "type": "invalid_request_error",
    "code": "user_already_exists",
    "message": "A user with this phone number already exists",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
422Invalid parameter, or Idempotency-Key reused with a different body.

Example: validation_error

Example 422 response
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_error",
    "message": "phone: has an invalid format",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}

Example: idempotency_key_reuse

Example 422 response
{
  "error": {
    "type": "idempotency_error",
    "code": "idempotency_key_reuse",
    "message": "This Idempotency-Key was already used with a different request",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
429Rate limit exceeded. Retry after the Retry-After delay (seconds).

Example: rate_limit_exceeded

Example 429 response
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Slow down and retry after the delay in Retry-After.",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}
500Internal error. Retry; give request_id to support if it persists.

Example: internal_error

Example 500 response
{
  "error": {
    "type": "api_error",
    "code": "internal_error",
    "message": "Internal server error",
    "request_id": "0b2c8f6e-41f9-4c0a-8d55-6f6a3c1d9e21"
  }
}

Headers on every response

  • X-Request-Id Identifier of the request, also present in error bodies. Give it to support.
  • X-API-Version Version of the API that answered.
  • X-RateLimit-Limit / -Remaining / -Reset Quota of your key for the current window. See Rate limits.

Errors#

Errors share one format, described in Errors. Branch your code on error.code.

Errors this route can return
StatusCodeMeaning
400invalid_cursorInvalid request (malformed JSON, unknown cursor, invalid Idempotency-Key header).
401missing_api_keyMissing, invalid or revoked API key.
401invalid_api_keyMissing, invalid or revoked API key.
401api_key_revokedMissing, invalid or revoked API key.
403organization_suspendedOrganization suspended, live access not enabled, or sandbox-only route.
403live_not_enabledOrganization suspended, live access not enabled, or sandbox-only route.
403sandbox_onlyOrganization suspended, live access not enabled, or sandbox-only route.
404user_not_foundUnknown user (or belonging to another project or environment).
409user_already_existsConflict with the state of the resource, or the original idempotent request is still in progress.
422validation_errorUnsupported currency or operation.
422idempotency_key_reuseInvalid parameter, or Idempotency-Key reused with a different body.
429rate_limit_exceededRate limit exceeded. Retry after the Retry-After delay (seconds).
500internal_errorInternal error. Retry; give request_id to support if it persists.