homeaboutvideotry it nowpricingdocs
Docs

Getting Started

HTTP API reference

Every public Fileboy endpoint, generated from the same OpenAPI document that you can download for code generators and API clients: openapi.json or openapi.yaml. Most people will want an SDK instead of calling these directly.

Base URLhttps://api.fileboy.ioJump toMetaManagementFilesFoldersExpiring linksImagesVideos

Authentication. Uploads send your app's public key as Authorization: public YOUR_PUBLIC_KEY. Apps that use a private key send a short-lived signed token as Authorization: token PUBLIC$NONCE$JWT. Reading files, images and video needs no authorization, unless the app requires signed reads (then every read of the app does) or the file's own read permission is authenticated (then reads of that file do, through its file, data, image and label URLs, and so do image URLs that draw it as an overlay): such a read needs a signed URL (fb_exp and fb_sig query parameters, see https://fileboy.io/docs/delivery/signed-urls) or the app's private key, and anything else gets 401 signature_required or 403. Videos follow the app setting alone. The Management endpoints (list, update and delete) only accept a token signed with the private key: a public key, or a token limited to uploads or reads, gets 403 private_key_required. Errors. Routes that report errors as JSON use { "error": "code", "message": "..." }. The file, image and data read routes answer with a plain text message instead.

Fileboy also calls your server when things happen. Those requests are described under webhooks in the spec and in the webhooks reference.

Files

Upload, read and serve files.

POST/files/upload

Upload a file

Send the file as multipart/form-data, or send JSON with a url and Fileboy fetches it for you. The demo key only accepts small images and is rate limited. Uploads count towards your plan's file limit. Send folderId or folderPath to upload straight into a folder. A request signed with your private key creates any missing folders on folderPath; the public key and access tokens can only use folders that already exist (404 folder_not_found otherwise, and nothing is stored).

Authorization: public key or signed token

Request body

multipart/form-data
file *string (binary)
datastringOptional JSON string of name, mime, metadata, folderId and folderPath. name and mime default to the uploaded file's own.
urlstring (uri)If present, the file is fetched from this URL and file is ignored.
folderIdstring (uuid)Put the file in this folder. Can also be sent inside data.
folderPathstringPut the file in the folder at this path, like /uploads/avatars. Can also be sent inside data. See UploadFileData.
application/json
url *string (uri)An http or https address Fileboy can fetch.
namestring
metadataMetadata
folderIdstring (uuid)See UploadFileData.
folderPathstringSee UploadFileData.
expectstring | string[]Reject the download unless it matches. A comma separated string or an array of .ext, type/subtype, type/* or */subtype entries, like an HTML accept attribute.

Responses

200The stored file.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404The folder does not exist.
application/json
413An error. error is a short code and message says what went wrong.
application/json
415An error. error is a short code and message says what went wrong.
application/json
422location_not_removed: the app removes photo locations at upload (stripLocationOnUpload) and this photo's could not be removed, so it was not stored.
application/json
429An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/files/get/{id}

Get a file

Returns the stored bytes of a file. The id is a file id or PUBLIC_KEY+LABEL for a labelled file. If the query has a transform parameter the request is redirected (301) to the matching /images/get URL.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
downloadquerystringAdd ?download to send the file as an attachment so browsers save it. download=false turns it off.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The file's bytes. Content-Type is the stored type. Supports Range requests.
*/*
206The requested byte range.
*/*
301A transform query was given. Follow the redirect to /images/get/{id}.
400The id is not a valid file id or label.
text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that id or label.
text/plain
GET/files/get/{id}/{filename}

Get a file under a chosen file name

Returns the stored bytes of a file. The id is a file id or PUBLIC_KEY+LABEL for a labelled file. If the query has a transform parameter the request is redirected (301) to the matching /images/get URL.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
filename *pathstringFile name to serve the file as. If it has no extension, one is added from the file's type.
downloadquerystringAdd ?download to send the file as an attachment so browsers save it. download=false turns it off.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The file's bytes. Content-Type is the stored type. Supports Range requests.
*/*
206The requested byte range.
*/*
301A transform query was given. Follow the redirect to /images/get/{id}.
400The id is not a valid file id or label.
text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that id or label.
text/plain
GET/files/{id}DEPRECATED

Get a file

Legacy alias of /files/get/{id}. Returns the stored bytes of a file. The id is a file id or PUBLIC_KEY+LABEL for a labelled file. If the query has a transform parameter the request is redirected (301) to the matching /images/get URL.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
downloadquerystringAdd ?download to send the file as an attachment so browsers save it. download=false turns it off.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The file's bytes. Content-Type is the stored type. Supports Range requests.
*/*
206The requested byte range.
*/*
301A transform query was given. Follow the redirect to /images/get/{id}.
400The id is not a valid file id or label.
text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that id or label.
text/plain
GET/files/data/{id}

Get a file's details

Name, type, size, hash and metadata of a file. The id is a file id or PUBLIC_KEY+LABEL.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The file's details.
application/json
400The id is not a valid file id or label.
text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that id or label.
text/plain
GET/files/{id}/dataDEPRECATED

Get a file's details (legacy path)

Legacy alias of /files/data/{id}.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The file's details.
application/json
400The id is not a valid file id or label.
text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that id or label.
text/plain
GET/files/{id}/share

Get a file's share page

The data behind a file's share page, https://fileboy.io/f/{id}: its name, type and size, and the URLs the page shows and downloads from. The page is off unless you turn it on (sharePage on updateFile, or the dashboard), and Fileboy's own files (image copies, the parts of a video) never have one: both are 404 share_page_not_found. It follows the file's read access. A public file of a public app opens for anyone. A file that needs a signature (its read permission is authenticated, or the app requires signed reads) needs a signed share link: sign the page URL (https://fileboy.io/f/{id}, scope share) and the page passes fb_exp, fb_sig and fb_ip on to this route. Without one the answer is 401 signature_required, whether or not the page is on. The URLs in the answer are then signed with the link's own expiry and address range. A signature for the file itself does not open the page, and the page's signature does not read the file. Only file ids are accepted, not labels. Answers are kept by the browser for at most 60 seconds, so turning a page off reaches everyone within a minute.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)A file id. Labels are not accepted.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The share page's data.
application/json
400The id is not a file id.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404share_page_not_found: no such file, its page is off, or it is one of Fileboy's own files.
application/json

Images

Serve images and transform them with a URL.

GET/images/get/{id}

Get an image, optionally transformed

Serves an image, running the transforms in the transform query parameter in order. Results are cached per transform chain. A transform that does not parse, or would make the image too large, is answered with 400 and a JSON body saying what is wrong. Files that are not JPEG, PNG, WebP, BMP or TIFF (GIF, SVG, PDF...) are served unchanged. JPEG orientation from EXIF is applied, and transformed output carries no metadata. With format:auto the response varies on Accept and says so in Vary. Animated GIF and WebP are served unchanged. See the transform parameter for the grammar.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
transformquerystringTransforms joined by ; and run in order, each written name:value~option:value. At most 20 transforms and 2048 characters. Size and shape: resize:WxH (_ leaves a side free; options ~fit:cover|contain|fill|inside|outside, ~position:top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right, ~background:COLOUR, ~format:FORMAT, ~focus:X,Y to keep a point in view with fit cover, ~upscale:false to never make the image bigger than its source), resizeAR:WxH (crop or pad to an aspect ratio; same options as resize except focus), crop:WxH (sizes in px or 50pc; @X,Y places the centre of the crop, or ~position: anchors it), smartCrop:WxH (crops to the most detailed part of the image), rotate:DEGREES (clockwise, ~background:COLOUR), flip:x|y|xy, flop, radius:PX|max (rounded corners or a circle, ~background:), pad:ALL|V,H|T,R,B,L (~background:), border:PX (~color:), trim or trim:0-100 (cuts away a border of one colour, the top-left pixel's unless ~color: is given; the number is the tolerance, default 10), dpr:N (multiplies every pixel size, 0.1 to 5). Look: blur:0-100, sharpen or sharpen:0-10, grayscale, saturate:N (0 grey, 1 unchanged, up to 10), brightness:-100-100, contrast:-100-100, hue:DEGREES, gamma:0.1-10, sepia or sepia:0-100, tint:COLOUR (alpha sets strength), opacity:0-100, pixelate:1-200, invert. Layers: overlay:FILE_ID draws another image file of the same app on top (~width: and ~height: in px or pc of the image; one keeps its shape, both fit it inside the box; ~transform:(CHAIN) runs transforms on the overlay first). text:TEXT writes text, URL-encoded inside the transform (so encoded twice in the URL: %2520 for a space), up to 500 characters (~font:sans|sans-bold|sans-italic|mono|mono-bold, ~size:PX|Npc of the image height (default 32), ~color:, ~background: for a box, ~padding:PX, ~wrap:PX|Npc, ~align:left|center|right). Both take ~position: (default center), ~x: and ~y: (in from that edge, px or pc, may be negative), ~opacity:0-100, ~rotate:DEGREES and ~tile:true with ~gap: to repeat the layer as a pattern. At most 5 layers. An overlay must be a file of the same app (anything else is a 400 invalid_transform), an image of at most 25 MB; if it needs a signed URL, so does this request, even for a public image. Output: format:auto|avif|webp|jpeg|png|tiff|bmp|json (auto picks AVIF, then WebP, then the source format, from what Accept allows; images over 16 megapixels are sent as WebP instead of AVIF; json answers with the image's size instead of the image), quality:1-100 (the same scale for JPEG, WebP and AVIF), lossless (lossless WebP or AVIF; auto keeps lossless chains on WebP), background:COLOUR (the default for later transforms that leave empty space), strip (re-encode without metadata), palette or palette:json|css (the image's main colours instead of the image, see the Palette schema; ~colors:0-16, default 6, and for CSS ~prefix:NAME). Whichever of format and palette comes last decides the output. A transform's options can follow its name when its main value is left out, as in trim~color:white. Numbers past a limit are clamped (resize to 4000px, blur to 100...). Colours are hex(RGB), hex(RRGGBB), hex(RRGGBBAA), rgb(R,G,B), rgba(R,G,B,A) or a CSS name. Empty space is transparent in PNG, WebP, AVIF and TIFF and white in JPEG and BMP unless a background is given.
e.g. resize:300x_~fit:cover;format:webp;quality:75
e.g. resize:200x200~fit:contain~background:hex(fff)
e.g. smartCrop:96x96;radius:max;dpr:2;format:auto
e.g. resize:800x_;format:avif;quality:60
e.g. resize:1600x_;overlay:3f2a9c1e-7b4d-4e8a-9c6f-1d2e3f4a5b6c~width:15pc~position:bottom-right~x:24~y:24~opacity:85
e.g. text:%C2%A9%20Jane%20Doe~size:4pc~color:white~background:hex(00000080)~padding:8~position:bottom-left~x:16~y:16
e.g. resize:1200x600~focus:70pc,30pc;format:auto;quality:80
e.g. resize:1600x_~upscale:false;format:auto
e.g. trim;pad:24~background:white;resize:600x600~fit:contain~background:white
e.g. resize:300x_;format:json
e.g. palette~colors:4
e.g. crop:100pcx20pc~position:top;palette:css~prefix:hero
e.g. resizeAR:4x3~fit:contain~background:white;pad:16;border:1~color:hex(ddd)
downloadquerystringAdd ?download to send the file as an attachment so browsers save it. download=false turns it off.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The image. Content-Type is the output format. With format:json, a JSON description of the image instead; with palette, its colours as JSON (a Palette) or, with palette:css, a stylesheet.
image/*, text/css, application/json
400The transform is not valid, the image is too large to transform, or an overlay is not an image file of this app (JSON, error is invalid_transform), or the id is not valid or the file could not be read (plain text).
application/json, text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that label.
text/plain
422A palette was asked for a file that is not a JPEG, PNG, WebP, BMP or TIFF image. error is unsupported_image.
application/json
500The image could not be transformed. error is transform_failed or internal_error.
application/json
GET/images/get/{id}/{filename}

Get an image under a chosen file name

Serves an image, running the transforms in the transform query parameter in order. Results are cached per transform chain. A transform that does not parse, or would make the image too large, is answered with 400 and a JSON body saying what is wrong. Files that are not JPEG, PNG, WebP, BMP or TIFF (GIF, SVG, PDF...) are served unchanged. JPEG orientation from EXIF is applied, and transformed output carries no metadata. With format:auto the response varies on Accept and says so in Vary. Animated GIF and WebP are served unchanged. See the transform parameter for the grammar.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
filename *pathstringFile name to serve the file as. If it has no extension, one is added from the file's type.
transformquerystringTransforms joined by ; and run in order, each written name:value~option:value. At most 20 transforms and 2048 characters. Size and shape: resize:WxH (_ leaves a side free; options ~fit:cover|contain|fill|inside|outside, ~position:top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right, ~background:COLOUR, ~format:FORMAT, ~focus:X,Y to keep a point in view with fit cover, ~upscale:false to never make the image bigger than its source), resizeAR:WxH (crop or pad to an aspect ratio; same options as resize except focus), crop:WxH (sizes in px or 50pc; @X,Y places the centre of the crop, or ~position: anchors it), smartCrop:WxH (crops to the most detailed part of the image), rotate:DEGREES (clockwise, ~background:COLOUR), flip:x|y|xy, flop, radius:PX|max (rounded corners or a circle, ~background:), pad:ALL|V,H|T,R,B,L (~background:), border:PX (~color:), trim or trim:0-100 (cuts away a border of one colour, the top-left pixel's unless ~color: is given; the number is the tolerance, default 10), dpr:N (multiplies every pixel size, 0.1 to 5). Look: blur:0-100, sharpen or sharpen:0-10, grayscale, saturate:N (0 grey, 1 unchanged, up to 10), brightness:-100-100, contrast:-100-100, hue:DEGREES, gamma:0.1-10, sepia or sepia:0-100, tint:COLOUR (alpha sets strength), opacity:0-100, pixelate:1-200, invert. Layers: overlay:FILE_ID draws another image file of the same app on top (~width: and ~height: in px or pc of the image; one keeps its shape, both fit it inside the box; ~transform:(CHAIN) runs transforms on the overlay first). text:TEXT writes text, URL-encoded inside the transform (so encoded twice in the URL: %2520 for a space), up to 500 characters (~font:sans|sans-bold|sans-italic|mono|mono-bold, ~size:PX|Npc of the image height (default 32), ~color:, ~background: for a box, ~padding:PX, ~wrap:PX|Npc, ~align:left|center|right). Both take ~position: (default center), ~x: and ~y: (in from that edge, px or pc, may be negative), ~opacity:0-100, ~rotate:DEGREES and ~tile:true with ~gap: to repeat the layer as a pattern. At most 5 layers. An overlay must be a file of the same app (anything else is a 400 invalid_transform), an image of at most 25 MB; if it needs a signed URL, so does this request, even for a public image. Output: format:auto|avif|webp|jpeg|png|tiff|bmp|json (auto picks AVIF, then WebP, then the source format, from what Accept allows; images over 16 megapixels are sent as WebP instead of AVIF; json answers with the image's size instead of the image), quality:1-100 (the same scale for JPEG, WebP and AVIF), lossless (lossless WebP or AVIF; auto keeps lossless chains on WebP), background:COLOUR (the default for later transforms that leave empty space), strip (re-encode without metadata), palette or palette:json|css (the image's main colours instead of the image, see the Palette schema; ~colors:0-16, default 6, and for CSS ~prefix:NAME). Whichever of format and palette comes last decides the output. A transform's options can follow its name when its main value is left out, as in trim~color:white. Numbers past a limit are clamped (resize to 4000px, blur to 100...). Colours are hex(RGB), hex(RRGGBB), hex(RRGGBBAA), rgb(R,G,B), rgba(R,G,B,A) or a CSS name. Empty space is transparent in PNG, WebP, AVIF and TIFF and white in JPEG and BMP unless a background is given.
e.g. resize:300x_~fit:cover;format:webp;quality:75
e.g. resize:200x200~fit:contain~background:hex(fff)
e.g. smartCrop:96x96;radius:max;dpr:2;format:auto
e.g. resize:800x_;format:avif;quality:60
e.g. resize:1600x_;overlay:3f2a9c1e-7b4d-4e8a-9c6f-1d2e3f4a5b6c~width:15pc~position:bottom-right~x:24~y:24~opacity:85
e.g. text:%C2%A9%20Jane%20Doe~size:4pc~color:white~background:hex(00000080)~padding:8~position:bottom-left~x:16~y:16
e.g. resize:1200x600~focus:70pc,30pc;format:auto;quality:80
e.g. resize:1600x_~upscale:false;format:auto
e.g. trim;pad:24~background:white;resize:600x600~fit:contain~background:white
e.g. resize:300x_;format:json
e.g. palette~colors:4
e.g. crop:100pcx20pc~position:top;palette:css~prefix:hero
e.g. resizeAR:4x3~fit:contain~background:white;pad:16;border:1~color:hex(ddd)
downloadquerystringAdd ?download to send the file as an attachment so browsers save it. download=false turns it off.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The image. Content-Type is the output format. With format:json, a JSON description of the image instead; with palette, its colours as JSON (a Palette) or, with palette:css, a stylesheet.
image/*, text/css, application/json
400The transform is not valid, the image is too large to transform, or an overlay is not an image file of this app (JSON, error is invalid_transform), or the id is not valid or the file could not be read (plain text).
application/json, text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that label.
text/plain
422A palette was asked for a file that is not a JPEG, PNG, WebP, BMP or TIFF image. error is unsupported_image.
application/json
500The image could not be transformed. error is transform_failed or internal_error.
application/json
GET/images/{id}DEPRECATED

Get an image, optionally transformed

Legacy alias of /images/get/{id}. Serves an image, running the transforms in the transform query parameter in order. Results are cached per transform chain. A transform that does not parse, or would make the image too large, is answered with 400 and a JSON body saying what is wrong. Files that are not JPEG, PNG, WebP, BMP or TIFF (GIF, SVG, PDF...) are served unchanged. JPEG orientation from EXIF is applied, and transformed output carries no metadata. With format:auto the response varies on Accept and says so in Vary. Animated GIF and WebP are served unchanged. See the transform parameter for the grammar.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
transformquerystringTransforms joined by ; and run in order, each written name:value~option:value. At most 20 transforms and 2048 characters. Size and shape: resize:WxH (_ leaves a side free; options ~fit:cover|contain|fill|inside|outside, ~position:top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right, ~background:COLOUR, ~format:FORMAT, ~focus:X,Y to keep a point in view with fit cover, ~upscale:false to never make the image bigger than its source), resizeAR:WxH (crop or pad to an aspect ratio; same options as resize except focus), crop:WxH (sizes in px or 50pc; @X,Y places the centre of the crop, or ~position: anchors it), smartCrop:WxH (crops to the most detailed part of the image), rotate:DEGREES (clockwise, ~background:COLOUR), flip:x|y|xy, flop, radius:PX|max (rounded corners or a circle, ~background:), pad:ALL|V,H|T,R,B,L (~background:), border:PX (~color:), trim or trim:0-100 (cuts away a border of one colour, the top-left pixel's unless ~color: is given; the number is the tolerance, default 10), dpr:N (multiplies every pixel size, 0.1 to 5). Look: blur:0-100, sharpen or sharpen:0-10, grayscale, saturate:N (0 grey, 1 unchanged, up to 10), brightness:-100-100, contrast:-100-100, hue:DEGREES, gamma:0.1-10, sepia or sepia:0-100, tint:COLOUR (alpha sets strength), opacity:0-100, pixelate:1-200, invert. Layers: overlay:FILE_ID draws another image file of the same app on top (~width: and ~height: in px or pc of the image; one keeps its shape, both fit it inside the box; ~transform:(CHAIN) runs transforms on the overlay first). text:TEXT writes text, URL-encoded inside the transform (so encoded twice in the URL: %2520 for a space), up to 500 characters (~font:sans|sans-bold|sans-italic|mono|mono-bold, ~size:PX|Npc of the image height (default 32), ~color:, ~background: for a box, ~padding:PX, ~wrap:PX|Npc, ~align:left|center|right). Both take ~position: (default center), ~x: and ~y: (in from that edge, px or pc, may be negative), ~opacity:0-100, ~rotate:DEGREES and ~tile:true with ~gap: to repeat the layer as a pattern. At most 5 layers. An overlay must be a file of the same app (anything else is a 400 invalid_transform), an image of at most 25 MB; if it needs a signed URL, so does this request, even for a public image. Output: format:auto|avif|webp|jpeg|png|tiff|bmp|json (auto picks AVIF, then WebP, then the source format, from what Accept allows; images over 16 megapixels are sent as WebP instead of AVIF; json answers with the image's size instead of the image), quality:1-100 (the same scale for JPEG, WebP and AVIF), lossless (lossless WebP or AVIF; auto keeps lossless chains on WebP), background:COLOUR (the default for later transforms that leave empty space), strip (re-encode without metadata), palette or palette:json|css (the image's main colours instead of the image, see the Palette schema; ~colors:0-16, default 6, and for CSS ~prefix:NAME). Whichever of format and palette comes last decides the output. A transform's options can follow its name when its main value is left out, as in trim~color:white. Numbers past a limit are clamped (resize to 4000px, blur to 100...). Colours are hex(RGB), hex(RRGGBB), hex(RRGGBBAA), rgb(R,G,B), rgba(R,G,B,A) or a CSS name. Empty space is transparent in PNG, WebP, AVIF and TIFF and white in JPEG and BMP unless a background is given.
e.g. resize:300x_~fit:cover;format:webp;quality:75
e.g. resize:200x200~fit:contain~background:hex(fff)
e.g. smartCrop:96x96;radius:max;dpr:2;format:auto
e.g. resize:800x_;format:avif;quality:60
e.g. resize:1600x_;overlay:3f2a9c1e-7b4d-4e8a-9c6f-1d2e3f4a5b6c~width:15pc~position:bottom-right~x:24~y:24~opacity:85
e.g. text:%C2%A9%20Jane%20Doe~size:4pc~color:white~background:hex(00000080)~padding:8~position:bottom-left~x:16~y:16
e.g. resize:1200x600~focus:70pc,30pc;format:auto;quality:80
e.g. resize:1600x_~upscale:false;format:auto
e.g. trim;pad:24~background:white;resize:600x600~fit:contain~background:white
e.g. resize:300x_;format:json
e.g. palette~colors:4
e.g. crop:100pcx20pc~position:top;palette:css~prefix:hero
e.g. resizeAR:4x3~fit:contain~background:white;pad:16;border:1~color:hex(ddd)
downloadquerystringAdd ?download to send the file as an attachment so browsers save it. download=false turns it off.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The image. Content-Type is the output format. With format:json, a JSON description of the image instead; with palette, its colours as JSON (a Palette) or, with palette:css, a stylesheet.
image/*, text/css, application/json
400The transform is not valid, the image is too large to transform, or an overlay is not an image file of this app (JSON, error is invalid_transform), or the id is not valid or the file could not be read (plain text).
application/json, text/plain
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No file with that label.
text/plain
422A palette was asked for a file that is not a JPEG, PNG, WebP, BMP or TIFF image. error is unsupported_image.
application/json
500The image could not be transformed. error is transform_failed or internal_error.
application/json

Videos

Upload video, read processing state and stream it.

POST/videos/upload

Upload a video

The file's content type must be video/*. Encoding happens in the background: poll /videos/{id}/data until extractionStatus finishes. Not available with the demo key.

Authorization: public key or signed token

Request body

multipart/form-data
file *string (binary)The video.
data *stringA JSON string.

Responses

200The new video. This response is not wrapped in data.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/data

Get a video's processing state and renditions

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The video.
application/json
400The id is not a valid video id.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No such video exists.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/info

Get a video's basic details

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The video. Not wrapped in data.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500The id is not valid or no such video exists.
application/json
GET/videos/{id}/player-config

Get the player branding for a video

The app's player branding with the video's own on top, ready for a player: colours, the logo as an image URL, every control's switch, a download URL for the original when downloads are on, and the autoplay, muted and loop defaults. <fileboy-player branding> and the watch and embed pages read it. A video with no branding gets the defaults (no colours or logo, every control but download). In an app that requires signed reads it needs the video's signature like the other video routes, and the logo and download URLs come back signed to expire with it. Cached for at most a minute, so dashboard changes show quickly.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The resolved branding.
application/json
400The id is not a valid video id.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No such video exists.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/manifest

Get the streaming manifest

An HLS (application/x-mpegURL) or DASH (application/dash+xml) manifest for players. Each GET counts as a play. type=auto picks DASH for Chrome and HLS for everything else.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
typequery"auto" | "hls" | "dash"
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The manifest. Range requests get 206.
application/x-mpegURL, application/dash+xml
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500Invalid type or id, no such video, or the video is still processing.
application/json
HEAD/videos/{id}/manifest

Check the streaming manifest

Same as the GET, without the body and without counting a play.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
typequery"auto" | "hls" | "dash"
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200Headers only.
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/hls-sub-manifest

Get one rendition's HLS playlist

Referenced by the main HLS manifest. Players follow it automatically.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
videoFileId *querystringA rendition's id from videoFiles in the video data.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200An HLS media playlist.
application/x-mpegURL
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500An error. error is a short code and message says what went wrong.
application/json
HEAD/videos/{id}/hls-sub-manifest

Check one rendition's HLS playlist

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
videoFileId *querystring
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200Headers only.
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/file

Get one encoded rendition

Referenced by the manifests. Supports Range requests.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
file *querystringThe rendition's file name, as used in the manifest.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The bytes.
*/*
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/poster

Get a video's poster image

The custom poster if one was uploaded, otherwise the generated frame.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The image.
image/*
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500No such video, or it has no poster yet.
application/json
POST/videos/{id}/poster/upload

Upload a custom poster

The content type must be image/*. Not available with the demo key.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.

Request body

multipart/form-data
file *string (binary)

Responses

200The stored image file.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json
POST/videos/{id}/transcripts/upload

Attach a transcript

The content type must be text/* (WebVTT or plain text). Not available with the demo key.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.

Request body

multipart/form-data
file *string (binary)The transcript.
data *stringA JSON string.

Responses

200The new transcript.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/thumbnails.vtt

Get a video's seek-preview thumbnails as WebVTT

One cue per frame, each pointing at its region of a sprite sheet with a media fragment (.../thumbnails/0.jpg?v=...#xywh=x,y,w,h). The format the Fileboy player, Plyr and most other players read for previews over the progress bar. Sheet URLs are absolute and carry this request's signature on, so in an app that requires signed reads sign this URL (or add signVideo's query) and the player can follow the rest. Up to 100 frames: one a second for videos up to 100 seconds, spread evenly over longer ones.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The thumbnails track.
text/vtt
400The id is not a valid video id.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No such video (video_not_found), or its thumbnails are not made yet, being made, or failed (thumbnails_not_found). See thumbnails.status in the video's data.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/thumbnails.json

Get a video's seek-preview thumbnails as a JSON storyboard

The same thumbnails as the WebVTT, for players that would rather not parse it: the tile size, the sheets and every tile's time range and position. URLs carry this request's signature on.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The storyboard.
application/json
400The id is not a valid video id.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No such video, or its thumbnails are not ready (thumbnails_not_found).
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/thumbnails/{sheet}.jpg

Get a sprite sheet of a video's seek-preview thumbnails

A JPEG grid of frames, 10 to a row. The VTT and JSON storyboard link to these with a v parameter that changes when the thumbnails are remade, so they can be cached for long.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
sheet *pathintegerThe sheet's number, from 0.
vquerystringCache key the VTT and JSON add. Ignored by the server.
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The sheet.
image/jpeg
400The id is not a valid video id.
application/json
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
404No such video or sheet, or the thumbnails are not ready.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/videos/{id}/transcripts/{transcriptId}

Get a transcript

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.
transcriptId *pathstring (uuid)
fb_expqueryinteger (int64)Unix time in seconds after which a signed URL stops working (30 seconds of leeway for clock differences). Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated).
fb_sigquerystringThe signature of a signed URL. Only used for reads that need a signature (apps that require signed reads, files whose read permission is authenticated), ignored otherwise.
fb_ipquerystringAn IP address or CIDR range the request must come from. Part of the signature, so it cannot be added or removed afterwards.

Responses

200The transcript text.
text/*
401The app requires signed reads, or the file's read permission is authenticated, and the request has no signature. In an app that requires signed reads the same answer is given whether or not the file exists.
application/json
403The signature is wrong (signature_invalid: tampered, for another file, transform or filename, or made with another key), has expired (signature_expired) or the request comes from an address the URL is not valid for (ip_not_allowed).
application/json
500No such video or transcript.
application/json

Management

List, search, update and delete your own files, videos and labels, and change whether reads need signed URLs, from your server. Needs your private key.

GET/files

List your files

Your app's files, newest first by default. Needs a token signed with your private key. Images Fileboy generates when resizing, and the parts of videos, are not listed. Filters combine with AND.

Authorization: public key or signed token

Parameters

NameInTypeDescription
limitqueryintegerPage size, 1 to 100.
cursorquerystringThe nextCursor of the previous page. Use it with the same filters and sort. Paging is stable: files added or deleted while you page are never skipped or repeated.
sortquery"createdAt" | "name" | "fileSize"
orderquery"asc" | "desc"Defaults to desc, except for sort=name which defaults to asc.
createdBeforequerystring (date-time)Only items created before this date or time (ISO 8601).
createdAfterquerystring (date-time)Only items created after this date or time (ISO 8601).
labelquerystringOnly the file this label points at.
mimequerystringOnly files whose type starts with this, like image/ or application/pdf.
namequerystringOnly files whose name contains this text, ignoring case.
hashquerystringOnly files with this SHA-1 hash.
metadataqueryMetadataOnly files whose metadata contains these pairs. Send metadata[key]=value once per pair (up to 20), or one JSON object like {"orderId":"42"}.
folderIdquerystring (uuid) | stringOnly files directly in this folder, or root for files in no folder. Without a folder filter every file is listed, whatever folder it is in. 404 if there is no such folder.
folderPathquerystringLike folderId, by path: /products/shoes, compared ignoring case. / is the root. Send folderId or folderPath, not both.
recursivequerybooleanWith folderId or folderPath, include the files in its subfolders too. folderId=root&recursive=true is every file.

Responses

200One page of files.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
POST/files/delete

Delete several files

Deletes up to 100 files in one request, with their stored data and cached image copies. Ids that are unknown, belong to another app or are already deleted are listed in notFound and are not an error, so the same request can be repeated safely. A file whose stored data cannot be removed stays in place and is listed in failed: send it again. Sends one file.deleted webhook per deleted file.

Authorization: public key or signed token

Request body

application/json
ids *string (uuid)[]

Responses

200What happened to each id.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
PATCH/files/{id}

Update a file

Change a file's name, type, metadata, labels, folder or share page. Only the fields you send change. metadata is merged into the existing metadata: keys you send are set, a null value removes a key and other keys stay. Send replaceMetadata: true to make metadata the complete new metadata instead. A label points at one file, so adding a label that is on another file moves it here. The id can also be PUBLIC_KEY+LABEL. folderId (null for the root) or folderPath moves the file to a folder; folderPath creates missing folders. sharePage turns the file's share page (https://fileboy.io/f/{id}) on or off, see getFileShare. The stored bytes and the file's URLs never change.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo

Request body

application/json
namestring
mimestring
metadataobjectPairs to set. A null value removes the key. Up to 100 keys, keys up to 128 characters, values up to 4096. The stored metadata is at most 16 KB.
replaceMetadatabooleanMake metadata the complete new metadata instead of changes to the old. Values cannot be null.
labelsobject
folderIdstring | nullMove the file to this folder, or to the root with null.
folderPathstringMove the file to the folder at this path, creating missing folders. / is the root. Send folderId or folderPath, not both.
sharePagebooleanTurn the file's share page on or off. A page that is on still follows the file's read access.

Responses

200The file as it is now.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
DELETE/files/{id}

Delete a file

Removes the file, its stored data and any cached image copies. Sends a file.deleted webhook. Answers 404 if there is no such file, which includes a file that was already deleted and a file of another app, so a repeated delete can treat 404 as done. If storage cannot be reached the answer is 500, nothing is deleted and the request can be repeated. The id can also be PUBLIC_KEY+LABEL.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo

Responses

204Deleted.
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/files/{id}/exif

Get a photo's EXIF data

The camera, lens, exposure, date taken, orientation, GPS position, colour profile and the rest of the EXIF, IPTC and XMP metadata of an image, read from JPEG, PNG, WebP, TIFF (and DNG) and HEIF/HEIC/AVIF files. fields is the normalised, typed view and raw every tag read. It is read when the image is uploaded; an image uploaded before that is read the first time it is asked for. It includes personal data (the GPS position, place names, serial numbers and the camera owner's name), so it needs a token signed with your private key: a public key, an access token or a signed read URL is refused, and no public route ever carries it. personal=false leaves the personal data out. Files that are not images answer with status: "unsupported". The id can also be PUBLIC_KEY+LABEL.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
personalquery"true" | "false"false leaves out the GPS position, place names, serial numbers and the camera owner's name, from fields and raw.

Responses

200The metadata.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
502exif_read_failed: an image never read before could not be fetched from storage. Try again.
application/json
GET/files/{id}/palette

Get an image's colour palette

The image's dominant colour, its main colours with their share of the image, the named swatches (vibrant, muted and their dark and light versions) and a readable text colour for each. It is worked out at upload; for images uploaded before then it is worked out on the first request and stored. The same palette is served on the image routes with the palette transform, which follows the image's read access instead of needing the private key. {id} can be PUBLIC_KEY+label.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstringA file id (UUID), or PUBLIC_KEY+LABEL to address a labelled file.
e.g. 2a860257-ecf9-424a-846e-00ab68e2fd58
e.g. YOUR_PUBLIC_KEY+logo
colorsqueryintegerHow many main colours to list. The dominant colour and swatches are always included.

Responses

200The palette.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
422The file is not a JPEG, PNG, WebP, BMP or TIFF image. error is unsupported_image.
application/json
500An error. error is a short code and message says what went wrong.
application/json
GET/labels

List labels

Your app's labels, by name. A label is a name that points at one file, so you can use PUBLIC_KEY+LABEL in place of a file id.

Authorization: public key or signed token

Responses

200All labels.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
POST/labels

Create a label

Label names are 1 to 100 characters with no spaces and none of - + / \ ? # % &. Optionally point it at a file straight away. Answers 409 if the name is taken.

Authorization: public key or signed token

Request body

application/json
name *string
fileIdstring | null

Responses

201The new label.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404fileId is not one of your files.
application/json
409An error. error is a short code and message says what went wrong.
application/json
DELETE/labels/{name}

Delete a label

Removes the label, not the file it points at. 404 if there is no such label.

Authorization: public key or signed token

Parameters

NameInTypeDescription
name *pathstring

Responses

204Deleted.
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
GET/usage

Get your app's usage

How many files and videos the app has and how many bytes it stores (originals, image copies, video renditions, posters and transcripts), with the limits set on the app. Transfer is not reported.

Authorization: public key or signed token

Responses

200Current usage.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
GET/usage/alerts

Get your usage alert settings and this month's alerts

When the app reaches a share of a plan limit (80% and 100% unless you change it) Fileboy emails the app's members and any extra recipients, shows a banner in the dashboard and sends a usage.threshold_reached webhook. Each threshold fires at most once a month (calendar months in UTC) per limit, and every threshold can fire again from the 1st. Usage is checked every few minutes. Files, videos and storage can alert; transfer is not measured per app yet.

Authorization: public key or signed token

Responses

200The settings, the current period and the alerts recorded in it.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
PATCH/usage/alerts

Change your usage alert settings

Only the fields you send change, and metrics only changes the limits it names. Thresholds are sorted and duplicates removed; email addresses are lower cased. Answers 400 validation_error for a value that is not allowed, invalid_json for an unknown field and empty_update when nothing is sent.

Authorization: public key or signed token

Request body

application/json
enabledboolean
thresholdsUsageAlertThresholds
metricsobject
emailMembersboolean
recipientsUsageAlertRecipients
webhookboolean

Responses

200The new settings, the current period and its alerts.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
GET/usage/storage

Get your app's storage breakdown

What the app stores by kind, its biggest files and videos, and one total a day. Every stored file counts once, under one kind, so the kinds add up to storageBytes, the same total GET /usage reports and the app's storage limit is measured against. Daily totals are recorded just after midnight UTC and kept for 400 days; days before tracking started are missing rather than filled in.

Authorization: public key or signed token

Parameters

NameInTypeDescription
daysqueryintegerHow many days of daily totals to return.
topqueryintegerHow many of the biggest files and videos to list.

Responses

200The storage breakdown.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
GET/app/settings

Get the app's read access, photo location and player branding settings

Whether reads of files, images and videos need a signed URL (off by default: nothing is private until you turn it on), whether GPS positions are removed from photos at upload (off by default), and the player branding every video starts with.

Authorization: public key or signed token

Responses

200The settings.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
PATCH/app/settings

Require signed URLs to read, remove photo locations at upload, or set the player branding

Send any of the settings. With requireSignedReads: true, every unsigned link to the app's files, images and videos stops working at once (401 signature_required) until it is signed with the private key. Applies to every route that reads a file, image or video, including video manifests, segments, posters and captions. Turning it off makes every link public again. With stripLocationOnUpload: true, the GPS position is removed from the EXIF and XMP data of every image uploaded from then on, before it is stored. The file is not re-encoded and nothing else in it changes; its hash is of the stored bytes. Files already uploaded are not changed. playerBranding replaces the app's player branding (null clears it). It applies to every video that does not set the same field itself, on the watch and embed pages and in <fileboy-player branding>. Nothing changes unless everything sent is valid.

Authorization: public key or signed token

Request body

application/json
requireSignedReadsboolean
stripLocationOnUploadboolean
playerBrandingPlayerBranding | null

Responses

200The settings as they are now.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
GET/videos

List your videos

Your app's videos, newest first by default. Every video has its description, tags and metadata. Needs a token signed with your private key.

Authorization: public key or signed token

Parameters

NameInTypeDescription
limitqueryintegerPage size, 1 to 100.
cursorquerystringThe nextCursor of the previous page. Use it with the same filters and sort. Paging is stable: files added or deleted while you page are never skipped or repeated.
sortquery"createdAt" | "name"
orderquery"asc" | "desc"Defaults to desc, except for sort=name which defaults to asc.
createdBeforequerystring (date-time)Only items created before this date or time (ISO 8601).
createdAfterquerystring (date-time)Only items created after this date or time (ISO 8601).
namequerystringOnly videos whose name contains this text, ignoring case.
statusquery"pending" | "processing" | "ready" | "failed"
tagsquerystring[]Only videos that have every one of these tags (up to 20). Comma-separated, tags=launch,2026, or repeated, tags=launch&tags=2026. Tags are case-sensitive.
metadataqueryMetadataOnly videos whose metadata contains these pairs. Send metadata[key]=value once per pair (up to 20), or one JSON object like {"orderId":"42"}.

Responses

200One page of videos.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
PATCH/videos/{id}

Change a video's name, description, tags, metadata or player branding

Only the fields you send change, and a request that would break a limit, or has an invalid field, changes nothing. description is public: the watch page and /videos/{id}/data show it. tags and metadata are private: they are only in management responses and webhooks. tags is a list that replaces the tags, null to remove them all, or {"add": [...], "remove": [...]} to change some. metadata is merged like a file's: a null value removes a key, replaceMetadata: true replaces it all. playerBranding is this video's own branding on top of the app's: each field it sets replaces the app's, controls merge control by control, and null makes the video follow the app again.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.

Request body

application/json
namestring
descriptionstring | nullPlain text, trimmed, line breaks kept. No control characters other than tabs and line breaks. "" or null removes it.
tagsVideoTags | null | objectA list replaces the tags, null removes them all, an object changes some.
metadataobjectPairs to set. A null value removes the key. A video can have up to 100 keys of 1 to 128 characters, with no [, ] or control characters, and values up to 4096 characters. The stored metadata is at most 16 KB.
replaceMetadatabooleanMake metadata the complete new metadata instead of changes to the old. Values cannot be null.
playerBrandingPlayerBranding | nullThis video's own player branding, on top of the app's. null makes the video follow the app again.

Responses

200The video as it is now.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
DELETE/videos/{id}

Delete a video

Removes the original, the posters, the transcripts and every rendition from storage, then the video. Sends a video.deleted webhook. 404 if there is no such video or it was already deleted. If storage cannot be reached the answer is 500: the video is still listed, with whatever was not yet removed, and the request can be repeated to finish.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)The video's id.

Responses

204Deleted.
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json

Folders

Organise your files in nested folders, from your server. Folders are never part of a file's URL, so renaming or moving one changes no links. Files with no folder are at the root. Needs your private key.

POST/files/move

Move files to a folder

Puts up to 100 files in one folder, or at the root with folderId: null. folderPath creates any missing folders on the path. Ids that are unknown or belong to another app are listed in notFound, so the request can be repeated safely. Moving never changes a file's URL.

Authorization: public key or signed token

Request body

application/json
ids *string (uuid)[]
folderIdstring | nullThe folder, or null for the root.
folderPathstringThe folder's path, like /products/shoes. / is the root.

Responses

200What happened to each id.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404The folder does not exist.
application/json
GET/folders

List folders

Your app's folders, by name. With parentId only the folders directly inside one folder (root for the top level), otherwise every folder. path looks up one folder by its path and returns it, or an empty list.

Authorization: public key or signed token

Parameters

NameInTypeDescription
limitqueryintegerPage size, 1 to 100.
cursorquerystringThe nextCursor of the previous page. Use it with the same filters and sort. Paging is stable: files added or deleted while you page are never skipped or repeated.
sortquery"name" | "createdAt"
orderquery"asc" | "desc"Defaults to desc, except for sort=name which defaults to asc.
parentIdquerystring (uuid) | stringOnly the folders directly inside this folder, or root for the top level.
namequerystringOnly folders whose name contains this text, ignoring case.
pathquerystringFind the folder at this path, like /products/shoes, ignoring case.

Responses

200One page of folders.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404parentId is not one of your folders.
application/json
POST/folders

Create a folder

Send a name, and a parentId to make it inside another folder: 201, or 409 folder_exists if that folder already has one of the same name, ignoring case. Or send a path to make every missing folder on it, like mkdir -p: 201 if anything was made, 200 if it all existed. Names are 1 to 255 characters with no / or \, and cannot be . or ... Folders nest up to 20 deep and an app can have up to 10,000.

Authorization: public key or signed token

Request body

application/json
namestring
parentIdstring | null
pathstring

Responses

200Every folder on path already existed. The last one.
application/json
201The new folder (with path, the last folder on it).
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403No private key, or folder_limit_reached.
application/json
404parentId is not one of your folders.
application/json
409An error. error is a short code and message says what went wrong.
application/json
GET/folders/{id}

Get a folder

One folder, with the folders above it in ancestors for breadcrumbs.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)A folder id.

Responses

200The folder.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
PATCH/folders/{id}

Rename or move a folder

Send name to rename it and parentId to move it, with what is inside, into another folder (null for the root). A folder cannot move into itself or one of its subfolders (400 invalid_move), and the destination cannot already have a folder of the same name (409 folder_exists). No file URLs change.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)A folder id.

Request body

application/json
namestring
parentIdstring | null

Responses

200The folder as it is now.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
409An error. error is a short code and message says what went wrong.
application/json
DELETE/folders/{id}

Delete a folder

contents says what happens to what is inside. refuse (the default) only deletes an empty folder and answers 409 folder_not_empty otherwise. moveToParent moves its files and subfolders up into its parent (the root for a top-level folder), and answers 409 folder_exists if a subfolder's name is taken there. delete deletes its subfolders and every file in them, stored data included, with a file.deleted webhook for each: up to 1000 files, more is 409 folder_too_large. If storage cannot be reached, the files already deleted stay deleted, the folder is kept and the request can be repeated.

Authorization: public key or signed token

Parameters

NameInTypeDescription
id *pathstring (uuid)A folder id.
contentsquery"refuse" | "moveToParent" | "delete"

Responses

200What was deleted and moved.
application/json
400An error. error is a short code and message says what went wrong.
application/json
401No key was sent.
application/json
403An error. error is a short code and message says what went wrong.
application/json
404An error. error is a short code and message says what went wrong.
application/json
409An error. error is a short code and message says what went wrong.
application/json
500An error. error is a short code and message says what went wrong.
application/json

Links to a file or an image transform that stop working at a time you choose and can be revoked early. Making, listing and revoking them needs your private key, opening one needs nothing.

Meta

Service status.

GET/

Service banner

Returns the text Fileboy API. Useful as a reachability check.

Authorization: none needed

Responses

200Plain text.
text/plain
hello@fileboy.io

Fileboy

HomeAboutPricingChangelog
© Copyright 2026, CD2 Solutions Ltd.
Terms and ConditionsPrivacy Policy