Skip to main content

Documentation Index

Fetch the complete documentation index at: https://spendguard.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Endpoint

POST /v1/simulate
Authentication: Optional
  • Without API key: Demo mode — max 10 actions, response includes "mode": "demo"
  • With API key: Simulation mode — max 100 actions, response includes "mode": "simulation"

Request Body

FieldTypeRequiredDescription
policy_idstringYesPolicy to simulate against
actionsarrayYesArray of action objects to simulate (min 1, max 100)
Each action in the actions array has the same fields as a check request:
FieldTypeRequiredDescription
agent_idstringYesAgent identifier
policy_idstringYesPolicy ID (must match the top-level policy_id)
action_typestringNo*refund, credit, discount, or spend
amountnumberYesDollar amount (>= 0)
currencystringYesISO 4217 currency code
counterpartystringYesCustomer or vendor ID
reason_textstringNo*Required if action_type is omitted
payment_methodstringNoPayment method
metadataobjectNoAdditional context

Example Request (Demo Mode — No Auth)

curl -X POST https://spendguardapi.com/v1/simulate \
  -H "Content-Type: application/json" \
  -d '{
    "policy_id": "demo_refund_policy",
    "actions": [
      {
        "agent_id": "demo-agent",
        "policy_id": "demo_refund_policy",
        "action_type": "refund",
        "amount": 50.00,
        "currency": "USD",
        "counterparty": "customer_001",
        "metadata": { "days_since_purchase": 10 }
      },
      {
        "agent_id": "demo-agent",
        "policy_id": "demo_refund_policy",
        "action_type": "refund",
        "amount": 750.00,
        "currency": "USD",
        "counterparty": "customer_002"
      }
    ]
  }'

Response — 200 OK

{
  "mode": "demo",
  "policy_id": "demo_refund_policy",
  "policy_version": 1,
  "results": [
    {
      "check_id": "chk_abc123",
      "decision": "allow",
      "confidence": "high",
      "reason_code": null,
      "message": "Action is within policy. Proceed.",
      "violated_rule_id": null,
      "violated_rule_description": null,
      "policy_version": 1,
      "next_step": "Proceed with the action.",
      "latency_ms": 3,
      "timestamp": "2026-04-03T12:00:00Z"
    },
    {
      "check_id": "chk_def456",
      "decision": "block",
      "confidence": "high",
      "reason_code": "max_amount_exceeded",
      "message": "Amount $750.00 exceeds the policy limit of $500.00.",
      "violated_rule_id": "r1",
      "violated_rule_description": "Refunds may not exceed $500 per transaction without escalation",
      "policy_version": 1,
      "next_step": "Reduce the amount to $500.00 or below, or escalate to a manager.",
      "latency_ms": 2,
      "timestamp": "2026-04-03T12:00:00Z"
    }
  ],
  "summary": {
    "total": 2,
    "allowed": 1,
    "blocked": 1,
    "escalated": 0
  }
}

Response Fields

FieldTypeDescription
modestring"demo" (no auth) or "simulation" (with auth)
policy_idstringPolicy that was evaluated
policy_versionintegerPolicy version used
resultsarrayIndividual decision for each action (same fields as check response)
summary.totalintegerTotal actions simulated
summary.allowedintegerCount of allow decisions
summary.blockedintegerCount of block decisions
summary.escalatedintegerCount of escalate decisions

Side-Effect Guarantee

Simulation never writes to any table:
  • No checks logged
  • No violations recorded
  • No duplicate guard fingerprints stored
  • No usage events emitted
You can call it as many times as you want with zero impact on your data.

Error Responses

StatusCodeWhen
404policy_not_foundPolicy ID does not exist
422demo_limit_exceededDemo mode with more than 10 actions
422validation_errorInvalid request body
429rate_limit_exceededToo many requests (demo: 10/min per IP)
500internal_errorServer error