Document Flow API
The Document Flow API lets you upload PDF files, start processes with up to 5 recipients, monitor their progress and download successive document versions. You can receive event notifications through webhooks.
Contents
- Access and authentication
- Endpoints
- Uploading a PDF
- Creating a process
- Recipients and approval
- Messages and PINs
- Process details and statuses
- Listing processes
- Downloading documents
- Validity and retention
- Errors and request retries
Access and authentication
API base URL:
https://api.sare.pl/ext/doc-flowThe Document Flow module must be enabled for the account. The integration key and secret are available in the module settings in the SARE panel. Include the following header in every request:
Authorization: Bearer <integrationKey>:<secret>Warning
Store credentials on the server. Do not include them in frontend code, URLs or logs. Generating a new secret invalidates the previous one.
Rate limits
Each endpoint below allows 30 requests per 60 seconds per IP address. Exceeding the limit returns 429.
Endpoints
The paths in this table are relative to the API base URL.
| Method | Path | Purpose |
|---|---|---|
POST | /uploads | Upload a PDF and obtain an uploadId |
POST | /processes | Create a process |
GET | /processes/{id} | Get process details and progress |
GET | /processes | List and filter processes |
GET | /processes/{id}/documents/current/download | Download the current document |
GET | /processes/{id}/documents/versions/{version}/download | Download a specific document version |
The public API does not support editing processes, starting drafts, pausing or cancelling processes. Perform these operations in the panel. Configure the webhook URL and event types in the panel as well, separately from the process creation request.
Uploading a PDF
POST /uploads accepts multipart/form-data with a single file field named file.
- Only PDF files with the
.pdfextension andapplication/pdfMIME type are supported, up to 20 MiB (20 971 520bytes). - Files undergo content validation and security scanning; encrypted PDFs and files containing prohibited active content or embedded attachments are rejected.
- The
201response includes theuploadIdneeded to create a process. - Each upload can be used once and remains valid for 24 hours;
validUntilcontains the exact expiry time.
curl -X POST 'https://api.sare.pl/ext/doc-flow/uploads' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
-F 'file=@./document.pdf;type=application/pdf'Example response:
{
"uploadId": "dfu_t1_exampleUpload",
"fileName": "document.pdf",
"mimeType": "application/pdf",
"sizeBytes": 123456,
"sha256": "bc0e83603ea8596cbd473e292981e3e7f93ba626f8f3eb858857bc767f13e6c5",
"validUntil": "2030-07-28T10:00:00.000Z"
}The identifiers and dates in these examples are illustrative. Use the values returned by the API in subsequent requests. sha256 identifies the stored file contents.
Creating a process
POST /processes accepts JSON and returns 201 with the new process details. Providing recipients starts the flow and queues invitations for active steps. Acceptance of the request does not confirm message delivery.
Save the following example as process.json, replace document.uploadId and the sender and recipient details, then send the request:
{
"referenceId": "ref_example_2030_0001",
"externalId": "case-2030-0001",
"name": "Agreement - Jan Kowalski",
"description": "Document approval",
"sourceSystem": "crm",
"expiresAt": "2030-08-10T12:00:00.000Z",
"mode": "sequential",
"fileAccessMode": "pin",
"approvalMode": "button_only",
"pinDeliveryChannel": "email",
"includeSignatureCard": true,
"sealingEnabled": false,
"sendFinalDocumentToAllRecipients": false,
"showCompletedSigners": false,
"sender": {
"name": "Customer service",
"email": "dokumenty@example.com"
},
"emailSubject": "Document for approval",
"emailPreheader": "Read the document and confirm receipt.",
"document": {
"uploadId": "dfu_t1_exampleUpload"
},
"recipients": [
{
"key": "step_1",
"name": "Jan Kowalski",
"email": "jan@example.com",
"role": "signer",
"orderIndex": 1,
"fileAccessMode": "pin",
"approvalMode": "button_only"
}
],
"metadata": {
"caseType": "contract"
}
}curl -X POST 'https://api.sare.pl/ext/doc-flow/processes' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
-H 'Content-Type: application/json' \
--data-binary @process.jsonProcess fields
| Field | Required | Meaning and default |
|---|---|---|
name | yes | Process name, 1-255 characters |
document.uploadId | yes | ID of an unused PDF upload belonging to the same account |
referenceId | no | Reference ID unique within the account, 3-120 characters. Generated automatically if omitted or empty |
externalId | no | External system ID unique within the account, 1-160 characters |
description | no | Description, up to 1000 characters |
sourceSystem | no | Source system name, 1-120 characters |
expiresAt | no | Future approval deadline in ISO 8601 format with a time zone. No deadline by default |
mode | no | sequential (default) or parallel |
fileAccessMode | no | pin (default) or none |
approvalMode | no | Defaults to button_only; other values are described below |
recipients | no | Up to 5 recipients. Omitted or empty arrays create a created draft that must be started in the panel |
includeSignatureCard | no | Append a signature card to the resulting document. Defaults to true |
sealingEnabled | no | EuroCert sealing. Enabled by default if available for the account; remains disabled if the service is unavailable |
eurocertSealId | no | ID of a seal available for the account, 1-120 characters. Uses account settings if omitted |
sendFinalDocumentToAllRecipients | no | Notify all recipients and provide access to the final document. Defaults to false |
showCompletedSigners | no | Show recipients who has completed their steps. Defaults to false |
metadata | no | Object containing additional integration data. The response also includes process settings added by the system |
Message and PIN delivery fields are described under Messages and PINs. The public API accepts documents through uploadId; do not send Base64 data or a file URL here.
Recipients and approval
In sequential mode, each person gains access after the previous step is completed. In parallel mode, steps are activated simultaneously.
| Recipient field | Required | Rules |
|---|---|---|
key | yes | Step key unique within the process, 1-80 characters |
name | yes | Full name or display name, 1-200 characters |
email | yes | Valid email address, up to 320 characters, also required for SMS PINs |
role | yes | Role label, 1-80 characters, e.g. signer |
orderIndex | for sequential | Positive integer unique within the process |
fileAccessMode | yes | none or pin; required even when set at process level |
approvalMode | yes | One of the values in the table below |
gsm | for SMS PINs without fallback | Phone number with country code: 8-15 digits, optional +, no spaces, e.g. +48500100200 |
pin | no | Initial code, 4-12 characters. Generated by the system if omitted; resending the PIN may replace it |
fileAccessMode controls document access: none provides access through the link, while pin requires a code. approvalMode determines how a step is completed:
approvalMode | Recipient action |
|---|---|
view_only | Viewing the document automatically completes the step |
button_only | Confirm using a button |
pin | Confirm using a PIN |
signature | Add a handwritten signature in the recipient panel |
pin_and_signature | PIN and handwritten signature |
Handwritten signatures in signature and pin_and_signature are separate from EuroCert sealing. Recipient-level settings define the requirements for that step.
Messages and PINs
| Process field | Meaning |
|---|---|
sender | Sender: required email (up to 320 characters), optional name (up to 200 characters). If omitted, the sender from module settings is used |
sender.replyTo | Accepted by the API, but the reply address is currently set to sender.email |
emailSubject | Invitation subject, up to 255 characters, without line breaks. Uses the process name if empty or omitted |
emailPreheader | Invitation preheader, up to 100 characters, without line breaks |
emailTemplateId | Positive integer ID of a ready-to-use SARE template on the account. Omitted or null selects the standard message |
pinDeliveryChannel | email (default) or sms |
pinSmsSender | Name of an SMS sender available on the account, up to 40 characters; required for the sms channel |
pinFallbackToEmail | Defaults to false. For the sms channel, allows the PIN to be sent by email if the recipient has no mobile number |
Process invitations are sent by email regardless of the PIN channel. Fallback applies when a mobile number is missing, not to arbitrary SMS sending errors. With the email channel, the fallback and SMS sender fields are unused.
Custom invitation template
The template selected by emailTemplateId must be a ready-to-use SARE template. Its HTML must contain a link with exactly href="{{doc_flow_url}}", without additional parameters, and the literal {{doc_flow_ref_id}} token in visible content. If the template includes a TXT version, it must also contain {{doc_flow_url}} and {{doc_flow_ref_id}}. If TXT is empty, the system generates it from HTML.
Optional tokens are {{doc_flow_process_name}} (process name), {{doc_flow_valid_until}} (access link expiry, rather than the approval deadline) and {{doc_flow_document_password}} (document password, when used). The password token is required if document settings require the password to be included in the invitation. Other tokens in the {{...}} format cause a validation error.
The custom template applies to invitations, including subsequent sequential steps. Messages containing PINs or final document access use standard content. Attachments stored in the SARE template are not attached to the invitation. The template is validated before use; its ID does not replace the sender field or the sender in module settings.
Process details and statuses
GET /processes/{id} returns process, recipient and document details. {id} is the dfp_... process ID, not referenceId, externalId or documentId.
curl 'https://api.sare.pl/ext/doc-flow/processes/dfp_t1_exampleProcess' \
-H 'Authorization: Bearer <integrationKey>:<secret>'Example response excerpt (other process settings omitted):
{
"id": "dfp_t1_exampleProcess",
"referenceId": "ref_example_2030_0001",
"externalId": "case-2030-0001",
"documentId": "dfd_t1_exampleDocument",
"name": "Agreement - Jan Kowalski",
"status": "in_progress",
"recipients": [
{
"key": "step_1",
"status": "email_sent",
"orderIndex": 1,
"name": "Jan Kowalski",
"email": "jan@example.com",
"gsm": null,
"role": "signer",
"fileAccessMode": "pin",
"approvalMode": "button_only",
"activatedAt": "2030-07-27T10:05:00.000Z",
"viewedAt": null,
"confirmedAt": null
}
],
"documents": [
{
"id": 123,
"uploadId": "dfu_t1_exampleUpload",
"processId": "dfp_t1_exampleProcess",
"documentId": "dfd_t1_exampleDocument",
"kind": "source",
"version": 1,
"fileName": "document.pdf",
"mimeType": "application/pdf",
"sha256": "bc0e83603ea8596cbd473e292981e3e7f93ba626f8f3eb858857bc767f13e6c5",
"sizeBytes": 123456,
"status": "attached",
"uploadedAt": "2030-07-27T10:00:00.000Z",
"attachedAt": "2030-07-27T10:05:00.000Z",
"validUntil": "2031-01-23T10:05:00.000Z",
"deletedAt": null
}
],
"createdAt": "2030-07-27T10:05:00.000Z",
"updatedAt": "2030-07-27T10:05:00.000Z",
"completedAt": null,
"expiresAt": "2030-08-10T12:00:00.000Z",
"readUntil": null,
"readOnly": false
}The response also includes process, message, PIN, sender and seal settings, as well as metadata. It does not include PIN values, tokens, public recipient links or storage file paths.
| Process status | Meaning |
|---|---|
created | Draft, not yet started |
in_progress | Flow in progress |
paused | Flow paused |
completed | All required steps completed |
cancelled | Process cancelled, rejected or expired |
failed | Process failed |
Step statuses in recipients[].status are pending, active, email_sent, viewed, confirmed, failed and skipped. email_sent means an invitation was queued, not that delivery was confirmed.
Document kinds are source (original PDF), artifact (resulting version) and sealed (sealed version), with status uploaded, attached, expired or replaced. A completed process status alone does not guarantee that a sealed version is available; track its creation through sealing events.
Listing processes
GET /processes supports the following parameters:
| Parameter | Meaning |
|---|---|
page, limit | Page number and result count; defaults to 1 and 10 |
sort | Sort field: id, name, status, createdAt, updatedAt, sourceSystem; defaults to id |
order | ASC (default) or DESC |
status | One of the process statuses |
referenceId, externalId, sourceSystem | Case-insensitive partial match against the identifier or system name |
recipient | Find a recipient by name or email address |
recipientEmail, recipientName | Search by recipient email address or name |
createdFrom, createdTo | Inclusive creation date boundaries in ISO 8601 format with a time zone |
search | Search process details, identifiers and recipient name or email |
curl --get 'https://api.sare.pl/ext/doc-flow/processes' \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
--data-urlencode 'page=1' \
--data-urlencode 'limit=20' \
--data-urlencode 'sort=createdAt' \
--data-urlencode 'order=DESC' \
--data-urlencode 'referenceId=ref_example_2030_0001'The response has the form { "pagination": { "totalCount": 1, "page": 1, "limit": 20 }, "processes": [...] }. Each processes item has the process detail structure, but its documents is an empty array. Retrieve documents through GET /processes/{id}. The public API does not support a batchId filter.
Downloading documents
Current document
Without kind, GET /processes/{id}/documents/current/download selects the latest available sealed document, falling back to artifact, then source. Use kind=source, kind=artifact or kind=sealed to select a specific kind.
curl --fail-with-body -o document.pdf \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
'https://api.sare.pl/ext/doc-flow/processes/dfp_t1_exampleProcess/documents/current/download'Specific version
GET /processes/{id}/documents/versions/{version}/download accepts a positive version number and optional kind. Without kind, it looks for an artifact. To download the original PDF, specify kind=source and its version number from documents.
curl --fail-with-body -o source-v1.pdf \
-H 'Authorization: Bearer <integrationKey>:<secret>' \
'https://api.sare.pl/ext/doc-flow/processes/dfp_t1_exampleProcess/documents/versions/1/download?kind=source'The 200 response is binary and includes Content-Type, Content-Disposition and Content-Length. Check the HTTP status before processing the saved file: error responses contain JSON. A missing document of the selected kind or version returns 404.
Validity and retention
Upload validity, the process approval deadline and the document read period are separate time limits:
| Item | Rules |
|---|---|
| Unused upload | Valid for 24 hours after upload; expiry in validUntil |
| Approval deadline | Optional expiresAt. After this deadline, the process becomes cancelled with reason expired and remains readable |
Link without expiresAt | Initially valid for 7 days after generation |
Link with expiresAt | Initially valid until the process deadline plus 30 days; approval is possible only before expiresAt |
| Reading after completion | For 30 days after completion, cancellation or rejection; readUntil gives the exact deadline and readOnly indicates read-only mode |
| Document attached to a process | 180 days by default. Retention is extended if the process deadline and read period require a later date; check documents[].validUntil |
Completing a step does not immediately disable its link. The same link can still provide read access during the readUntil period, including after approval. Access remains subject to PIN requirements and the restrictions of that step.
The API lets you set expiresAt. It does not expose separate settings for the 24-hour upload validity, default 180-day retention or 30-day read period. Longer file storage does not automatically extend public recipient access.
Errors and request retries
Business errors include a code in the message field, for example:
{
"statusCode": 400,
"message": "DOC_FLOW_UPLOAD_EXPIRED",
"error": "Bad Request"
}Validation errors may include additional information about invalid fields. Do not assume the RCS error format with a code field.
| HTTP | Example causes |
|---|---|
400 | Invalid data, oversized or prohibited file, used or expired upload, conflicting identifiers, unavailable template or seal |
401 | Missing or invalid credentials |
403 | Module disabled or insufficient permissions |
404 | Process, upload or document version not found |
429 | Rate limit exceeded |
5xx | Server error or temporary service unavailability, e.g. 503 during file security scanning |
Selected error codes:
| Code | Meaning |
|---|---|
DOC_FLOW_UPLOAD_ID_REQUIRED | Missing document.uploadId |
DOC_FLOW_UPLOAD_NOT_FOUND | Upload does not exist or belongs to another account |
DOC_FLOW_UPLOAD_EXPIRED | Upload expired |
DOC_FLOW_UPLOAD_ALREADY_ATTACHED | Upload already attached to a process |
DOC_FLOW_RECIPIENT_LIMIT_EXCEEDED | More than 5 recipients |
DOC_FLOW_MONTHLY_RECIPIENT_LIMIT_EXCEEDED | Monthly account participant limit exceeded |
DOC_FLOW_RECIPIENT_KEY_NOT_UNIQUE | Duplicate recipient key |
DOC_FLOW_ORDER_INDEX_REQUIRED | Missing order index in sequential mode |
DOC_FLOW_ORDER_INDEX_NOT_UNIQUE | Duplicate order index in sequential mode |
DOC_FLOW_REFERENCE_ID_NOT_UNIQUE | A process with this referenceId already exists |
DOC_FLOW_EXTERNAL_ID_NOT_UNIQUE | A process with this externalId already exists |
DOC_FLOW_PIN_SMS_SENDER_REQUIRED | Missing SMS PIN sender |
DOC_FLOW_PIN_SMS_SENDER_INVALID | Selected SMS sender is unavailable on the account |
DOC_FLOW_PIN_SMS_NOT_AVAILABLE | SMS channel unavailable on the account |
DOC_FLOW_RECIPIENT_GSM_REQUIRED | Recipient requiring a PIN has no mobile number and fallback is disabled |
DOC_FLOW_PROCESS_NOT_FOUND | Process not found |
DOC_FLOW_DOCUMENT_NOT_FOUND | Document of the selected kind not found |
DOC_FLOW_DOCUMENT_VERSION_NOT_FOUND | Selected document version not found |
DOC_FLOW_EMAIL_TEMPLATE_NOT_FOUND | Selected ready-to-use template does not exist |
DOC_FLOW_EMAIL_TEMPLATE_INVALID | Template does not meet Document Flow requirements |
DOC_FLOW_EMAIL_TEMPLATE_FETCH_FAILED | Could not fetch current template content |
DOC_FLOW_EMAIL_TEMPLATE_SOURCE_NOT_AVAILABLE | Template source or required document unavailable |
FILE_UPLOAD_FAILED | Missing file or invalid upload |
FILE_SIZE_EXCEEDED | File size limit exceeded |
FILE_TYPE_NOT_ALLOWED | Prohibited PDF format or content |
FILE_INFECTED | Security scan detected a threat |
Store id, referenceId, externalId and webhook event IDs. Set timeouts and use increasing delays when retrying reads after 429 or temporary 5xx errors. For 429, respect the Retry-After header. 5xx responses include the generic Internal Server Error message and a requestId to include when reporting a problem.
POST /processes does not support the Idempotency-Key header. If a response is lost, first search for the process using your referenceId or externalId. Repeating a request with the same identifier returns a uniqueness error rather than the previous result; reusing an uploadId may also fail.