RailGuardDocs

Decision object

Schema + three examples. This is the product.

Request

FieldTypeNotes
amountnumberRequired. USD (the only currency today).
merchantstringRequired.
categorystringRequired, e.g. AI & Compute.
railstripe | ramp | cryptoDefault stripe.
reasoningstring ≤4000Why the agent wants to buy. Stored in the audit log.
prompt_chain[{role, content}]Optional conversation context.
webhook_urlhttps URLOptional. Receives the human decision.
idempotency_keystring ≤200Optional. Same key + same body replays the original decision; changed body → 409.
recipient_addressstringRequired for crypto.
modeauthorize | reportreport = log-only, a payment already made.

The agent is identified by its API key, not a body field. currency is fixed to USD and idempotency_key (optional) makes retries safe — see Idempotency.

Response

statusHTTPMeaning
approved201Within all rules. payment holds the card / tx if a rail is configured.
flagged202Needs a human. Poll poll_url or wait for webhook.
blocked403Do not buy. error_code POLICY_BLOCKED.
approved
{
  "transaction_id": "7f3c…",
  "status": "approved",
  "decision": "approved",
  "reason": "Within all agent limits and attached policies — auto-approved.",
  "evaluations": [
    { "policyName": "Agent limits", "rule": "Per-transaction limit", "outcome": "pass", "detail": "$45.00 ≤ $500.00" },
    { "policyName": "Agent limits", "rule": "monthly spend cap", "outcome": "pass", "detail": "$45 of $455 remaining" }
  ],
  "payment": { "status": "issued", "credential": { "type": "card", "last4": "4242", "…": "…" } },
  "verification": { "status": "awaiting_receipt", "receipt_url": "…/receipt" },
  "poll_url": "https://railguardsecurity.com/api/public/transactions/7f3c…",
  "timing": { "decision_ms": 38, "rules_ms": 1 }
}
flagged
{
  "transaction_id": "a91e…",
  "status": "flagged",
  "decision": "pending",
  "reason": "$250.00 exceeds auto-approve threshold $100.00 — human approval required.",
  "instruction": "Pause: waiting for human approval. Poll poll_url or wait for your webhook.",
  "evaluations": [ { "rule": "Human approval threshold", "outcome": "review", "…": "…" } ],
  "payment": null,
  "poll_url": "…/api/public/transactions/a91e…"
}
blocked
{
  "transaction_id": "c04b…",
  "status": "blocked",
  "decision": "blocked",
  "error_code": "POLICY_BLOCKED",
  "reason": "Merchant \"CasinoX\" is on the blocklist.",
  "instruction": "Do not complete this purchase. Stop or choose an alternative within policy.",
  "evaluations": [ { "rule": "Merchant blocklist", "outcome": "block", "…": "…" } ]
}

Reason codes

Top-level error_code: POLICY_BLOCKED (engine) or HUMAN_REJECTED (approver said no). Per-rule detail is in evaluations[].rule:

  • Agent must be active · Per-transaction limit · daily/weekly/monthly spend cap · Policy spend cap
  • Allowed merchant categories · Merchant blocklist · Merchant allowlist · Time-of-day restriction
  • Human approval threshold (outcome review)

Strictest wins

Every rule from the agent and every attached policy is evaluated. Then:

Any block?Any review?Result
yes—blocked
noyesflagged
nonoapproved
Example: $500/transaction cap + $2,000/week cap with $1,800 already spent. A $300 request passes the first, fails the second (only $200 left) → blocked, reason names the weekly cap.