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. |
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.
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" }]
}
}
}'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 } }