Files and uploads
Files and uploads in the BlueSuite REST API
Attach files to contacts, requests, quotes, jobs, invoices, events, or timesheets. Workspace-level uploads are reserved for line-item images.
Permissions and visibility
Every upload operation requires files:read or files:write, plus the corresponding parent read/write scope. For example, attaching a job receipt needs files:write and jobs:write. Workspace line-item images require only the files scope, and module_id must equal the authenticated workspace ID.
module_type: "workspace" requires category: "line_item", and that category requires workspace ownership. Other categories include attachment, internal, public, and expense. Choose is_public deliberately; its default is false.
Upload using multipart form data. The binary file is separate from the fields in the table. Metadata updates use PATCH, and require at least one editable field. This API does not move a file to another parent or replace its binary content.
Example: attach a receipt
curl 'https://my.bluesuite.app/api/v1/uploads' \
-H "Authorization: Bearer $BLUESUITE_API_KEY" \
-F 'file=@receipt.pdf' \
-F 'module_type=job' -F 'module_id=42' -F 'category=expense'For AI-host attachments and file URLs, see the MCP upload tool.
Current listing limit
The list response includes pagination metadata, but the current query validator accepts only module_type, module_id, and category. Supplying page or per_page is rejected before pagination is applied, so this route currently exposes the first 25 results only. This also affects MCP list_files calls that supply pagination arguments.
GET /api/v1/uploads
GET /api/v1/uploadsRequired scopes: Determined by the parent entity; see the permissions above..
Query parameters
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
module_type | "contact", "request", "quote", "job", "invoice", "event", "timesheet", "workspace" | Yes | Parent entity type. |
module_id | integer | Yes | Parent entity ID. |
category | "attachment", "internal", "public", "expense", "line_item" | No |
Response
200 with { "success": true, "data": [...], "pagination": { "page": 1, "per_page": 25, "total_pages": 1 } }.
See response conventions and errors.
POST /api/v1/uploads
POST /api/v1/uploadsRequired scopes: Determined by the parent entity; see the permissions above..
Multipart form fields
Send multipart/form-data with a binary file part and the fields below. Let your HTTP client set the boundary.
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
module_type | "contact", "request", "quote", "job", "invoice", "event", "timesheet", "workspace" | Yes | |
module_id | integer | Yes | |
category | "attachment", "internal", "public", "expense", "line_item" | No | Default: "attachment". |
name | string | No | maxLength: 255. |
description | string | No | Default: "". maxLength: 2000. |
is_public | boolean or "true", "false" | No | Default: false. |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
201 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
GET /api/v1/uploads/:id
GET /api/v1/uploads/:idRequired scopes: Determined by the parent entity; see the permissions above..
Path parameters: id. Use positive integer record IDs from this workspace.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
PATCH /api/v1/uploads/:id
PATCH /api/v1/uploads/:idRequired scopes: Determined by the parent entity; see the permissions above..
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
name | string | No | minLength: 1. maxLength: 255. |
description | string or null | No | |
category | "attachment", "internal", "public", "expense", "line_item" | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
DELETE /api/v1/uploads/:id
DELETE /api/v1/uploads/:idRequired scopes: Determined by the parent entity; see the permissions above..
Path parameters: id. Use positive integer record IDs from this workspace.
No request body.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.