media-worker process.
All three BullMQ queues run at concurrency:1. This is a deliberate constraint — the server has 16GB RAM, and parallel media or LLM jobs would cause RAM exhaustion. Jobs execute sequentially per queue.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/queue/stats | Queue depths, job counts, and taxonomy cache status |
POST | /api/queue/media | Enqueue a job that has already been created in Directus |
POST | /api/queue/retry/:jobId | Re-enqueue a failed job at elevated priority |
POST | /api/queue/taxonomy/invalidate | Bust the taxonomy DuckDB cache |
GET /api/queue/stats
Returns the current depth and job counts for all BullMQ queues, plus the taxonomy cache stats.Response
POST /api/queue/media
Enqueues a media processing job. The caller is responsible for creating the Directusmedia_jobs record first, then calling this endpoint to push the job ID into BullMQ so the worker picks it up.
Body
The UUID of the existing
media_jobs record in Directus.The job type to execute. See the operations table below for valid values.
Directus file ID for the input asset. Required for operations that process an existing uploaded file.
URL of the input asset. Used for URL-based operations (e.g., scraping, remote downloads).
Operation-specific parameters. Structure varies by job type (see operations table).
Directus
creator_profiles record ID. Used to scope output storage and watermark identity.BullMQ priority. Lower numbers = higher priority. Default:
10. Retried jobs use 5.Response
true when the job was successfully enqueued.The BullMQ-assigned job ID for polling status directly against the Redis queue.
The Directus
media_jobs record ID (echoed from the request).Subscription quota check
Before enqueuing, the endpoint callscanPerform(userId, operation) from subscriptionValidator.js. If the user has exhausted their tier quota for the given operation, the job is rejected with a 403:
limit_reached or not_in_tier results reject the request.
POST /api/queue/retry/:jobId
Re-enqueues a failed job. The endpoint fetches the original job record from Directus, validates it is infailed or error status, and re-submits it to BullMQ with elevated priority (5).
| Status | Meaning |
|---|---|
200 | Job re-enqueued successfully |
404 | Job not found in Directus |
409 | Job is not in a failed state — cannot retry |
Queues
media-jobs
Image and video processing operations. FFmpeg/ImageMagick workers. concurrency:1.
scrape-jobs
Browser automation jobs via Stagehand/PinchTab. Profile scraping, post performance, session management. concurrency:1.
onboarding-jobs
LLM-heavy onboarding pipeline jobs. ETL from scraped platform data into
user_nodes. concurrency:1.Job types
Media operations (media-jobs)
| Operation | Input | Description |
|---|---|---|
convert_image | input_file_id | Convert image to a different format |
resize_image | input_file_id | Resize image to target dimensions |
crop_image | input_file_id | Crop image to bounding box |
resize_video | input_file_id | Resize video to target resolution |
crop_video | input_file_id | Crop video to bounding box |
compress_video | input_file_id | Re-encode video at lower bitrate |
apply_watermark | input_file_id | Apply visible watermark overlay |
apply_steganographic_watermark | input_file_id | Embed invisible fan-specific watermark |
create_teaser | input_file_id | Generate a short preview clip |
strip_metadata | input_file_id | Remove EXIF and metadata from file |
Scrape operations (scrape-jobs)
| Operation | Input | Description |
|---|---|---|
scrape_profile | creator_profile_id | Scrape platform profile stats |
scrape_post_performance | creator_profile_id | Scrape per-post engagement metrics |
publish_post | creator_profile_id | Automated post submission to platform |
Onboarding operations (onboarding-jobs)
Onboarding jobs follow the pattern onboarding:<phase> (e.g., onboarding:extract, onboarding:classify, onboarding:embed). These are triggered internally by the onboarding state machine, not directly by API consumers.
The
media-worker implementation was split into an operations/ module structure on 2026-03-15. Handlers live in operations/media.js, operations/scrape.js, operations/publish.js, and operations/onboarding.js, with shared helpers in operations/helpers.js.