Home/API Reference
Manage API keys
v1

BeeSign API Reference

The BeeSign REST API lets you manage documents, forms, templates, and organization members programmatically. All endpoints return JSON and are served over HTTPS.

Base URL

https://api.beesign.net

Authentication

Authenticate every request with an API key passed as a Bearer token in the Authorization header. Create and rotate keys from the API keys page. Keys grant full access on your behalf, so keep them secret.

Authorization header
Authorization: Bearer YOUR_API_KEY

Organization keys

Organization API keys can act on behalf of a specific member by adding an X-User-Id header. The request is then scoped to that member's workspace. Without it, the key operates on the organization's shared scope.

Errors

Errors return a non-2xx status with a JSON body of the shape { "error": "..." }. Common codes: 401 (missing or invalid key), 403 (key lacks access), 404 (resource not found), 400 (bad request).

Documents

Documents are the PDFs sent out for signature. Each is identified by an id like BSD-1718049600000.

List documents

GET/v1/documents

Returns every non-archived document in the authenticated workspace.

Request
curl https://api.beesign.net/v1/documents \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "documents": [
    {
      "id": "BSD-1718049600000",
      "name": "BSD-1718049600000",
      "size": 254013,
      "contentType": "application/pdf",
      "createdAt": "2025-06-10T18:40:00.000Z",
      "updatedAt": "2025-06-10T18:40:00.000Z",
      "metadata": { "recipients": "[ ... ]" }
    }
  ],
  "count": 1
}

Retrieve a document

GET/v1/documents/{documentId}

Fetches a single document's metadata. Archived documents return 404 as if they no longer exist.

Parameters

ParameterTypeInDescription
documentIdrequiredstringpathThe document identifier, e.g. BSD-1718049600000.
Request
curl https://api.beesign.net/v1/documents/BSD-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "id": "BSD-1718049600000",
  "name": "BSD-1718049600000",
  "size": 254013,
  "contentType": "application/pdf",
  "createdAt": "2025-06-10T18:40:00.000Z",
  "updatedAt": "2025-06-10T18:40:00.000Z",
  "metadata": { "recipients": "[ ... ]" }
}

Get a download URL

GET/v1/documents/{documentId}/download

Generates a short-lived, signed URL you can use to download the PDF directly. The URL expires after 15 minutes (900 seconds).

Parameters

ParameterTypeInDescription
documentIdrequiredstringpathThe document identifier.
Request
curl https://api.beesign.net/v1/documents/BSD-1718049600000/download \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "downloadUrl": "https://storage.googleapis.com/beesign/...&X-Goog-Signature=...",
  "expiresIn": 900
}

Archive a document

DELETE/v1/documents/{documentId}

Soft-deletes a document by moving it to ARCHIVE storage. It stops appearing in listings but is not permanently destroyed.

Parameters

ParameterTypeInDescription
documentIdrequiredstringpathThe document identifier.
Request
curl -X DELETE https://api.beesign.net/v1/documents/BSD-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "message": "Document deleted successfully",
  "id": "BSD-1718049600000"
}

Archive all documents

DELETE/v1/documents

Archives every document in the workspace in one call. Returns the number of documents that were archived.

Request
curl -X DELETE https://api.beesign.net/v1/documents \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "message": "All documents archived successfully",
  "archivedCount": 12,
  "storageClass": "ARCHIVE"
}

Forms

Forms are reusable, fillable PDFs grouped by category. Identified by an id like BSF-1718049600000.

Upload a form

POST/v1/forms

Uploads a new form. Send the request as multipart/form-data. If you omit formId, one is generated for you.

Parameters

ParameterTypeInDescription
filerequiredfileformThe PDF file to upload.
categoryrequiredstringformThe category the form belongs to.
formNamerequiredstringformA human-readable name for the form.
formIdoptionalstringformOptional custom id. Defaults to BSF-{timestamp}.
Request
curl -X POST https://api.beesign.net/v1/forms \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@./onboarding.pdf" \
  -F "category=HR" \
  -F "formName=Onboarding Agreement"
Response · 201 Created
{
  "id": "BSF-1718049600000",
  "name": "Onboarding Agreement",
  "category": "HR",
  "size": 84213,
  "contentType": "application/pdf",
  "path": "user_2ab.../forms/BSF-1718049600000"
}

List forms

GET/v1/forms

Returns every form in the authenticated workspace.

Request
curl https://api.beesign.net/v1/forms \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "forms": [
    {
      "id": "BSF-1718049600000",
      "name": "BSF-1718049600000",
      "size": 84213,
      "contentType": "application/pdf",
      "createdAt": "2025-06-10T18:40:00.000Z",
      "updatedAt": "2025-06-10T18:40:00.000Z",
      "metadata": { "category": "HR", "formName": "Onboarding Agreement" }
    }
  ],
  "count": 1
}

Retrieve a form

GET/v1/forms/{formId}

Fetches a single form's metadata.

Parameters

ParameterTypeInDescription
formIdrequiredstringpathThe form identifier.
Request
curl https://api.beesign.net/v1/forms/BSF-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "id": "BSF-1718049600000",
  "name": "BSF-1718049600000",
  "size": 84213,
  "contentType": "application/pdf",
  "createdAt": "2025-06-10T18:40:00.000Z",
  "updatedAt": "2025-06-10T18:40:00.000Z",
  "metadata": { "category": "HR", "formName": "Onboarding Agreement" }
}

Get a download URL

GET/v1/forms/{formId}/download

Generates a signed download URL valid for 15 minutes.

Parameters

ParameterTypeInDescription
formIdrequiredstringpathThe form identifier.
Request
curl https://api.beesign.net/v1/forms/BSF-1718049600000/download \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "downloadUrl": "https://storage.googleapis.com/beesign/...&X-Goog-Signature=...",
  "expiresIn": 900
}

Delete a form

DELETE/v1/forms/{formId}

Permanently deletes a single form.

Parameters

ParameterTypeInDescription
formIdrequiredstringpathThe form identifier.
Request
curl -X DELETE https://api.beesign.net/v1/forms/BSF-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "message": "Form deleted successfully",
  "id": "BSF-1718049600000"
}

Delete all forms

DELETE/v1/forms

Permanently deletes every form in the workspace.

Request
curl -X DELETE https://api.beesign.net/v1/forms \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "message": "All forms deleted successfully",
  "deletedCount": 8
}

Templates

Templates are reusable signature setups, each bundling one or more documents under a manifest.

List templates

GET/v1/templates

Returns every template in the authenticated workspace.

Request
curl https://api.beesign.net/v1/templates \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "templates": [
    {
      "id": "BST-1718049600000",
      "name": "NDA Template",
      "createdAt": "2025-06-10T18:40:00.000Z",
      "updatedAt": "2025-06-10T18:40:00.000Z",
      "metadata": { "name": "NDA Template" }
    }
  ],
  "count": 1
}

Retrieve a template

GET/v1/templates/{templateId}

Fetches a template's metadata along with the list of documents it contains.

Parameters

ParameterTypeInDescription
templateIdrequiredstringpathThe template identifier.
Request
curl https://api.beesign.net/v1/templates/BST-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "id": "BST-1718049600000",
  "name": "NDA Template",
  "createdAt": "2025-06-10T18:40:00.000Z",
  "updatedAt": "2025-06-10T18:40:00.000Z",
  "metadata": { "name": "NDA Template" },
  "documents": [
    {
      "id": "doc-1.pdf",
      "name": "doc-1.pdf",
      "size": 120344,
      "contentType": "application/pdf",
      "createdAt": "2025-06-10T18:40:00.000Z",
      "updatedAt": "2025-06-10T18:40:00.000Z",
      "metadata": {}
    }
  ],
  "documentCount": 1
}

Send a template for signature

POST/v1/templates/{templateId}/use_template

Instantiates a template and sends its documents out for signature. Each document in the template is uploaded as a new document and emailed to the relevant recipients. Optionally remap the template's placeholder recipients to real people by name via the assignments body, and fill in the template's variables via the variables body. If the template defines approvers, the documents are sent as an approval batch and a batchId is returned. When called with an organization key, the X-User-Id header is required so the documents are created under that member's workspace.

Parameters

ParameterTypeInDescription
templateIdrequiredstringpathThe template identifier.
X-User-IdoptionalstringheaderRequired for organization API keys — the member to send on behalf of. Ignored for personal keys.
assignmentsoptionalobjectbodyMaps a template recipient's name to the real recipient's { name, email }. Recipients not listed keep the template's defaults.
variablesoptionalobjectbodyFills the template's variables, keyed by variable name (or variable id). Each value is stamped into the document wherever that variable is placed. Variables not listed fall back to their defaultValue, or render blank if none is set.
Request
curl -X POST https://api.beesign.net/v1/templates/BST-1718049600000/use_template \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "assignments": {
      "Signer 1": { "name": "Jordan Lee", "email": "[email protected]" }
    },
    "variables": {
      "Location": "California"
    }
  }'
Response · 200 OK
{
  "success": true,
  "templateId": "BST-1718049600000",
  "documentsSent": 1,
  "batchId": null
}

Download a template document

GET/v1/templates/{templateId}/download/{documentId}

Generates a signed download URL for a specific document inside a template.

Parameters

ParameterTypeInDescription
templateIdrequiredstringpathThe template identifier.
documentIdrequiredstringpathThe document identifier within the template.
Request
curl https://api.beesign.net/v1/templates/BST-1718049600000/download/doc-1.pdf \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "downloadUrl": "https://storage.googleapis.com/beesign/...&X-Goog-Signature=...",
  "expiresIn": 900,
  "templateId": "BST-1718049600000",
  "documentId": "doc-1.pdf"
}

Delete a template

DELETE/v1/templates/{templateId}

Permanently deletes a template and all of the documents it contains.

Parameters

ParameterTypeInDescription
templateIdrequiredstringpathThe template identifier.
Request
curl -X DELETE https://api.beesign.net/v1/templates/BST-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "message": "Template deleted successfully",
  "id": "BST-1718049600000",
  "deletedFiles": 3
}

Delete all templates

DELETE/v1/templates

Permanently deletes every template in the workspace.

Request
curl -X DELETE https://api.beesign.net/v1/templates \
  -H "Authorization: Bearer YOUR_API_KEY"
Response · 200 OK
{
  "message": "All templates deleted successfully",
  "deletedTemplates": 4,
  "deletedFiles": 11
}

Contacts

Contacts are the people a workspace sends documents to. Each is identified by an id like BSC-1718049600000, and lives in one of two address books: an organization book the whole workspace shares and only an admin may write, or a member's personal book, which also fills itself in from the documents that member sends. The scope field says which book a contact is in. Within a book an email address identifies exactly one contact, so a write that would claim an address another contact already holds comes back as 409 email_taken with that contact's id.

List contacts

GET/v1/contacts

Returns the organization's shared contacts plus the calling member's own. A person held in both books appears once, as the organization entry — an admin curated those fields, whereas a personal copy is usually just the name typed into a recipient field on some past send.

Parameters

ParameterTypeInDescription
scopeoptionalstringqueryNarrow to one book: "organization" or "personal". Defaults to both.
X-User-IdoptionalstringheaderRequired with an organization key to identify whose personal contacts to include. Without it only the shared book is returned.
Request
curl https://api.beesign.net/v1/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-User-Id: user_2ab..."
Response · 200 OK
{
  "contacts": [
    {
      "id": "BSC-1718049600000",
      "email": "[email protected]",
      "name": "Jordan Lee",
      "company": "Acme Inc.",
      "phone": "+1 555 0100",
      "notes": null,
      "scope": "organization",
      "source": "manual",
      "lastSentAt": "Mon Jun 10 2025 18:40:00 GMT+0000",
      "createdByUserId": "user_2ab..."
    }
  ],
  "count": 1
}

Retrieve a contact

GET/v1/contacts/{contactId}

Returns one contact along with every document the workspace has sent to their address. The history is workspace-wide even when the contact record is personal — it answers what the workspace sent this person, not who happens to hold their address. Both books are searched, the member's own first.

Parameters

ParameterTypeInDescription
contactIdrequiredstringpathThe contact identifier, e.g. BSC-1718049600000.
X-User-IdoptionalstringheaderRequired with an organization key to search that member's personal book as well as the shared one.
Request
curl https://api.beesign.net/v1/contacts/BSC-1718049600000 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-User-Id: user_2ab..."
Response · 200 OK
{
  "id": "BSC-1718049600000",
  "email": "[email protected]",
  "name": "Jordan Lee",
  "company": "Acme Inc.",
  "phone": "+1 555 0100",
  "notes": null,
  "scope": "organization",
  "lastSentAt": "Mon Jun 10 2025 18:40:00 GMT+0000",
  "createdByUserId": "user_2ab...",
  "documents": [
    {
      "documentId": "BSD-1718049600000",
      "documentName": "Mutual NDA",
      "recipientType": "signer",
      "sentAt": "Mon Jun 10 2025 18:40:00 GMT+0000",
      "sentByUserId": "user_2ab..."
    }
  ]
}

List a contact's documents

GET/v1/contacts/{contactId}/documents

Everything the workspace has sent to this contact's address, newest first. The same list the retrieve endpoint embeds, on its own for when you only need the history.

Parameters

ParameterTypeInDescription
contactIdrequiredstringpathThe contact identifier, e.g. BSC-1718049600000.
limitoptionalintegerqueryMaximum documents to return. Defaults to 50.
Request
curl https://api.beesign.net/v1/contacts/BSC-1718049600000/documents \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-User-Id: user_2ab..."
Response · 200 OK
{
  "contactId": "BSC-1718049600000",
  "email": "[email protected]",
  "documents": [
    {
      "documentId": "BSD-1718049600000",
      "documentName": "Mutual NDA",
      "recipientType": "signer",
      "sentAt": "Mon Jun 10 2025 18:40:00 GMT+0000",
      "sentByUserId": "user_2ab..."
    }
  ],
  "count": 1
}

Create a contact

POST/v1/contacts

Adds a contact and returns it with the id it was given. Writes to the calling member's own book unless scope is "organization", which requires an organization admin — a personal API key is a workspace of one, has no shared book, and always writes personal. An address is unique within a book: if the target book already holds it, the call is refused with 409 and names the contact that has it, rather than overwriting details the new request left blank.

Parameters

ParameterTypeInDescription
emailrequiredstringbodyThe contact's email address. Case is normalised.
scopeoptionalstringbody"personal" (default) or "organization". Sharing requires an organization admin.
nameoptionalstringbodyDisplay name.
companyoptionalstringbodyCompany or organization.
phoneoptionalstringbodyPhone number.
notesoptionalstringbodyFree-text notes.
X-User-IdoptionalstringheaderRequired with an organization key so the contact is filed under that member, and to establish their role when sharing.
Request
curl -X POST https://api.beesign.net/v1/contacts \
  -H "Authorization: Bearer YOUR_ORG_API_KEY" \
  -H "X-User-Id: user_2ab..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "name": "Jordan Lee",
    "company": "Acme Inc.",
    "scope": "organization"
  }'
Response · 201 Created
{
  "id": "BSC-1718049600000",
  "email": "[email protected]",
  "name": "Jordan Lee",
  "company": "Acme Inc.",
  "phone": null,
  "notes": null,
  "scope": "organization",
  "source": "manual",
  "createdByUserId": "user_2ab..."
}

Update a contact

PATCH/v1/contacts/{contactId}

Updates the fields you supply on an existing contact. Passing a different scope moves the contact between books, keeping its id — so the link to it stays valid. Repointing a contact at an address another contact in the target book already holds is refused with 409: those are two people, and writing one onto the other would destroy it. Editing or sharing an organization contact requires an admin; a member may always edit their own.

Parameters

ParameterTypeInDescription
contactIdrequiredstringpathThe contact identifier, e.g. BSC-1718049600000.
emailoptionalstringbodyThe contact's email address.
scopeoptionalstringbodyMove the contact to the other book: "personal" or "organization".
nameoptionalstringbodyDisplay name.
companyoptionalstringbodyCompany or organization.
phoneoptionalstringbodyPhone number.
notesoptionalstringbodyFree-text notes.
Request
curl -X PATCH https://api.beesign.net/v1/contacts/BSC-1718049600000 \
  -H "Authorization: Bearer YOUR_ORG_API_KEY" \
  -H "X-User-Id: user_2ab..." \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+1 555 0100",
    "notes": "Prefers a call before anything goes out."
  }'
Response · 200 OK
{
  "id": "BSC-1718049600000",
  "email": "[email protected]",
  "name": "Jordan Lee",
  "company": "Acme Inc.",
  "phone": "+1 555 0100",
  "notes": "Prefers a call before anything goes out.",
  "scope": "organization"
}

Delete a contact

DELETE/v1/contacts/{contactId}

Removes one contact from the book that holds it. Documents already sent to them, and the record of those sends, are untouched — so the person still appears in any other member's book. Deleting an organization contact requires an admin.

Parameters

ParameterTypeInDescription
contactIdrequiredstringpathThe contact identifier, e.g. BSC-1718049600000.
Request
curl -X DELETE https://api.beesign.net/v1/contacts/BSC-1718049600000 \
  -H "Authorization: Bearer YOUR_ORG_API_KEY" \
  -H "X-User-Id: user_2ab..."
Response · 200 OK
{
  "id": "BSC-1718049600000",
  "deleted": true,
  "scope": "organization"
}

Erase a person from the workspace

POST/v1/contacts/erase

Removes an email address from every book in the workspace — the shared one and every member's — along with the record of what was sent to it. This is the endpoint that serves an erasure request from a recipient who never signed up for BeeSign. It is keyed by address rather than by contact id, because the same person may sit in several books under different ids. The signed documents themselves are unaffected; only the lookup records go. Requires an organization admin.

Parameters

ParameterTypeInDescription
emailrequiredstringbodyThe address to erase. Case is normalised.
Request
curl -X POST https://api.beesign.net/v1/contacts/erase \
  -H "Authorization: Bearer YOUR_ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'
Response · 200 OK
{
  "email": "[email protected]",
  "erased": true,
  "deletedHistoryRows": 3
}

Users

List the members of an organization. Available only to organization API keys — personal keys receive a 403.

List organization users

GET/v1/users

Returns the members of the organization that owns the API key, including their role.

Request
curl https://api.beesign.net/v1/users \
  -H "Authorization: Bearer YOUR_ORG_API_KEY"
Response · 200 OK
{
  "users": [
    {
      "id": "user_2ab...",
      "name": "Jordan Lee",
      "email": "[email protected]",
      "role": "org:admin"
    }
  ],
  "count": 1
}