Before you begin
- Store your API key in the
SAJN_API_KEYenvironment variable. To create a key, go to workspace settings in the sajn app, then Utvecklare (Developer) > API-nycklar (API keys). - Have a
DRAFTdocument with content and at least one party. For more information, see Create a document. - Give each party an address for its delivery method: an email address for
EMAIL, a phone number forSMS.
Send the document
1
Send the draft
Send a Replace The document’s status is
POST request to /api/v1/documents/DOCUMENT_ID/send. The optional customMessage replaces the invitation message:DOCUMENT_ID with the ID of your draft. The Idempotency-Key header makes a retry of the same request safe: the API replays the first response instead of sending the document twice.The response is the document, in the same shape as Get a document by ID without fields. The following example leaves out documentMeta and parties:PENDING. Each party is invited on its own deliveryMethod. With SEQUENTIAL signing, only the first party in signingOrder is invited.If you lack the permission to send without approval, the request fails with 409 APPROVAL_REQUIRED and the document stays a DRAFT. Request an approval instead, as described in the following step.2
Optional: Request an approval
To submit the draft for internal approval, send a Replace
POST request to /api/v1/approval-requests with the documentId and the user IDs of the approvers in approverIds. To submit the approvers already on the document, leave out approverIds:APPROVER_USER_ID with the id of a member from GET /api/v1/members?permission=APPROVE_DOCUMENT.The response is the approval request, with status PENDING. The document’s status changes to PENDING_APPROVAL, and sajn notifies the approvers. When the request is approved, sajn sends the document for signing, unless the request has autoSend set to false. In that case, the document stays PENDING_APPROVAL until the user who requested the approval sends it with POST /api/v1/documents/DOCUMENT_ID/send. For more information, see Request approval of a document.3
Share signing links for parties you reach yourself
A party with Replace The signing URL works without a login, so treat it as a secret. Every request to this endpoint is recorded in the document’s audit log, so fetch the URL only when you’re about to use it. To show the signing page inside your app, see Embedded signing.
"deliveryMethod": "NONE" gets no invitation. To show the signing page in your own app or send the link yourself, get the party’s signingUrl:PARTY_ID with the party’s id. The response is the party, including its signingUrl. The following example leaves out some party fields:4
Track progress
We recommend subscribing to webhooks instead of polling. The Each party has a A
document.party.signed event fires when a party signs, and document.completed fires when everyone has signed and the sealed PDF is ready. For more information, see Webhooks and Event types.To check the state at any time, get the document:readStatus of NOT_OPENED, OPENED, or READ, and a signingStatus of NOT_SIGNED, SIGNED, or REJECTED. The following example leaves out most fields:sendStatus of BOUNCED or FAILED means the invitation didn’t arrive. Correct the address with Update a party, and then send a reminder.5
Download the sealed PDF
When every signing party has signed, the document’s status changes to For the response and the other file types, see Download documents.
COMPLETED and sajn seals the PDF. Get a download URL for it with the SIGNED file type:Personalize the invitation message
customMessage supports line breaks as \n and the following variables, written as {{variableName}}. Each party gets its own copy of the message.
- Recipient:
{{firstName}},{{lastName}},{{fullName}},{{recipientEmail}},{{recipientPhone}},{{recipientCompanyName}},{{recipientCompanyRole}}, and{{recipientCompanyOrgNumber}}.{{recipientFirstName}},{{recipientLastName}}, and{{recipientFullName}}are the same as the first three. - Sender:
{{senderFirstName}},{{senderLastName}},{{senderFullName}},{{senderEmail}},{{senderPhone}}, and{{senderCompanyName}}. - Document:
{{documentName}},{{documentId}},{{documentValue}},{{documentCreatedDate}},{{expirationDate}}, and{{signUrl}}. - Custom fields:
{{custom.FIELD_SLUG}}, whereFIELD_SLUGis the field name in lowercase with hyphens. For example, a field named “Start date” is{{custom.start-date}}. Secured custom fields aren’t available.
Remind parties and change the deadline
- To remind parties who haven’t signed, send a
POSTrequest to/api/v1/documents/DOCUMENT_ID/reminders. Each party can get one reminder per 24 hours. - To move the deadline of a sent document, send a
POSTrequest to/api/v1/documents/DOCUMENT_ID/extend-expiration.
Withdraw a sent document
To stop the signing, for example to fix the content or the signing order, withdraw the document:DRAFT, existing signatures are removed, and every party who was invited gets an email with the reason. Make your changes, and then send the document again.
Handle errors
Branch on the errorcode:
409 INVALID_STATE: the document isn’t aDRAFT, or its approval request is still pending. A document inPENDING_APPROVALis sent when the request is approved.409 APPROVAL_REQUIRED: you lack the permission to send without approval. Request an approval with Request approval of a document.403 LIMIT_EXCEEDED: the organization reached its monthly limit of sent documents.403 PERMISSION_DENIED: a party’s signing method isn’t included in the organization’s plan. TheuserMessagenames the method.
Next steps
Multi-party signing
Control the signing order and the role of each party.
Webhooks
Get notified when parties sign.
Download documents
Get the sealed PDF and the audit trail.
Send document for signing
See the endpoint in the API reference.

