Tracking and results
Once a document is out, check its status, read the activity history, and download the signed PDF and the certificate of completion when it's done.
Check for updates
The API doesn't send webhooks yet, so check for changes on a schedule:
- One document:
GET /documents/{id}and readstatusand each recipient'sstatus. - Many documents:
GET /documents?status=completed&created_after=…on a schedule, then download anything new.
Every few minutes is plenty for most apps. Signers usually take minutes or hours, not seconds.
// Every 5 minutes: download documents completed since the last run
const since = lastRun.toISOString();
for await (const d of allDocuments({ status: "completed", created_after: since })) {
if (!alreadySaved(d.id)) await saveSignedPdf(d.id);
}# Every 5 minutes: download documents completed since the last run
for d in all_documents(status="completed", created_after=last_run.isoformat()):
if not already_saved(d["id"]):
save_signed_pdf(d["id"])created_after filters by when the document was created, so look back far enough to include documents that are still out. The allDocuments and all_documents helpers are on the conventions page.
Activity history
GET /documents/{id}/events lists everything that happened to a document, oldest first: sent, viewed, signed, reminders and more.
{
"object": "list",
"data": [
{
"id": "evt_k2m8q4",
"object": "event",
"type": "sent",
"description": "Sent for signature",
"actor": "api",
"recipient_id": null,
"created_at": "2026-11-09T15:04:05Z"
}
],
"has_more": false
}Each event has an actor that says who did it: owner, api, recipient, system, admin, ai_claude or ai_chatgpt. Use description to show the history to a person, and type to act on it.
type |
What happened |
|---|---|
sent |
Sent for signature |
sender_not_signing |
Sent without the sender's own signature |
self_sign |
Ready for the sender to sign |
send_failed |
Sending failed; tokens returned |
notified |
Signing request emailed |
texted |
Signing request texted |
reminded |
Reminder emailed |
text_reminded |
Reminder texted |
text_delivered |
Text delivered |
text_failed |
Text not delivered |
text_not_sent |
Couldn't text, so it was emailed instead |
opened |
A recipient opened it |
sample_opened |
A recipient opened the sample PDF |
code_sent |
Text code sent |
verified |
Text code confirmed |
verify_failed |
Wrong text code entered |
verify_locked |
Link locked after too many wrong codes |
consented |
Agreed to sign electronically |
link_reissued |
A fresh signing link was sent |
signed |
A recipient signed |
declined |
A recipient declined |
recipient_email_changed |
A recipient's email was changed |
cancelled |
Cancelled; links stopped working |
completed |
Everyone signed |
sealed |
Signed copy ready |
delivered |
Signed copy emailed |
downloaded |
A recipient downloaded the signed copy |
ai_created |
Created with Ask Ready |
ai_suggested |
Ready it placed fields |
ai_accepted |
Ready it's fields accepted |
New types may be added, so show description for any you don't recognize.
Download the signed PDF
GET /documents/{id}/signed-pdf redirects (302) to a download link that works for 10 minutes. Request it again whenever you need a new link, and don't store the link itself.
curl -fL https://api.readyink.ai/v1/documents/doc_c9x1q8/signed-pdf \
-H "Authorization: Bearer $READYINK_API_KEY" -o signed.pdfconst res = await fetch(`${BASE}/documents/${docId}/signed-pdf`, { headers });
if (!res.ok) throw new Error((await res.json()).error.message);
await writeFile(`${docId}.pdf`, Buffer.from(await res.arrayBuffer()));res = requests.get(f"{BASE}/documents/{doc_id}/signed-pdf", headers=H)
res.raise_for_status() # 409 not_completed until everyone has signed
open(f"{doc_id}.pdf", "wb").write(res.content)Download the certificate
GET /documents/{id}/certificate works the same way and returns the certificate of completion, which records who signed and when.
Both downloads work only on completed documents. Otherwise you get 409 not_completed.
Verify a file
Each document has two SHA-256 hashes:
version_hash: the document as it was sent.final_hash: the sealed, signed PDF.
To confirm a stored PDF hasn't changed, hash it and compare with final_hash. The signed copy is also stamped with readyink_id.
shasum -a 256 signed.pdf