Delivering assets
Getting bytes out follows the same rule as getting them in: they do not travel through the API. You request a signed URL and fetch from storage.
Download one file
Code
Answers with a signed, expiring URL. The optional size parameter (small, medium or
large) requests a rendition instead of the original, which is what you want for
anything being displayed rather than downloaded. It applies to images; other file types
return the original whatever you request.
The response body is the URL as a bare JSON string, "https://…", not an object
wrapping it. Parse it as a string.
Fetch the signed URL without your API credentials, because the signature is the authorization. These URLs last 15 minutes and should not be stored. Request a fresh one when you need the bytes: a URL cached in your database is a link that stops working and, until it does, a credential you did not intend to keep.
For a specific version, GET /files/{id}/versions/{version_id}/download-url does the same
for one point in the file's history.
When you cannot fetch cross-origin
GET /files/{id}/image-data streams the bytes through the API instead. It exists for
callers that cannot fetch cross-origin, most often a browser canvas that would be tainted
by the request. Request a rendition rather than the original where one exists, since this
path does carry the bytes through the API.
Download many files
Two endpoints, differing in how long the work takes.
POST /files/actions/download packs a small selection and streams the ZIP back in the
response. It suits a handful of files.
POST /download-jobs hands the work to a background worker and returns a job to poll.
Use it for anything substantial, up to 5,000 files per job:
Then poll GET /download-jobs/{id}:
Code
download_url appears only once status is completed. A failed job carries
error instead. DELETE /download-jobs/{id} cancels one still running.
A job belongs to whoever created it: the person who started it is the person who can poll it.
Files you cannot read are dropped from the selection rather than failing the call, so
file_count on the job may be lower than the list you sent. Compare the two if the count
matters.
Share links
A share link publishes to someone with no account and no key. There are two kinds, chosen
with share_type.
Download links
Code
Up to 500 files per link. The response includes kiosk_url, which is the address to
send the recipient:
Code
Two defaults are worth knowing: links expire after 7 days unless you pass
expires_at, and a password is optional. Omit it and anyone with the URL can open the
link. share_password_set reports which applies, and the password itself is never
returned.
share_view_count and share_download_count are maintained for you, so a link doubles as
a lightweight measure of whether what you sent was opened.
Upload links
share_type: "upload" runs the other way: a link that lets someone outside send files
in without an account. It uses the same three-step upload described in uploading
files, performed against the public surface with a token instead of a
key.
Code
| Option | |
|---|---|
album_ids | Albums the arriving files land in. |
pre_tags | Media tags applied on arrival, so contributions are filed correctly without the sender having to do anything. |
max_files, max_size | Caps on the drop. |
allow_change_tags, allow_change_albums | Whether the sender may change any of the above, or just accept them. |
Files arriving this way enter the library like any other, with the same statuses, the same processing and the same AI analysis.
The public endpoints
The recipient's browser talks to the unauthenticated /public surface: GET /public/share/{token} opens a link, POST /public/share/{token}/verify checks a
password, and the download endpoints mirror the ones above. Upload links have the
matching set under /public/upload/{token}.
You need these only if you are building your own recipient experience instead of sending
people to kiosk_url. They are rate-limited more tightly than the rest of the API. See
rate limits.
Manage links
GET /share-links lists your own links. PATCH /share-links/{id} changes expiry,
password or contents, and DELETE /share-links/{id} revokes one immediately. Revoke a
link that has been forwarded somewhere it should not go: a URL cannot be recalled, but it
can be made to stop answering.
Next steps
- Uploading files is the ingest side of the same flow.
- Organizing and finding assets is how you select what to deliver.
- Sharing and access explains how ACLs decide who sees what.
