ROOKDocs
5 min readUpdated August 2026

Real-Time Authorization Engine

Decide card authorizations with program rules, then optionally take the final approve-or-decline call on an HTTPS endpoint you host.

Rules run on every authorization before the network response is sent. Authorization Stream is a callback Rook POSTs to your responder during that same window. Use rules for declarative policy. Use the stream when the decision depends on balances, risk systems, or other state you hold.

Authorization rules

Create a rule with POST /v1/authorization-rules. Every rule has a name, a scope, a type, and parameters discriminated on type.

scope is one of:

type Applies to
PROGRAM Every authorization on the program.
WALLET Authorizations on wallet_ids.
CARD Authorizations on card_ids.

state ACTIVE evaluates the current version. INACTIVE stores the rule and skips it. A draft version is never applied to live traffic.

Types and parameters

parameters is a oneOf discriminated on type. The rule-level type must match parameters.type.

type When it fires Effect
CONDITIONAL_BLOCK Every conditions[] item matches Decline
VELOCITY_LIMIT Spend or count in velocity.period would exceed the cap Decline
MERCHANT_LOCK Merchant is not on merchant_lock.merchants Decline
CONDITIONAL_ACTION Every conditions[] item matches action: DECLINE or CHALLENGE

Conditions are AND-combined. Each item has attribute, operation, and value.

operation value
IS_ONE_OF / IS_NOT_ONE_OF String array
MATCHES / DOES_NOT_MATCH Regex string
IS_GREATER_THAN / IS_LESS_THAN Integer. TRANSACTION_AMOUNT (the card authorization amount) is minor units, never a float

Attributes include MCC, COUNTRY (ISO 3166-1 alpha-2), CURRENCY (ISO 4217), MERCHANT_ID, DESCRIPTOR, LIABILITY_SHIFT, PAN_ENTRY_MODE, TRANSACTION_AMOUNT, RISK_SCORE, and trailing CARD_TRANSACTION_COUNT_* windows.

Velocity period is a calendar window (DAY, WEEK, MONTH, YEAR in Eastern Time) or CUSTOM with duration_seconds. At least one of limit_amount or limit_count must be set. limit_amount uses integer minor units.

Merchant lock is an allow-list. An authorization matches an entry when every supplied field (merchant_id, descriptor) equals the request.

Draft, promote, versions

POST /v1/authorization-rules/{authorization_rule_id}/draft writes a proposed next version. Reports include shadow counts for that draft. POST .../promote makes the draft current. GET .../versions lists every version, newest first.

Reports, backtests, results, features

GET .../report?begin&end returns daily approved and declined counts for the current version and, when present, the draft. begin and end are UTC calendar days, inclusive.

POST .../backtests replays historical authorizations in [start, end] against the current and draft versions. Retrieve simulation results with GET .../backtests/{backtest_id}. While status is PENDING, results is null.

GET /v1/authorization-rules/results is the per-authorization (CARD transaction) evaluation log (authorization_rule_id, version, result).

GET /v1/authorization-rules/features returns trailing counts and spend for an wallet_id and/or card_id. These are the counters conditional and velocity rules read.

Authorization Stream

Enroll an HTTPS URL with POST /v1/responder-endpoints and type AUTH_STREAM. Rook POSTs an authorizationRequest callback to that URL on every authorization. Respond within 1500 milliseconds with:

{
  "object": "authorization_stream_decision",
  "result": "APPROVED",
  "decline_reason": null,
  "avs_result": "MATCH",
  "balance": { "amount": 125000, "currency": "USD" }
}

result is APPROVED, DECLINED, or PARTIAL_APPROVAL. When DECLINED, set decline_reason to a catalogue value (SUSPECTED_FRAUD, INSUFFICIENT_FUNDS, and the rest of the closed set). When PARTIAL_APPROVAL, set approved_amount to the amount you are approving in the program’s home currency — valid only when the request has partial_approval_capable true. avs_result and balance may be null when you do not override them.

The request body is a transaction snapshot (object is authorization_request): amounts in integer minor units, merchant, network risk score, POS entry mode, and AVS. It never includes PAN or CVV.

Timeout and fallback

If your endpoint does not return HTTP 200 with a valid decision body within 1500 milliseconds (including connection errors, TLS failures, 5xx, and malformed JSON), Rook declines the authorization with GENERIC_DECLINE. Prefer failing closed: keep the responder fast and reachable, and treat a timeout as a decline in your own logs.

Signature

Callbacks are signed with the same HMAC-SHA256 scheme as Event deliveries. Retrieve the secret with GET /v1/authorization-stream/secret. Use the entire whsec_... string as the key.

Header Value
Rook-Timestamp Unix time in seconds when the signature was computed.
Rook-Signature v1=<hex>. Multiple v1= values may be comma-separated during rotation.

Signed material is {timestamp}.{raw_body}. Reject a callback whose timestamp is more than 300 seconds from the current time. After POST /v1/authorization-stream/secret/rotate, the previous secret remains valid for 24 hours.

Getting Started → Webhook signing covers the same scheme.

Responder types

A program may enroll at most one endpoint per type:

type Callback
AUTH_STREAM authorizationRequest (this page)
TOKENIZATION_DECISIONING tokenizationRequest (Digital Wallets)

GET /v1/responder-endpoints lists enrollments. DELETE /v1/responder-endpoints/{responder_endpoint_id} stops callbacks of that type immediately.

Was this page helpful?