Skip to content

Create a draft envelope

POST
/envelopes
curl --request POST \
--url https://api.sealpost.app/v1/envelopes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "title": "example", "message": "example", "subject": "example", "status": "draft", "test_mode": true, "files": [ { "file_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "url": "https://example.com", "base64": "example", "name": "example", "kind": "example" } ], "recipients": [ { "name": "example", "email": "hello@example.com", "kind": "signer", "routing_order": 1, "required": true, "phone": "example", "language": "example", "redirect_url": "https://example.com" } ], "fields": [ { "identifier": "example", "type": "signature", "recipient": 1, "file": 0, "page": 1, "x": 1, "y": 1, "width": 1, "height": 1, "unit": "pt", "requirement": "required", "label": "example", "placeholder": "example", "options": [ "example" ], "group": "example" } ], "flexible_signing": false, "sequential": false, "allow_decline": true, "allow_reassign": false, "requester_name": "example", "requester_email": "hello@example.com", "redirect_url": "https://example.com", "redirect_decline_url": "https://example.com", "expires_at": "2026-04-15T12:00:00Z", "language": "en", "metadata": { "additionalProperty": "example" }, "client_reference": "example" }'

Scope envelopes:write. Files by file_id (from /files), url or base64, in order; recipients; fields placed by page and box in a declared unit (pt default, px72, px96, percent; see docs/envelopes.md). Every box is converted to points and checked against the file’s real page size (invalid_field_geometry). test_mode is taken from the key or Sign-Test-Mode, never from the body, and is immutable. A signer needs at least one field unless flexible_signing is true. Created as draft; sending is a later operation. Honours Idempotency-Key.

Idempotency-Key
string
>= 1 characters <= 255 characters

Client-chosen key, 1 to 255 characters, scoped to (tenant, API key, method, path). The first response is stored for 24 hours and replayed for repeats with the same body (Idempotent-Replayed: true). A repeat with a different body is a 422 idempotency_key_reused; a repeat while the first request is still running is a 409 idempotency_in_flight (a request that dies mid-flight releases its lock after 60 seconds).

Media typeapplication/json
object
title
required
string
>= 1 characters <= 200 characters
message
string
<= 5000 characters
subject
string
<= 300 characters
status

Only draft in this release.

string
default: draft
Allowed values: draft
test_mode

Optional and informational: must agree with the key / Sign-Test-Mode, which decide.

boolean
files
required
Array<object>
>= 1 items <= 100 items

One of file_id (from /files), url, or base64 + name; plus an optional kind.

object
file_id
string format: uuid
url
string format: uri
base64
string
name
string
kind
string
/^[a-z0-9_-]{1,50}$/
recipients
Array<object>
<= 100 items
object
name
required
string
<= 200 characters
email
required
string format: email
kind
string
default: signer
Allowed values: signer cc viewer approver
routing_order

Only meaningful when the envelope is sequential.

integer
default: 1 >= 1 <= 100
required
boolean
default: true
phone

E.164, for SMS authentication later.

string
language
string
redirect_url
string format: uri
fields
Array<object>
<= 1000 items

A box on one page of one file, in the declared unit. The verbatim object is kept as source.

object
identifier

Unique within the envelope; defaults to {type}_{n}.

string
/^[A-Za-z0-9_.-]{1,80}$/
type
required
string
Allowed values: signature initials date_signed text checkbox radio dropdown attachment image note
recipient

Index into recipients. Required except for note.

integer
file

Index into files.

integer
0
page
required

1-based page within that file.

integer
>= 1
x
required
number
y
required
number
width
required
number
height
required
number
unit

Coordinate unit of a field box. pt PDF points (default); px72 pixels of a 72 dpi render, which equal points and are what the EMA CRM’s field table uses; px96 pixels of a 96 dpi render (CSS px, x 0.75); percent of the visual page width (x, width) and height (y, height). Origin is the top-left of the page as a viewer shows it. See docs/envelopes.md.

string
default: pt
Allowed values: pt px72 px96 percent
requirement
string
default: required
Allowed values: required optional read_only
label
string
<= 200 characters
placeholder
string
options

Choices for radio and dropdown.

Array<string>
group

Radio / checkbox group key.

string
flexible_signing

No fields; each signer places their own signature (the CRM’s fallback when a document type has no field map).

boolean
sequential
boolean
allow_decline
boolean
default: true
allow_reassign
boolean
requester_name
string
requester_email
string format: email
redirect_url
string format: uri
redirect_decline_url
string format: uri
expires_at

At least one hour in the future.

string format: date-time
language
string
default: en
metadata

Your own key/value bag, returned unchanged and filterable later. Keys match ^[A-Za-z0-9_.-]{1,40}$.

object
<= 20 properties
key
additional properties
string
<= 500 characters
client_reference
string
<= 200 characters

The envelope with its files, recipients and fields (fields in points).

Media typeapplication/json
object
id
required
string format: uuid
status
required
string
Allowed values: draft sent in_progress completed declined cancelled expired
test_mode
required
boolean
title
required
string
message
string | null
subject
string | null
sequential
boolean
flexible_signing
boolean
allow_decline
boolean
allow_reassign
boolean
requester_name
string | null
requester_email
string | null
redirect_url
string | null
redirect_decline_url
string | null
expires_at
string | null format: date-time
language
string
metadata
object
key
additional properties
string
client_reference
string | null
page_count
integer | null
files
required
Array<object>
object
id
required
string format: uuid
envelope_id

Null until the file is attached to an envelope.

string | null format: uuid
position

1-based order within the envelope.

integer | null
name
required
string
kind

The caller’s label for the document type, e.g. merchant_application; used to split a signed envelope back into its documents.

string | null
mime
required
string
bytes
required
integer
sha256

SHA-256 (hex) of the original bytes, exactly as uploaded. Null while pending.

string | null
pdf_version
string | null
page_count
integer | null
page_sizes
Array<object> | null

One page’s visual size in points (after /Rotate).

object
w
required
number
h
required
number
rotate
required
integer
Allowed values: 0 90 180 270
status
required
string
Allowed values: pending converting ready failed
error
string | null
upload_expires_at

When an unattached upload is swept (30 days). Null once attached.

string | null format: date-time
created_at
required
string format: date-time
recipients
required
Array<object>
object
id
required
string format: uuid
kind
required
string
name
required
string
email
required
string
phone
string | null
language
string
routing_order
required
integer
required
boolean
auth_method
string
status
required
string
Allowed values: pending sent viewed signed declined reassigned bounced expired cancelled removed
deliver_email
boolean
redirect_url
string | null
position
integer
sent_at
string | null format: date-time
signed_at
string | null format: date-time
fields
required
Array<object>

Always returned in points (unit: pt), origin top-left; source is what you sent.

object
id
required
string format: uuid
identifier
required
string
type
required
string
file_id
required
string format: uuid
recipient_id
string | null format: uuid
page
required
integer
x
required
number
y
required
number
width
required
number
height
required
number
unit
required
string
Allowed values: pt
source
object | null
requirement
string
label
string | null
placeholder
string | null
options
Array<string> | null
group
string | null
value
string | null
sent_at
string | null format: date-time
completed_at
string | null format: date-time
created_at
required
string format: date-time
updated_at
string format: date-time

Example

{
"status": "draft",
"files": [
{
"page_sizes": [
{
"rotate": 0
}
],
"status": "pending"
}
],
"recipients": [
{
"status": "pending"
}
],
"fields": [
{
"unit": "pt"
}
]
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

Idempotent-Replayed
boolean

Present and true when the response was replayed from a stored earlier response for the same Idempotency-Key.

The request could not be read (malformed JSON, bad header).

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

No key, an unknown key, or a revoked or expired key.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

The key is valid but lacks the scope, or a test key tried a live-only action.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

A request with the same Idempotency-Key is still in flight.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

A file is over 25 MB (10 MB inline as base64); use /files/presign.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

The request was read but a value is invalid, or an Idempotency-Key was reused with a different body.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

The key is over its per-minute budget (600 live, 60 test, sliding window).

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

Retry-After
integer

Seconds to wait before retrying.

RateLimit-Limit
integer

Requests allowed per minute for this key (600 live, 60 test).

RateLimit-Remaining
integer

Requests remaining in the current window.

RateLimit-Reset
integer

Seconds until the window has capacity again.

Something failed on our side. The request_id is in our logs.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

The document service could not be reached; nothing was stored. Retry after Retry-After seconds with the same Idempotency-Key.

Media typeapplication/problem+json

RFC 9457 problem details plus a stable code and the request_id.

object
type
required

https://sealpost.app/errors/{code}

string format: uri
title
required
string
status
required
integer
detail

Human-readable, safe to show to a developer, never contains secrets or signer data.

string
instance

The request path.

string
code
required

Stable machine-readable code from the catalogue (docs/errors.md).

string
request_id
required
string
errors

Field-level detail on validation_failed.

Array<object>
object
param
required

JSON pointer-ish path, e.g. scopes[2].

string
message
required
string

Example

{
"type": "https://sealpost.app/errors/insufficient_scope",
"title": "Forbidden",
"status": 403,
"detail": "This key lacks the api_keys:write scope.",
"code": "insufficient_scope",
"request_id": "req_01J9ZK3V8Q4M2XQ7W0E5D1R6TA"
}
Sign-Request-Id
string

Unique id of this request (req_…). Quote it in support requests.

Retry-After
integer

Seconds to wait before retrying.