Crowdee
Core Concepts

Files & Enrichment

How files are uploaded, stored, and enriched with metadata before verification.

Files are the primary input to every verification pipeline. Before a pipeline can analyse a file, Crowdee runs an enrichment step that extracts structured technical metadata — codec information, EXIF data, loudness levels, page counts, and more. Most pipelines require enrichment to complete before they will accept a run request.

This page explains the full lifecycle: upload, enrichment, and accessing the enriched file data.

Supported Media Types

TypeFormatsNotes
ImageJPEG, PNG, WebP, TIFF, GIFEXIF extraction; frames extracted for animated GIF
AudioMP3, WAV, FLAC, OGG, M4ASpectral and loudness analysis
VideoMP4, MOV, WebM, AVIFrame extraction and audio track analysis
TextTXT, MD, HTMLWord and character count
DocumentPDFPage count, embedded metadata, and text extraction

Uploading Files

Upload files using a multipart/form-data POST to the project files endpoint. The project_id is part of the URL path — files always belong to a specific project.

curl -X POST https://api.crowdee.ai/v2/projects/{projectId}/files \
  -H "X-API-Key: crw_YOUR_API_KEY" \
  -F "file=@photo.jpg"

Example response:

{
  "id": "file_xyz789",
  "name": "photo.jpg",
  "mimeType": "image/jpeg",
  "size": 2048576,
  "enrichmentStatus": "pending",
  "privacyLevel": "private",
  "createdAt": "2024-11-15T10:01:00Z"
}

Save the id — you will use it as {fileId} in all subsequent requests.

Enrichment Process

Enrichment starts automatically immediately after upload. The enrichment worker processes the file in the background and populates the metadata field with structured technical data.

Upload completes — the file record is created with enrichmentStatus: "pending".

Worker picks up the job — the enrichment worker dequeues the file and begins analysis. Status transitions to enrichmentStatus: "running".

Metadata extracted — the worker uses ffprobe (media) or a document parser (PDF/text) to extract structured fields.

Enrichment resolves — on success, enrichmentStatus becomes "completed" and file.metadata is populated. On failure, enrichmentStatus becomes "failed" and a enrichmentError field is set.

Pipelines will return a 422 Unprocessable Entity error if you attempt to start them on a file whose enrichmentStatus is not "completed". Always poll the file endpoint until enrichment finishes before creating a verification run.

Poll the file status:

curl https://api.crowdee.ai/v2/projects/{projectId}/files/{fileId} \
  -H "X-API-Key: crw_YOUR_API_KEY"

Enrichment Fields by Media Type

After enrichment completes, the file.metadata object contains the fields below depending on the file type.

{
  "width": 4032,
  "height": 3024,
  "format": "jpeg",
  "exif": {
    "gps": {
      "latitude": 48.8566,
      "longitude": 2.3522
    },
    "cameraModel": "iPhone 15 Pro",
    "creationDate": "2024-11-14T16:42:00Z",
    "software": "17.1.1"
  }
}
FieldDescription
width / heightImage dimensions in pixels
formatDetected format (jpeg, png, webp, tiff, gif)
exif.gpsGPS coordinates embedded in the file, if present
exif.cameraModelCamera or device model from EXIF
exif.creationDateOriginal capture timestamp from EXIF
exif.softwareSoftware or firmware that created or last edited the file
{
  "duration": 183.4,
  "codec": "mp3",
  "sampleRate": 44100,
  "channels": 2,
  "bitrate": 320000,
  "loudness": {
    "integrated": -14.2,
    "range": 7.1,
    "peak": -0.3
  }
}
FieldDescription
durationLength in seconds
codecAudio codec (mp3, flac, aac, opus, etc.)
sampleRateSample rate in Hz
channelsNumber of audio channels (1 = mono, 2 = stereo)
bitrateBitrate in bits per second
loudness.integratedIntegrated loudness in LUFS (EBU R128)
loudness.rangeLoudness range in LU
loudness.peakTrue peak level in dBTP
{
  "duration": 94.7,
  "codec": "h264",
  "resolution": {
    "width": 1920,
    "height": 1080
  },
  "fps": 29.97,
  "bitrate": 8500000,
  "extractedFrameFileIds": [
    "file_frame_01",
    "file_frame_02",
    "file_frame_03"
  ]
}
FieldDescription
durationLength in seconds
codecVideo codec (h264, hevc, vp9, av1, etc.)
resolutionFrame dimensions in pixels
fpsFrame rate (frames per second)
bitrateOverall bitrate in bits per second
extractedFrameFileIdsArray of file IDs for key frames extracted at regular intervals; each is a full file record usable in image pipelines
{
  "wordCount": 1842,
  "charCount": 10973,
  "pageCount": 6,
  "author": "Jane Smith",
  "creationDate": "2024-10-20T09:15:00Z"
}
FieldDescription
wordCountNumber of words extracted from the document
charCountNumber of characters (including spaces)
pageCountNumber of pages (PDF only; null for plain text)
authorAuthor field from document metadata, if present
creationDateDocument creation timestamp from embedded metadata, if present

Presigned File Access

To download the original file, call the download endpoint. The API responds with a 302 redirect to a temporary presigned URL hosted on S3-compatible storage.

# -L follows the redirect automatically
curl -L https://api.crowdee.ai/v2/files/{fileId}/download \
  -H "X-API-Key: crw_YOUR_API_KEY" \
  -o downloaded-file.jpg

Presigned URLs expire after 15 minutes. Do not cache or share the redirect URL — instead, re-fetch the download endpoint each time you need access to the file.

File Privacy Levels

Files are private by default. The privacyLevel field controls who can access a file:

LevelDescription
privateAccessible only to members of the owning organization
sensitiveRestricted to admin-level and above within the organization
internalAccessible to all authenticated Crowdee users
publicNo authentication required (use only for non-sensitive content)

Retrying Failed Enrichment

If enrichment fails due to a transient error (service unavailability, temporary storage issue), retry it without re-uploading:

curl -X POST \
  https://api.crowdee.ai/v2/projects/{projectId}/files/{fileId}/enrichment/retry \
  -H "X-API-Key: crw_YOUR_API_KEY"

The file will re-enter the pendingrunningcompleted cycle. If enrichment fails repeatedly, check that the file format is supported and that the file is not corrupted.

How is this guide?

© 2026 Crowdee GmbH. All rights reserved.

On this page