Documents

Upload and retrieve documents

Encode files locally, attach them at the right stage, and handle readiness and partial outcomes explicitly.

7 minAPI v2Integration guide

Choose when to upload

You can include session_documents during creation or add them later with POST /sessions/{bn_session_id}/documents. Prepare required documents before directing participants into signing.

ApproachUse when
Upload at creationYour application already has the final input PDF.
Upload after creationDocuments arrive in a later application step.
Preparation holdFields must be placed and reviewed before invitations.
Saved templatesA prepared document or repeatable field layout is reusable.

Encode a PDF locally

Send JSON with an array of document objects. The later-upload endpoint validates readable PDF content and does not accept multipart form uploads.

JAVASCRIPT
import { readFile } from 'node:fs/promises';

const bytes = await readFile('./agreement.pdf');
const body = {
  session_documents: [{
    name: 'agreement.pdf',
    base64Doc: bytes.toString('base64')
  }]
};
Account for encoding overhead

Base64 increases the payload size. Confirm tested endpoint and gateway limits for your document sizes rather than treating a logging limit as an upload limit.

Respect session and merge restrictions

Documents cannot be added to a closed session. A merged document with fields placed after the merge can also block additions to preserve preparation work.

ConditionCurrent outcome
Cancelled, complete, expired, or terminatedUpload blocked with a closed-session response.
Completion marker says completedUpload blocked.
Fields placed after a document merge409 merge-lock response.
Session closes during a batchPartial attachment can return 409 with counts.

Handle partial attachment

A batch is not guaranteed to be atomic. If the session closes after some documents attach, the response can report how many were stored. Other per-file and annotation/template failures may still produce a generic success when some work succeeds.

JSON
{
  "response": "Partial",
  "error_reason": "session_closed_partial_upload",
  "stored_documents_count": 1,
  "requested_documents_count": 2
}
Reconcile before retrying

Do not blindly replay a document batch after an ambiguous timeout or partial result. Already stored documents can remain attached.

Retrieve the final PDFs

Use GET /sessions/{bn_session_id}/signed_documents. The response contains Base64 files under final_documents. An empty array can mean files are not yet available.

JSON
{
  "final_documents": [
    {
      "name": "signed-agreement.pdf",
      "base64Doc": "BASE64_PDF_CONTENT",
      "initial_document_name": "agreement.pdf"
    }
  ]
}

Separate API retrieval from webhook delivery

Webhook delivery can carry files, temporary download links, or names only. These choices are independent from signer-facing final-document release settings.

ChannelFormat
Signed documents APIBase64 content in final_documents.
Webhook files modeBase64 content inside the event’s document array.
Webhook links modedocument_url and document_url_expires_at; current links expire after 24 hours.
Webhook none modeNames and metadata only.
Completion reportOptional separate artifact in GET session; not automatically added to signed_documents.

Persist the artifacts you need

Decode Base64 on your server, verify the expected files, and save them under your application’s access and retention policy. Store the original-document mapping and session ID with each output. Treat temporary download links as access credentials, not durable storage locations.

Keep building