Getting started

Quickstart

Create a document, send it for signature, and watch it complete — in four calls. Around ten minutes, most of which is getting a key.

What you need

  • A key from Settings → API keys. Use a xo_test_ key so nothing is emailed while you experiment. Self-serve keys need the Crew plan or above.
  • The scopes documents:write, documents:send, and documents:read — the default set.
shell
export XOSIGN_API_KEY="xo_test_..."

1Check your key works

Before anything else, confirm the key is live and see what it can do. This call needs no scope and changes nothing.

curl https://xosign.ai/api/v1/account \
  -H "Authorization: Bearer $XOSIGN_API_KEY"

A 200 means you are ready. Check that mode says test and that scopes contains the three above. A 401 here is almost always a truncated key or a non-canonical host — see always call xosign.ai.

2Create a draft

A draft holds the document and its recipients. Nothing is delivered yet, so this step is always safe to repeat.

curl -X POST https://xosign.ai/api/v1/documents \
  -H "Authorization: Bearer $XOSIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "title": "Framing Agreement",
    "type": "contract",
    "recipients": [
      {
        "name": "Jane Contractor",
        "email": "jane@example.com",
        "channel": "email",
        "role": "signer"
      }
    ],
    "content": {
      "message": "Please review and sign by Friday.",
      "expires_in_days": 14
    }
  }'

You get back a 201 with the created document:

json
{
  "object": "document",
  "id": "9f1c7d2e-4b3a-4c88-9e21-7a5b0c4d8e13",
  "type": "contract",
  "status": "draft",
  "title": "Framing Agreement",
  "recipient_count": 1,
  "sent_at": null,
  "completed_at": null,
  "created_at": "2026-08-04T10:22:31.482Z",
  "updated_at": "2026-08-04T10:22:31.482Z"
}

Keep the id — the next two steps need it.

This creates a real document

Even with a xo_test_ key, the draft above is written to your real account and will appear in the web app alongside everything else. Test mode suppresses email and SMS; it does not give you a separate dataset. Tidy up after yourself, and do not point a test loop at an account you care about.

3Send it for signature

Sending moves the document to sent and delivers a signature request to each recipient. The body is empty — send options were already set in content when you created the draft.

curl -X POST https://xosign.ai/api/v1/documents/$DOCUMENT_ID/send \
  -H "Authorization: Bearer $XOSIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'

With a test key the document still becomes sent, but Jane receives nothing. Swap in a xo_live_ key when you are ready for a real signature request to go out.

Use an Idempotency-Key here above all

If the connection drops after we received your send but before you got the response, retrying without a key could deliver a second round of signature requests to real people. With one, the retry replays the original response and sends nothing. See idempotency.

4Watch it complete

Poll the document for its overall status, or its recipients for per-person progress — who opened it, who signed, who declined.

# Status only.
curl -s https://xosign.ai/api/v1/documents/$DOCUMENT_ID \
  -H "Authorization: Bearer $XOSIGN_API_KEY" | jq '.status'

# Who has signed, and who has not.
curl -s https://xosign.ai/api/v1/documents/$DOCUMENT_ID/recipients \
  -H "Authorization: Bearer $XOSIGN_API_KEY" \
  | jq '.data[] | {display_name, status, signed_at}'

status moves sentpartially_signed completed, or lands on declined, voided, or expired. Treat those four as terminal and stop polling.

Do not poll in a tight loop

Signing is a human action that takes hours or days. Once a minute is plenty and sits far inside every plan’s rate limit. Better still, register a webhook and let us tell you the moment it completes.

Where to go next

  • Webhooks — stop polling and get told when something happens.
  • API reference — every parameter of the calls you just made.
  • Errors — what to do when one of them fails.
  • Roadmap — what the API cannot do yet, before you design around it.
Quickstart · XOsign API docs