Skip to content
Fluxer API

GIFs

A GIF is one animated media item held by the deployment’s active GIF provider. Fluxer stores none of them, so every route on this page reads the provider live and returns provider URLs beside signed Media Proxy URLs.

Every route requires a session credential. A bot token and an OAuth2 bearer credential are both refused with 403 ACCESS_DENIED. Save meme from URL saves a result into the account’s own collection.

klipy is the only provider name a deployment binds. Get instance discovery publishes it as the GIF provider object. An instance that has bound no provider key refuses every route on this page with 403 FEATURE_TEMPORARILY_DISABLED. That same key drives gif_enabled in service availability, a flag an operator can also set by hand, so a client that reads gif_enabled as true can still receive the 403.

A provider outage, a request that outlives its deadline, and an unreadable provider payload all surface as 503 SERVICE_UNAVAILABLE. The deadline is 12 seconds everywhere except Register a GIF share, which uses 3 seconds. An operator can change both.

Every route takes an optional locale drawn from the supported locale registry, in the query string on the four GET routes and in the body of Register a GIF share. It defaults to en-US. A tag outside the registry fails with 400 INVALID_FORM_BODY.

Fluxer also derives a two-letter country from the requesting address by geolocation, and uses US when geolocation resolves none. No route accepts the country as a parameter, so a client cannot override it. Get GIF search suggestions is the one route that ignores it.

Every response under /gifs, /tenor, and /klipy has these three headers, including error responses and responses to a path no route claims. The three values repeat the GIF provider object, so a client follows a provider change without refetching /.well-known/fluxer.

FieldTypeDescription
X-Fluxer-GIF-Provider1stringThe machine name of the active provider, which is klipy on every deployment today
X-Fluxer-GIF-Provider-Display-Name1stringThe provider name a client displays
X-Fluxer-GIF-Provider-Attribution-Required1stringThe literal true or false, stating whether a client shows the provider attribution mark

1 All three are absent together while the instance has bound no provider key, which is the same condition that answers 403 FEATURE_TEMPORARILY_DISABLED

Fluxer caches one answer for each combination of operation, locale, country, and query. Past the refresh bound a request still receives the stored answer, and past the discard bound it waits for a fresh answer.

AnswerRefresh boundDiscard bound
Search results30 seconds5 minutes
Search suggestions1 minute10 minutes
Featured GIFs and trending GIFs5 minutes30 minutes
Featured categories24 hours48 hours

A deployment can configure a further cache in front of those bounds. Neither cache is keyed by the caller, so two accounts sending the same query in the same country receive the same answer. No route on this page invalidates a cached answer.

A GIF object is one media item the active provider owns. Every URL in it resolves to bytes the provider hosts.

FieldTypeDescription
id1stringThe provider-stable identifier of the GIF
slug1stringThe canonical slug used to share the GIF or resolve it again
providerstringThe name of the provider that produced the GIF (1-32 characters)
titlestringThe title the provider gives the GIF
urlstringThe provider page URL for the GIF
src2stringThe direct media URL of the format the server chose
proxy_src2stringThe Media Proxy URL of that same format
width2integerThe width of the chosen format in pixels
height2integerThe height of the chosen format in pixels
media3map[string, GIF media format object]The formats keyed by GIF media format name
placeholder?4?stringThe compact thumbhash placeholder rendered while the GIF loads

1 The active provider writes the same slug into both, so id is the value Register a GIF share takes

2 Copied from the webm entry of media when the provider returned one, and from the first entry it returned otherwise

3 Empty when no format the provider returned could be proxied. No key is guaranteed, so a client walks a priority list

4 The active provider emits none, so the field is absent from every GIF these routes return. Resolve GIF URLs is the operation that produces one

A GIF has no snowflake and no creation timestamp. id is the provider’s own identifier, so it does not sort by time, and no other Fluxer route resolves it.

{
"id": "goat-plays-banjo-4",
"slug": "goat-plays-banjo-4",
"provider": "klipy",
"title": "Goat Plays Banjo",
"url": "https://klipy.com/gifs/goat-plays-banjo-4",
"src": "https://static.example.com/goat-plays-banjo.webm",
"proxy_src": "https://media.example.com/external/9f21c0/goat-plays-banjo.webm",
"width": 220,
"height": 229,
"media": {
"webm": {
"src": "https://static.example.com/goat-plays-banjo.webm",
"proxy_src": "https://media.example.com/external/9f21c0/goat-plays-banjo.webm",
"width": 220,
"height": 229
},
"tinygif": {
"src": "https://static.example.com/goat-plays-banjo-tiny.gif",
"proxy_src": "https://media.example.com/external/4ad117/goat-plays-banjo-tiny.gif",
"width": 137,
"height": 90
}
}
}

A GIF category object pairs a category search term with a preview GIF for that term.

FieldTypeDescription
namestringThe search term the category stands for, translated for the requested locale
src1stringThe direct media URL of the preview GIF
proxy_src1stringThe Media Proxy URL of the preview GIF
gif?GIF objectThe preview GIF, or null when the preview lookup returned nothing

1 Copied from the same field of gif, and the empty string when gif is null

To open the category, a client sends name as the q of Search GIFs.

Two vendor-named prefixes serve the same five handlers as /gifs. Each answers exactly as its successor does and has the same provider headers.

MethodDeprecated pathSuccessor
GET/v1/tenor/searchSearch GIFs
GET/v1/tenor/featuredGet featured GIFs
GET/v1/tenor/trending-gifsGet trending GIFs
GET/v1/tenor/suggestGet GIF search suggestions
POST/v1/tenor/register-shareRegister a GIF share
GET/v1/klipy/searchSearch GIFs
GET/v1/klipy/featuredGet featured GIFs
GET/v1/klipy/trending-gifsGet trending GIFs
GET/v1/klipy/suggestGet GIF search suggestions
POST/v1/klipy/register-shareRegister a GIF share

A response from one of the ten has three further headers.

FieldTypeDescription
DeprecationstringThe literal value true
LinkstringThe literal value </gifs>; rel="successor-version"
Warning1stringA 299 warning naming the successor prefix

1 The exact value is 299 - "Use /gifs/* instead - these vendor-specific paths are deprecated and will be removed."

The vendor name in the path selects nothing. A request to /v1/tenor/search reaches the same active provider as /v1/gifs/search, and the provider field of every GIF it returns names that provider.

GET/v1/gifs/search

Searches the active provider for GIFs matching a query. Returns at most 50 GIF objects in the order the provider returned them.

FieldTypeDescription
qstringThe search term (1-256 characters)
locale?stringA supported locale, default en-US

Fluxer does not stem, expand, or spell-correct the term. A term that matches nothing returns 200 with an empty array.

StatusBodyCondition
200array[GIF object]Results were returned, possibly as an empty array
400error responseq is absent, empty, or longer than 256 characters, or locale is outside the registry, each returning INVALID_FORM_BODY
403error responseCaller is a bot or presents a bearer credential and the request returns ACCESS_DENIED
403error responseThe account has an outstanding required action and the request returns ACCOUNT_SUSPICIOUS_ACTIVITY
403error responseThe instance has bound no provider key and the request returns FEATURE_TEMPORARILY_DISABLED
503error responseThe provider failed, the request outlived its deadline, or the gifs service answered with a payload the API could not read, each returning SERVICE_UNAVAILABLE

40 requests per 10 seconds for each authenticated user, on the gif:search bucket.

GET/v1/gifs/featured

Returns the provider’s featured GIFs and the category terms offered alongside them.

FieldTypeDescription
locale?stringA supported locale, default en-US
FieldTypeDescription
gifs1array[GIF object]The featured GIFs for the resolved locale and country
categories2array[GIF category object]The category terms offered for the resolved locale

1 At most one entry. Get trending GIFs is the route that returns a full listing

2 At most 50 entries, deduplicated by search term and kept in the order the provider returned them

Fluxer resolves the category list against the country US for every request, whatever country geolocation produced, so two callers in different countries receive the same categories and different gifs. A category whose preview lookup returned nothing is still listed, with gif null and both URLs empty.

StatusBodyCondition
200response bodyFeatured GIFs and categories were returned
400error responselocale is outside the registry and the request returns INVALID_FORM_BODY
403error responseCaller is a bot or presents a bearer credential and the request returns ACCESS_DENIED
403error responseThe account has an outstanding required action and the request returns ACCOUNT_SUSPICIOUS_ACTIVITY
403error responseThe instance has bound no provider key and the request returns FEATURE_TEMPORARILY_DISABLED
503error responseThe provider failed, the request outlived its deadline, or the gifs service answered with a payload the API could not read, each returning SERVICE_UNAVAILABLE

Fluxer fetches both halves in one operation. A failure on either one fails the whole request and returns no partial body.

40 requests per 10 seconds for each authenticated user, on the gif:featured bucket.

GET/v1/gifs/trending

Returns at most 50 trending GIF objects for the resolved locale and country.

FieldTypeDescription
locale?stringA supported locale, default en-US
StatusBodyCondition
200array[GIF object]Trending GIFs were returned, possibly as an empty array
400error responselocale is outside the registry and the request returns INVALID_FORM_BODY
403error responseCaller is a bot or presents a bearer credential and the request returns ACCESS_DENIED
403error responseThe account has an outstanding required action and the request returns ACCOUNT_SUSPICIOUS_ACTIVITY
403error responseThe instance has bound no provider key and the request returns FEATURE_TEMPORARILY_DISABLED
503error responseThe provider failed, the request outlived its deadline, or the gifs service answered with a payload the API could not read, each returning SERVICE_UNAVAILABLE

Trending and featured read the same provider listing, trending for 50 results and featured for one. The two are cached separately, so the single GIF in a featured response can be older than the first entry here.

40 requests per 10 seconds for each authenticated user, on the gif:trending bucket.

GET/v1/gifs/suggest

Returns search-term suggestions for a partial query, as an array of strings.

FieldTypeDescription
qstringThe partial search term (1-256 characters)
locale?stringA supported locale, default en-US

This route sends no country to the provider. Its answers are keyed by locale and query alone, and do not vary with the requesting address.

StatusBodyCondition
200array[string]Suggestions were returned, possibly as an empty array
400error responseq is absent, empty, or longer than 256 characters, or locale is outside the registry, each returning INVALID_FORM_BODY
403error responseCaller is a bot or presents a bearer credential and the request returns ACCESS_DENIED
403error responseThe account has an outstanding required action and the request returns ACCOUNT_SUSPICIOUS_ACTIVITY
403error responseThe instance has bound no provider key and the request returns FEATURE_TEMPORARILY_DISABLED
503error responseThe provider failed, the request outlived its deadline, or the gifs service answered with a payload the API could not read, each returning SERVICE_UNAVAILABLE

Each suggestion is a term a client sends back as the q of Search GIFs.

40 requests per 10 seconds for each authenticated user, on the gif:suggest bucket.

POST/v1/gifs/register-share

Tells the active provider that the caller is sharing one of its GIFs, and returns 204 with an empty body.

FieldTypeDescription
id1stringThe id of the shared GIF object (1-300 characters)
q?2?stringThe search term that produced the GIF (0-256 characters)
locale?stringA supported locale, default en-US

1 The provider reads it as a slug or a slug-id token. Fluxer does not check it against a GIF it has returned, so an identifier the provider does not recognise fails at the provider

2 An omitted or null value is sent to the provider as the empty string

The deadline on this route is 3 seconds.

StatusBodyCondition
204emptyThe provider accepted the registration
400error responseid is absent, empty, or longer than 300 characters, q is longer than 256 characters, or locale is outside the registry, each returning INVALID_FORM_BODY
403error responseCaller is a bot or presents a bearer credential and the request returns ACCESS_DENIED
403error responseThe account has an outstanding required action and the request returns ACCOUNT_SUSPICIOUS_ACTIVITY
403error responseThe instance has bound no provider key and the request returns FEATURE_TEMPORARILY_DISABLED
503error responseThe provider rejected the registration, the gifs service did not answer within the deadline, or it answered with something other than an acknowledgement, each returning SERVICE_UNAVAILABLE

The registration reaches the provider and changes no Fluxer state, so it emits no Gateway Dispatch and does not add the GIF to the account’s memes.

Fluxer neither caches nor deduplicates the call, so registering the same id twice reaches the provider twice.

60 requests per 10 seconds for each authenticated user, on the gif:register_share bucket.