The /access-link endpoints give you a signed URL for a file that Daily stores for you. This applies to recordings, transcripts, and batch processor outputs.
A signed URL works for a short time and then stops working. It is not a permanent address for the file.
Use the URL exactly as returned
The query string is what authorizes the download. Expires, Signature, and Key-Pair-Id are all part of a signature that is checked on every request.
If you add a query parameter, drop one, reorder them, or re-encode them, the signature no longer matches. The download then fails with a 403, even though the API call that gave you the link returned a 200.
Pass the whole URL through unchanged. Do not run it through a URL builder, a proxy that rewrites query strings, or an encoder.
Read the host from the response
Do not build your own download URL from your bucket name. Read the host from the response.
The host in the link is not always the storage bucket host, and it can change over time. Code that hard-codes a bucket hostname and appends the file path will start returning 403 when the host changes, with no other warning.
Files kept in your own S3 bucket are served from your bucket instead. That is one more reason to read the host from the response rather than assume one.
Links expire
Request a fresh link when you need the file. Do not store a link in your database and reuse it later.
For recordings, the expires field is the Unix timestamp when the link stops working. Call the endpoint again to get a new one.
Troubleshooting
You called the access-link endpoint and got a 200, but downloading the file returns a 403. Common causes: