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.