API Reference
Complete REST API reference for PINTI.
Base URL
https://pinti.ai/api/v1Authentication
All endpoints require an API key via the x-api-key header.
x-api-key: pinti_xxxxxxxx_...Note
amountMinor: 5000.Error Format
{
"error": "Human-readable error message"
}Rate Limits
| Plan | Evaluations/day | Policies | API Keys |
|---|---|---|---|
| Free | 100 | 1 | 1 |
| Pro ($29/mo) | Unlimited | Unlimited | Unlimited |
POST /spend/evaluate
Evaluate a spend intent against workspace policies. Returns a SAT (Spend Authorization Token) on ALLOW.
Request Body
{
"agentId": "my-agent", // required — who is spending
"amountMinor": 5000, // required — amount in minor units (cents)
"unit": "USD", // required — currency
"merchant": "openai.com", // required — where
"category": "api", // required — what type
"reason": "Monthly credits", // required — why
"metadata": {}, // optional — extra context
"idempotencyKey": "abc123", // optional — deduplication
"handleId": "clxyz...", // optional — payment handle (falls back to workspace default)
"callbackUrl": "https://..." // optional — webhook URL for approval notifications
}Response
{
"decision": "ALLOW",
"decisionReason": "OK",
"spendRequestId": "cm4abc123...",
"sat": "eyJ2ZXJzaW9uIjox..." // present on ALLOW
}Decision Values
| Decision | Reason Examples |
|---|---|
ALLOW | OK |
DENY | BLOCKED_MERCHANT, EXCEEDS_SINGLE_LIMIT, EXCEEDS_DAILY_LIMIT, EXCEEDS_MONTHLY_LIMIT, NO_ACTIVE_POLICY, BLOCKED_CATEGORY, MERCHANT_NOT_ALLOWED, CATEGORY_NOT_ALLOWED, VELOCITY_LIMIT_MINUTE, VELOCITY_LIMIT_HOUR |
REQUIRE_APPROVAL | REQUIRES_APPROVAL |
POST /spend/receipt
Submit a payment receipt (SDK Guard mode). Compares actual payment values against SAT claims and flags anomalies. Idempotent — same SAT returns the same receiptId.
Request Body
{
"spendRequestId": "cm...",
"sat": "eyJ...",
"railId": "stripe", // required — "stripe", "moonpay", "evm", "custom:xxx"
"providerTransactionId": "ch_xxx", // optional — provider reference
"destination": null, // optional — address / account
"actualNetwork": "stripe", // optional — "eth:1", "solana:mainnet", etc.
"actualAmountMinor": 5000, // required — actual amount paid (minor units)
"actualCurrency": "usd", // required — actual currency
"actualMerchantNormalized": "aws", // optional — for merchant mismatch detection
"rawReceipt": { ... } // optional — sanitized provider response
}Response
{
"receiptId": "cl...",
"anomalyFlags": [], // or ["AMOUNT_MISMATCH", "CURRENCY_MISMATCH"]
"recorded": true
}Note
executionMode: "sdk" can be used with this endpoint. External executor and managed mode SATs must use /payment/execute.POST /payment/execute
Execute a payment through a payment handle (External Executor or Managed mode). Requires a valid SAT. Not available for SDK Guard mode.
Request Body
{
"paymentHandleId": "clxyz...",
"sat": "eyJ...",
"params": {
"amountMinor": 5000,
"currency": "usd",
"description": "Monthly API credits"
}
}Response
{
"executed": true,
"spendRequestId": "cm...",
"transaction": {
"id": "tx_xxxxxxxxxx",
"status": "completed"
}
}GET /policies
List all policies for the workspace.
[
{
"id": "cm...",
"name": "Default Policy",
"maxSingleAmount": 10000,
"dailyLimit": 50000,
"monthlyLimit": null,
"requireApprovalOver": 5000,
"maxTransactionsPerMinute": null,
"maxTransactionsPerHour": null,
"unit": "USD",
"allowedMerchants": [],
"blockedMerchants": ["evil.com"],
"allowedCategories": [],
"blockedCategories": [],
"isActive": true,
}
]POST /policies
Create a new policy.
{
"name": "API Spend Policy",
"maxSingleAmount": 10000,
"dailyLimit": 50000,
"monthlyLimit": 500000,
"requireApprovalOver": 5000,
"maxTransactionsPerMinute": 10,
"maxTransactionsPerHour": 100,
"unit": "USD",
"allowedMerchants": [],
"blockedMerchants": ["evil.com"],
"allowedCategories": [],
"blockedCategories": []
}Note
GET /api-keys
List all API keys for the workspace (prefix only, never the full key).
POST /api-keys
Generate a new API key. The full plaintext key is returned only once in the response.
{
"id": "cm...",
"keyPrefix": "pinti_ABcd1234",
"plaintext": "pinti_ABcd1234_...",
"createdAt": "2026-01-01T00:00:00.000Z"
}Warning
GET /spend-requests/:id
Get the status of a spend request. Includes approval details if the decision was REQUIRE_APPROVAL.
{
"id": "cm...",
"decision": "REQUIRE_APPROVAL",
"decisionReason": "REQUIRES_APPROVAL",
"approval": {
"id": "cm...",
"status": "PENDING",
"decidedAt": null,
"note": null
}
}POST /approvals/:id/resolve
Approve or reject a pending approval.
{
"status": "APPROVED",
"note": "Looks good, proceed."
}Status values: APPROVED or REJECTED.