Guide
Setup and example usage. For design/architecture see Architecture; for pipeline details see Transcoding.
Setup
- Clone all required repositories and install β follow Installation
cd Quickstartdocker login registry.nexus.castis.iomake media-d- Test:
curl localhost:3000/api/v1/media
Required services: SeaweedFS (object storage, S3 API :8333 +
Filer API :8888), seaweedfs_init (one-shot bucket creation), tusd
(resumable upload server, calls CoreAPI's /hooks/tusd on finish). All
in the LITE infra group used by make media.
Document rasterization also needs LibreOffice (headless,
PPT/PPTX/ODP β PDF) and ghostscript β both baked into CoreAPI's own
Docker image (apk add libreoffice ghostscript), not separate compose
services. Rebuild the CoreAPI image if it predates this
(docker compose build coreapi).
Example usage
All examples assume localhost:3000; swap for staging as needed β see
the servers: list in media.yaml.
1. Pick a profile (seeded profiles always present β see Transcoding Β§ Seeded Profiles):
curl "localhost:3000/api/v1/media/transcoding-profiles?category=image"
2. Prepare + upload with that profile's id:
curl -X POST localhost:3000/api/v1/media/prepare \
-H 'Content-Type: application/json' \
-d '{"title":"deck","originalName":"deck.pptx","fileSize":123456,"tenant":"jastv","folder":"test","transcodingProfileId":<id>}'
# β { "token": "...", "expiresAt": "..." }
/tusd/ (suite-wide shared path) with
metadata.uploadToken set to that token β easiest driven through
PlayoutAdmin's "Add content" sheet rather than a hand-rolled TUS client.
3. Verify, per category:
curl localhost:3000/api/v1/media/<id> | jq '.data.transcodingStage, .data.optimizedKey'
curl localhost:3000/api/v1/media/<id>/slides | jq # document only β [] until rasterized
4. Passthrough: repeat step 2 with the seeded *-PASSTHROUGH
profile's id for the category β expect transcodingStage: "done"
quickly, no optimizedKey/slides produced.
5. Purge + audit:
curl -X DELETE localhost:3000/api/v1/media/<id> # purge defaults to true
curl "localhost:3000/api/v1/media/storage-audit?prefix=test/"
Frontend integration notes
Things not obvious from the route list alone β relevant if you're building or porting a client against this API (see also the capability apps that already do this for PlayoutAdmin):
- No auth is enforced by this domain today β media routes aren't wired to the RS256 JWT validator at registration (unlike identity/tenancy). Don't assume a bearer token is required or checked.
VITE_CDN_HOSTmust already include the serving route + bucket, not just a bare host β see Architecture Β§ Asset URL Strategy for the exact staging bug this caused (source/optimized/slide links breaking while the plain download link kept working).purgedefaults totrueonDELETE /media/:idβ pass?purge=falseexplicitly to keep the old DB-only soft-delete.GET /media/:id/slidesalways returns an array, never 404, for a document that hasn't been rasterized or was passthrough β treat[]as "no slides yet," not an error.- No mime-type allowlist/rejection at
POST /media/prepareor upload time βmediaType/mimeTypeare stored as given and used to pick a pipeline; validate on the client if you want to reject unsupported files before spending an upload. /assets/*may not be CoreAPI in your deployment β in the PlayoutAdmin/Quickstart topology, nginx routes/assets/straight to cproxyβSeaweedFS, bypassing CoreAPI's ownServeAssetroute entirely. Confirm which one your environment actually points at before relying on CoreAPI-specific behavior (e.g. presigned URLs) for asset delivery./hooks/tusdhas no signature check β if you're standing up your own tusd instance against this API, know that only theuploadTokenvalue gates the webhook, not a shared secret.ValidatePrepareonly checks 3 fields (title,originalName,fileSize > 0) β everything else on the prepare payload is optional and unvalidated server-side.