> You are reading the Docusign Developer Documentation. For clean Markdown of any page, append .md to the page URL.
>
> Documentation indexes by section:
> - APIs and SDKs: https://docusign.docs.buildwithfern.com/docs/llms.txt
> - Platform 101: https://docusign.docs.buildwithfern.com/platform/llms.txt
> - Extension Apps: https://docusign.docs.buildwithfern.com/extension-apps/llms.txt
> - Docusign CLI: https://docusign.docs.buildwithfern.com/docusign-cli/llms.txt
>
> Authentication (OAuth, JWT Grant, M2M): https://docusign.docs.buildwithfern.com/platform/auth
> Webhooks and Connect: https://docusign.docs.buildwithfern.com/platform/webhooks
>
> OpenAPI specifications: https://docusign.docs.buildwithfern.com/openapi.json
> MCP server: https://docusign.docs.buildwithfern.com/_mcp/server

# Bulk upload agreements

> Learn how to bulk upload your agreements into the Agreement Manager.

Bulk Upload enables developers to programmatically upload many agreements into the Agreement manager at the same time, triggering AI extraction where applicable on your uploaded documents or applying your supplied metadata directly.

Agreement manager bulk upload works by generating upload URLs as part of a bulk job and passing them back to your app. Your app then uploads one document to each upload URL and, when all of your documents are uploaded, calls an endpoint to signal completion. This removes the overhead of proxying large files and enables you to easily and painlessly mass-onboard legacy documents, such as old contracts from disparate systems, split between different file formats and organization systems.

## Bulk upload use cases

**Bulk upload enables you to migrate large numbers of legacy agreements into one place for management.** Bulk upload legacy contracts from disparate systems such as your on-premises storage, SharePoint, Google Drive, or Dropbox into the Agreement Management platform.

You can use AI extraction to order and apply metadata to these documents, or upload documents alongside structured metadata such as custom field values, record IDs, or tags, to skip AI extraction overhead and maintain data fidelity.

For example, a bank with contracts going back years or decades, in many different formats, from many different regions, wants to standardize their documents and manage them from one place. Bulk upload is the mechanism by which the masses of these documents can be added to Agreement Manager for ingestion, sorting, and categorization.

## How bulk upload works

You can create bulk upload jobs for documents using the following steps:

### 1. Create a bulk upload job

Call the `POST /v1/accounts/{accountId}/upload/jobs` endpoint to create a job, providing a name, language, and the number of docs to be uploaded.

The response includes a job ID and pre-signed blob storage URLs for each document, which are valid for 8 hours.

The `document_uploader_write` and `document_uploader_read` scopes are required for performing bulk upload tasks with the API. The `adm_store_unified_repo_read` is also required for tasks that involve reading agreement records.

**`Example request`**

```bash title="Example request"
curl --location \
  'https://api-d.docusign.com/v1/accounts/08b4799a-xxxx-xxxx-xxxx-b5b4b8a97604/upload/jobs' \
  --header 'Authorization: Bearer eyJ…1UA' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "job_name": "Q4 Contract Migration",
    "expected_number_of_docs": 3,
    "language": "en-US",
    "agreement_set_ids": [
      "-8c-dVtBzjSe7nh_zAf9L"
    ]
  }'
```

**`Example response`**

```bash title="Example response"
{
    "id": "c5f018e6-xxxx-xxxx-xxxx-539c6f505a95",
    "name": "Q4 Contract Migration",
    "status": "OPEN",
    "status_enum": [
        "OPEN",
        "UPLOAD_COMPLETE",
        "IN_PROGRESS",
        "COMPLETE",
        "FAILED",
        "CANCELED"
    ],
    "created_at": "2026-04-30T17:02:17.423534599Z",
    "modified_at": "2026-04-30T17:02:17.423534699Z",
    "expires_at": "2026-05-03T17:02:17.423534599Z",
    "ttl_period": "P3D",
    "upload_settings": {
        "ai_extraction": true
    },
    "_embedded": {
        "documents": [
            {
                "id": "52195f0f-xxxx-xxxx-xxxx-feebc5ad8750",
                "sequence": 1,
                "_actions": {
                    "upload_document": "<Document_Upload_URL1>."
                }
            },
            {
                "id": "8b6d6138-xxxx-xxxx-xxxx-73af695dcd2f",
                "sequence": 2,
                "_actions": {
                    "upload_document": "<Document_Upload_URL2>"
                }
            },
            {
                "id": "e7d7feb3-xxxx-xxxx-xxxx-507bacc66709",
                "sequence": 3,
                "_actions": {
                    "upload_document": "<Document_Upload_URL3>"
                }
            }
        ]
    },
    "_action_templates": {
        "upload_document": {
            "method": "PUT",
            "required": true,
            "description": "Upload the document binary content",
            "template_variables": {
                "document_name": "Client-provided filename, used in x-ms-meta-filename header"
            },
            "headers": {
                "x-ms-blob-type": "BlockBlob",
                "x-ms-meta-filename": "{document_name}"
            },
            "constraints": {
                "max_size_mb": 500,
                "allowed_formats": [
                    "pdf",
                    "eml",
                    "msg",
                    "doc",
                    "docx",
                    "dot",
                    "rtf",
                    "wpd",
                    "xls",
                    "xlsx",
                    "xlsb",
                    "ppt",
                    "pptx",
                    "pps",
                    "ppsx",
                    "html",
                    "htm",
                    "jpeg",
                    "jpg",
                    "png",
                    "tif",
                    "tiff"
                ],
                "timeout_seconds": 300
            },
            "success_status_code": 200
        }
    },
    "constraints": {
        "max_documents_per_job": 10000
    },
    "metadata": {
        "response_timestamp": "2026-04-30T17:02:17.602320006Z",
        "response_duration": 374
    },
    "message": "Files exceeding 500MB or more than 10,000 per job will be rejected. Files over 190MB are not processed by AI. For documents exceeding 300 pages, only the first 300 pages are processed by AI."
}
```

### 2. Upload documents to pre-signed URLs

For each document URL in the `_embedded.documents` array, make an HTTP PUT request providing the binary file content. The required headers for these calls are:

* `x-ms-blob-type`: `BlockBlob`: Required.
* `x-ms-meta-filename: YourDocumentName.pdf`: Recommended. Defaults to your document ID if omitted.
* `Content-Type`: The appropriate MIME type for your file. Required.

Documents can be uploaded in parallel, with your own retry logic, and integrated into existing file processing pipelines.

You can also add a metadata header alongside each document to be uploaded. When metadata is provided, the platform skips the AI extraction step for that document since the metadata already exists. This metadata must be provided in JSON format via the API (CSV-based metadata is a UI-only feature).

Supported file formats for bulk upload documents are:

* .pdf
* .docx
* .doc
* .pptx
* .txt
* .html
* .htm
* .rtf
* .jpg or .jpeg
* .png
* .tiff or .tif
* .eml
* .zip

For the authoritative list of supported formats, size limits, and headers, always refer to the `allowed_formats` and headers in the `_action_templates` section of the `createBulkUploadJob` response.

**`Example metadata`**

```json title="Example metadata"
{
   "provisions":{
      "jurisdiction":"California"
   },
   "custom_provisions":{
      "c_ClientId":{
         "value":"12345"
      }
   }
}
```

**`Example request`**

```bash title="Example request"
curl --location \
  '<Document_Upload_URL1>' \
  --request PUT \
  --header 'x-ms-blob-type: BlockBlob' \
  --header 'x-ms-meta-filename: contract-001.pdf' \
  --header 'x-ms-meta-metadata: {"provisions":{"jurisdiction":"California"},"custom_provisions":{"c_ClientId":{"value":"12345"}}}' \
  --header 'Content-Type: application/pdf' \
  --data-binary '@/path/to/contract-001.pdf'
```

### 3. Mark the job complete

Once all of the documents have been uploaded, make a POST `/v1/accounts/{accountId}/upload/jobs/{jobId}/actions/complete` call to mark the job complete, triggering ingestion of the documents and AI extraction.

**`Example request`**

```bash title="Example request"
curl --location \
  'https://api-d.docusign.com/v1/accounts/08b4799a-xxxx-xxxx-xxxx-b5b4b8a97604/upload/jobs/c5f018e6-xxxx-xxxx-xxxx-539c6f505a95/actions/complete' \
  --request POST \
  --header 'Authorization: Bearer eyJ…1UA' \
  --header 'Content-Type: application/json'
```

**`Example response`**

```bash title="Example response"
{
    "id": "c5f018e6-xxxx-xxxx-xxxx-539c6f505a95",
    "name": "Q4 Contract Migration",
    "status": "UPLOAD_COMPLETE",
    "status_enum": [
        "OPEN",
        "UPLOAD_COMPLETE",
        "IN_PROGRESS",
        "COMPLETE",
        "FAILED",
        "CANCELED"
    ],
    "created_at": "2026-04-30T17:02:17.423535Z",
    "modified_at": "2026-04-30T17:02:17.423535Z",
    "expires_at": "2026-05-03T17:02:17.423535Z",
    "ttl_period": "P3D",
    "upload_settings": {
        "ai_extraction": true
    },
    "metadata": {
        "response_timestamp": "2026-04-30T17:17:30.079345004Z",
        "response_duration": 61
    }
}
```

## Bulk upload rules and rate limits

| **Constraint**                | **Description**                                                                                   |
| ----------------------------- | ------------------------------------------------------------------------------------------------- |
| Maximum documents per job     | 10,000 documents. For uploads exceeding 10,000 documents, you must use multiple bulk upload jobs. |
| Maximum file size             | 500 MB per file.                                                                                  |
| AI extraction file size limit | 190 MB (up to 300 pages).                                                                         |
| Pre-signed URL validity       | 8 hours.                                                                                          |
| Bulk upload job lifespan      | A job will expire after 3 days.                                                                   |

## Next steps

* Learn how to [Unlock Your Historical Agreements: Agreement Manager API Bulk Ingestion Made Simple](https://www.docusign.com/blog/developers/navigator-api-bulk-ingestion-made-simple)
* See the Agreement Manager [Bulk Jobs API reference](/docs/agreement-manager-api/reference/agreementmanager#bulkjob)