The handshake
The handshake tells Pepys what is coming so it can authorise a one-off upload URL. Send the filename, the content type, and the exact byte size; the response returns the URL to PUT to, the media_ref that identifies the file afterwards, and how long the URL stays valid.
curl -X POST https://pepys.co/api/v1/uploads \
-H "Authorization: Bearer pk_live_…" \
-d '{ "filename": "call.mp3", "content_type": "audio/mpeg", "bytes": 5242880 }'
# → { "upload_url": "https://…", "media_ref": "uploads/<you>/<uuid>.mp3", "expires_in": 600 }Upload the bytes
PUT the file to the presigned URL. The Content-Type and Content-Length must match what you declared in the handshake – a mismatch is rejected, since the URL was authorised for that exact size and type.
curl -X PUT "<upload_url>" -H "Content-Type: audio/mpeg" --data-binary @call.mp3Transcribe the upload
Pass the media_ref as the source of a transcription job. From there it behaves like any other job: poll Get a transcription or wait for a webhook.
curl -X POST https://pepys.co/api/v1/transcriptions \
-H "Authorization: Bearer pk_live_…" \
-d '{ "media_ref": "uploads/<you>/<uuid>.mp3" }'