Menu

API reference · CRM

Files

crm · files · 4 operations

DELETE/v1/crm/files/{file_id}

Delete a file attached to a record

crm.files.delete

IrreversibleIdempotentSince 2026-11-01

Deletes a file attached to a deal, person, company or prospect (its Files tab): the stored file and its entry. Pass the record the file belongs to (entity_type and entity_id, the same as in crm.files.list) and the file_id. The stored file is removed only when its key is in this record's own folder of CRM files (organizations/{org_id}/crm/files/{entity_type}/{entity_id}/, where MB Suite uploads them); an entry whose stored key points anywhere else is removed and the object it points to is left untouched. It does NOT go to the trash and cannot be restored. Its size goes back to the storage quota: right away for a file stored more than a day ago, and with the next storage recount (within 6 hours) for a newer one. The timeline entry of the upload stays, marked as deleted (who and when). Deleting a file that no longer exists succeeds without changes. To attach a file use crm.files.create. Requires the edit permission of that record type (edit_deal, edit_person, edit_company or edit_prospect; a seller only on their own or unassigned records). Outside the screen it requires a confirmation (dry run and confirm_token) and a key allowed to delete.

Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.

Scope
crm:write and “Allow deletions” (crm:delete in OAuth)
Permission
Edit in the module
MCP tool
crm_files_deleteOn the full surface; on the compact one, mb_execute_operation with id: "crm.files.delete".

Declared cost: up to 7 reads and 7 writes per call (they count against the daily quota).

Parameters

file_idstringpathrequired

The file: an id of crm.files.list for that record.

entity_typeenumbodyrequired

The kind of record the file belongs to: deal, person, company or prospect (the one passed to crm.files.list).

Values: deal, person, company, prospect

entity_idstringbodyrequired

The id of the record the file belongs to (the one passed to crm.files.list).

Response

oktrue

Errors

Example

curl -X DELETE "https://api.mb-suite.com/v1/crm/files/{file_id}" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "entity_type": "deal",
  "entity_id": "ENTITY_ID",
  "dry_run": true
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X DELETE "https://api.mb-suite.com/v1/crm/files/{file_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "entity_type": "deal",
  "entity_id": "ENTITY_ID",
  "dry_run": true
}'
GET/v1/crm/files

List the files attached to a record

crm.files.list

ReadIdempotentSince 2026-11-01

Lists the files attached to a deal, person, company or prospect (its Files tab), newest first, paginated by cursor (limit up to 200). Each file brings file_name, mime_type, size in bytes, who uploaded it and when, storage_path and download_url: a signed link to download it without a session that expires in an hour (download_url_expires_at); it is null when the stored key is not in this record's own folder of CRM files (organizations/{org_id}/crm/files/{entity_type}/{entity_id}/). Not found (entity_not_found) if the record does not exist or is out of the caller's scope (a seller with a restricted scope sees the files of their own or unassigned records, and of the people and companies of their deals). Needs view access to the CRM.

Scope
crm:read
Permission
View the module
MCP tool
crm_files_listOn the full surface; on the compact one, mb_execute_operation with id: "crm.files.list".

Declared cost: up to 203 reads and 0 writes per call (they count against the daily quota).

Parameters

entity_typeenumqueryrequired

The kind of record the files belong to: deal, person, company or prospect.

Values: deal, person, company, prospect

entity_idstringqueryrequired

The record's id (crm.deals.list, crm.persons.list, crm.companies.list or crm.prospects.list).

limitintegerqueryoptional

How many items this page brings at most (see the maximum and the default in the schema).

Default: 50

cursorstringqueryoptional

The next_cursor of the previous page, exactly as it came (only for the same list and filters); without it, the first page.

Response

dataarray<object>
has_moreboolean
next_cursorstring

Errors

Example

curl "https://api.mb-suite.com/v1/crm/files?entity_type=deal&entity_id=ENTITY_ID" \
  -H "Authorization: Bearer $MB_API_KEY"

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl "https://api.mb-suite.com/v1/crm/files?entity_type=deal&entity_id=ENTITY_ID" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/crm/files

Attach a file to a record

crm.files.create

WriteIdempotentSince 2026-11-01

Attaches a file to a deal, person, company or prospect (its Files tab) and leaves a file entry in the record's timeline, like uploading it from the app. Two ways: send the file itself as content_base64 with content_type (up to 768000 bytes = 750 KB decoded, because the request body is capped at 1 MB), or upload it first with crm.files.uploads.create (up to 50 MB), PUT the bytes and pass the storage_path it returned. file_name is the name shown in the app. Accepted types: images (JPEG, PNG, WebP, GIF), videos (MP4, MOV, WebM), PDF, Word, Excel, PowerPoint, CSV, plain text, Markdown, ZIP and audio (MP3, M4A, OGG, WAV). Idempotent: the same storage_path, or the same content with the same name on the same record, returns the file already there with created: false. Returns file_id, the file (with a download_url signed for one hour) and activity_id. Inline bytes count toward the organization's storage quota (a storage_path already counted when its upload URL was issued). Errors: entity_not_found, invalid_input (also an entity_id that is a reserved storage folder name: thumbnails, booking_avatar, and a content_type outside the accepted ones, with the list), storage_path_invalid (a key that is not from crm.files.uploads.create for this record), storage_object_not_found (nothing was PUT to it), unsupported_media_type (the file PUT to storage_path is of a type the Files tab does not take), file_too_large, limit_reached (details.resource storage: the storage is full), crm_action_denied (the edit permission of that record type: edit_deal, edit_person, edit_company or edit_prospect; a seller only on their own or unassigned records). Does not send the file to anyone: to send it by WhatsApp use crm.whatsapp.uploads.create and crm.whatsapp.send_media.

Instructions for agents

Tell the person the file was attached to the record (or that it was already there, when created is false), with its name.

Scope
crm:write
Permission
Edit in the module
MCP tool
crm_files_createOn the full surface; on the compact one, mb_execute_operation with id: "crm.files.create".

Declared cost: up to 170 reads and 3 writes per call (they count against the daily quota).

Parameters

entity_typeenumbodyrequired

The kind of record the files belong to: deal, person, company or prospect.

Values: deal, person, company, prospect

entity_idstringbodyrequired

The record's id (crm.deals.list, crm.persons.list, crm.companies.list or crm.prospects.list).

file_namestringbodyrequired

The name the Files tab and the timeline show.

storage_pathstringbodyoptional

The storage_path crm.files.uploads.create returned, once its PUT finished. Exactly one of storage_path and content_base64.

content_base64stringbodyoptional

The file itself, standard base64, up to 750 KB decoded. Exactly one of storage_path and content_base64.

content_typeenumbodyoptional

Its type, one of the accepted ones (another is invalid_input on content_type). Required with content_base64; with storage_path, if sent, it must be the uploaded file's.

Values: image/jpeg, image/png, image/webp, image/gif, video/mp4, video/quicktime, video/webm, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/plain, text/markdown, text/csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/zip, application/x-zip-compressed, audio/mpeg, audio/mp4, audio/ogg, audio/wav

sizeintegerbodyoptional

Optional: if sent, it must be the real size in bytes.

Response

file_idstring
createdboolean
fileobject
activity_idstring | null

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/files" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "entity_type": "deal",
  "entity_id": "ENTITY_ID",
  "file_name": "FILE_NAME"
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/crm/files" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "entity_type": "deal",
  "entity_id": "ENTITY_ID",
  "file_name": "FILE_NAME"
}'
POST/v1/crm/files/uploads

Get a signed URL to upload a file for a record

crm.files.uploads.create

WriteSince 2026-11-01

First step to attach a file of up to 50 MB to a deal, person, company or prospect through the API (a file of up to 750 KB can go in one call: crm.files.create with content_base64). Send entity_type, entity_id, file_name, content_type and the exact size in bytes; it checks the record, its edit permission and the storage quota, and returns upload_url, the headers to send, storage_path and expires_at (10 minutes to start the upload). Then PUT the raw bytes to upload_url from a server with exactly those headers and exactly size bytes (the URL is bound to that size and content type: anything else is rejected), and call crm.files.create with that storage_path and file_name: until then the file is not in the record. The size counts toward the storage quota when the URL is issued. Each call issues a new URL (not idempotent). Errors: entity_not_found, invalid_input (also an entity_id that is a reserved storage folder name: thumbnails, booking_avatar), filename_invalid, limit_reached (details.resource storage: the storage is full), crm_action_denied (the record's edit permission, as in crm.files.create). Needs full access to the CRM.

Instructions for agents

If the upload URL expired before the PUT, ask for a new one; do not register a storage_path that was never uploaded.

Scope
crm:write
Permission
Edit in the module
MCP tool
crm_files_uploads_createOn the full surface; on the compact one, mb_execute_operation with id: "crm.files.uploads.create".

Declared cost: up to 151 reads and 1 writes per call (they count against the daily quota).

Parameters

entity_typeenumbodyrequired

The kind of record the files belong to: deal, person, company or prospect.

Values: deal, person, company, prospect

entity_idstringbodyrequired

The record's id (crm.deals.list, crm.persons.list, crm.companies.list or crm.prospects.list).

file_namestringbodyrequired

The file's name (it goes, cleaned, into the storage key).

content_typeenumbodyrequired

The file's type: the PUT must send exactly this Content-Type.

Values: image/jpeg, image/png, image/webp, image/gif, video/mp4, video/quicktime, video/webm, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/plain, text/markdown, text/csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/zip, application/x-zip-compressed, audio/mpeg, audio/mp4, audio/ogg, audio/wav

sizeintegerbodyrequired

The exact size in bytes of the file to upload: the URL accepts only that size.

Response

upload_urlstring
method"PUT"
headersobject
storage_pathstring
expires_atnumber
max_sizenumber

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/files/uploads" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "entity_type": "deal",
  "entity_id": "ENTITY_ID",
  "file_name": "FILE_NAME",
  "content_type": "image/jpeg",
  "size": 1
}'

Try it with your test API key

With a test API key the request always goes to your practice organization: example data you can reset.

curl -X POST "https://api.mb-suite.com/v1/crm/files/uploads" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "entity_type": "deal",
  "entity_id": "ENTITY_ID",
  "file_name": "FILE_NAME",
  "content_type": "image/jpeg",
  "size": 1
}'