Crowdee
API Reference

Files API

Upload files, poll enrichment status, access presigned download URLs, and manage file metadata.

Files are the primary input to verification pipelines. After upload, Crowdee automatically enriches each file — extracting technical metadata, content fingerprints, and format-specific signals — so pipelines can operate on structured data rather than raw bytes.

Endpoint Reference

MethodPathDescription
POST/v2/projects/{projectId}/filesUpload a file
GET/v2/projects/{projectId}/filesList project files
GET/v2/files/{fileId}Get file details
PUT/v2/files/{fileId}Update file metadata
DELETE/v2/files/{fileId}Delete a file
GET/v2/files/{fileId}/downloadGet presigned download URL

Upload a File

POST /v2/projects/{projectId}/files

Files are uploaded as multipart/form-data. Do not set the Content-Type header manually — let the HTTP client set it (with the correct boundary) automatically.

Supported formats

CategoryAccepted MIME types
Imageimage/jpeg, image/png, image/webp, image/gif, image/bmp, image/heic, image/avif
Audioaudio/mpeg, audio/wav, audio/ogg, audio/mp4, audio/flac
Videovideo/mp4, video/webm, video/quicktime, video/x-msvideo
Documentapplication/pdf, text/plain, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document
curl -X POST https://api.crowdee.ai/v2/projects/proj_abc123/files \
  -H "X-API-Key: crw_YOUR_API_KEY" \
  -F "file=@photo.jpg"

Response

{
  "id": "file_xyz789",
  "projectId": "proj_abc123",
  "name": "photo.jpg",
  "mimeType": "image/jpeg",
  "size": 2457600,
  "enrichmentStatus": "pending",
  "tags": [],
  "privacyLevel": "private",
  "createdAt": "2024-11-15T10:01:00Z",
  "updatedAt": "2024-11-15T10:01:00Z"
}

Enrichment starts automatically. The enrichmentStatus will transition from pending to running within seconds.

Polling Enrichment Status

GET /v2/files/{fileId} or GET /v2/projects/{projectId}/files/{fileId} — both endpoints return the same object.

The enrichmentStatus field follows this state machine:

pending → running → completed
                 ↘ failed

Do not start a verification run until enrichmentStatus is "completed". Submitting a run against an un-enriched file returns a 422 UNPROCESSABLE_ENTITY error.

Recommended polling intervals:

File typePoll interval
ImageEvery 5 seconds
Audio (< 10 min)Every 10 seconds
Audio (> 10 min)Every 30 seconds
Video (< 5 min)Every 15 seconds
Video (> 5 min)Every 30–60 seconds
Document / textEvery 5 seconds
curl https://api.crowdee.ai/v2/files/file_xyz789 \
  -H "X-API-Key: crw_YOUR_API_KEY"

Enriched file response:

{
  "id": "file_xyz789",
  "name": "photo.jpg",
  "mimeType": "image/jpeg",
  "size": 2457600,
  "enrichmentStatus": "completed",
  "enrichment": {
    "width": 3024,
    "height": 4032,
    "colorSpace": "sRGB",
    "hasExif": true,
    "captureDevice": "Apple iPhone 15 Pro",
    "capturedAt": "2024-10-28T14:32:11Z",
    "gpsCoordinates": { "lat": 52.5200, "lng": 13.4050 }
  },
  "createdAt": "2024-11-15T10:01:00Z",
  "updatedAt": "2024-11-15T10:01:07Z"
}

List Project Files

GET /v2/projects/{projectId}/files

Query parameters

ParameterTypeDescription
enrichmentStatusstringFilter by status: pending, running, completed, failed
mimeTypestringFilter by MIME type prefix, e.g. image/ or video/mp4
limitintegerDefault 20, max 200
offsetintegerDefault 0
curl "https://api.crowdee.ai/v2/projects/proj_abc123/files?enrichmentStatus=completed&limit=100" \
  -H "X-API-Key: crw_YOUR_API_KEY"

Update File Metadata

PUT /v2/files/{fileId}

Update the file's display name, tags, privacy level, or custom metadata. The file content and enrichment data are immutable after upload.

Updatable fields

FieldTypeDescription
namestringDisplay name for the file
tagsstring[]Arbitrary labels for grouping and filtering
privacyLevelstringprivate | sensitive | internal | public
additionalInfoobjectFree-form JSONB for custom metadata
curl -X PUT https://api.crowdee.ai/v2/files/file_xyz789 \
  -H "X-API-Key: crw_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "protest-photo-berlin-2024.jpg",
    "tags": ["berlin", "protest", "2024"],
    "privacyLevel": "sensitive",
    "additionalInfo": {
      "source": "Telegram channel",
      "receivedAt": "2024-10-28T15:00:00Z"
    }
  }'

Presigned Download URL

GET /v2/files/{fileId}/download

Returns a 302 redirect to a temporary presigned S3 URL. The URL is valid for 15 minutes.

Presigned URLs expire after 15 minutes. Re-fetch the /download endpoint as needed — it always returns a fresh URL. Do not cache the redirect target for longer than 10 minutes.

# Use -L to follow the redirect and save the file
curl -L https://api.crowdee.ai/v2/files/file_xyz789/download \
  -H "X-API-Key: crw_YOUR_API_KEY" \
  -o photo.jpg

Delete a File

DELETE /v2/files/{fileId}

Deleting a file removes it from storage permanently. Verification runs that referenced the file retain their results and verdicts, but re-running is not possible without re-uploading the file. Consider archiving via privacyLevel: "sensitive" before deleting.

curl -X DELETE https://api.crowdee.ai/v2/files/file_xyz789 \
  -H "X-API-Key: crw_YOUR_API_KEY"

Returns 204 No Content on success.

How is this guide?

© 2026 Crowdee GmbH. All rights reserved.

On this page