ClearPact API
Programmable escrow for autonomous agent payments. Lock funds, verify conditions, settle automatically.
Quick Start
Get from zero to your first escrow in 3 steps. No signup form, no OAuth. Just an email and an API call.
Get an API Key
Create a key with your email. You'll get a key that starts with cpk_live_. Save it — it's only shown once.
curl
curl -X POST https://clearpact.polsia.app/api/keys \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com", "name": "My First Key"}'
Create an Escrow
Lock USDC between two parties with conditions for release.
curl
curl -X POST https://clearpact.polsia.app/api/escrow \
-H "Content-Type: application/json" \
-H "X-API-Key: cpk_live_YOUR_KEY_HERE" \
-d '{
"payer": "0xAliceWallet",
"payee": "0xBobWallet",
"amount": "250.00",
"token": "USDC",
"conditions": [
{"type": "task_completion", "description": "Complete data analysis"}
]
}'
Settle When Conditions Are Met
Verify conditions and release funds to the payee.
curl
curl -X POST https://clearpact.polsia.app/api/escrow/ESCROW_ID/settle \
-H "Content-Type: application/json" \
-H "X-API-Key: cpk_live_YOUR_KEY_HERE" \
-d '{
"verifications": {"0": {"completed": true}},
"actor": "0xAliceWallet"
}'
Try It: Generate an API Key
Enter your email to get a live API key right now.
Save this key now. It won't be shown again.
Key ID:
Authentication
All escrow endpoints require an API key passed in the X-API-Key header. Key management endpoints (/api/keys) are public.
API Key Format: Keys start with cpk_live_ followed by 48 hex characters. Example: cpk_live_a1b2c3d4e5f6...
# Every request to /api/escrow/* must include:
X-API-Key: cpk_live_your_key_here
Protected endpoints (require X-API-Key):
| Method | Endpoint | Description |
|---|---|---|
POST | /api/escrow | Create escrow |
GET | /api/escrow/:id | Get escrow details |
POST | /api/escrow/:id/settle | Settle escrow |
Public endpoints (no auth needed):
| Method | Endpoint | Description |
|---|---|---|
POST | /api/keys | Create API key |
GET | /api/keys | List your keys |
DELETE | /api/keys/:key_id | Revoke a key |
POST | /api/keys/:key_id/rotate | Rotate a key |
Rate Limits
Each API key has independent rate limits. Default limits:
| Limit | Default | Header |
|---|---|---|
| Per minute | 60 requests | X-RateLimit-Limit |
| Per day | 10,000 requests | - |
| Remaining | - | X-RateLimit-Remaining |
When rate limited, responses include a Retry-After header (in seconds). Response code: 429.
Create API Key
Generate a new API key. Maximum 5 active keys per email.
REQUEST BODY
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Your email address | |
| name | string | No | Human-readable label (default: "Default") |
curl -X POST https://clearpact.polsia.app/api/keys \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com", "name": "Production"}'
const res = await fetch("https://clearpact.polsia.app/api/keys", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: "dev@example.com", name: "Production" }) }); const { key } = await res.json(); console.log("Save this key:", key);
import requests res = requests.post("https://clearpact.polsia.app/api/keys", json={ "email": "dev@example.com", "name": "Production" }) data = res.json() print(f"Save this key: {data['key']}")
RESPONSE (201)
{
"success": true,
"message": "API key created. Save it now — it won't be shown again.",
"key": "cpk_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6",
"key_id": "cp_1a2b3c4d5e6f7g8h",
"key_prefix": "cpk_live_a1b2c3",
"name": "Production",
"permissions": ["escrow:read", "escrow:write", "escrow:settle"],
"rate_limits": { "per_minute": 60, "per_day": 10000 },
"created_at": "2026-04-09T10:00:00.000Z"
}
List API Keys
List all API keys associated with your email. Keys are returned without the secret value.
curl "https://clearpact.polsia.app/api/keys?email=dev@example.com"
const res = await fetch( "https://clearpact.polsia.app/api/keys?email=dev@example.com" ); const { keys } = await res.json();
res = requests.get("https://clearpact.polsia.app/api/keys", params={ "email": "dev@example.com" }) keys = res.json()["keys"]
RESPONSE (200)
{
"success": true,
"keys": [
{
"key_id": "cp_1a2b3c4d5e6f7g8h",
"key_prefix": "cpk_live_a1b2c3",
"name": "Production",
"is_active": true,
"last_used_at": "2026-04-09T10:30:00.000Z",
"requests_today": 42,
"created_at": "2026-04-09T10:00:00.000Z"
}
],
"count": 1
}
Revoke API Key
Immediately revoke an API key. All future requests with this key will be rejected.
curl -X DELETE https://clearpact.polsia.app/api/keys/cp_1a2b3c4d5e6f7g8h \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com"}'
await fetch("https://clearpact.polsia.app/api/keys/cp_1a2b3c4d5e6f7g8h", { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: "dev@example.com" }) });
Rotate API Key
Revoke the old key and generate a new one with the same settings. Zero-downtime key rotation.
curl -X POST https://clearpact.polsia.app/api/keys/cp_1a2b3c4d5e6f7g8h/rotate \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com"}'
const res = await fetch( "https://clearpact.polsia.app/api/keys/cp_1a2b3c4d5e6f7g8h/rotate", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: "dev@example.com" }) } ); const { key } = await res.json(); // Update your config with the new key
Create Escrow
Create a new escrow contract between two parties. Requires X-API-Key header.
REQUEST BODY
| Field | Type | Required | Description |
|---|---|---|---|
| payer | string | Yes | Payer wallet address or identifier |
| payee | string | Yes | Payee wallet address or identifier |
| amount | string/number | Yes | Amount in token units (e.g. "250.00") |
| token | string | No | Token symbol (default: "USDC") |
| conditions | array | No | Settlement conditions (see Condition Types) |
| metadata | object | No | Arbitrary metadata (project name, etc.) |
| expires_at | string | No | ISO 8601 expiration timestamp |
curl -X POST https://clearpact.polsia.app/api/escrow \
-H "Content-Type: application/json" \
-H "X-API-Key: cpk_live_YOUR_KEY" \
-d '{
"payer": "0xAlice",
"payee": "0xBob",
"amount": "500.00",
"token": "USDC",
"conditions": [
{"type": "task_completion", "description": "Ship v2.0 release"},
{"type": "approval", "approver": "0xAlice"}
],
"metadata": {"project": "agent-audit"},
"expires_at": "2026-12-31T00:00:00Z"
}'
const res = await fetch("https://clearpact.polsia.app/api/escrow", { method: "POST", headers: { "Content-Type": "application/json", "X-API-Key": "cpk_live_YOUR_KEY" }, body: JSON.stringify({ payer: "0xAlice", payee: "0xBob", amount: "500.00", conditions: [ { type: "task_completion", description: "Ship v2.0" }, { type: "approval", approver: "0xAlice" } ] }) }); const { escrow } = await res.json(); console.log("Escrow ID:", escrow.id);
import requests res = requests.post( "https://clearpact.polsia.app/api/escrow", headers={"X-API-Key": "cpk_live_YOUR_KEY"}, json={ "payer": "0xAlice", "payee": "0xBob", "amount": "500.00", "conditions": [ {"type": "task_completion", "description": "Ship v2.0"} ] } ) escrow = res.json()["escrow"] print(f"Escrow ID: {escrow['id']}")
RESPONSE (201)
{
"success": true,
"escrow": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"payer": "0xAlice",
"payee": "0xBob",
"amount": 500,
"token": "USDC",
"status": "pending",
"conditions": [
{"type": "task_completion", "description": "Ship v2.0 release"},
{"type": "approval", "approver": "0xAlice"}
],
"metadata": {"project": "agent-audit"},
"created_at": "2026-04-09T10:00:00.000Z",
"expires_at": "2026-12-31T00:00:00.000Z"
}
}
If conditions is empty or not provided, the escrow status starts as "active" instead of "pending".
Get Escrow
Retrieve escrow details and full event audit trail.
curl https://clearpact.polsia.app/api/escrow/550e8400-e29b-41d4-a716-446655440000 \ -H "X-API-Key: cpk_live_YOUR_KEY"
const res = await fetch( "https://clearpact.polsia.app/api/escrow/550e8400-...", { headers: { "X-API-Key": "cpk_live_YOUR_KEY" } } ); const { escrow, events } = await res.json();
res = requests.get(
"https://clearpact.polsia.app/api/escrow/550e8400-...",
headers={"X-API-Key": "cpk_live_YOUR_KEY"}
)
data = res.json()
RESPONSE (200)
{
"success": true,
"escrow": { /* full escrow object */ },
"events": [
{
"event_type": "created",
"actor": "0xAlice",
"details": {"amount": 500, "token": "USDC"},
"created_at": "2026-04-09T10:00:00.000Z"
}
]
}
Settle Escrow
Verify all conditions and release funds. All conditions must be met for settlement.
REQUEST BODY
| Field | Type | Required | Description |
|---|---|---|---|
| verifications | object | Yes | Map of condition index to verification data |
| actor | string | No | Who is triggering the settlement |
curl -X POST https://clearpact.polsia.app/api/escrow/ESCROW_ID/settle \
-H "Content-Type: application/json" \
-H "X-API-Key: cpk_live_YOUR_KEY" \
-d '{
"verifications": {
"0": {"completed": true},
"1": {"approved": true, "approver": "0xAlice"}
},
"actor": "0xOracle"
}'
const res = await fetch( `https://clearpact.polsia.app/api/escrow/${escrowId}/settle`, { method: "POST", headers: { "Content-Type": "application/json", "X-API-Key": "cpk_live_YOUR_KEY" }, body: JSON.stringify({ verifications: { "0": { completed: true }, "1": { approved: true, approver: "0xAlice" } }, actor: "0xOracle" }) } ); const { settlement } = await res.json(); console.log("Settled:", settlement.amount, settlement.token);
res = requests.post(
f"https://clearpact.polsia.app/api/escrow/{escrow_id}/settle",
headers={"X-API-Key": "cpk_live_YOUR_KEY"},
json={
"verifications": {
"0": {"completed": True},
"1": {"approved": True, "approver": "0xAlice"}
},
"actor": "0xOracle"
}
)
settlement = res.json()["settlement"]
RESPONSE — SUCCESS (200)
{
"success": true,
"message": "Escrow settled. 500 USDC released to 0xBob",
"escrow": { "status": "settled", /* ... */ },
"settlement": {
"amount": 500,
"token": "USDC",
"from": "0xAlice",
"to": "0xBob",
"conditions": [
{"index": 0, "type": "task_completion", "met": true},
{"index": 1, "type": "approval", "met": true}
],
"settled_at": "2026-04-09T12:00:00.000Z"
}
}
RESPONSE — CONDITIONS NOT MET (422)
{
"success": false,
"message": "Not all conditions are met",
"conditions": [
{"index": 0, "type": "task_completion", "met": true},
{"index": 1, "type": "approval", "met": false}
]
}
Condition Types
Conditions define what must be true before funds are released. Each escrow can have multiple conditions — all must be met for settlement.
task_completion
Requires explicit confirmation that work is done.
Condition: {"type": "task_completion"}
Verification: {"completed": true}
approval
Requires sign-off from a specific approver address.
Condition: {"type": "approval", "approver": "0x..."}
Verification: {"approved": true, "approver": "0x..."}
deadline
Automatically met if current time is before the deadline.
Condition: {"type": "deadline", "deadline": "2026-12-31T..."}
Verification: None needed (auto-checked)
threshold
A numeric value must meet or exceed a minimum.
Condition: {"type": "threshold", "min_value": 100}
Verification: {"value": 150}
oracle
An external oracle must confirm the outcome.
Condition: {"type": "oracle"}
Verification: {"oracle_confirmed": true}
custom
Any custom condition type. Requires explicit met flag.
Condition: {"type": "my_custom_check"}
Verification: {"met": true}
Error Codes
All errors return JSON with success: false and a descriptive error code.
| HTTP | Error Code | Description |
|---|---|---|
| 400 | invalid_email | Email is missing or malformed |
| 400 | invalid_escrow_id | Escrow ID is not a valid UUID |
| 401 | missing_api_key | X-API-Key header not provided |
| 401 | invalid_api_key | API key not recognized |
| 401 | invalid_api_key_format | Key doesn't match cpk_ format |
| 401 | api_key_revoked | Key has been revoked |
| 401 | api_key_expired | Key has expired |
| 404 | escrow_not_found | No escrow with that ID |
| 404 | key_not_found | API key not found or already revoked |
| 409 | already_settled | Escrow is already settled/expired/cancelled |
| 422 | conditions_not_met | Not all conditions verified — includes details per condition |
| 429 | rate_limit_exceeded | Too many requests per minute |
| 429 | daily_limit_exceeded | Daily request limit reached |
ERROR RESPONSE FORMAT
{
"success": false,
"error": "missing_api_key",
"message": "API key required. Pass your key in the X-API-Key header.",
"docs": "https://clearpact.polsia.app/docs#authentication"
}
Escrow Status Values
| Status | Description | Can Settle? |
|---|---|---|
pending | Created with conditions, waiting for verification | Yes |
active | Created without conditions, funds are locked | Yes |
settled | All conditions met, funds released to payee | No |
expired | Passed expires_at timestamp without settlement | No |
cancelled | Cancelled before settlement | No |