API reference
A tiny REST API. Your agent asks a human before it acts, and you get back a signed, tamper-proof record of the decision.
Base URL: https://api.approv.dev (replace with your Supabase functions URL).
Quickstart
Create an approval. Approv messages your approver on WhatsApp or SMS and returns immediately with an id.
curl -X POST https://api.approv.dev/ \
-H "Authorization: Bearer $APPROV_KEY" \
-H "Content-Type: application/json" \
-d '{
"approver_id": "apr_...",
"action": "Refund $4,200 to customer #8831",
"amount": 4200,
"currency": "USD"
}'Authentication
Send your project API key as a Bearer token on every request. Create and rotate keys in Settings. Keep the key server-side — never ship it in a browser or app bundle.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx
Create an approval
/Returns 202 with an id while delivery happens in the background.
| Field | Type | Notes |
|---|---|---|
| approver_id | string | Required. Who approves. |
| action | string | Required. Human-readable description. |
| amount | number | Optional. Money at stake. |
| currency | string | Optional. ISO 4217, e.g. USD. |
| context | object | Optional. Extra data shown/stored. |
| callback_url | string | Optional. Webhook on decision. |
| timeout_seconds | number | Optional. Auto-expire window. |
{
"id": "req_9f2a…",
"status": "pending",
"expires_at": "2026-07-14T12:30:00Z",
"replayed": false
}Get status
/:idPoll for the decision. decision is null until the approver replies.
{
"id": "req_9f2a…",
"status": "decided",
"action": "Refund $4,200 to customer #8831",
"amount": 4200,
"currency": "USD",
"decision": {
"outcome": "approved",
"decided_via": "whatsapp",
"decided_by": "+1415…",
"decided_at": "2026-07-14T12:04:11Z"
}
}Get audit trail
/:id/auditEvery state change is hash-chained and signed with Ed25519. The response includes the public key and the exact formula so anyone can verify it independently — you don't have to trust us.
{
"verification": { "valid": true, "event_count": 4, "issues": [] },
"algorithm": {
"hash": "sha256",
"signature": "ed25519",
"hash_formula": "sha256( prev_hash | event_type | canonical_json(payload) | created_at )"
},
"public_key": { "key_id": "k1", "format": "spki-der-base64", "key": "MCowBQ…" },
"events": [ { "seq": 1, "event_type": "created", "hash": "…", "signature": "…" } ]
}Webhooks
Pass a callback_url when creating an approval. On decision, Approv sends a signed POST so your agent can continue automatically — no polling required.
POST <your callback_url>
{
"id": "req_9f2a…",
"outcome": "approved",
"decided_via": "sms",
"decided_at": "2026-07-14T12:04:11Z"
}Errors
Errors return a JSON body with a stable code and a human message.
{ "error": { "code": "validation", "message": "Provide a name and a phone in E.164 format." } }