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 path | What it does |
|---|---|
POST /v1/prepare | Create (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}/issue | Issue the stamp. {"context_disclosed": true} is your statement that the signer saw the context. |
POST /v1/records/{id}/sign-pdf | pdf_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.png | The 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
401 | Missing, wrong or revoked key. |
403 | Not your record, account suspended, or trial ended / no active plan. |
409 | Wrong state, e.g. signing a record twice or reusing a request key with different context. |
422 | The PDF cannot be signed (encrypted, rotated page, stamp does not fit). |
429 | Rate 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
- Scan the QR: the record page shows who signed, when, the public description and whether the record is still valid. You can drop the file there to check it is byte-for-byte the archived one (it is not uploaded).
- Open the PDF in Adobe Acrobat or another reader to see the digital signature. Readers show the signer as unknown until they trust the Odin Sign root certificate.
- Public ledger: https://signatures.ai-water.uk/ledger shows the hash chain of all records, signed daily and timestamped by an outside authority.