---
title: document_create_upload
description: Reserve a file on a brand, and get a URL for its bytes. This is the first step of an upload.
---

Ask to add a file to a brand. This tool is the first of three steps: it reserves the file and gives the agent a URL for the bytes.

> "Upload our brand book to Acme."

The agent calls `document_create_upload`. Then it sends the file to that URL from its own runtime, and it finishes with [`document_finalize`](/mcp/tools/document-finalize). You then see the brand book in the files of Acme.

The job guide [Describe a brand](/mcp/tools/describe-a-brand) shows each step of the job.

## Reference

Reserve a document against a brand and get a short-lived URL to upload the bytes to. Upload the file yourself with an HTTP PUT to that URL, then call document_finalize. The bytes never pass through this tool — only your runtime touches them.

### Input

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `brand_name` | string | yes | The brand slug this document belongs to. |
| `content_type` | string | yes | The file's content type. Accepted: application/pdf, image/gif, image/jpeg, image/png, image/webp. |
| `filename` | string | yes | The original filename, for display. |

### Output

A successful call returns this object in `structuredContent`.

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `documentId` | string | yes | The id of the reserved document (`doc_…`). Send it to `document_finalize`. |
| `expiresInSeconds` | number | yes | How long `uploadUrl` stays valid, in seconds. When it expires, reserve again. |
| `uploadUrl` | string | yes | A presigned URL. Send the bytes of the file to it with an HTTP `PUT`. Each person who has the URL can write the file until the URL expires. |

### Failure codes

A failed call has `isError` set, and `structuredContent.error` holds one of these codes. [Errors](/mcp/errors) describes the shape of a failed call.

- `not_found`
- `unsupported_type`
- `forbidden`
- `invalid_request`
- `internal_error`

### Scope

The token must hold `brand:write`. [Auth & scopes](/mcp/auth) lists each scope.

### Annotations

A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.

- **Writes.** The tool can change data.
- **Destructive.** The tool can make a change that you cannot undo. A client can ask you to confirm before it calls the tool.
- **Not idempotent.** A second call with the same arguments can change more.
- **Closed world.** The tool reads and writes the data of AdCrunch only.

### Example

The arguments:

```json
{
  "brand_name": "acme",
  "content_type": "application/pdf",
  "filename": "acme-brand-guidelines.pdf"
}
```

The result, in `structuredContent`:

```json
{
  "documentId": "doc_5e2b41",
  "expiresInSeconds": 900,
  "uploadUrl": "https://3f9c2a7b1e0d4c6a8b5e2f1d9c7a4b60.r2.cloudflarestorage.com/documents/org_3a7f10/doc_5e2b41?X-Amz-Expires=900&X-Amz-Date=20260925T184612Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=5b2e7c1f9a0d4e3b8c6f2a1d7e9b4c05%2F20260925%2Fauto%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=e2ea52baf6fb964e4a650eb7aa0341ae656d1cdf36e8923a247576ec9273f2ca"
}
```
