Media reference

Config options

OptionDefaultMeaning
recordStored1Where media records live. d1 makes transcriptions and extracted text queryable; kv is key lookup only
Enrichment togglesoffAlt text, transcription, text extraction — each independent
Backend per type—Which store handles images, video, audio and documents

Pick d1 unless you are certain you will never want to search the text. Enrichment produces text so that something can read it, and kv closes that door.

The choice also changes what provisioning creates: the KV namespace exists only in kv mode, and in d1 mode the binding is dropped rather than pointed at a namespace that never existed.

Bindings

BindingTypeWritten by
DBd1pithy add
MEDIA_BUCKETr2pithy add
MEDIA_IMAGE_TO_TEXTworkflow, optionalpithy media provision
MEDIA_AUDIO_TRANSCRIBEworkflow, optionalpithy media provision
The video Workflowworkflow, optionalpithy media provision

The Workflow bindings are declared optional so an app still boots before provisioning has deployed the host — which is what makes a first pithy dev work on a project that has never reached an account.

Secrets

One of these is read by storage, not by media.

Two, because there are two owners.

SecretBelongs to
media-storage-credentialsMedia’s own token for minting direct-upload URLs
media-r2-credentialsThe object store media presigns through — and whose key pair media never sees

Neither is minted. There is no API for creating an S3 access-key pair, and the permission catalog carries no keys for the image or video stores. You make them by hand.

Backends per type

Why each type resolves the way it does is a backend per media type; the calls are in Using Media; standing them up is pithy media.

TypeTypically
ImageThe image store, for variants and transformation
VideoThe streaming store, for adaptive playback
Audio, documentsR2, through the object-store seam

Ownership is metadata, not a name

An asset in the image or video store is keyed by an id the store mints, so there is no name to put a project segment into.

Every asset is stamped with the project and the environment, the same two keys in both stores, so one query answers what does this project own across them.

The stamp is merged last, so a caller’s own metadata cannot displace it. A Worker that cannot name its project refuses to mint.

What it does not inherit from storage

It presigns through the object-store seam, against its own bucket and credential name — and inherits none of that capability’s tables, routes, quotas or share links.

So composing both gives you two independent products rather than one with two front doors.

Peer capabilities

Required: secrets.

Optional: auth — effectively required, since an upload belongs to somebody.

Composes naturally with vector, whose corpus is the obvious destination for extracted text.

Provisioning

pithy media provision creates the bucket and the namespace, writes both credential secrets, and deploys the host that runs the enrichment Workflows.

Each environment’s deploy needs the app database id and that environment’s secrets database, and both are refused rather than deployed around.

ESC