> Documentation index: https://beezr.io/developers/api/llms.txt

# Files

## Upload inside create or update

A CONTENT field takes one upload object in `data`. MULTI_CONTENT and MEDIA_IMG_GALLERY fields take an array of upload objects. Use a field's System name, such as `contract_pdf`.

```json
{"module":"cm_equipment_requests_base","data":{"title":"Laptop","contract_pdf":{"fileName":"contract.pdf","contentType":"application/pdf","data":"<base64>"}}}
```

Send this body to create. For update, add the record `id` and send only the fields you want to change. Encode the file bytes as base64. Each file can be at most 10 MB after decoding. `contentType` is informational; the extension comes from `fileName`.

If a file is rejected, the whole create or update stops with 400 and changes nothing: `INVALID_CONTENT_PAYLOAD` (the value isn't a file object, or an array for multi-file fields), `CONTENT_DECODE_FAILED` (`data` isn't valid base64) or `CONTENT_TOO_LARGE` (over 10 MB). The message names the field. In bulk calls, that item fails with the same message and the others carry on. To keep an existing file as it is during an update, leave its field out.

## Read file references

Query and get on v4 return a reference for CONTENT fields and an array of references for MULTI_CONTENT or MEDIA_IMG_GALLERY fields. The reference carries `unstructuredId`, `fieldName`, `fileName`, `fileExtension`, `fileSize`, `module`, `objectId` and `context`.

Use `fileExtension` exactly as returned.

## Download with the record id

Take `unstructuredId` and `module` from the reference. Use the record's `id` as `objectId`, even if the reference has `objectId: 0`.

```curl
curl --fail-with-body --silent --show-error \
  'https://services.beezr.io/generic/api/v4/records/content' \
  -H "X-API-Key: $BEEZR_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{
  "unstructuredId": "a1b2c3d4",
  "objectId": 482913,
  "unstructuredModel": {"module":"cm_equipment_requests_base"}
}' \
  --output contract.pdf
```

A successful call returns raw bytes, not a JSON envelope. Save the bytes to a file. A JSON error response must not be treated as a successful file download.

## Read download headers

| Header | Meaning |
|---|---|
| `Content-Type` | `application/pdf`, `image/png`, `image/jpeg`, otherwise `application/octet-stream` |
| `Content-Length` | Byte length |
| `Content-Disposition` | `attachment; filename="..."` |
| `X-Beezr-File-Name` | File name |
| `X-Beezr-File-Extension` | Extension |

Missing download fields return `MISSING_REQUIRED_FIELD`. If the file isn't attached to that record or bytes are unavailable, the response is `CONTENT_NOT_FOUND`. Files over 10 MB return `CONTENT_TOO_LARGE` on download.

See [Attach and download a PDF](/developers/api/guides-pdf/).

