---
title: API Reference
description: Complete REST API documentation for all Seal endpoints
---

# API Reference

The Seal API is organized around REST principles. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

## Base URL

All API requests should be made to:

```
https://api.seal.nyc/api/v1
```

## Authentication

All API endpoints require authentication using an API key. Include your API key in the `Authorization` header:

```
Authorization: Bearer ak_your_api_key_here
```

See the [Authentication Guide](/docs/getting-started/authentication) for details on creating and managing API keys.

## Interactive Reference

Explore all endpoints in the interactive API playground:

**[Open API Playground →](/reference)**

Try every endpoint live — browse schemas, fill in parameters, and run real
requests against the Seal API.

## API Resources

The Seal API is organized into the following resource categories:

**[Documents](/docs/api-reference/documents)**

Upload, send, track, void, and download signed documents

**[Recipients](/docs/api-reference/recipients)**

Manage document recipients with role-based access control

**[Templates](/docs/api-reference/templates)**

Create and manage reusable document templates

**[Signatures](/docs/api-reference/signatures)**

Verify signatures and access audit trails

**[Contacts](/docs/api-reference/contacts)**

Manage your workspace contact directory

**[Members](/docs/api-reference/members)**

List and retrieve workspace team members

**[Analytics](/docs/api-reference/analytics)**

Document completion rates, signing metrics, and workspace trends

**[Audit Log](/docs/api-reference/audit-log)**

Tamper-evident activity history for compliance and security

**[Settings](/docs/api-reference/settings)**

Read and update workspace configuration programmatically

**[Webhooks](/docs/api-reference/webhooks)**

Configure webhook endpoints for real-time notifications

**[Uploads](/docs/api-reference/uploads)**

Generate secure upload URLs for document files

## URL Routing

The Seal API uses query-parameter-based routing for resource operations. Resource IDs are passed as query parameters:

```
GET  /api/v1/documents              # List documents
GET  /api/v1/documents/get?id={id}  # Get a specific document
PUT  /api/v1/documents/update?id={id}  # Update a document
DELETE /api/v1/documents/delete?id={id}  # Delete a document
POST /api/v1/documents/send?id={id}  # Send a document
```

For nested resources like recipients and signatures, the parent document ID is also passed as a query parameter:

```
GET  /api/v1/recipients?document_id={docId}  # List recipients
POST /api/v1/recipients?document_id={docId}  # Add a recipient
```

## Request Format

All POST and PUT requests must include a `Content-Type: application/json` header and a JSON-encoded body.

### Example Request

```typescript
const response = await fetch("https://api.seal.nyc/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",
  }),
});
```

## Response Format

All responses are returned as JSON with appropriate HTTP status codes.

### Success Response

```json
{
  "id": "jd7k8l9m0n1p2q3r4s5t6u7v",
  "title": "Service Agreement",
  "status": "draft",
  "created_at": "2024-01-27T10:30:00Z"
}
```

### Error Response

```json
{
  "type": "https://seal.nyc/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "Field 'title' is required",
  "instance": "/api/v1/documents"
}
```

See the [Error Handling Guide](/docs/getting-started/error-handling) for complete error documentation.

## HTTP Status Codes

| Code | Description                                          |
| ---- | ---------------------------------------------------- |
| 200  | OK - Request succeeded                               |
| 201  | Created - Resource created successfully              |
| 204  | No Content - Request succeeded with no response body |
| 400  | Bad Request - Invalid request parameters             |
| 401  | Unauthorized - Missing or invalid API key            |
| 403  | Forbidden - Insufficient permissions                 |
| 404  | Not Found - Resource doesn't exist                   |
| 429  | Too Many Requests - Rate limit exceeded              |
| 500  | Internal Server Error - Server error                 |

## Rate Limiting

Rate limiting infrastructure is in place and will be enforced in a future release. Planned limits:

- **60 requests per minute** per API key
- **1000 requests per hour** per API key

When enforced, rate limit information will be included in response headers:

```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1706356800
```

We recommend implementing exponential backoff and retry logic to handle future rate limits gracefully.

## Pagination

List endpoints support cursor-based pagination:

### Request Parameters

| Parameter | Type   | Description                                       |
| --------- | ------ | ------------------------------------------------- |
| `limit`   | number | Number of results to return (max 100, default 20) |
| `cursor`  | string | Pagination cursor from previous response          |

### Response Format

```json
{
  "data": [...],
  "has_more": true,
  "next_cursor": "eyJpZCI6ImFiYzEyMyJ9"
}
```

### Example

```typescript
// First page
const page1 = await fetch("https://api.seal.nyc/api/v1/documents?limit=20");
const { data, has_more, next_cursor } = await page1.json();

// Next page
if (has_more) {
  const page2 = await fetch(
    `https://api.seal.nyc/api/v1/documents?limit=20&cursor=${next_cursor}`
  );
}
```

## Timestamps

All timestamps are returned in ISO 8601 format with UTC timezone:

```
2024-01-27T10:30:00Z
```

## Idempotency

POST requests that create resources support idempotency keys to safely retry requests without creating duplicate resources. Include an `Idempotency-Key` header with a unique value:

```typescript
const response = await fetch('https://api.seal.nyc/api/v1/documents', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ak_your_api_key_here',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'unique-key-123'
  },
  body: JSON.stringify({...})
});
```

Requests with the same idempotency key will return the same response without creating duplicate resources.

## Next Steps

- **[Documents API](/docs/api-reference/documents)** - Complete document management endpoints
- **[Quick Start Guide](/docs/getting-started/quick-start)** - Send your first document
- **[Webhooks](/docs/webhooks)** - Set up real-time event notifications
