Before you begin
- Get a bearer token for the workspace: an API key, or an OAuth access token. To create an API key, go to workspace settings in the sajn app, then Utvecklare (Developer) > API-nycklar (API keys). Store it in the
SAJN_API_KEYenvironment variable. - Make sure your workspace role has the permissions for the task:
MANAGE_FORMto create, edit, and publish forms,DELETE_FORMto delete them, andREAD_FORM_SUBMISSIONSto read responses. To publish, you also need permission to create documents and send them without approval, and the workspace must not require approval before sending.
Create and publish a form
1
Create a draft
Send a Replace
POST request to /api/v1/forms. To copy an existing template, send its templateId. To start with a blank document and one respondent party, send {}:TEMPLATE_ID with the template to copy. The response is the form: its id, templateId (the form’s own template), respondentPartyId, url, its settings, and publishIssues. The copy has new field and party IDs, and later changes to the source template don’t affect it.2
Configure the questions and settings
Send a Replace
PATCH request to /api/v1/forms/FORM_ID:FORM_ID with the form id. The request works as follows:- Settings you leave out stay unchanged, and
nullclears a nullable setting. Forpassword, leaving it out keeps the password,nullremoves it, and a string replaces it. Responses showhasPassword, never the password. questionsreplaces the whole ordered list. The kinds areNAME,EMAIL,PHONE,FIELD,TEXT,HEADING, andPARAGRAPH. TheNAMEquestion is always required.- A
FIELDquestion writes its answer into the document, through akeyfrom the form’sslots. ATEXTanswer is stored on the submission only. redirectUrlmust be anhttporhttpsURL.
3
Edit the template and the respondent
Read
GET /api/v1/forms/FORM_ID/template for the template’s settings, content blocks, and parties. Then change them with the form’s template endpoints:PATCH /api/v1/forms/FORM_ID/template: changenameandtemplateMeta, such assigningMode. The response is the template.PUT /api/v1/forms/FORM_ID/template/fields: replacefieldswith the complete ordered list of content blocks. Include the IDs of fields to keep, and leave out IDs for new fields. Fields you leave out are deleted, and existing fields can’t change type.PUT /api/v1/forms/FORM_ID/template/parties: replaceparties. Include the IDs of parties to keep, and leave out IDs for new parties. Properties you leave out on kept parties, including contact links and write-only PINs, stay unchanged, andnullclears a property. Parties you leave out are deleted. Like other parties, these nest their company incompany, withname,orgNumber, androle.PUT /api/v1/forms/FORM_ID/respondentwith{ "partyId": "PARTY_ID" }: choose whichSIGNERparty the visitor becomes.
GET /api/v1/forms/FORM_ID afterward for publishIssues and the bindable slots.4
Publish the form
url. Visitors answer and sign on the hosted pages; the API can’t submit or sign on their behalf.To stop new submissions and keep the URL for later, send a POST request to /api/v1/forms/FORM_ID/unpublish. To replace the link, for example after it leaked, send a POST request to /api/v1/forms/FORM_ID/rotate-token; the response is the form with the new url. The old link stops working, including printed QR codes, but signing links already sent keep working.5
Sync the responses
Subscribe a webhook to The response has the submissions in
form.submitted to hear about each submission; the event’s data.object is the submission. To sync the submissions, page through the ones that changed since your last sync, oldest change first:data, plus hasMore and nextCursor. While hasMore is true, pass nextCursor as cursor with the same filters and sort. A submission can change while you page, so upsert each one by its ID.updatedAfterfinds status changes since your last sync.submittedAfterfilters by submission time.statustakesSTARTED,SUBMITTED,COMPLETED, orEXPIRED.- Each submission has the respondent’s contact details, the answers, timestamps, and the
documentIdof the document it created. Read the document’s content and signing progress through the document endpoints. Submissions don’t include IP addresses, user agents, or signing tokens.
Delete a form
DELETE /api/v1/forms/FORM_ID permanently removes the form, its template, and its submission records, and returns { "id": "FORM_ID", "deleted": true }. Export the responses you need first. Documents the form already created stay as ordinary documents.
Handle errors
400 VALIDATION_FAILED: a question or a setting is invalid. Readissuesfor the path.- An error from
publish: a readiness check failed. ReadGET /api/v1/forms/FORM_IDforpublishIssues, fix each one, and publish again. 403 PERMISSION_DENIEDor403 INSUFFICIENT_SCOPE: your role or token lacks a permission or scope from the preceding table.
Next steps
Templates and forms
Learn how forms differ from templates.
Webhook events
Handle
form.submitted and document events.Create a draft form
See the form endpoints in the API reference.

