For the complete documentation index, see llms.txt. This page is also available as Markdown.

Files

Upload and manage files and attachments. Files are uploaded with multipart/form-data via POST /api/files/upload and can be linked to companies, contacts, deals, and notes.

List files

get

Returns file records the user has access to. Filter by workspace using the where parameter: {"workspaceId": "<WORKSPACE_UUID>"}.

Files can also be filtered by companyId, contactId, dealId, or noteId to retrieve files attached to a specific record.

Note: Files are created by uploading via POST /api/files/upload (multipart/form-data), not by a JSON POST /api/files.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Query parameters
fieldsstringOptional

Comma-separated list of fields to return. Defaults to all fields.

Example: id,name,domain
wherestringOptional

JSON-encoded filter object. All top-level conditions are combined with AND logic. Use $or for OR logic.

The available operators depend on the data type of the field you are filtering on.


String fields

Fields like name, domain, description, linkedin, source, externalId, location.

OperatorDescriptionExample
(exact)Exact match{"name": "Linear"}
$eqExplicit exact match{"name": {"$eq": "Linear"}}
$notNot equal{"source": {"$not": "import"}}
$inMatches any value in array{"domain": {"$in": ["linear.app", "granola.so"]}}
$notInMatches none of the values{"source": {"$notIn": ["import", "api"]}}
$containsCase-insensitive word-boundary substring match{"name": {"$contains": "YC"}}
$notContainsDoes not contain{"name": {"$notContains": "Test"}}
$containsAnyContains any of the given strings{"name": {"$containsAny": ["YC", "Techstars"]}}
$startsWithStarts with prefix{"domain": {"$startsWith": "app."}}
$endsWithEnds with suffix{"email": {"$endsWith": "@zero.inc"}}
$existsField is present and truthy{"linkedin": {"$exists": true}}
$notExistsField is absent, null, or empty{"linkedin": {"$notExists": true}}

Number fields

Fields like value, confidence.

OperatorDescriptionExample
(exact)Exact match{"value": 5000}
$eqExplicit exact match{"value": {"$eq": 5000}}
$notNot equal{"value": {"$not": 0}}
$gtGreater than{"value": {"$gt": 10000}}
$gteGreater than or equal{"value": {"$gte": 5000}}
$ltLess than{"value": {"$lt": 10000}}
$lteLess than or equal{"value": {"$lte": 50000}}
$inMatches any value in array{"confidence": {"$in": [0.25, 0.5, 0.75]}}
$notInMatches none of the values{"confidence": {"$notIn": [0, 1]}}
$existsField is present and truthy{"value": {"$exists": true}}
$notExistsField is absent, null, or zero{"value": {"$notExists": true}}

Multiple operators can be combined on one field:

{"value": {"$gte": 5000, "$lt": 10000}}

Date fields

Fields like closeDate, startDate, endDate, createdAt, updatedAt.

Values can be ISO 8601 strings ("2026-01-01", "2026-01-01T00:00:00Z") or relative time macros.

Relative time macros: +Nd / -Nd (days), +Nw / -Nw (weeks), +Nm / -Nm (months), +Ny / -Ny (years), +Nh / -Nh (hours), +Ns / -Ns (seconds), now().

OperatorDescriptionExample
$gteOn or after{"closeDate": {"$gte": "2026-01-01"}}
$lteOn or before{"closeDate": {"$lte": "2026-03-31"}}
$gtAfter{"createdAt": {"$gt": "2026-01-01T00:00:00Z"}}
$ltBefore{"createdAt": {"$lt": "now()"}}
$dateExact date match (compares date portion only){"closeDate": {"$date": "2026-01-15"}}
$existsField is present and truthy{"closeDate": {"$exists": true}}
$notExistsField is absent or null{"closeDate": {"$notExists": true}}

Date range example:

{"closeDate": {"$gte": "2026-01-01", "$lte": "2026-03-31"}}

Relative date example (closing in next 30 days):

{"closeDate": {"$gte": "now()", "$lte": "+30d"}}

Array fields

Fields like listIds, ownerIds, contactIds.

OperatorDescriptionExample
$includesArray contains the given value (use this — bare exact match is not supported){"listIds": {"$includes": "<LIST_UUID>"}}
$notIncludesArray does not contain the given value{"ownerIds": {"$notIncludes": "<USER_UUID>"}}
$overlapsArray contains at least one of the given values{"ownerIds": {"$overlaps": ["<UUID_1>", "<UUID_2>"]}}
$notOverlapsArray contains none of the given values{"listIds": {"$notOverlaps": ["<UUID_1>", "<UUID_2>"]}}
$allArray contains all of the given values{"listIds": {"$all": ["<UUID_1>", "<UUID_2>"]}}
$lengthFilter by array length (supports nested operators){"contactIds": {"$length": {"$gte": 2}}}
$existsField is present and non-empty{"ownerIds": {"$exists": true}}
$notExistsField is absent or empty{"ownerIds": {"$notExists": true}}

UUID / ID fields

Fields like id, workspaceId, companyId, stage.

OperatorDescriptionExample
(exact)Exact match{"stage": "<PIPELINE_STAGE_UUID>"}
$inMatches any value in array{"stage": {"$in": ["<UUID_1>", "<UUID_2>"]}}
$notInMatches none of the values{"stage": {"$notIn": ["<UUID_1>"]}}
$notNot equal{"stage": {"$not": "<UUID>"}}

Boolean fields

Fields like archived.

OperatorDescriptionExample
(exact)Exact match{"archived": false}
$notNot equal{"archived": {"$not": true}}

Logical operators

These work across all data types.

$or — matches if any sub-condition is true:

{
  "workspaceId": "<WORKSPACE_UUID>",
  "$or": [
    {"ownerIds": {"$overlaps": ["<USER_UUID_1>", "<USER_UUID_2>"]}},
    {"closeDate": {"$gte": "2026-01-01"}}
  ]
}

$and — matches if all sub-conditions are true (useful when you need multiple conditions on the same field):

{
  "$and": [
    {"name": {"$contains": "Enterprise"}},
    {"name": {"$notContains": "Test"}}
  ]
}

Dot-notation (relation filtering)

Use dot-syntax to filter records based on properties of related objects:

{"company.name": "Linear"}
{"company.domain": {"$in": ["linear.app", "granola.so"]}}
{"company.location.city": "San Francisco"}
{"companyProfile.categories": {"$overlaps": ["Sales", "Marketing"]}}

All operators available for the target field's data type can be used with dot-notation.


Custom property filtering

Custom properties are stored in the custom object on records, keyed by UUID. Use GET /api/columns to discover the available custom property IDs, types, and options for a workspace.

Filter on custom properties using custom.<COLUMN_ID> with operators appropriate for the column's type.

Note: For select and multiselect columns, option values are UUIDs (the key field from the column's options array). Use the UUID, not the human-readable name.

// Text custom property
{"custom.54e1ca7d-69c3-4b77-8266-8085b5834116": {"$contains": "enterprise"}}

// Select custom property (use the option key UUID)
{"custom.a1b2c3d4-e5f6-7890-abcd-ef1234567890": "3e839b5c-b311-4887-b2da-727d2d75cdd6"}

// Multi-select custom property (use option key UUIDs)
{"custom.b2c3d4e5-f6a7-8901-bcde-f12345678901": {"$overlaps": ["a1b1c1d1-e1f1-1111-aaaa-111111111111", "b2b2c2d2-e2f2-2222-bbbb-222222222222"]}}

// Currency/number custom property
{"custom.c3d4e5f6-a7b8-9012-cdef-123456789012": {"$gte": 100000}}

// Date custom property
{"custom.d4e5f6a7-b8c9-0123-defa-234567890123": {"$gte": "2026-01-01"}}

// Boolean custom property
{"custom.e5f6a7b8-c9d0-1234-efab-345678901234": true}

// Check if custom property has a value
{"custom.f6a7b8c9-d0e1-2345-fabc-456789012345": {"$exists": true}}

Complex example

All top-level keys are ANDed together:

{
  "name": {"$contains": "Zero"},
  "location.city": "Helsinki",
  "location.country": {"$in": ["United Kingdom", "Germany", "Sweden"]},
  "value": {"$gte": 10000},
  "closeDate": {"$gte": "2026-01-01", "$lte": "2026-03-31"},
  "ownerIds": {"$includes": "<USER_UUID>"},
  "stage": {"$in": ["<UUID_1>", "<UUID_2>"]},
  "lastActivity": {"$exists": true},
  "companyProfile.categories": {"$overlaps": ["Sales", "Marketing"]},
  "custom.54e1ca7d-69c3-4b77-8266-8085b5834116": {"$contains": "enterprise"}
}
Example: {"stage":"<PIPELINE_STAGE_UUID>"}
limitintegerOptional

Maximum number of records to return

Default: 100
offsetintegerOptional

Pagination offset

Default: 0
orderBystringOptional

JSON string for sort order

Example: {"name":"asc"}
Responses
200

Successful response

application/json
totalintegerOptional
get/api/files

Upload a file

post

Upload a file or image using multipart/form-data. Unlike the JSON CRUD endpoints, this endpoint does not accept a JSON body — send the binary in a file form part alongside text form fields.

The maximum file size is 32 MB; larger uploads are rejected with HTTP 413.

Upload types

The type form field selects how the file is stored and what is returned:

  • file — A general document or attachment (PDF, image, video, etc.). The binary is stored in cloud storage and thumbnails/previews are generated for supported content types. Requires workspaceId. Can be linked to a record via companyId, contactId, dealId, or noteId. Returns the full file record (see the File schema).

  • image — An image asset, typically for logos, avatars, or inline attachments. Requires folder. Returns a lightweight object with the hosted image URL.

Thumbnails & previews

For type=file, thumbnailUrl and previewUrl are generated automatically for these content types: image/jpeg, image/png, image/gif, image/webp, application/pdf, video/mp4, video/mpeg, video/ogg, video/webm, video/quicktime. For other types they are null.

Downloading

For type=file, the stored url points to authenticated storage and is not directly accessible. Use GET /api/files/download?fileId=<FILE_ID> to obtain a short-lived signed URL, and GET /api/files/pages?fileId=<FILE_ID> to list per-page preview images for multi-page documents.

Example (curl)

curl -X POST https://api.zero.inc/api/files/upload \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "type=file" \
  -F "workspaceId=<WORKSPACE_UUID>" \
  -F "companyId=<COMPANY_UUID>" \
  -F "file=@/path/to/proposal.pdf"
Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Body
filestring · binaryRequired

The binary file contents. Maximum 32 MB.

typestring · enumRequired

file stores a general document/attachment; image stores an image asset (logos, avatars, inline attachments).

Possible values:
workspaceIdstring · uuidOptional

Required when type=file. Optional when type=image.

folderstring · enumOptional

Required when type=image. Storage folder for the image.

Possible values:
transformationstringOptional

type=image only. When set to any non-empty value, the image is scaled down to a maximum of 128×128 px WebP (aspect ratio preserved; used for avatars and logos).

companyIdstring · uuidOptional

type=file only. Link the file to a company.

contactIdstring · uuidOptional

type=file only. Link the file to a contact.

dealIdstring · uuidOptional

type=file only. Link the file to a deal.

noteIdstring · uuidOptional

type=file only. Link the file to a note.

placementstringOptional

type=file only. Optional placement/context label for the file.

descriptionstringOptional

type=file only. Optional human-readable description.

externalIdstringOptional

Optional ID from an external system for integrations.

Responses
200

File uploaded successfully.

For type=file, data is the full file record. For type=image, data is a lightweight object with the hosted image URL.

application/json
dataone ofOptional
or
post/api/files/upload

Get a file download URL

get

Returns a short-lived signed URL for downloading a type=file upload from storage. The URL expires 15 minutes after it is issued.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Query parameters
fileIdstring · uuidRequired
Responses
200

Signed download URL

application/json
urlstring · uriOptional

Signed, time-limited download URL (valid for 15 minutes).

get/api/files/download

Get file page previews

get

Returns per-page thumbnail and preview image URLs for a file, useful for multi-page documents such as PDFs.

If the file's content type does not support previews, data is false.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Query parameters
fileIdstring · uuidRequired
Responses
200

Page previews. data is false when the file type does not support previews.

application/json
dataone ofOptional
booleanOptionalExample: false
or
get/api/files/pages

Get a file

get

Returns a single file record by ID.

If the file does not exist, the API returns HTTP 200 with an empty body ({}).

To obtain a downloadable URL for the file contents, use GET /api/files/download?fileId=<FILE_ID>.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Path parameters
fileIdstring · uuidRequired
Responses
200

Successful response

application/json
get/api/files/{fileId}

Delete a file

delete

Delete a file. Use archive=true for soft delete (recoverable), or omit for permanent deletion.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Path parameters
fileIdstring · uuidRequired
Query parameters
archivebooleanOptional

If true, soft deletes (archives) the file instead of permanently deleting it.

Default: false
Responses
200

File deleted successfully

application/json
dataone ofOptional

Hard delete (archive omitted or false): returns 1 on success. Soft delete (archive=true): returns a single-element array containing the archived file object.

integerOptionalExample: 1
or
delete/api/files/{fileId}

Update file metadata

patch

Update metadata on an existing file (e.g. name, description, or the record it is linked to). The file's binary contents cannot be changed — re-upload via POST /api/files/upload to replace contents.

Note: The response only returns the fields that were changed — not the full file object.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Path parameters
fileIdstring · uuidRequired
Body

Editable file metadata. The file's binary contents cannot be changed via PATCH — re-upload to replace them.

namestringOptional
descriptionstringOptional
placementstringOptional
companyIdstring · uuidOptional
contactIdstring · uuidOptional
dealIdstring · uuidOptional
noteIdstring · uuidOptional
externalIdstringOptional
Responses
200

File updated successfully. Only the fields that were changed are returned in data.

application/json
dataobjectOptional

Partial file object containing only the updated fields plus updatedAt and updatedById.

patch/api/files/{fileId}

Last updated