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.

API Key Authentication

Every request to SpendGuard (except the health check and demo simulation) requires an API key. Send your key in the X-API-Key header on every request:
curl -X GET https://spendguardapi.com/v1/policies/my_policy \
  -H "X-API-Key: sg_live_your_key_here"

Key Format

SpendGuard API keys follow this format:
sg_live_ + 32 random hex characters
Example: sg_live_4a8f2c1b9e7d3056ef28a1c4b7e93f1d
Your API key is shown exactly once when it’s created. SpendGuard stores only a SHA-256 hash of the key — the original cannot be retrieved. If you lose your key, you’ll need to create a new one.

Endpoints That Don’t Require Auth

Two endpoints work without an API key:
EndpointWhy
GET /healthHealth check for monitoring — always public
POST /v1/simulate (demo mode)Public demo — limited to 10 actions per request, responses marked "mode": "demo"
Everything else requires a valid, active API key.

Error Responses

If authentication fails, SpendGuard returns a clear error in the standard format:

Missing or Invalid Key — 401 Unauthorized

{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key. Provide a valid key in the X-API-Key header.",
    "request_id": "req_a1b2c3d4e5f6",
    "timestamp": "2026-04-03T12:00:00Z"
  }
}
Common causes:
  • No X-API-Key header in the request
  • Key is misspelled or truncated
  • Key was never created (not in the database)

Inactive Key — 401 Unauthorized

{
  "error": {
    "code": "api_key_inactive",
    "message": "This API key has been deactivated.",
    "request_id": "req_a1b2c3d4e5f6",
    "timestamp": "2026-04-03T12:00:00Z"
  }
}
Common causes:
  • Key was deactivated by an admin
  • Subscription was cancelled (future billing integration)

Rate Limits

SpendGuard applies rate limits to protect the service and ensure fair usage.

Default Limits

ModeLimitScope
Authenticated100 requests/minutePer API key
Demo (no auth)10 requests/minutePer IP address
Enterprise customers can have custom rate limits configured per key.

Rate Limit Headers

Every response includes rate limit information in the headers:
HeaderDescription
X-RateLimit-LimitYour maximum requests per minute
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets

When You Hit the Limit — 429 Too Many Requests

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Try again later.",
    "request_id": "req_a1b2c3d4e5f6",
    "timestamp": "2026-04-03T12:00:00Z"
  }
}
The response includes a Retry-After header telling you how many seconds to wait. How to handle this in your agent:
import time
import requests

def check_action(payload, api_key):
    response = requests.post(
        "https://spendguardapi.com/v1/checks",
        headers={"X-API-Key": api_key, "Content-Type": "application/json"},
        json=payload,
    )

    if response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 5))
        time.sleep(retry_after)
        return check_action(payload, api_key)  # Retry once

    return response.json()

Security Best Practices

Store it in environment variables or a secrets manager. Never commit it to source code.
import os

api_key = os.environ["SPENDGUARD_API_KEY"]
If you have multiple agents, create a separate API key for each one. This way, if one key is compromised, you can revoke it without affecting the others.
Regularly check GET /v1/violations to see what your agents are trying to do. A sudden spike in blocks might mean a bug in your agent, not a policy problem.
When retrying checks after a network error, include an idempotency_key in your request. This prevents duplicate audit log entries and ensures you get the same response.

Quick Reference

WhatValue
HeaderX-API-Key
Key formatsg_live_ + 32 hex characters
Auth error codeunauthorized
Inactive key errorapi_key_inactive
Rate limit (auth)100 req/min per key
Rate limit (demo)10 req/min per IP
Rate limit errorrate_limit_exceeded (HTTP 429)