Skip to main content

Prerequisites

Set your token as an environment variable so the examples below work as-is:
export DONE_API_KEY=your_token_here

Step 1 — Create a schema

A schema is a reusable contract template. This one is fulfilled when both a buyer and seller submit a signed event — or an admin overrides.
curl -X POST https://api.done.app/v1/schemas \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contract": {
      "price": 100.00,
      "activity_window": 3600,
      "review_window": 86400,
      "timeout_outcome": "fail",
      "fulfillment_condition": {
        "op": "OR",
        "conditions": [
          {
            "op": "AND",
            "conditions": [
              { "event": "signed_by_buyer" },
              { "event": "signed_by_seller" }
            ]
          },
          { "event": "admin_override" }
        ]
      }
    }
  }'
Save the id from the response — you’ll use it to create claims.
{
  "id": "018e1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c",
  "contract": { ... }
}

Step 2 — Provision a customer

Claims must be associated with a customer. Create one using your own internal identifier.
curl -X POST https://api.done.app/v1/customers \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "user_42"
  }'
{
  "id": "02b4d5e6-f7a8-9b0c-1d2e-3f4a5b6c7d8e",
  "external_id": "user_42",
  "created_at": "2024-01-15T09:59:00Z"
}
Save the id — you’ll pass it as customer_id when creating a claim.

Step 3 — Create a claim

A claim is an instance of your schema tied to a customer. The contract is snapshotted at creation time.
curl -X POST https://api.done.app/v1/claims \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "schema_id": "018e1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c",
    "customer_id": "02b4d5e6-f7a8-9b0c-1d2e-3f4a5b6c7d8e"
  }'
The claim starts in the OPEN state:
{
  "id": "019a3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "customer_id": "02b4d5e6-f7a8-9b0c-1d2e-3f4a5b6c7d8e",
  "status": "OPEN",
  "status_since": "2024-01-15T10:00:00Z",
  "scheduled_outcome": null,
  "contract": { ... }
}

Step 5 — Submit events

Push events to the claim. The fulfillment condition is re-evaluated after each one.
# Buyer signs
curl -X POST https://api.done.app/v1/events \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "claim_id": "019a3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "type": "signed_by_buyer" }'

# Seller signs — condition is now satisfied
curl -X POST https://api.done.app/v1/events \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "claim_id": "019a3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "type": "signed_by_seller" }'
Both calls return 204 No Content. After the second event, the claim automatically transitions to PENDING.

Step 6 — Check the claim

curl https://api.done.app/v1/claims/019a3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
  -H "Authorization: Bearer $DONE_API_KEY"
{
  "id": "019a3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "status": "PENDING",
  "status_since": "2024-01-15T10:01:30Z",
  "scheduled_outcome": "CONFIRMED",
  "contract": { ... },
  "events": [
    { "type": "signed_by_buyer", "data": {}, "created_at": "2024-01-15T10:01:00Z" },
    { "type": "signed_by_seller", "data": {}, "created_at": "2024-01-15T10:01:30Z" }
  ]
}
scheduled_outcome: "CONFIRMED" means the claim will be confirmed when the review_window (24 hours) elapses.

What’s next

Claim lifecycle

States, time windows, and how pg_cron drives transitions.

Fulfillment conditions

AND, OR, nested trees, and how evaluation works.

Create a schema

Full API reference for schema creation.

Submit an event

Full API reference for event submission.