- For HubSpot, use the built-in integration: send
integrationLinkwhen you create the document, and sajn prefills mapped custom fields and product tables from the deal and writes the signing status back to it. - For any other CRM, map CRM properties to the keys of the template’s form fields, and fill them in through the API.
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). - Create a template whose FORM fields have keys that match your CRM properties, such as
customer-nameandcontract-value. For more information, see Create documents from templates. - For HubSpot, connect HubSpot and configure the field mapping in the sajn app under Integrationer (Integrations).
Use the HubSpot integration
SendintegrationLink with the deal’s ID when you create the document:
HUBSPOT_DEAL_ID with the HubSpot deal ID. sajn prefills the custom fields and product-table rows that the workspace’s field mapping covers, and writes the signing status back to the deal. Values you send in customFields take precedence over prefilled ones. hubspot deals are the only supported record type.
Connect another CRM
1
Create the document and link it to the record
Create the document from the template, with the CRM record’s ID in Store the document
externalId:id on the CRM record. With externalId, you can also find the document from the record: GET /api/v1/documents?externalId=deal-12345 matches the value exactly.2
Map CRM properties to field keys
Keep the mapping in your code, from CRM property to field key. Keys stay the same for every document created from the template, and they survive edits to the text around the fields:To list the keys on a document, call
GET /api/v1/documents/DOCUMENT_ID/field-values.3
Write the values, and rewrite them when the deal changes
Send every value in one request. Call the same code whenever the deal changes before the document is sent:The function returns
remaining, the required values that are still empty. Values can change only while the document is a DRAFT, so stop syncing after you send it.The keys address form values. To replace a whole text section, such as the terms, update that TEXT or HTML field by its id with PATCH /api/v1/documents/DOCUMENT_ID/fields/FIELD_ID. Find the ID in GET /api/v1/documents/DOCUMENT_ID/fields.4
Write the signing status back to the CRM
Subscribe a webhook endpoint to
document.completed, and the party events you want to show in the CRM, such as document.party.signed. The event’s data.object is the document, so find the deal by its externalId:crm stands for your CRM’s client. document.completed fires after the signed PDF is ready. To verify the signature, see Verify webhook signatures. For a complete flow, see Send a contract from your CRM.Handle errors
results[].success: falsefromfield-values: the key doesn’t exist on the document, or the value doesn’t match the field’s type or options. Readerror.codeanderror.message; the other values are written.409 INVALID_STATE: the document isn’t aDRAFT. Stop syncing values to a sent document.- Empty custom fields after creating with
integrationLink: the prefill failed, for example because HubSpot isn’t connected or the deal doesn’t exist. A failed prefill doesn’t block creating the document, so check the values before you send it.
Next steps
Send a contract from your CRM
Run the whole flow from deal to signed PDF.
Custom fields
Store CRM values as document metadata.
Sync documents
Mirror documents into your system.

