Files API
Errors
Every error is a JSON object with a single error string:
{ "error": "<message>" }The messages are written to be shown to a person, so an integration can pass them straight through.
HTTP status codes
| Status | Meaning |
|---|---|
200 | Success (GET, DELETE, and POST /api/v1/files/upload-url) |
201 Created | The file was attached (POST /api/v1/files) |
400 Bad Request | A missing or invalid field, a file the record refuses, or a record in a state that does not allow the change. Examples below |
401 Unauthorized | Missing, malformed, expired, or revoked API key |
403 Forbidden | The key lacks the scope: read:files for GET, write:files for POST and DELETE |
404 Not Found | No record with that ID or externalId, no file with that ID, or nothing uploaded yet at the s3Key you sent |
413 Payload Too Large | The file is over the limit for the upload method or the record type |
429 Too Many Requests | Rate limit exceeded |
503 Service Unavailable | File storage isn't configured on the deployment |
Examples
Validation (400):
{ "error": "entity must be one of: CONTACT, LEAD, DEAL, COMPANY, QUOTE, CONTRACT, TASK, NOTE, CASE, CAMPAIGN, OFFERING." }{ "error": "Provide exactly one of contentBase64, url, or s3Key (or send multipart/form-data with a file field)." }{ "error": "Missing the file field. Send the file as form field \"file\"." }{ "error": "The file is empty." }{ "error": "File url must be https." }Record rules (400):
{ "error": "Offerings accept images, or documents as PDF, Excel, CSV or Word files." }{ "error": "Max 20 documents per offering. Remove one first." }{ "error": "Files can only be added to a campaign before it sends." }{ "error": "Invalid s3Key. Use the key returned by the upload-url endpoint for this record." }Not found (404): the message names the record type you asked for.
{ "error": "Deal not found." }{ "error": "No uploaded file was found at that s3Key. PUT the bytes to the uploadUrl first." }Too large (413):
{ "error": "That file is too large for a direct upload (10 MB). Use POST /api/v1/files/upload-url for files up to 50 MB." }{ "error": "Offering images are limited to 10 MB." }Limits
| Limit | Value |
|---|---|
| Multipart, base64 or URL upload | 10 MB |
| Two-step upload | 50 MB |
| Offering document | 25 MB, 20 per offering |
| Offering photo | 10 MB, 12 per offering |
| Upload URL lifetime | 5 minutes |
| Download URL lifetime | 5 minutes |
Each API key is limited to 120 requests per minute (platform-enforced). Exceeding it returns 429 with a Retry-After header giving the seconds until the window resets. The PUT to an upload URL goes straight to storage and does not count toward that limit.