PUT it to a signed URL, then
transcribe it with one call like any episode. The transcript is private to
your account.
You are responsible for holding the rights to have what you upload
transcribed; see the terms. How you obtain the
file is up to you: a recording, an export from your editor, or a download you
made yourself with a tool such as yt-dlp.
The three calls
1
Announce the file
Tell Audivo the file’s SHA-256, its exact length, its content type and how
long it plays. The duration is what the quote is priced from.Set
content_type to the file’s real type; the accepted values are in
Limits below.The answer is 201 with an upload_id, a put_url, the put_headers
the PUT must carry, put_url_expires_at (one hour from now) and
retained_until (seven days from now). If ffprobe is not installed,
declare the duration your player shows, in seconds.2
Send the file
PUT the body to put_url with exactly the returned headers and nothing
else; they are part of the signature. The object store refuses a body
whose length or hash differs from what you announced.400 from the object store means the bytes you sent do not match the
announcement: announce the file as it is now and send it again. The
signed URL expires after one hour; announce again if it lapses.3
Transcribe it
Send the The call checks the object once (present, the announced length, the
announced hash), prices it from the declared duration with the usual 25%
ceiling, and answers
upload_id to the same endpoint every episode uses:202 with a job to
poll and read exactly as for a feed episode — or 200
with the transcript, if this account already transcribed the same file."uploads": [{ "upload_id": … }, …] — and confirm it; see
Price a selection.
When an upload is refused
The same three checks run on a submit and on a quote. A submit answers with an error; a quote lists the upload underexcluded with the same reason.
A job or quote entry from an upload reports
quote_basis: declared.
Pricing and the declared duration
An upload is priced from the duration you declared, the same way a feed episode is priced from its<itunes:duration>: estimated_credits from the
minutes, a ceiling 25% above it, and settlement at the measured minutes
capped at the ceiling. If the audio runs past the ceiling the declaration
reserved, the job fails as processing_failed with the message “The audio
runs past the ceiling the quote reserved for its declared duration”, and the
reservation is released. Declare the real duration: rounding up a little is
fine, rounding down is not. Credits explains the four moments.
Privacy and retention
- The transcript is cached for your account alone. Another account uploading the same bytes gets its own transcript at full price, and nothing about your upload is visible to it.
- The audio is sent to Audivo’s inference sub-processor to be transcribed, the same as any episode; see Your data.
- The file is deleted seven days after announcement. The transcript and the job records stay with your account like any other.
- Each account may hold 10 GiB across 100 unexpired uploads at once. An
announcement counts against this even if no file is sent; the room comes
back at its
retained_until. Over it, the announcement is refused as429 upload_quota_exceededand the message names the earliest time enough room returns. - In the transcript’s provenance the show is your private “Uploads” show,
with the feed URL
audivo://uploads/<your account id>; the episode title is thetitleyou announced.
Limits
The schemas are in the API Reference under Uploads.
From an MCP client or the skill
The local MCP server’stranscribe tool takes a file path, or a YouTube
link it downloads on your machine with yt-dlp, and does all three calls; its
upload_audio tool does the first two when you want to quote the upload
yourself. See
Transcribe audio you have. The
agent skill ships
skills/audivo/scripts/upload.sh for the same flow from a shell.
