Seal Docs

Documents API

Complete API reference for document management endpoints

Documents API

The Documents API allows you to upload, send, track, void, and download signed documents. Documents are the core resource in Seal's signing workflow.

The Document Object

Attributes

AttributeTypeDescription
idstringUnique document identifier
titlestringDocument title
descriptionstringOptional document description
statusstringWorkflow status: draft, sent, in_progress, completed, cancelled, declined
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last update timestamp
recipients_countnumberTotal number of recipients
signed_countnumberNumber of recipients who have signed
deadlinestringOptional ISO 8601 signing deadline

Example Object

{
  "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "title": "Service Agreement",
  "description": "Annual service contract for review and signature",
  "status": "sent",
  "created_at": "2024-01-27T10:30:00Z",
  "updated_at": "2024-01-27T10:31:00Z",
  "recipients_count": 2,
  "signed_count": 0,
  "deadline": "2024-02-10T23:59:59Z"
}

List Documents

Retrieve a paginated list of documents for your organization.

Endpoint

GET /api/v1/documents

Required Scope

seal:documents:read

Query Parameters

ParameterTypeDescription
limitnumberNumber of results (max 100, default 20)
cursorstringPagination cursor from previous response
statusstringFilter by workflow status

TypeScript Example

const response = await fetch("https://seal.convex.site/api/v1/documents?limit=20&status=sent", {
  headers: {
    Authorization: "Bearer ak_your_api_key_here",
  },
});

const { data, has_more, next_cursor } = await response.json();

cURL Example

curl -X GET "https://seal.convex.site/api/v1/documents?limit=20&status=sent" \
  -H "Authorization: Bearer ak_your_api_key_here"

Response

{
  "data": [
    {
      "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
      "title": "Service Agreement",
      "status": "sent",
      "created_at": "2024-01-27T10:30:00Z",
      "updated_at": "2024-01-27T10:31:00Z",
      "recipients_count": 2,
      "signed_count": 0
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Get Document

Retrieve a single document by ID.

Endpoint

GET /api/v1/documents/get?id={id}

Required Scope

seal:documents:read

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID
include_recipientsbooleanInclude recipient details in response

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/get?id=jd7k8l9m0n1p2q3r4s5t6u7v&include_recipients=true",
  {
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
    },
  },
);

const document = await response.json();

cURL Example

curl -X GET "https://seal.convex.site/api/v1/documents/get?id=jd7k8l9m0n1p2q3r4s5t6u7v&include_recipients=true" \
  -H "Authorization: Bearer ak_your_api_key_here"

Response

{
  "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "title": "Service Agreement",
  "description": "Annual service contract",
  "status": "sent",
  "created_at": "2024-01-27T10:30:00Z",
  "updated_at": "2024-01-27T10:31:00Z",
  "recipients_count": 2,
  "signed_count": 1,
  "download_url": "https://storage.convex.cloud/...",
  "recipients": [
    {
      "id": "rec_abc123",
      "email": "john@example.com",
      "name": "John Doe",
      "role": "signer",
      "status": "signed",
      "signed_at": "2024-01-27T11:00:00Z"
    },
    {
      "id": "rec_def456",
      "email": "jane@example.com",
      "name": "Jane Smith",
      "role": "signer",
      "status": "pending"
    }
  ]
}

Create Document

Create a new document from an uploaded file.

Endpoint

POST /api/v1/documents

Required Scope

seal:documents:write

Request Body

FieldTypeRequiredDescription
titlestringYesDocument title
descriptionstringNoDocument description
storage_idstringYesStorage ID from upload endpoint
file_sizenumberYesFile size in bytes
file_typestringYesMIME type (e.g., "application/pdf")
page_countnumberNoNumber of pages in document
deadlinestringNoISO 8601 signing deadline

TypeScript Example

const response = await fetch("https://seal.convex.site/api/v1/documents", {
  method: "POST",
  headers: {
    Authorization: "Bearer ak_your_api_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Service Agreement",
    description: "Annual service contract",
    storage_id: "kg2h4j5k6l7m8n9p0q1r2s3t",
    file_size: 245760,
    file_type: "application/pdf",
    page_count: 5,
    deadline: "2024-02-10T23:59:59Z",
  }),
});

const document = await response.json();

cURL Example

curl -X POST https://seal.convex.site/api/v1/documents \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Service Agreement",
    "description": "Annual service contract",
    "storage_id": "kg2h4j5k6l7m8n9p0q1r2s3t",
    "file_size": 245760,
    "file_type": "application/pdf",
    "page_count": 5,
    "deadline": "2024-02-10T23:59:59Z"
  }'

Response

{
  "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "title": "Service Agreement",
  "description": "Annual service contract",
  "status": "draft",
  "created_at": "2024-01-27T10:30:00Z",
  "updated_at": "2024-01-27T10:30:00Z",
  "recipients_count": 0,
  "signed_count": 0,
  "deadline": "2024-02-10T23:59:59Z"
}

Update Document

Update a document's metadata.

Endpoint

PUT /api/v1/documents/update?id={id}

Required Scope

seal:documents:write

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

Request Body

FieldTypeDescription
titlestringNew document title
descriptionstringNew document description
deadlinestringNew ISO 8601 signing deadline

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/update?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    method: "PUT",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: "Updated Service Agreement",
      deadline: "2024-02-15T23:59:59Z",
    }),
  },
);

const document = await response.json();

cURL Example

curl -X PUT "https://seal.convex.site/api/v1/documents/update?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated Service Agreement",
    "deadline": "2024-02-15T23:59:59Z"
  }'

Delete Document

Permanently delete a document.

Endpoint

DELETE /api/v1/documents/delete?id={id}

Required Scope

seal:documents:write

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/delete?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    method: "DELETE",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
    },
  },
);

const result = await response.json();
// Returns { "deleted": true } with status 200

cURL Example

curl -X DELETE "https://seal.convex.site/api/v1/documents/delete?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here"

Response

{
  "deleted": true
}

Warning: Deleting a document is permanent and cannot be undone. All associated recipients, signatures, and audit trail data will also be deleted.

Send Document

Send a document to all recipients for signing.

Endpoint

POST /api/v1/documents/send?id={id}

Required Scope

seal:documents:write

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

Request Body

FieldTypeRequiredDescription
messagestringNoCustom message to include in email notification

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/send?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message: "Please review and sign this agreement at your earliest convenience.",
    }),
  },
);

const result = await response.json();

cURL Example

curl -X POST "https://seal.convex.site/api/v1/documents/send?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Please review and sign this agreement."
  }'

Response

Returns the updated document object.

{
  "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "title": "Service Agreement",
  "status": "sent",
  "created_at": "2024-01-27T10:30:00Z",
  "updated_at": "2024-01-27T10:31:00Z",
  "recipients_count": 2,
  "signed_count": 0,
  "download_url": "https://storage.convex.cloud/..."
}

Void Document

Cancel a document and prevent further signing.

Endpoint

POST /api/v1/documents/void?id={id}

Required Scope

seal:documents:write

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

Request Body

FieldTypeRequiredDescription
reasonstringNoReason for voiding the document

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/void?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      reason: "Contract terms changed, new version required",
    }),
  },
);

const result = await response.json();

cURL Example

curl -X POST "https://seal.convex.site/api/v1/documents/void?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Contract terms changed"
  }'

Response

{
  "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "status": "cancelled",
  "voided_at": "2024-01-27T12:00:00Z",
  "void_reason": "Contract terms changed"
}

Note: Voiding a document prevents recipients from signing but preserves the document and audit trail for record-keeping.

Download Document

Get a temporary download URL for the document PDF.

Endpoint

GET /api/v1/documents/download?id={id}

Required Scope

seal:documents:read

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/download?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
    },
  },
);

const { download_url, expires_at } = await response.json();

// Download the file
const fileResponse = await fetch(download_url);
const blob = await fileResponse.blob();

cURL Example

curl -X GET "https://seal.convex.site/api/v1/documents/download?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here"

Response

{
  "download_url": "https://storage.convex.cloud/...",
  "expires_at": "2024-01-27T11:00:00Z"
}

Note: Download URLs are temporary and expire after a short period (typically 1 hour). Generate a new URL if the previous one has expired.

Get Document Access

Retrieve the current sharing mode for a document.

Endpoint

GET /api/v1/documents/access?id={id}

Required Scope

seal:documents:read

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/access?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
    },
  },
);

const access = await response.json();
console.log(access.sharing_mode); // "private" | "workspace" | "specific"

cURL Example

curl -X GET "https://seal.convex.site/api/v1/documents/access?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here"

Response

{
  "document_id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "sharing_mode": "private"
}
sharing_modeDescription
privateOnly the document owner can access it
workspaceAll workspace members can view the document (Pro)
specificAccess granted to specific users only

Update Document Access

Change the sharing mode for a document.

Endpoint

PATCH /api/v1/documents/access?id={id}

Required Scope

seal:documents:write

Query Parameters

ParameterTypeDescription
idstringRequired. Document ID

Request Body

FieldTypeRequiredDescription
sharing_modestringYesNew sharing mode: private, workspace, or specific

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/access?id=jd7k8l9m0n1p2q3r4s5t6u7v",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ sharing_mode: "workspace" }),
  },
);

const result = await response.json();
// { "success": true }

cURL Example

curl -X PATCH "https://seal.convex.site/api/v1/documents/access?id=jd7k8l9m0n1p2q3r4s5t6u7v" \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"sharing_mode": "workspace"}'

Response

{
  "success": true
}

Bulk Void Documents

Void (cancel) multiple documents in a single request. Each document is processed independently — failures in one do not block others.

Endpoint

POST /api/v1/documents/bulk-void

Required Scope

seal:documents:write

Request Body

FieldTypeRequiredDescription
document_idsstring[]YesIDs of documents to void (max 50)
reasonstringNoCancellation reason shown to recipients

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/bulk-void",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      document_ids: [
        "jd7k8l9m0n1p2q3r4s5t6u7v",
        "ab1cd2ef3gh4ij5kl6mn7op8",
      ],
      reason: "Contract terms updated — please sign the revised version",
    }),
  },
);

const result = await response.json();
console.log(`Voided: ${result.succeeded} / ${result.total_requested}`);

cURL Example

curl -X POST "https://seal.convex.site/api/v1/documents/bulk-void" \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "document_ids": ["jd7k8l9m0n1p2q3r4s5t6u7v", "ab1cd2ef3gh4ij5kl6mn7op8"],
    "reason": "Superseded by revised agreement"
  }'

Response

{
  "total_requested": 2,
  "succeeded": 1,
  "failed": 1,
  "results": [
    {
      "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
      "success": true
    },
    {
      "id": "ab1cd2ef3gh4ij5kl6mn7op8",
      "success": false,
      "error": "Cannot void a completed document"
    }
  ]
}

Documents that are already completed, cancelled, or declined cannot be voided and will appear in results with success: false.

Bulk Send Documents

Send multiple draft documents to their recipients in a single request. Each document is processed independently.

Endpoint

POST /api/v1/documents/bulk-send

Required Scope

seal:documents:write

Request Body

FieldTypeRequiredDescription
document_idsstring[]YesIDs of draft documents to send (max 50)

TypeScript Example

const response = await fetch(
  "https://seal.convex.site/api/v1/documents/bulk-send",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer ak_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      document_ids: [
        "jd7k8l9m0n1p2q3r4s5t6u7v",
        "ab1cd2ef3gh4ij5kl6mn7op8",
        "cd3ef4gh5ij6kl7mn8op9qr0",
      ],
    }),
  },
);

const result = await response.json();
console.log(`Sent: ${result.succeeded} / ${result.total_requested}`);

cURL Example

curl -X POST "https://seal.convex.site/api/v1/documents/bulk-send" \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "document_ids": [
      "jd7k8l9m0n1p2q3r4s5t6u7v",
      "ab1cd2ef3gh4ij5kl6mn7op8"
    ]
  }'

Response

{
  "total_requested": 3,
  "succeeded": 2,
  "failed": 1,
  "results": [
    { "id": "jd7k8l9m0n1p2q3r4s5t6u7v", "success": true },
    { "id": "ab1cd2ef3gh4ij5kl6mn7op8", "success": true },
    {
      "id": "cd3ef4gh5ij6kl7mn8op9qr0",
      "success": false,
      "error": "Document has no recipients"
    }
  ]
}

Only draft documents with at least one recipient can be bulk-sent. Documents that are already sent, completed, or cancelled will appear in results with success: false.

Document Status Workflow

Documents progress through the following statuses:

draft → sent → in_progress → completed

                cancelled (voided)

                declined (recipient declined)
StatusDescription
draftDocument created but not yet sent
sentDocument sent to recipients
in_progressAt least one recipient has viewed/signed
completedAll recipients have completed their actions
cancelledDocument voided by sender
declinedDocument declined by a recipient

Next Steps

Last updated on

On this page