Attachments
Photos and PDFs on a lead, stored and displayed exactly like a staff upload in the CRM.
POST Upload attachments
/v1/leads/{id}/attachmentsAttaches up to ten files to a lead in one multipart/form-data request. They are stored and
shown in the CRM exactly like a staff upload, in the photo view for images. Files cannot be sent
with the lead payload: create the lead first, then post the files to its id.
idstring · uuidRequiredThe lead's id from create or list.
Idempotency-Keystring · max 200Makes a retry safe: the same key on the same lead returns 200 with created: false and the
files from the first call, without storing anything. Send the retry exactly as before.
Recommended.
filesfile · 1 to 10RequiredRepeat the part for several files. JPEG, PNG, WebP, GIF, HEIC/HEIF and PDF, decided by the file's content, not its name. 25 MB each, 50 MB per request.
documentTypestring · id or nameFiles the whole batch under a document type from list categories; the category comes with the type. Images without one go to the organisation's Photos category, as the CRM does; anything else is left uncategorized.
commentstringApplies to every file in the batch.
curl https://api.evacrm.co.uk/v1/leads/1e4e3f90-4384-42ce-90c3-540db5343964/attachments \
-H "Authorization: Bearer sk_..." \
-H "Idempotency-Key: order-8812-photos" \
-F "files=@front.jpg" -F "files=@survey.pdf" -F "comment=Site survey" -F "documentType=Survey report"{
"created": true,
"lead": { "id": "1e4e3f90-4384-42ce-90c3-540db5343964", "code": "L013898" },
"data": [
{
"id": "9c1b6e4a-…",
"attachmentId": "5d0f2c77-…",
"name": "front.jpg",
"type": "image",
"mimeType": "image/jpeg",
"size": 2481733,
"photoNo": "001",
"comment": "Site survey",
"category": { "id": "6d2a…", "name": "Surveys" },
"documentType": { "id": "b41c…", "name": "Survey report" },
"source": "api",
"createdAt": "2026-09-02T11:14:03.512+01:00",
"urls": {
"download": "https://…",
"thumbnail": "https://…",
"medium": "https://…",
"large": "https://…"
},
"urlsExpireAt": "2026-09-02T12:14:03.512+01:00"
},
{
"id": "…", "name": "survey.pdf", "type": "document", "mimeType": "application/pdf",
"size": 88213, "photoNo": null, "urls": { "download": "https://…" }
}
]
}What is accepted
The type of each file is decided by its content, not its name or the Content-Type of the
part. Accepted: JPEG, PNG, WebP, GIF, HEIC/HEIF and PDF. SVG is not. A file that does not match
is a 422 naming it, and nothing from that request is stored. name comes back with the
extension the bytes warrant.
What happens to images
Images get the same thumbnail, medium and large versions the CRM makes for its own uploads, so
they appear in the CRM's photo view like any staff upload. photoNo is the CRM's per-lead
numbering (L013898-001.jpg), reserved in order within the request. HEIC is converted to JPEG on
arrival. Image metadata, including GPS position if present, is kept, as it is for staff uploads;
strip it before sending if you do not want it stored.
Links
urls are signed and expire at urlsExpireAt, an hour after the response. They are for
fetching now, not storing; GET the list again for fresh ones.
Filing
The CRM files documents in categories (folders, which can be nested) containing document
types. Send documentType as a type's id or name and the batch is filed under it; the
category comes with the type, since every type belongs to exactly one. Names match
case-insensitively; a name that exists under more than one category is a 422 asking for the id.
A type the CRM restricts to named staff is refused, because files under it would be hidden from
this API afterwards. Both come back as category and documentType on every file, null when
unset.
GET List categories
/v1/leads/attachments/categoriesThe document categories and types your organisation offers on a lead, archived ones excluded,
each type marked restricted when the CRM limits it to named staff. parent links a nested
category to the one it sits in. No parameters. Cached for five minutes.
curl https://api.evacrm.co.uk/v1/leads/attachments/categories \
-H "Authorization: Bearer sk_..."{
"object": "list",
"data": [
{
"id": "6d2a…",
"name": "Surveys",
"description": null,
"parent": null,
"types": [
{ "id": "b41c…", "name": "Survey report", "description": null, "restricted": false },
{ "id": "0f9e…", "name": "Structural calculations", "description": null, "restricted": true }
]
},
{ "id": "7c11…", "name": "Photos", "description": null, "parent": null, "types": [] }
]
}GET List attachments
/v1/leads/{id}/attachmentsEverything attached to the lead, whoever uploaded it, newest first, in the file shape above.
source says where a file came from: api, web (the CRM) or mobile. Files filed under a
document type the CRM restricts to named staff are omitted. Capped at 500, not paginated.
idstring · uuidRequiredThe lead's id.
curl https://api.evacrm.co.uk/v1/leads/1e4e3f90-4384-42ce-90c3-540db5343964/attachments \
-H "Authorization: Bearer sk_..."{
"object": "list",
"data": [
{
"id": "9c1b6e4a-2f7d-4c3e-8a1b-5d6e7f8a9b0c",
"attachmentId": "5d0f2c77-…",
"name": "front.jpg",
"type": "image",
"mimeType": "image/jpeg",
"size": 2481733,
"photoNo": "001",
"comment": "Site survey",
"category": {
"id": "6d2a…",
"name": "Surveys"
},
"documentType": {
"id": "b41c…",
"name": "Survey report"
},
"source": "api",
"createdAt": "2026-09-02T11:14:03.512+01:00",
"urls": {
"download": "https://…",
"thumbnail": "https://…",
"medium": "https://…",
"large": "https://…"
},
"urlsExpireAt": "2026-09-02T12:14:03.512+01:00"
},
{
"id": "…",
"attachmentId": "5d0f2c77-…",
"name": "survey.pdf",
"type": "document",
"mimeType": "application/pdf",
"size": 88213,
"photoNo": null,
"comment": "Site survey",
"category": {
"id": "6d2a…",
"name": "Surveys"
},
"documentType": {
"id": "b41c…",
"name": "Survey report"
},
"source": "api",
"createdAt": "2026-09-02T11:14:03.512+01:00",
"urls": {
"download": "https://…"
},
"urlsExpireAt": "2026-09-02T12:14:03.512+01:00"
}
]
}DEL Delete an attachment
/v1/leads/{id}/attachments/{fileId}Removes one file, its derivatives, and its entry in the CRM. Only files that came through this API can be deleted through it.
idstring · uuidRequiredThe lead's id.
fileIdstring · uuidRequiredThe file's id from the upload or list response.
curl -X DELETE https://api.evacrm.co.uk/v1/leads/1e4e3f90-4384-42ce-90c3-540db5343964/attachments/9c1b6e4a-2f7d-4c3e-8a1b-5d6e7f8a9b0c \
-H "Authorization: Bearer sk_..."{
"deleted": true,
"id": "9c1b6e4a-2f7d-4c3e-8a1b-5d6e7f8a9b0c"
}