Skip to main content
POST
Create an envelope from a template, and optionally send it.

Authorizations

Authorization
string
header
required

Authorization: Bearer vsk_live_…. Chosen over a bespoke X-API-KEY header because every client, proxy and log-redaction rule already knows this one. What a key may DO is its scopes — see x-scopes at the root of this document and x-required-scope on each operation. The scope list is not written here because OpenAPI reserves a requirement’s scope array for oauth2 and openIdConnect and requires it to be empty for an http scheme.

Headers

Idempotency-Key
string
required

Any string that identifies this request; a UUID is the usual choice, and at most 255 characters. ⚠️ REQUIRED. Without it a timeout is unresolvable: you cannot learn whether the envelope was created, and retrying makes a second one and emails everybody twice. The caller’s own request identifier.

Example:

"01960000-0000-4000-8000-00000000ffff"

Body

application/json

The template, the people, the values, and whether to send.

The request.

template_id
string<uuid>
required

The template to instantiate. Layout is authored there, never here (§3).

Example:

"01960000-0000-4000-8000-0000000007e1"

recipients
object[]
required

⚠️ THE ORDER OF THIS ARRAY IS THE ROUTING ORDER. It becomes order_index, which is what a template with sequential signing gates on — so reordering it is a different request, and an idempotency key will not replay across the two.

values
object[]

Optional. Values to prefill, as triples. Omitted means none. ⚠️ A signature, a date_signed, a signer_name and a signer_email may not be prefilled — they are acts, or they are written by this system.

send
boolean

Optional, default false. False creates a draft and emails nobody; true sends it, consuming the plan’s allowance and delivering an invitation to everyone whose turn it is.

expires_at
string<date-time> | null

Optional, default null — no deadline. When this envelope stops being signable, as an ISO 8601 instant. ⚠️ AN ABSOLUTE TIME RATHER THAN A DURATION, so a retried request carrying the same Idempotency-Key asks for the same deadline the first attempt did. At least 1 hour out and at most 365 days out; anything else is invalid_request. ⚠️ IT CANNOT BE CHANGED AFTERWARDS — there is no endpoint that extends a deadline yet, and an envelope that reaches one while partly signed can only be voided and started again, discarding the signatures already collected. It is enforced: every signing link is capped by it, no link can be reissued past it, and the envelope transitions to expired and emits envelope.expired once it passes.

brand_id
string<uuid> | null

Optional, default null — the organisation’s default brand. Which brand the envelope goes out under: the letterhead, the colours and the sending name a signer sees. ⚠️ THIS IS THE FIELD FOR SENDING ON BEHALF OF MANY CUSTOMER BRANDS FROM ONE ACCOUNT — change it between calls and the same integration sends Customer A’s paperwork under Customer A’s brand and Customer B’s under Customer B’s.

⚠️ AN ID THAT NAMES NO LIVE BRAND OF YOUR ORGANISATION IS REFUSED WITH brand_unknown, NOT IGNORED — including one that has been archived. The branding an envelope went out under is frozen the moment it is sent and cannot be corrected afterwards, so a wrong constant in your configuration would otherwise put somebody else’s letterhead on every envelope you ever send and nothing would say so.

It is recorded on the envelope, so a draft created with send: false still goes out under this brand when it is sent later.

completion_delivery
enum<string>

Who tells the recipients the envelope is done and sends them the executed document. vumasign (the default for a send from the dashboard) means we email the sender and every recipient we are able to email, with the sealed PDF attached. integrator (the default for a send made with an API key) means we send nothing at completion and you do it. Omit it and the origin of the send decides — an envelope created with send: false and then sent from the dashboard is vumasign. It cannot be changed once the envelope has been sent.

⚠️ AN embedded RECIPIENT IS NEVER EMAILED, WHATEVER THIS SAYS. We issue one no signing link and send them no invitation, because their address may be an identifier of yours rather than a mailbox — so they are not sent the completed document either, even under vumasign. Delivering the executed document to an embedded recipient is yours on every envelope, and this field only decides who tells everybody else.

⚠️ IF YOU TAKE THIS ON, SUBSCRIBE TO envelope.sealed RATHER THAN envelope.completed. envelope.completed fires when the last person signs, which is about a minute before the executed document exists, and envelope.sealing_failed tells you it never will.

Available options:
vumasign,
integrator

Response

The envelope, as it stands. Idempotency-Replayed says whether this request created it (false) or is being shown an earlier one’s result (true); the status is 201 either way, deliberately, so that a client branching on it behaves identically on a retry.

The envelope.

id
string<uuid>
required

The envelope’s id. A bare uuid.

status
string
required

draft or sent from this endpoint. Later states arrive as people act.

template_id
string<uuid> | null
required

The template this was made from, or null when there was none — an envelope created by POST /api/v1/envelopes/one-off carries the document itself and never had a template. Branch on null, never on the empty string.

title
string
required

What the signers see naming the document. Defaults to the template’s name.

created_at
string<date-time>
required

ISO 8601, UTC.

sent_at
string<date-time> | null
required

ISO 8601, UTC. Null while it is a draft.

expires_at
string<date-time> | null
required

ISO 8601, UTC. Null when this envelope has no deadline, which is the default. Read back from the stored value rather than echoed, so an offset you sent comes back as the same instant in UTC.

recipients
object[]
required

In routing order.