Skip to main content
There are two ways to get a document in front of the people who sign it, and the question that chooses between them is whether you will send this document again.
  • A template is a library entry: a kind of document — an employment contract, a membership form — whose fields are placed once and which you send many times. POST /api/v1/templates creates it, and every envelope after that is POST /api/v1/envelopes with its template_id and the people this copy is for — or POST /api/v1/envelopes/batches for many copies at once.
  • A one-off envelope is a document that exists once, for one set of people — a Letter of Authority, an offer of employment generated for one candidate. POST /api/v1/envelopes/one-off takes the document and the people in a single request and creates no template: the envelope’s template_id comes back null.
⚠️ Do not register a template per send. A template stays in your library and in GET /api/v1/templates until somebody archives it in the dashboard, and this API has no operation that deletes one. An integration that creates a template for every offer letter leaves one behind for every offer letter. If the document is generated fresh each time, it is a one-off.

Choosing

Choose a template when the document is the same every time and only the people and a few answers change: it is placed once, reviewed once in the editor, and each envelope is a small request that names the people and what to prefill. Choose a one-off when your own system generates the document — conditional clauses, a page count that varies — so there is nothing stable to reuse, and the document can carry its own fields as text tags.

The limits

The document bound is on the whole request, not on each document: a document travels base64-encoded inside the JSON body, and every document in a one-off request shares one body. Documents larger than that go through the upload screen instead, which sends the file itself.

From a template

Create the template once. file is the whole document, base64-encoded — the value below is a truncated stub, not a document — and roles names who signs it, in order.
POST /api/v1/templates
The answer carries the template’s id and the fields that were placed, each with its own id and, where the document named one, the data_key a prefilled value is addressed to. Then each envelope names the people by the template’s role names, and may prefill what your own records already know, and lock some of it:
POST /api/v1/envelopes
The envelope uses the template’s documents as they are: nothing is uploaded again. send defaults to false, which creates a draft and emails nobody — send it later with POST /api/v1/envelopes/{envelopeId}/send. Every role that has a field needs a recipient who is not a copy, or the request is refused recipient_role_missing; a role the template declares but places no field for needs nobody. A name the template does not declare is refused recipient_role_unknown; Roles and recipients has the rules. Not every field takes a value, and not every field that takes one can be locked. A job title or a company belongs to whoever fills the role, not to the box, so locked on one is refused value_not_lockable: send the value without locked, or set job_title and company on the recipient, which is where those fields are filled from. What a value does to each field type, in a batch row too:

Many envelopes from one template

A batch is the bulk path, and it exists only from a template. Each row is one envelope — its recipients and its values — and send, expires_at, brand_id and completion_delivery apply to every row.
POST /api/v1/envelopes/batches
  • A mistake in any row’s own data refuses the whole batch, and nothing is created: a mapping error in one row is usually in all of them.
  • Past that, sending is per row. The status line says whether every row went out; when one did not — most often because the plan’s send allowance ran out partway — its draft is kept and named in the answer, and the remedy is to send those drafts rather than to rebuild the batch.
  • A batch counts one unit per row against the rate limit, not one per request.
  • There is no one-off batch. For many generated documents, make one one-off request each.

One-off

The document and its people, in one request. Each recipient’s role is the slot a text tag names, so <<sig:Employee>> in the document places a signature for the recipient whose role is Employee.
POST /api/v1/envelopes/one-off
documents is a list, in the order a signer meets them. They are stacked into one scroll on the signing screen, and each is sealed on its own with its own certificate of completion. As on the template path, a Word .docx is accepted and converted to PDF on our side, and its tags survive the render.

What a one-off refuses

  • ⚠️ An envelope with no tags in any of its documents is refused, template_has_no_fields, and nothing is created. A one-off has no detection and no editor behind it — this API has no operation that places a field later — so an envelope with no field could never become signable. The count is over the whole request, not per document: an annexure with no tags is accepted as long as another document in the same request places a field.
  • ⚠️ Roles are declared inline, and only there. A tag naming a role no recipient holds is refused with the tag, its page and the roles the request does declare; so is a subject(...) tag, since a one-off declares no subjects. signerN counts the entries in recipients, copies included.
  • One signing role, one person. Two recipients on the same role that is not a copy are refused recipient_role_duplicated: both would answer every box on that role. Give each person a role of their own and tag each role where that person signs.
  • Every role with a field needs somebody who can fill it. A tag for a role whose only recipient is a cc is refused recipient_role_missing, because a copy is never asked to sign.
  • There is no values array, so you prefill nothing and lock nothing.
That is not the same as the signer typing every box. On either path, some tags arrive already filled, and the first row is never asked at all. A recipient’s job_title and company are what seed the second row. Every refusal POST /api/v1/envelopes/one-off declares, with what each one means, as the reference publishes them:

Retrying safely

Every request on this page requires an Idempotency-Key — one key per request you intend, reused only to retry that same request. A retry with the same key and the same body returns the first answer and creates nothing; a batch replay returns the same batch, failed rows and all. A different body under a used key is refused idempotency_key_reused. Reordering recipients is a different body, because that order is the routing order. How long a key is remembered, and what to do past it, is in Retrying a request safely.