Skip to content
View as Markdown

Upload a file ​

POST /v1/leads/{lead_id}/files

Adds one file to a file or image custom field of the lead's pipeline card.

Scope: leads:write

Access: The key's member must also be allowed to see files.

The body is multipart/form-data with exactly one part: the file, in a part named file, sent as a file (with a filename). Let your HTTP client set the Content-Type and its boundary.

The type is recognized from the file's content (its magic bytes): PDF, JPEG, PNG, WebP, HEIC or HEIF. The part's Content-Type and the file name's extension are ignored, so a renamed file of another type is rejected with 415. Image fields take images only, unless your team set the field to also accept files. The stored name is the part's filename without any directory or control characters, shortened to 200 characters (keeping its extension); without a usable name the file is called upload.<ext>, for example upload.pdf.

The file goes to the lead's main card in its campaign (never a linked card on another team's pipeline). A follow-through card shares its main card's files, as in DialEcho, so a member who sees the lead only through a follow-through card uploads to those same files. A field can hold several files and an upload never replaces one: to replace a file, upload the new one, then delete the old one. The file records the API key (by its prefix) as its uploader.

Retries are safe with the same Idempotency-Key: the same file (same lead, field, file name and content) answers 201 with the same file_id and stores nothing new. Using the key for anything else is 409 idempotency_conflict. Create a new key for every new upload.

Headers ​

NameTypeRequiredDescription
Idempotency-KeystringYesOne key per upload, reused on its retries. 16 to 128 printable ASCII characters, no spaces (a UUID works).

Path parameters ​

NameTypeRequiredDescription
lead_idUUIDYesThe lead.

Query parameters ​

NameTypeRequiredDescription
fieldstringYesSlug of a file or image custom field of the lead's campaign. Any other slug (unknown, deleted, another type or another campaign's field) is 422 unknown_field.

Body ​

Content type: multipart/form-data

NameTypeRequiredDescription
filefileYesThe document or photo, sent as a file part with a filename. Empty files are rejected. Up to 10 MB (10,485,760 bytes). PDF, JPEG, PNG, WebP, HEIC or HEIF.

Response ​

Status: 201 Created

NameTypeDescription
file_idUUIDThe stored file. Keep it to delete the file later.
lead_idUUIDThe lead.
fieldstringThe custom field slug.
filenamestringThe name the file was stored under.
content_typestringThe type DialEcho recognized, for example application/pdf.
size_bytesintegerSize of the stored file.

Example request ​

curl

bash
curl -X POST "https://development.agencydevworks.ai/v1/leads/aaaaaaaa-0000-4000-8000-000000000001/files?field=utility_bill" \
  -H "Authorization: Bearer dei_your_key" \
  -H "Idempotency-Key: 0f0f0f0f-0000-4000-8000-00000000abcd" \
  -F "file=@utility-bill.pdf"

JavaScript

js
import { openAsBlob } from "node:fs";

const form = new FormData();
form.append("file", await openAsBlob("utility-bill.pdf"), "utility-bill.pdf");

const response = await fetch("https://development.agencydevworks.ai/v1/leads/aaaaaaaa-0000-4000-8000-000000000001/files?field=utility_bill", {
  method: "POST",
  headers: {
    "Authorization": "Bearer dei_your_key",
    "Idempotency-Key": "0f0f0f0f-0000-4000-8000-00000000abcd",
  },
  body: form,
});
const data = await response.json();

Example response ​

Status: 201 Created

json
{
  "file_id": "55555555-0000-4000-8000-000000000001",
  "lead_id": "aaaaaaaa-0000-4000-8000-000000000001",
  "field": "utility_bill",
  "filename": "utility-bill.pdf",
  "content_type": "application/pdf",
  "size_bytes": 482133
}

Errors ​

HTTPCodeWhen
403insufficient_scopeThe key does not have leads:write.
403permission_deniedThe key's member may not see files. Only for a lead they can see; any other lead is 404.
404not_foundThe lead does not exist or the key cannot reach it.
409no_pipeline_cardThe lead has no pipeline card. Nothing was stored.
409idempotency_conflictThe Idempotency-Key was already used for a different upload. Nothing was stored.
413file_too_largeThe file is larger than 10 MB. Nothing was stored.
415unsupported_media_typeThe content is not a PDF, JPEG, PNG, WebP, HEIC or HEIF file, or is a PDF sent to an image-only field. Nothing was stored.
422unknown_fieldfield is not a file or image custom field of the lead's campaign.
422invalid_requestlead_id is not a UUID, field or Idempotency-Key is missing or malformed, or the file is empty or the body is not exactly one file part named file (these two carry an empty error.fields).
503dependency_unavailableThe file could not be stored right now. Retry with the same Idempotency-Key.

Every endpoint can also answer 401 invalid_api_key, 429 rate_limited and 503 dependency_unavailable. See Errors in the overview.