The REST API v1 endpoints of SI E-Sign Contracts & Waivers: list and read signed agreements, their audit trail and PDF, verify them and resend the signed copy. The key, limits, pagination and error format are the same as for all our apps: see the API overview. The same operations are in GraphQL: GraphQL API reference: E-Sign Contracts & Waivers.
Needs the E-Sign Contracts & Waivers app. It works on a store without Rentals & Bookings. Make the key in the app under Settings › API access; a key made in any of our apps works too, because keys belong to the store. On a store without the app, every endpoint here answers 403 with the code rentals_rest_app_not_installed and data.app: "contracts".
The store’s signed agreements. See Signed agreements, Verify and record keeping. {id} is the agreement’s id, as in the order’s _contract attribute (8 to 32 letters and digits).
The examples use two shell variables, API="https://YOUR-API-ADDRESS/api/v1" and KEY="sirb_your_secret_key". GET needs a read key; everything else needs a key with Allow changes (write).
Signed agreements #
An agreement’s status is signed (signed, but the order isn’t placed or linked yet), linked (on its order) or redacted (personal data removed). stored is verified (the stored PDF matches its hash), none (no stored copy yet: the PDF link gives a watermarked preview) or altered (the stored PDF no longer matches its hash: it is never served).
GET /api/v1/contracts #
Agreements, newest first. Paged. Parameters: status (signed, linked or redacted), search (an order name, or the signer’s name or email), order_id.
curl -s "$API/contracts?status=linked&per_page=20" -H "Authorization: Bearer $KEY"
# 200, X-Total: 48
[{"id": "Q7mK2pX9aLr4", "status": "linked", "method": "typed", "method_label": "Typed name", "signer_name": "Jordan Lee",
"signer_email": "[email protected]", "signed_at": "2026-11-02T14:03:40+00:00", "signed_at_label": "Nov 2, 2026 9:03 AM",
"order_id": 5550001, "order_name": "#1042", "has_pdf": true, "redacted": false}]
GET /api/v1/contracts/{id} #
One agreement: the summary above, plus how and where it was signed and the evidence: signature_id, customer_id, ip, user_agent, typed_name, has_drawing, consent_text, terms_sha256, pdf_sha256, pdf_sha256_unsigned, pdf_generated_at, pdf_error, emailed_at, email_error, linked_at, stored, items, audit. 404 not_found otherwise.
curl -s "$API/contracts/Q7mK2pX9aLr4" -H "Authorization: Bearer $KEY"
# 200 (trimmed)
{"id": "Q7mK2pX9aLr4", "status": "linked", "method": "typed", "signer_name": "Jordan Lee", "order_id": 5550001,
"ip": "203.0.113.7", "typed_name": "Jordan Lee", "has_drawing": false,
"consent_text": "I agree to sign this rental agreement electronically, …",
"terms_sha256": "216c…d1f4", "pdf_sha256": "2b75…500f", "stored": "verified", "items": [],
"audit": [{"event": "consent_given", "label": "Consent to sign electronically given", "at": "2026-11-02T14:03:39Z",
"detail": "browser time 2026-11-02 14:03:39.950 UTC", "hash": "0149a4cb2a25…db1540"}]}
GET /api/v1/contracts/{id}/audit #
The audit trail, oldest first: [{event, label, at, detail, hash}]. Each entry is chained to the one before (signed, linked, PDF made, emailed, downloaded, verified …).
GET /api/v1/contracts/{id}/pdf #
A link to the signed PDF that works for 10 minutes without a key: {"kind": "signed", "url": "https://…", "expires_at": "…"}. Before a copy is stored, kind is preview (a watermarked preview). Downloads are recorded in the audit trail. 409 altered when the stored PDF no longer matches its hash.
curl -s "$API/contracts/Q7mK2pX9aLr4/pdf" -H "Authorization: Bearer $KEY"
POST /api/v1/contracts/{id}/verify #
Checks the stored PDF’s hash, the terms’ hash and the audit chain again. The check is recorded in the trail.
curl -s -X POST "$API/contracts/Q7mK2pX9aLr4/verify" -H "Authorization: Bearer $KEY"
# 200
{"ok": true, "redacted": false, "file": true, "file_hash_ok": true, "terms_hash_ok": true, "chain_ok": true,
"chain": {"…": "…"}, "stored_hash": "2b75…500f", "computed_hash": "2b75…500f", "checked_at": "2026-11-30T10:15:00+00:00"}
POST /api/v1/contracts/{id}/resend #
Emails the signed copy to the signer again: {"sent": true, "contract": {…}}.
GET /api/v1/contracts/orders/{orderId} #
An order’s agreement: {"order_id": 5550001, "contract": {…}}, or "contract": null when the order has none. An order that isn’t linked yet is linked now, from its _contract attribute.
curl -s "$API/contracts/orders/5550001" -H "Authorization: Bearer $KEY"
