Signature requests
Send a template for signature, poll its status, and download the signed document.
A signature request sends a published template to its signing parties and tracks it to completion.
Send for signature
curl -X POST https://api.instaspace.ai/api/v1/esign/submissions \
-H "Authorization: Bearer isk_live_..." \
-H "Content-Type: application/json" \
-d '{
"templateId": "0b9f6f2e-…",
"submitters": [
{ "role": "First Party", "name": "Dana Client", "email": "dana@client.com" },
{ "role": "Second Party", "name": "Sami Counsel", "email": "sami@yourfirm.com" }
],
"values": { "client_name": "Client Co. LLC" },
"message": "Please sign before Friday.",
"sendEmail": true,
"idempotencyKey": "crm-deal-4821"
}'submitters— exactly one recipient per role the template defines (up to 10).values— optional. Keyed by variable key (flowtemplates) or field name (coordinatetemplates); see reading the template shape.message— optional note carried in the signature email, so it only applies whensendEmailis true.sendEmail— defaults totrue. Whenfalse, signers are not emailed; share the signing links yourself.idempotencyKey— optional, and you should always send one. Retrying a request with a key already used returns the original signature request instead of sending a duplicate round of emails, and doesn't count against your monthly allowance again. It is also how you recover a response lost in transit: replay the same call rather than guessing whether the first one landed.
The response is the signature request:
{
"id": "7c1d34…",
"templateId": "0b9f6f2e-…",
"templateName": "Mutual NDA",
"status": "pending",
"submitters": [
{
"role": "First Party",
"name": "Dana Client",
"email": "dana@client.com",
"status": "awaiting",
"completedAt": null
}
],
"hasSignedDocument": false,
"createdAt": "2026-08-06T12:00:00.000Z",
"completedAt": null
}Poll status
curl https://api.instaspace.ai/api/v1/esign/submissions/{id} \
-H "Authorization: Bearer isk_live_..."The request's status moves through pending → opened → completed, or
ends as declined, expired, or voided. Each submitter carries their own
status (awaiting, opened, completed, declined).
Stop polling on any of the four terminal statuses, not just completed.
A signer can decline from the signing page, the workspace can void a request,
and a request can expire — a poller that waits only for completed keeps
asking forever about a request that has already finished.
hasSignedDocument turns true in the same operation that sets
status: completed, so there is no window where a request reads completed but
the document is not there yet.
Send a reminder
curl -X POST https://api.instaspace.ai/api/v1/esign/submissions/{id}/remind \
-H "Authorization: Bearer isk_live_..."Signing is sequential, so this reminds whichever signer's turn it currently is — the same target the in-app "Resend" action picks. There is no way to choose a different recipient; the request takes no body.
{ "reminded": true, "recipient": { "email": "dana@client.com" } }When the request is already completed, declined, expired or voided (or every
submitter has otherwise already acted), this still answers 200 rather than
an error:
{ "reminded": false, "reason": "no_pending_signer" }so an unattended integration can call this on a schedule and treat "nothing to do" as routine rather than a failure to handle specially.
Reminding the same signer again inside 15 minutes returns 429 with a
Retry-After header instead of sending a second email:
{
"statusCode": 429,
"message": "A reminder was already sent to this signer recently",
"code": "reminder_cooldown",
"retryAfterSeconds": 612
}List signature requests
curl "https://api.instaspace.ai/api/v1/esign/submissions?status=pending&limit=25" \
-H "Authorization: Bearer isk_live_..."Newest first. Optional status and templateId filter, limit (1–100,
default 25) and offset page:
{ "submissions": [], "total": 0, "limit": 25, "offset": 0 }This is how an unattended integration reconciles. If a send call times out you
cannot know whether it took effect — replay it with the same idempotencyKey,
which returns the original request instead of sending a second one, or find it
here.
Check your remaining allowance
curl https://api.instaspace.ai/api/v1/esign/usage \
-H "Authorization: Bearer isk_live_..."{
"signatureRequests": {
"limit": 50,
"used": 12,
"remaining": 38,
"periodStart": "2026-08-01T00:00:00.000Z"
}
}limit and remaining are the string "unlimited" on Enterprise. Reading
usage is never metered — check it before a batch rather than discovering the
ceiling as a failed send.
Download the signed document
Once hasSignedDocument is true — before that the endpoint answers 404:
curl -L -o signed.pdf \
https://api.instaspace.ai/api/v1/esign/submissions/{id}/document \
-H "Authorization: Bearer isk_live_..."You get the executed PDF with the audit certificate appended — signer identities, IP addresses, timestamps and document hashes — in one file. The download is recorded in the workspace audit log with your API key's identity.
There are no outbound webhooks yet — poll the status endpoint for updates. A completed request also notifies the workspace inside instaSpace as usual.

