Appearance
Packets
A packet is a set of documents generated from a packet template and sent to one or more signers.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/packets | List packets |
GET | /api/packets/:id | Get a packet |
POST | /api/packets | Create a packet |
POST | /api/packets/:id/send | Send a packet |
POST | /api/packets/:id/void | Void a packet |
GET | /api/packets/:id/status | Get packet status |
GET | /api/packets/:id/archive | Archive a packet |
GET | /api/packets/:id/restore | Restore a packet |
Packet statuses
| Status | Meaning |
|---|---|
draft | Created, not yet sent. |
sent | Sent to signers. |
viewed | At least one signer has opened it. |
awaiting_signatures | At least one signer has signed and others are outstanding. |
complete | Every signer has signed. |
voided | Cancelled. |
The packet object
List responses return the summary fields. Single-packet responses add the detail fields.
Summary fields
| Field | Type | Description |
|---|---|---|
id | integer | Packet ID. |
name | string | Packet name. |
status | string | One of the packet statuses. |
submitter_name | string | Name of the primary signer. |
submitter_email | string | Email of the primary signer. |
sent_at | timestamp | When the packet was sent. |
completed_at | timestamp | When the last signer signed. |
voided_at | timestamp | When the packet was voided. |
void_reason | string | Reason given when voiding. |
archived_at | timestamp | When the packet was archived. |
created_at | timestamp | |
updated_at | timestamp |
Detail fields
| Field | Type | Description |
|---|---|---|
slug | string | Public identifier for the packet. |
packet_template_id | integer | Template the packet was created from. |
signers | array | Each signer's name, email and role. |
signed_document_url | string | Download URL for the signed PDF. null until complete. |
certificate_url | string | Download URL for the audit trail. null until complete. |
metadata | object | Reference data stored on the packet. Echoed in webhook payloads. |
variables | object | Values merged into the documents. |
cc_emails | array | Addresses copied on completion. |
cc_attach_pdf | boolean | Whether the signed PDF is attached to the CC email. |
cc_notified_at | timestamp | When CC recipients were notified. |
test_mode | boolean | Whether the packet is a test packet. |
reminders_enabled | boolean | Whether reminder emails are on. |
first_reminder_days | integer | Days before the first reminder. |
repeat_reminders | boolean | Whether reminders repeat. |
repeat_interval_days | integer | Days between repeat reminders. |
reminder_count | integer | Reminders sent so far. |
last_reminder_sent_at | timestamp |
List packets
GET /api/packetsAccepts the standard list parameters. Archived packets are excluded unless you send filters[include_archived]=true.
bash
curl "https://app.docrunner.io/api/packets?per_page=50" \
-H "X-API-Key: $DOCRUNNER_API_KEY"json
{
"packets": [
{
"id": 123,
"name": "Lease for 123 Main St",
"status": "sent",
"completed_at": null,
"submitter_email": "jane@example.com",
"submitter_name": "Jane Doe",
"archived_at": null,
"voided_at": null,
"void_reason": null,
"sent_at": "2026-04-06T10:00:00Z",
"created_at": "2026-04-06T09:58:12Z",
"updated_at": "2026-04-06T10:00:00Z"
}
],
"meta": { "current_page": 1, "total_pages": 1, "total_count": 1, "per_page": 50 }
}Get a packet
GET /api/packets/:idReturns the packet with its detail fields.
bash
curl https://app.docrunner.io/api/packets/123 \
-H "X-API-Key: $DOCRUNNER_API_KEY"Returns 404 with { "error": "Packet 123 not found" } if the packet is not in your account.
Create a packet
POST /api/packetsCreates a draft packet. Creating a packet does not send it. Call send next.
Body
All fields go inside a packet object.
| Field | Type | Required | Description |
|---|---|---|---|
packet_template_id | integer | Yes | The template to build from. |
packet_name | string | No | Name for the packet. |
roles | object | Yes | Signers grouped by role key. See below. |
variables | object | No | Values merged into the documents. See below. |
cc_emails | array | No | Addresses to copy when the packet completes. Invalid addresses are dropped. |
cc_attach_pdf | boolean | No | Attach the signed PDF to the CC email. Defaults to false. |
Roles
roles is an object keyed by role. Each value is an array of signers with name and email.
- Each key must match a role
keyon the packet template. Read them fromrecipient_roleson the packet template. - A role accepts up to its
max_countsigners. nameandemailare both required for every signer.
Supported role keys
The API currently accepts the role keys owner, tenant and pm. Other keys are ignored.
Variables
variables is an object of key/value pairs merged into the packet's documents, for example a merge field for the date the packet was created.
- Each key corresponds to a merge field defined in the packet template's documents. Keys with no matching merge field are ignored.
- Values are sent as strings.
variablesis echoed back on the packet's detail fields.
Example
bash
curl -X POST https://app.docrunner.io/api/packets \
-H "X-API-Key: $DOCRUNNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"packet": {
"packet_template_id": 9,
"packet_name": "Lease for 123 Main St",
"cc_emails": ["office@example.com"],
"cc_attach_pdf": true,
"roles": {
"tenant": [
{ "name": "Jane Doe", "email": "jane@example.com" },
{ "name": "Sam Doe", "email": "sam@example.com" }
],
"owner": [{ "name": "John Smith", "email": "john@example.com" }]
},
"variables": {
"created_on": "2026-04-06"
}
}
}'The response is the new packet with its detail fields.
Errors
Returned as 422 with the reasons joined in error.
| Message | Cause |
|---|---|
Packet template 9 not found | No template with that ID in your account. |
This packet template is archived. Restore it before creating a packet. | |
This packet template has no documents. | |
Unknown role: landlord | The role key is not defined on the template. |
Too many signers for role tenant (max 2) | |
Name and email are required for role tenant |
Send a packet
POST /api/packets/:id/sendSends a draft packet to its signers.
Body
| Field | Type | Required | Description |
|---|---|---|---|
packet.send_email_body | string | Yes | Message included in the signing invitation email. |
bash
curl -X POST https://app.docrunner.io/api/packets/123/send \
-H "X-API-Key: $DOCRUNNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "packet": { "send_email_body": "Please review and sign." } }'json
{
"packet": {
"id": 123,
"success_info": { "message": "Packet sent for signing!" }
}
}Test mode
For a test-mode packet, no email is sent. The response lists a signing URL for each signer who is up next, alongside a message:
json
{
"packet": {
"id": 123,
"success_info": {
"test_signing_urls": ["https://app.docrunner.io/sign/sign_abc123"]
}
}
}If sending fails, the response is 422 with { "error": "Failed to send: ..." }.
Void a packet
POST /api/packets/:id/voidCancels a packet. If it was already sent, signers are notified. Voiding also archives the packet.
Body
| Field | Type | Required | Description |
|---|---|---|---|
packet.void_reason | string | Yes | Reason shown to signers. |
bash
curl -X POST https://app.docrunner.io/api/packets/123/void \
-H "X-API-Key: $DOCRUNNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "packet": { "void_reason": "Lease terms changed." } }'json
{
"packet": {
"id": 123,
"success_info": { "message": "Document has been voided and submitters have been notified." }
}
}Get packet status
GET /api/packets/:id/statusA lightweight check that returns only the ID, name and status.
json
{
"packet": { "id": 123, "name": "Lease for 123 Main St", "status": "sent" }
}Archive and restore
GET /api/packets/:id/archive
GET /api/packets/:id/restoreArchiving hides a packet from list responses. Restoring brings it back. Both return the packet ID:
json
{ "packet": { "id": 123 } }