# Large arguments and uploads

## The body limit

A JSON body may be up to **4 MB**. A larger one is refused with `413 too_large` before any of it is read as arguments.

## Arguments too large for a body

Stage them first, then name the staged upload instead of sending a body:

1. Call [`begin_upload`](/docs/operations/begin_upload) with `purpose: "arguments"`, the workspace, the exact size in bytes and `content_type: "application/json"`. It answers an `upload_id` and a signed `url`.
2. `PUT` the arguments, as one JSON object, to that `url`.
3. Call the operation with no body and the header `X-Arguments-Upload: <upload_id>`. It runs exactly as if the object had been the body.

Sending a body and the header together is refused. An upload can carry up to 64 MB of arguments and expires two hours after it is begun.

The `mdbrain` CLI does all of this by itself when a call's arguments are over the limit.

## Uploading an image

[`upload_image`](/docs/operations/upload_image) takes the image in one of two ways:

- **In the call**, base64-encoded in `data_base64`, for an image that fits the body limit once encoded.
- **Staged**, for an image of any size: call `begin_upload` with `purpose: "image"`, `PUT` the bytes to its `url`, then call `upload_image` with the `upload_id` in place of `data_base64`.

Either way the answer is the new file's id and path. Reference it from a document as `![alt](<name>)`.

`mdbrain upload <workspace> <file>` stages and commits an image in one command.
