Skip to content

What to store in your database

The File Service keeps the bytes and everything about them. Your database keeps the link between your records and the files. This page says what that link should hold, so your records stay correct when files are renamed, moved, given a new version or processed.

file_id is the one field you must store. It is a ULID, never reused, and it does not change for the life of the file: not on a rename, a move, a new version or a restore from the trash. Names and paths can change; ids cannot. To keep people from renaming, moving or deleting the files your records point at, put them in an application-managed folder.

{ "id": 123, "text": "look at my beach photo",
"media": [ { "file_id": "01J9Z6S9Q5F5R6Y2W2GZ3B3K4D", "kind": "image", "mime_type": "image/jpeg", "name": "IMG_5913.jpg", "width": 4032, "height": 3024 } ] }

Everything next to file_id above is a convenience copy, so the feed can lay out the page without a call per file. Copy it at completion time, from the file the completion answers (or from media once processing has read it). If it goes stale, nothing breaks: the service has the truth.

Set external_ref on the ticket to your own id, for example post:123 or contract:2026-17. It is at most 200 characters, not unique, and you can change it later.

Download, preview and batch URLs are signed and expire after 15 minutes by default. Mint them when you render (POST P/files/urls for a whole page) and hand them out with the response. Storing one gives you a broken image later.

The exception is a public file: its public_url is stable and cacheable, so you may store it once when the application allows public files. See Delivery and visibility.

You store You do not store
file_id, and the link to your record URLs (they expire), object locations (you never see them)
Convenience copies: kind, mime_type, name, width, height, duration_ms processing, state or rendition status (they change after completion)
Your own rules: who may attach to what A copy of the service’s access entries
upload_id only while the upload is open The ticket’s signed URLs

To show whether a thumbnail exists, ask the service (GET P/files/:file_id, or the per-item error of POST P/files/urls) or react to file.ready.

Trash the file with DELETE P/files/:file_id. It stays restorable for the application’s trash retention (default 30 days), then the service purges it and releases the quota. If you need it gone at once, purge it with POST P/files/:file_id/purge. A file that was never linked (the user abandoned the post) is best trashed too; an upload that never completed is cleaned up by the service on its own when the ticket expires.