Docs · API
API reference
The OpenAPI contract, then the designed endpoints.
Base URL: https://sandbox.api.insimbi.xyz. The first part is the OpenAPI contract. Request access for the full specification.
In the OpenAPI contract
| GET /health | Liveness. Returns 204 with no body. No token needed. |
|---|---|
| POST /oauth2/token | Exchange a signed client assertion for a short-lived Bearer token. Form fields: grant_type=client_credentials, client_id, client_assertion_type, client_assertion and an optional scope. |
| GET /.well-known/oauth-authorization-server | Authorization server metadata: issuer, token endpoint, JWKS URI, the client_credentials grant, private_key_jwt client authentication and RS256. |
| GET /.well-known/jwks.json | Public RS256 keys to verify tokens, each with a kid. During rotation more than one key is published. |
| GET /v1/organizations/{organization_id} | Read an organization. Needs organization.read. Returns id, environment, environment_id and status. |
| GET /v1/legal-entities/{legal_entity_id} | Read a legal entity. Needs legal_entity.read. Adds organization_id. |
| GET /v1/merchant-accounts/{merchant_account_id} | Read a merchant account. Needs merchant_account.read. Adds organization_id and legal_entity_id. |
From the OpenAPI contract
{
"issuer": "https://sandbox.api.insimbi.xyz",
"token_endpoint": "https://sandbox.api.insimbi.xyz/oauth2/token",
"jwks_uri": "https://sandbox.api.insimbi.xyz/.well-known/jwks.json",
"grant_types_supported": [
"client_credentials"
],
"token_endpoint_auth_methods_supported": [
"private_key_jwt"
],
"token_endpoint_auth_signing_alg_values_supported": [
"RS256"
]
}
Errors
Account reads return one error shape. The request_id matches the X-Request-ID header.
From the OpenAPI contract
{
"error_version": "error/1.0",
"code": "insufficient_authority",
"message": "<message>",
"request_id": "<request_id>"
}
| 401 | invalid_identity: The token is missing, expired or invalid. |
|---|---|
| 403 | insufficient_authority: The token is valid but lacks the permission for this resource. |
| 404 | not_found: The resource doesn't exist or isn't visible to you. |
| 429 | rate_limited: Too many requests. |
| 503 | unavailable: The service can't decide safely right now. |
The token endpoint returns the OAuth error shape, {"error": "<code>"}, with Cache-Control: no-store. Codes: invalid_request, invalid_client, invalid_scope and unsupported_grant_type with 400, and temporarily_unavailable with 503. It also returns 405 for the wrong method and 429 when rate limited.
Request IDs
Every response carries an X-Request-ID header. On token and account requests we always assign a fresh one. On other paths, an ID you send is kept if it is 1 to 128 letters, digits, dots, underscores or hyphens. Quote the request ID when you contact us, and never put secrets or personal data in it.
Retries
Retry 429 and 503 with exponential backoff and jitter, and get a fresh token if yours has expired. Don't retry 400, 401, 403 or 404 unchanged: fix the request, the credentials or the grant first. When a decision can't be made safely, the API returns 503, never a cached allow.
Designed endpoints
Designed. These endpoints are specified in our designs and are not in the OpenAPI contract yet. Paths and fields are illustrative and can change.
| GET /v1/grants/{grant_id} | Read an access grant. |
|---|---|
| POST /v1/payments | Create a payment. Requires Idempotency-Key. |
| POST /v1/payments/{payment_id}/captures | Capture an authorized payment. |
| GET /v1/transactions | Search transactions by status. |
| GET /v1/tickets/{ticket_id} | Read a ticket: fee lines with rule citations, decision and event references. |
| POST /v1/cutoffs/preview | See what a cutoff change would do. Changes nothing. |
| POST /v1/exports/preview | Start an export job. |
| GET /v1/exports/{job_id} | Check an export job. |
| GET /v1/events | List events with cursor pagination. |
| GET /v1/webhooks/{webhook_id}/deliveries | List deliveries for an endpoint. |
| GET /v1/webhooks/{webhook_id}/deliveries/{delivery_id}/attempts | See every attempt, status and timing. |
| POST /v1/webhooks/{webhook_id}/deliveries/{delivery_id}/replays | Replay a delivery. |
POST /v1/payments: a payment, end to end
Designed. Payment endpoints are designed. Every check in this flow is written to the record.
Steps in text
- Your app or agent to insimbi API: POST /v1/payments with an Idempotency-Key
- insimbi API: Authenticate the token and record the access decision
- insimbi API to Rules and mandate check: Check the payment against your rules and the agent's mandate
- Rules and mandate check to Operator: Above your threshold: propose for approval
- Operator to Rules and mandate check: A person approves
- Rules and mandate check to insimbi API: Allowed. The rail rule chooses the rail.
- insimbi API to Rail: Submit on the chosen rail
- Rail to insimbi API: Rail result
- insimbi API to Record: Write the ledger entry, fee lines cited to rules, and the ticket
- insimbi API to Your app or agent: 201 with the ticket id
- insimbi API to Your app or agent: Event delivered to your webhook endpoint
Example: price a payment before it runs
Agents use the designed quote_ticket tool (see MCP tools). It returns the fee lines and the perimeter decision that would apply, without submitting anything.
Illustrative example
{
"tool": "quote_ticket",
"input": {
"amount": "0.02",
"currency": "USD",
"payee": "api.example-data.com"
}
}
Illustrative example
{
"lines": [
{
"label": "network",
"amount": "0.0004",
"rule": "rule:rail.stablecoin.fee@v1"
}
],
"perimeter": {
"id": "per_01J9",
"version": 3,
"decision": "allow"
}
}