How to use Odin Sign

Three ways in: the web app for people, a REST API for your systems, and an MCP server for AI agents. All three sign as your account, with your handwriting and your certificate.

1. Web app

Open https://signatures.ai-water.uk/app with the sign-in link we e-mail you. Save your signature once (draw it or upload a photo), then drop in a PDF, PNG or JPEG, tap where the signature goes and download the signed file. On a phone, use “Add to Home Screen” to install it like an app.

2. REST API

Create a key in the app under API & agents (keys start with osk_ and are shown once). Send it as a bearer token. Base URL:

https://signatures.ai-water.uk/v1

Sign a PDF in three calls

KEY=osk_...   # from the app
# 1. Describe the document. purpose is private; public_description appears on the QR page.
curl -s https://signatures.ai-water.uk/v1/prepare -H "Authorization: Bearer $KEY" -H "content-type: application/json" -d '{
  "request_key": "contract-2026-0042-v1",
  "context": {"purpose": "Supplier contract approval", "public_description": "Contract 2026-0042",
              "source_ref": "erp/contracts/0042", "inferred_fields": [], "claimed_document_date": null}}'
# -> {"id": "RECORD_ID", "context_to_disclose": {...}, ...}

# 2. Issue the stamp (only after the signer has seen the context above).
curl -s https://signatures.ai-water.uk/v1/records/RECORD_ID/issue -H "Authorization: Bearer $KEY" \
  -H "content-type: application/json" -d '{"context_disclosed": true}'

# 3. Send the final PDF; Odin places the stamp, signs (PAdES) and archives it.
curl -s https://signatures.ai-water.uk/v1/records/RECORD_ID/sign-pdf -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d "{\"pdf_b64\": \"$(base64 < contract.pdf | tr -d '\n')\", \"layout\": \"compact\",
       \"placement\": {\"page\": -1, \"x_mm\": 120, \"y_mm\": 20, \"width_mm\": 60}}" \
  | python3 -c 'import sys,json,base64; d=json.load(sys.stdin); open("contract-signed.pdf","wb").write(base64.b64decode(d["pdf_b64"])); print(d["verification_url"], d["sha256"])'

Endpoints

Method and pathWhat it does
POST /v1/prepareCreate (idempotently) a draft record. request_key: 16-128 characters, one per document. public_description: at most 240 bytes, shown publicly - no personal data.
POST /v1/records/{id}/issueIssue the stamp. {"context_disclosed": true} is your statement that the signer saw the context.
POST /v1/records/{id}/sign-pdfpdf_b64 (max 15 MiB), optional layout (full | compact), placement (page: 1-based, negative from the end; x_mm, y_mm from the bottom-left; width_mm 30-250), certify (lock an unsigned PDF). Returns the signed PDF and its SHA-256.
GET /v1/records/{id}/stamp.pngThe stamp image (?layout=compact), if you place it yourself. Then report placement and archive events.
POST /v1/records/{id}/events{"type":"placement","document_ref":"…","evidence":"…"}, {"type":"archive","pdf_b64":"…"}, {"type":"revoke","reason":"…"}.
GET /v1/records/{id}Your record: context, state, events, archived SHA-256.

A record signs one document. A changed document needs a new record (the archived file cannot be replaced). Earlier signatures in a PDF stay valid when you add yours.

Errors and limits

401Missing, wrong or revoked key.
403Not your record, account suspended, or trial ended / no active plan.
409Wrong state, e.g. signing a record twice or reusing a request key with different context.
422The PDF cannot be signed (encrypted, rotated page, stamp does not fit).
429Rate limit: 120 requests a minute per key and 30 new stamps an hour per account by default. Retry after the Retry-After seconds.

3. AI agents (MCP)

Any MCP client that supports remote servers over HTTP can use Odin Sign. Server URL and header:

URL:     https://signatures.ai-water.uk/v1/mcp
Header:  Authorization: Bearer osk_...

Claude Code

claude mcp add --transport http odin-sign https://signatures.ai-water.uk/v1/mcp --header "Authorization: Bearer osk_..."

Cursor, Windsurf and other clients with an mcp.json

{"mcpServers": {"odin-sign": {"url": "https://signatures.ai-water.uk/v1/mcp", "headers": {"Authorization": "Bearer osk_..."}}}}

Tools

prepare_signature, issue_stamp, get_stamp, sign_pdf, report_placement, archive_pdf, get_record, revoke_record. The server tells the agent its rules: sign only what the person authorised in the current request, show them the public description before issuing, one record per document, and report the verification link and SHA-256 back.

Checking a signed document