Templates API
Reusable documents with roles and fields. Create an envelope from a template by filling its roles.
List templates
/v1/templatesYour templates and the ones your team shares with you, most recently updated first.
Required scope:templates:read
Query parameters
searchstringMatches the title.
pageintegerPage number, starting at 1.
default 1
per_pageintegerItems per page.
default 20
Response
A page of templates.
objectstring= "list"dataarray of TemplateChild attributes (Template)
objectstring= "template"idstring · uuidtitlestringdescriptionstring | nullrolesarray of TemplateRoleChild attributes (TemplateRole)
role_namestringName you pass in
roles[].role_namewhen using the template.rolestringsignersigns remotely;in_person_signersigns on your device (embedded signing);approverapproves without signing;viewermust open the document;ccgets a copy when it completes.One of
signerin_person_signerapproverviewerccrouting_orderinteger
field_countintegerpage_countintegershared_with_teambooleanusesintegerHow many envelopes were created from it.
created_atstring · date-timeupdated_atstring · date-time
pageintegerper_pageintegertotalintegerhas_morebooleanWhether another page follows.
Response headers: X-Request-Id, Signkoi-Version, X-RateLimit-Limit, X-RateLimit-Remaining.
Errors
- 401Missing, invalid, expired or revoked API key (
api_key_missing,invalid_api_key). - 403The key lacks a required scope (
insufficient_scope) or the account is suspended (account_suspended). - 422Invalid parameters (
validation_failed, withparamanderrors) or a business rule failed (e.g.missing_signature_field). - 429Too many requests (
rate_limited): your key's per-minute limit, or an endpoint's own limit. Wait forRetry-Afterseconds. - 500Something went wrong on our side (
internal_error). Safe to retry with the same Idempotency-Key.
Every error uses the error object.
Example request
curl https://signkoi.com/api/v1/templates \
-H "Authorization: Bearer $SIGNKOI_API_KEY"Example response
{
"object": "list",
"data": [
{
"object": "template",
"id": "3f8a6d2c-1e9b-4c75-b0a4-7d2e5f8c9a16",
"title": "Mutual NDA",
"description": "Two-party non-disclosure agreement.",
"roles": [
{
"role_name": "Client",
"role": "signer",
"routing_order": 1
},
{
"role_name": "Company",
"role": "signer",
"routing_order": 2
}
],
"field_count": 6,
"page_count": 2,
"shared_with_team": true,
"uses": 41,
"created_at": "2026-08-02T11:20:00Z",
"updated_at": "2026-10-28T16:45:13Z"
}
],
"page": 1,
"per_page": 20,
"total": 1,
"has_more": false
}Retrieve a template
/v1/templates/{id}The template with its roles and fields. Fields reference roles by role_name.
Required scope:templates:read
Path parameters
idstring · uuidrequiredTemplate id.
Response
objectstring= "template"idstring · uuidtitlestringdescriptionstring | nullrolesarray of TemplateRoleChild attributes (TemplateRole)
role_namestringName you pass in
roles[].role_namewhen using the template.rolestringsignersigns remotely;in_person_signersigns on your device (embedded signing);approverapproves without signing;viewermust open the document;ccgets a copy when it completes.One of
signerin_person_signerapproverviewerccrouting_orderinteger
field_countintegerpage_countintegershared_with_teambooleanusesintegerHow many envelopes were created from it.
created_atstring · date-timeupdated_atstring · date-timefieldsarray of TemplateFieldChild attributes (TemplateField)
objectstringrequired= "field"idstringrequiredField id.
role_namestringThe template role that fills this field.
typestringrequiredOne of
signatureinitialsnameemailcompanytitledatetextnumbercheckboxradiodropdownattachmentformulanotepageintegerrequiredPage number, 1-based.
≥ 1
xnumberrequiredLeft edge as a fraction of the page width (origin top-left).
0–1
ynumberrequiredTop edge as a fraction of the page height (origin top-left).
0–1
widthnumberrequiredWidth as a fraction of the page width.
0.02–1
heightnumberrequiredHeight as a fraction of the page height.
0.01–1
requiredbooleanrequiredWhether the recipient must fill the field.
labelstring | nullLabel shown to the recipient.
max 120 chars
placeholderstring | nullmax 120 chars
optionsarray of string | nullChoices for
dropdown(and the value of eachradiobutton).max 50 items
group_namestring | nullGroups
radiobuttons; required for radio fields.max 120 chars
default_valuestring | nullPre-filled value. Required for
notefields (the text shown).max 2000 chars
validationstring | nullInput format check for
textfields.One of
emailnumberphonezipdateformulastring | nullOnly for
formulafields, e.g.[qty] * [price].max 500 chars
read_onlybooleanfont_sizeinteger | null8–20
Response headers: X-Request-Id, Signkoi-Version, X-RateLimit-Limit, X-RateLimit-Remaining.
Errors
- 401Missing, invalid, expired or revoked API key (
api_key_missing,invalid_api_key). - 403The key lacks a required scope (
insufficient_scope) or the account is suspended (account_suspended). - 404No such resource, or it belongs to someone else (
resource_missing, e.g. "No such envelope." / "No such recipient."). - 429Too many requests (
rate_limited): your key's per-minute limit, or an endpoint's own limit. Wait forRetry-Afterseconds. - 500Something went wrong on our side (
internal_error). Safe to retry with the same Idempotency-Key.
Every error uses the error object.
Example request
curl https://signkoi.com/api/v1/templates/3f8a6d2c-1e9b-4c75-b0a4-7d2e5f8c9a16 \
-H "Authorization: Bearer $SIGNKOI_API_KEY"Example response
{
"object": "template",
"id": "3f8a6d2c-1e9b-4c75-b0a4-7d2e5f8c9a16",
"title": "Mutual NDA",
"description": "Two-party non-disclosure agreement.",
"roles": [
{
"role_name": "Client",
"role": "signer",
"routing_order": 1
},
{
"role_name": "Company",
"role": "signer",
"routing_order": 2
}
],
"field_count": 6,
"page_count": 2,
"shared_with_team": true,
"uses": 41,
"created_at": "2026-08-02T11:20:00Z",
"updated_at": "2026-10-28T16:45:13Z",
"fields": [
{
"object": "field",
"id": "48213",
"type": "signature",
"page": 1,
"x": 0.12,
"y": 0.82,
"width": 0.3,
"height": 0.06,
"required": true,
"label": null,
"placeholder": null,
"options": null,
"group_name": null,
"default_value": null,
"validation": null,
"formula": null,
"read_only": false,
"font_size": null,
"role_name": "Client"
}
]
}Create an envelope from a template
/v1/templates/{id}/envelopesFills each template role with a person and creates an envelope with the template's document and fields. Sent immediately unless send is false; if sending fails, the draft is deleted, the quota refunded and you get a 422 with the reason. Role names match case-insensitively, and roles may be omitted when every role already has a name and email. Needs both the templates:write and envelopes:write scopes, and counts against your monthly document allowance.
Required scopes:templates:writeenvelopes:write
Path parameters
idstring · uuidrequiredTemplate id.
Headers
Idempotency-KeystringAny unique string (1–255 chars), e.g. a UUID. Retrying with the same key and body within 24 hours returns the original response instead of repeating the action.
Request body application/json
titlestringDefaults to the template title.
max 150 chars
messageTemplateMessageInputChild attributes (TemplateMessageInput)
subjectstring | nullDefaults to "Please sign: {title}".
max 255 chars
bodystring | nullmax 5000 chars
rolesarray of objectWho fills each template role.
role_namematching is case-insensitive. May be omitted when every role of the template already has a name and email.Child attributes
role_namestringrequiredMust match a role of the template (case-insensitive).
namestringrequiredRecipient name.
max 255 chars
emailstring · emailrequiredmax 255 chars
languagestringLanguage of the emails and signing page. Defaults to your account language.
One of
enesfrdeptitnlplrujazhhiverificationstringExtra identity check before signing. Defaults to
none.One of
noneaccess_codeemail_otpsms_otpaccess_codestring | nullRequired when
verificationisaccess_code. Share it with the recipient yourself; it is stored hashed and never returned.max 64 chars
phonestring | nullE.164 phone number, required when
verificationissms_otp. Returned masked.
metadataMetadataYour own key/value pairs (string → string). Up to 20 keys; keys up to 40 characters of letters, digits,
_,.and-; string values up to 500 characters (numbers are converted to strings; booleans and nested objects are rejected). Echoed on the envelope and in webhooks; filter lists withmetadata[key]=value.max 20 keys
expires_in_daysinteger | nullDays the envelope stays signable after sending;
null= never expires.One of
13730sendbooleanSend immediately (default). Pass
falseto create a draft. If sending fails, the draft is deleted, the quota refunded and you get a 422 with the reason.default true
Response
An envelope including its fields (returned by retrieve, create and every update).
objectstringrequired= "envelope"idstring · uuidrequiredtitlestringrequiredstatusstringrequireddraft(not sent yet) →sent(out for signature) →completed(everyone finished). An envelope can also end asdeclined,voidedorexpired.One of
draftsentcompleteddeclinedvoidedexpiredmessageobjectEmail sent to recipients.
Child attributes
subjectstring | nullbodystring | null
metadataMetadataYour own key/value pairs (string → string). Up to 20 keys; keys up to 40 characters of letters, digits,
_,.and-; string values up to 500 characters (numbers are converted to strings; booleans and nested objects are rejected). Echoed on the envelope and in webhooks; filter lists withmetadata[key]=value.max 20 keys
template_idstring · uuid | nullTemplate the envelope was created from.
sourcestringCreated through the API or on the website.
One of
apiapppage_countintegerremindersobjectChild attributes
delay_daysinteger | nullDays before the first reminder.
frequency_daysinteger | nullDays between reminders after that.
recipientsarray of RecipientrequiredSorted by routing order.
Child attributes (Recipient)
objectstringrequired= "recipient"idstring · uuidrequiredrolestringrequiredsignersigns remotely;in_person_signersigns on your device (embedded signing);approverapproves without signing;viewermust open the document;ccgets a copy when it completes.One of
signerin_person_signerapproverviewerccrole_namestring | nullTemplate role this recipient fills, if any.
namestring | nullemailstring · email | nullrouting_orderintegerrequiredstatusstringrequiredpending: not their turn yet (or the envelope is a draft);sent: invited;viewed: opened the envelope;completed: finished;declined;delegated: handed over to someone else.One of
pendingsentviewedcompleteddeclineddelegatedlanguagestring | nullverificationstringOne of
noneaccess_codeemail_otpsms_otpphonestring | nullMasked, e.g.
+44 ••• ••• 4821.sent_atstring · date-time | nullviewed_atstring · date-time | nullcompleted_atstring · date-time | nulldeclined_atstring · date-time | nulldecline_reasonstring | null
filesobjectrequiredDownload URLs (authenticate with your API key).
signedandcertificatearenulluntil the envelope is completed.Child attributes
originalstring · urisignedstring · uri | nullcertificatestring · uri | null
created_atstring · date-timerequiredsent_atstring · date-time | nullcompleted_atstring · date-time | nulldeclined_atstring · date-time | nullvoided_atstring · date-time | nullvoid_reasonstring | nullexpires_atstring · date-time | nullAfter this the envelope can no longer be signed;
null= never.fieldsarray of FieldChild attributes (Field)
objectstringrequired= "field"idstringrequiredField id.
recipient_idstring · uuid | nullThe recipient who fills this field.
typestringrequiredOne of
signatureinitialsnameemailcompanytitledatetextnumbercheckboxradiodropdownattachmentformulanotepageintegerrequiredPage number, 1-based.
≥ 1
xnumberrequiredLeft edge as a fraction of the page width (origin top-left).
0–1
ynumberrequiredTop edge as a fraction of the page height (origin top-left).
0–1
widthnumberrequiredWidth as a fraction of the page width.
0.02–1
heightnumberrequiredHeight as a fraction of the page height.
0.01–1
requiredbooleanrequiredWhether the recipient must fill the field.
labelstring | nullLabel shown to the recipient.
max 120 chars
placeholderstring | nullmax 120 chars
optionsarray of string | nullChoices for
dropdown(and the value of eachradiobutton).max 50 items
group_namestring | nullGroups
radiobuttons; required for radio fields.max 120 chars
default_valuestring | nullPre-filled value. Required for
notefields (the text shown).max 2000 chars
validationstring | nullInput format check for
textfields.One of
emailnumberphonezipdateformulastring | nullOnly for
formulafields, e.g.[qty] * [price].max 500 chars
read_onlybooleanfont_sizeinteger | null8–20
valuestring | boolean | object | any | nullOnly present once the envelope is
completed. Text value;true/falsefor checkboxes;{ "filled": true }for signature, initials and attachment fields;nullif left empty.
Response headers: X-Request-Id, Signkoi-Version, X-RateLimit-Limit, X-RateLimit-Remaining.
Errors
- 401Missing, invalid, expired or revoked API key (
api_key_missing,invalid_api_key). - 402The plan's monthly document allowance is used up (
plan_limit). - 403The key lacks a required scope (
insufficient_scope) or the account is suspended (account_suspended). - 404No such resource, or it belongs to someone else (
resource_missing, e.g. "No such envelope." / "No such recipient."). - 422Invalid request (
validation_failed), or the envelope could not be sent:no_recipients,missing_recipient_details,unassigned_fields,missing_signature_field. - 429Too many requests (
rate_limited): your key's per-minute limit, or an endpoint's own limit. Wait forRetry-Afterseconds. - 500Something went wrong on our side (
internal_error). Safe to retry with the same Idempotency-Key.
Every error uses the error object.
Example request
curl -X POST https://signkoi.com/api/v1/templates/3f8a6d2c-1e9b-4c75-b0a4-7d2e5f8c9a16/envelopes \
-H "Authorization: Bearer $SIGNKOI_API_KEY" \
-H "Idempotency-Key: 5f1d7c1e-0b8a-4c2e-9f3d-61a2b7e4c905" \
-H "Content-Type: application/json" \
-d '{
"roles": [
{
"role_name": "Client",
"name": "Maya Patel",
"email": "maya@example.com"
},
{
"role_name": "Company",
"name": "Rina Koh",
"email": "rina@acme.example"
}
],
"metadata": {
"crm_deal_id": "D-10492"
},
"expires_in_days": 7
}'Example response
{
"object": "envelope",
"id": "9b2f4c1e-7a3d-4e8b-9c51-2d6f8a0b3e47",
"title": "Mutual NDA",
"status": "sent",
"message": {
"subject": "Please sign: Consulting agreement",
"body": "Hi Maya, here is the agreement we discussed."
},
"metadata": {
"crm_deal_id": "D-10492"
},
"template_id": "3f8a6d2c-1e9b-4c75-b0a4-7d2e5f8c9a16",
"source": "api",
"page_count": 3,
"reminders": {
"delay_days": 2,
"frequency_days": 3
},
"recipients": [
{
"object": "recipient",
"id": "c4e1a8f2-3b7d-4f19-a6c2-8e5d0b9f1a73",
"role": "signer",
"role_name": null,
"name": "Maya Patel",
"email": "maya@example.com",
"routing_order": 1,
"status": "sent",
"language": "en",
"verification": "email_otp",
"phone": null,
"sent_at": "2026-11-14T09:30:12Z",
"viewed_at": null,
"completed_at": null,
"declined_at": null,
"decline_reason": null
},
{
"object": "recipient",
"id": "e7b3d915-0c4a-4b6e-8f27-5a1c9d3e6b08",
"role": "cc",
"role_name": null,
"name": "Jonas Weber",
"email": "jonas@example.com",
"routing_order": 2,
"status": "pending",
"language": "de",
"verification": "none",
"phone": null,
"sent_at": null,
"viewed_at": null,
"completed_at": null,
"declined_at": null,
"decline_reason": null
}
],
"files": {
"original": "https://signkoi.com/api/v1/envelopes/9b2f4c1e-7a3d-4e8b-9c51-2d6f8a0b3e47/files/original",
"signed": null,
"certificate": null
},
"created_at": "2026-11-14T09:30:05Z",
"sent_at": "2026-11-14T09:30:12Z",
"completed_at": null,
"declined_at": null,
"voided_at": null,
"void_reason": null,
"expires_at": "2026-12-14T09:30:12Z",
"fields": [
{
"object": "field",
"id": "48213",
"recipient_id": "c4e1a8f2-3b7d-4f19-a6c2-8e5d0b9f1a73",
"type": "signature",
"page": 1,
"x": 0.12,
"y": 0.82,
"width": 0.3,
"height": 0.06,
"required": true,
"label": null,
"placeholder": null,
"options": null,
"group_name": null,
"default_value": null,
"validation": null,
"formula": null,
"read_only": false,
"font_size": null
},
{
"object": "field",
"id": "48214",
"recipient_id": "c4e1a8f2-3b7d-4f19-a6c2-8e5d0b9f1a73",
"type": "date",
"page": 1,
"x": 0.6,
"y": 0.84,
"width": 0.2,
"height": 0.04,
"required": true,
"label": null,
"placeholder": null,
"options": null,
"group_name": null,
"default_value": null,
"validation": null,
"formula": null,
"read_only": false,
"font_size": null
}
]
}