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
| Method | Path | Description |
|---|---|---|
POST | /v2/projects/{projectId}/files | Upload a file |
GET | /v2/projects/{projectId}/files | List 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}/download | Get 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
| Category | Accepted MIME types |
|---|---|
| Image | image/jpeg, image/png, image/webp, image/gif, image/bmp, image/heic, image/avif |
| Audio | audio/mpeg, audio/wav, audio/ogg, audio/mp4, audio/flac |
| Video | video/mp4, video/webm, video/quicktime, video/x-msvideo |
| Document | application/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
↘ failedDo 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 type | Poll interval |
|---|---|
| Image | Every 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 / text | Every 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
| Parameter | Type | Description |
|---|---|---|
enrichmentStatus | string | Filter by status: pending, running, completed, failed |
mimeType | string | Filter by MIME type prefix, e.g. image/ or video/mp4 |
limit | integer | Default 20, max 200 |
offset | integer | Default 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
| Field | Type | Description |
|---|---|---|
name | string | Display name for the file |
tags | string[] | Arbitrary labels for grouping and filtering |
privacyLevel | string | private | sensitive | internal | public |
additionalInfo | object | Free-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.jpgDelete 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?
Projects API
Create, list, update, and delete projects; manage files, runs, and dossiers.
Datasets API
Create and manage versioned media file collections, apply cleaning pipelines, and export processed files.