File search

Search files in your project with POST /files/search/. A single request can combine full-text search, exact matching, range filters, and tag filters. This page explains the query syntax, how conditions combine, and shows worked request/response examples.

File search requires API version 0.7. Send the Accept: application/vnd.uploadcare-v0.7+json header with every request.

Newly uploaded and recently changed files are indexed asynchronously and may not appear in (or disappear from) search results immediately. Expect a short delay, usually a few seconds.

Quick start

$curl -L -X POST 'https://api.uploadcare.com/files/search/' \
> -H "Accept: application/vnd.uploadcare-v0.7+json" \
> -H "Content-Type: application/json" \
> -H "Authorization: Uploadcare.Simple $YOUR_PUBLIC_KEY:$YOUR_SECRET_KEY" \
> -d '{"query": "vacation"}'

At least one search condition is required. With no conditions, the request returns 400.

Search conditions

A request body is a JSON object. Each of the following keys is optional, but at least one must be present.

KeyTypePurpose
querystringQuick full-text search across filename, metadata, and MIME type at once (plus a UUID match). Minimum 4 characters.
phraseobjectFull-text search scoped to specific fields.
exactobjectExact value matching per field.
datetime_uploadedobjectRange filter on upload date (ISO 8601).
sizeobjectRange filter on file size in bytes.
is_imagebooleantrue returns images only; false excludes images.
tagsobjectFilter by file tags with any / all / none.

Plus these modifiers:

KeyTypePurpose
fuzzinessbooleanTypo-tolerant matching for query and phrase. Default false.
sortarray1–4 sort keys; prefix with - for descending.

Pagination and appdata are controlled with query parameters — see Pagination and Including appdata.

How conditions combine

Understanding the boolean model is the key to building complex queries.

  • Different top-level conditions are combined with AND. A request with phrase, size, and is_image returns files that match all three.
  • There is no top-level OR and no general NOT. You cannot ask for “filename contains photo OR is an image”. The only ways to express OR and NOT are the narrow cases listed below.
WhereLogic
Multiple top-level keys (phrase + size + …)AND
Multiple fields inside phraseAND
Multiple values in an exact field, e.g. "original_filename": ["a.jpg", "b.png"]OR (matches any)
Multiple keys inside exactAND
query across its fieldsOR (matches any field)
tags.anyOR (at least one)
tags.allAND (every tag)
tags.noneNOT (exclude)
gte + lt inside datetime_uploaded / sizeAND (a range)

Full-text search: query and phrase

query and phrase run full-text search. query searches all full-text fields (original_filename, metadata, detected_mime_type) at once, while phrase targets specific fields:

1{
2 "phrase": {
3 "original_filename": "report",
4 "detected_mime_type": "pdf"
5 }
6}

Both are substring-aware: a term matches anywhere inside a word, not only at the start. Searching photo finds photo.jpg, photographer.png, and holiday-photo.jpg. Filenames are also split on separators such as -, _, and case boundaries before matching.

A few rules follow from this:

  • Minimum 4 characters for every query and phrase value. Shorter terms cannot match — use exact for short or precise values.
  • Very long terms (over ~15 characters) may not match via full-text; prefer exact for full filenames or full MIME types.
  • phrase.metadata searches across all metadata keys and values at once. To match a specific metadata key, use exact with metadata[key].

query also matches against the file UUID with a relevance boost: if you paste a UUID into query, that exact file is returned at the top of the results while the rest of the term is still matched as full text.

Typo tolerance with fuzziness

Set fuzziness: true to tolerate small spelling differences in query and phrase (it does not affect exact). The allowed edit distance scales with term length (roughly 1 edit for 3–5 characters, 2 for longer).

1{ "query": "barbarain", "fuzziness": true }

Fuzzy matching significantly increases query latency. Enable it only when you need it.

Exact matching

exact matches stored values exactly. Each field takes a non-empty array; multiple values in one field are OR-ed:

1{
2 "exact": {
3 "original_filename": ["logo.png", "icon.png"],
4 "detected_mime_type": ["image/png"],
5 "uuid": ["21975c81-7f57-4c7a-aef9-acfe28779f78"]
6 }
7}

To match an arbitrary metadata field, use metadata[key] syntax:

1{
2 "exact": {
3 "metadata[camera]": ["Canon"],
4 "metadata[order_id]": ["12345", "12346"]
5 }
6}

A field cannot appear in both phrase and exact in the same request.

Range filters: datetime_uploaded and size

Both accept the operators gt, gte, lt, and lte. At least one operator is required; combine two to form a range.

1{
2 "datetime_uploaded": { "gte": "2024-01-01T00:00:00Z", "lt": "2025-01-01T00:00:00Z" },
3 "size": { "gte": 1024, "lte": 10485760 }
4}

datetime_uploaded values are ISO 8601 timestamps; size is in bytes.

Filter by tags

Use tags to filter by file tags. All three keys are optional, but at least one must be non-empty. Tag values are normalized (lowercased, whitespace-stripped) before matching.

1{
2 "tags": {
3 "any": ["cat", "dog"],
4 "all": ["outdoor"],
5 "none": ["archived"]
6 }
7}
KeySemantics
anyFile must have at least one of these tags
allFile must have all of these tags
noneFile must have none of these tags

Sorting

sort is an array of 1–4 keys. Prefix a key with - for descending order. You cannot pass both directions of the same key, and keys must be unique.

KeySorts by
score / -scoreRelevance
datetime_uploaded / -datetime_uploadedUpload date
size / -sizeFile size
original_filename / -original_filenameFilename
1{ "sort": ["-datetime_uploaded", "original_filename"] }

If sort is omitted, results are ordered by relevance. For filter-only requests (no query or phrase), there is no relevance to rank by, so the order is undefined — always pass an explicit sort in that case.

Pagination

Pagination uses the limit and offset query parameters (not the body):

ParameterDefaultRange
limit201–100
offset0offset + limit must not exceed 1000
$curl -L -X POST 'https://api.uploadcare.com/files/search/?limit=50&offset=50' \
> -H "Accept: application/vnd.uploadcare-v0.7+json" \
> -H "Content-Type: application/json" \
> -H "Authorization: Uploadcare.Simple $YOUR_PUBLIC_KEY:$YOUR_SECRET_KEY" \
> -d '{"query": "invoice"}'

The response includes ready-to-use next and previous URLs. Results beyond the first 1000 cannot be paged through; narrow your query instead of deep paging.

Including appdata

Pass include=appdata as a query parameter to embed application data (such as moderation or virus-scan results) in each result:

POST /files/search/?include=appdata

appdata is currently the only supported value.

Response

1{
2 "next": "https://api.uploadcare.com/files/search/?limit=20&offset=20",
3 "previous": null,
4 "total": 42,
5 "per_page": 20,
6 "results": [
7 {
8 "uuid": "575ed4e8-f4e8-4c14-a58b-1527b6d9ee46",
9 "original_filename": "vacation-photo.jpg",
10 "size": 145212,
11 "highlight": {
12 "original_filename": ["<em>vacation</em>-photo.jpg"]
13 }
14 }
15 ]
16}
  • total — number of matching files (may be approximate for very large result sets).
  • results — file objects in the same shape as file info, plus a highlight field.
  • highlight — for fields that matched a full-text condition, the matched tokens wrapped in <em> tags. original_filename and detected_mime_type are arrays of strings; metadata is an object keyed by metadata field name. Absent for filter-only matches.

Worked examples

Recent images, largest first

1{
2 "is_image": true,
3 "datetime_uploaded": { "gte": "2024-06-01T00:00:00Z" },
4 "sort": ["-size"]
5}

PDFs whose name contains “invoice”, uploaded in 2024

1{
2 "phrase": { "original_filename": "invoice" },
3 "exact": { "detected_mime_type": ["application/pdf"] },
4 "datetime_uploaded": {
5 "gte": "2024-01-01T00:00:00Z",
6 "lt": "2025-01-01T00:00:00Z"
7 }
8}

Outdoor photos tagged cat or dog, excluding archived

1{
2 "is_image": true,
3 "tags": {
4 "all": ["outdoor"],
5 "any": ["cat", "dog"],
6 "none": ["archived"]
7 },
8 "sort": ["-datetime_uploaded"]
9}

Files with a specific metadata value

1{
2 "exact": { "metadata[order_id]": ["12345"] }
3}

Errors

A 400 response body is a JSON object mapping field names to arrays of error strings. Errors that span more than one field appear under non_field_errors.

1{ "non_field_errors": ["At least one search criterion must be specified."] }
Example errorCause
At least one search criterion must be specified.Empty request body.
Fields cannot appear in both phrase and exact: ['original_filename'].Same field used in phrase and exact.
Must be at least 4 characters.A query or phrase value is too short.
offset + limit must be <= 1000.Paging past the 1000-result window.
Sort keys must be unique.Duplicate keys in sort.

Get $YOUR_PUBLIC_KEY and $YOUR_SECRET_KEY from API keys.