Skip to main content
The Flowsign REST API lets you create packages from templates, send them, read their status and manage webhook endpoints. This page gets you to a sent package as quickly as the public API allows.
The API and webhooks are available on the Enterprise plan. Calls from other plans return 402.
Base URL: https://my.flowsign.app. Every success response is wrapped as { "data": ... }; every error is { "error": "...", "details"?: {...} }. See Errors.
1

Create an API key

In the app, open Settings > API keys (my.flowsign.app/settings/api-keys) and create a key. Give it a name, choose the role it acts as and the workspace it works in, and optionally set an expiry date. The key is shown once; copy it now.Only an owner can create keys. The role you choose must have the API access permission; the Admin profile has it by default, and an administrator can grant it to other profiles from Roles & Permissions. The key acts with that role’s permissions in that workspace, not as the person who issued it.
2

Check the key works

List the workspaces the key can act in. A key is bound to one workspace, so the response lists that one and names it as the active workspace.
You can send X-Workspace-Id: <id> on any request to be explicit, but it may only name the key’s own workspace; any other value is refused with 401. To work in another workspace, create a key for it. See Workspaces.
3

Build a template in the app

The quickest route to a sent package is a template: it already holds the documents, roles and fields, so the API only needs the recipients. Create one in the app with at least one document, one role and the fields each role must complete, then set it to ACTIVE. See Building a workflow. (The API can also upload documents and place fields itself; see Creating a package without a template.)Find its id with the API:
Each template in the response lists its roles. You map recipients onto roles by role name in the next step.
4

Create a package from the template

POST /api/v1/packages/from-template creates a DRAFT package from an ACTIVE template; a template still in DRAFT is refused with 409 until it is published in the app. Supply one recipient per role, naming the role with role; roles are matched by name, not by position, and every role in the template must be given a recipient. Merge field values go in fields, keyed by merge field key; a blank value takes the field’s default, and keys the template does not ask the sender for are rejected with 422. Pass an externalId of your own to make the call idempotent: repeating it returns the existing package instead of creating another.
Pass "status": "sent" to send the package in the same call (the response then reports IN_PROGRESS), or scheduledAt (an ISO 8601 timestamp) to create a SCHEDULED package that Flowsign sends at that time. Do not call send on a scheduled package.
5

Send it

Sending is an action on the package. Only DRAFT packages can be sent, and the key’s role needs the send permission.
With parallel signing, every Signer and Viewer now receives their invitation email; with a signing order on, only the first turn is invited and the rest follow as each turn completes. Sending charges one package against your allowance. A 402 means the organisation has run out of packages (or its plan no longer includes the feature), and a 409 means a document’s file has not finished uploading.
6

Follow progress

Poll the package, or register a webhook and react to SESSION_COMPLETED and PACKAGE_COMPLETED instead.
The response includes status, each recipient’s session with sentAt, openedAt, completedAt and declinedAt, the documents, and the last 100 audit events.

The same flow in code

The steps above are the cURL walkthrough. Here is the whole run in one file, in three of the languages the endpoint reference also shows.

Other package actions

PATCH /api/v1/packages/{packageId} also accepts:

Custom fields

Custom fields are the organisation’s own reference values on a package, such as an employee ID or a cost centre. They are defined in the app under Settings > Custom fields (the API reads their values but does not create or edit the definitions); each one has a key that never changes. GET /api/v1/custom-fields lists them. Packages carry their values as metadata, an object keyed by custom field key. GET /api/v1/packages, GET /api/v1/packages/{packageId} and every webhook event include it, as {} when nothing is set. GET /api/v1/templates/{templateId} returns the template’s defaults the same way; they are set in the app, and POST or PATCH on /api/v1/templates refuses metadata with 400. Set values with metadata on POST /api/v1/packages/from-template or POST /api/v1/packages. A package from a template starts with the template’s defaults, and each key you send replaces one; an empty string clears it.
The request fails with 422 and details.metadata when a key is not a live custom field that applies to the package, and when a required custom field is empty on a call that sends or schedules the package. Sending a draft with PATCH checks its required custom fields the same way.

Creating a package without a template

POST /api/v1/packages creates a DRAFT package from a title, recipients and document descriptors (fileName, pageCount, nonce), or a SCHEDULED one when you pass scheduledAt. Each document comes back with an uploadUrl: PUT the PDF bytes to it to attach the file. The URL is single-use and expires after two hours, and sending is refused with 409 while any document’s file has not arrived. Documents can also be added later with POST /api/v1/packages/{packageId}/documents, or taken from the library with POST /api/v1/packages/{packageId}/library-documents, and fields are placed with PUT /api/v1/packages/{packageId}/fields. Templates accept documents the same way through POST /api/v1/templates/{templateId}/documents and PUT /api/v1/templates/{templateId}/fields. Use a template when the same documents go out repeatedly; build the package directly when every send carries its own files.

Release labels

Parts of the app carry a label such as Experimental or Coming soon, explained in Release labels. Those labels describe the app, not this API: an experimental feature is not part of the public API unless an endpoint says so.

Next

Authentication

Key lifecycle, permissions, plan requirements and the IP allowlist.

Errors and rate limits

Status codes, validation details and the 120 requests per minute limit.

Webhooks

Signed event deliveries with retries.

Endpoint reference

Every request and response field, with copyable code samples.