API · authenticated
POST /api/v1/decisions
Submit a refund, credit, or adjustment intent and receive an allow/pending_approval/denied decision evaluated against your tenant's active policies. Decisions are persisted to the append-only ledger and are reproducible via replay.
Authentication
Send your API key as a Bearer token. Generate keys from your organization's API keys settings. Keys begin with ak_.
Authorization: Bearer ak_live_…Request
curl -X POST https://www.axiru.com/api/v1/decisions \
-H "Authorization: Bearer ak_live_…" \
-H "content-type: application/json" \
-H "Idempotency-Key: ignored — use idempotency_key in body" \
-d '{
"intent": {
"kind": "refund",
"amount_cents": 17500,
"currency": "usd",
"stripe_connection_id": "stripe_conn_abc123"
},
"context": {
"customer_tenure_days": 412,
"reason_code": "duplicate_charge"
},
"idempotency_key": "support_ticket_4821"
}'
# → {
# "decision_id": "ed_…",
# "outcome": "pending_approval",
# "reason": "amount_above_default_threshold",
# "matched_rule": "policy:slug:v3",
# "policy_version": "v3",
# "approver_role": "controller",
# "audit": {
# "logged_at": "2026-04-28T20:00:00Z",
# "ledger_id": "lr_…"
# }
# }Live endpoint. Wire the same call against your tenant via /docs.
Response shape
{
"decision_id": "ed_…",
"outcome": "allowed" | "pending_approval" | "denied",
"reason": "snake_case_reason",
"matched_rule": "policy:slug:v3" | "default_allow",
"policy_version": "v3",
"approver_role": "controller" | null,
"audit": {
"logged_at": "2026-04-28T20:00:00Z",
"ledger_id": "lr_…"
},
"cached": true // only present on idempotency replays
}Idempotency
Pass idempotency_key in the request body. Replays within 24 hours return the original decision with cached: true. Keys are scoped per organization.
Rate limits
100 requests / minute per API key. Exceeding the limit returns 429 with a Retry-After header.
Error codes
| HTTP | error | When |
|---|---|---|
400 | invalid_request | Body fails Zod validation. field_errors details which fields. |
400 | invalid_json | Body is not valid JSON. |
401 | missing_authorization | Missing or empty Authorization header. |
401 | invalid_authorization_scheme | Header does not use the Bearer scheme. |
401 | invalid_api_key | Token is unknown or revoked. |
429 | rate_limited | Per-API-key limit exceeded. |
500 | decision_failed | Internal evaluation error. |