Skip to content
Fluxer API

Unfurl

Unfurl turns one URL into the preview a message would show for it, as an array of embed objects. It fetches the URL again on every call.

The route is user-only, so a bot token or OAuth2 bearer credential gets 403 ACCESS_DENIED.

The sites below get a dedicated preview. Any other URL gets a preview from its page metadata, or a media embed when it points to an image, video or audio file.

SiteMatched URL
Hacker Newsnews.ycombinator.com/item with an id query parameter
Klipy1klipy.com and www.klipy.com
Tenortenor.com
xkcdxkcd.com
YouTube1youtube.com and its www, m and music hosts, youtube-nocookie.com and www.youtube-nocookie.com, and youtu.be
Wikipediawikipedia.org and its www, en, de, fr, es, it, ja, ru and zh hosts, under /wiki/
BlueskyPost and profile URLs on bsky.app
FxTwitterfxtwitter.com, fixupx.com, twittpr.com, xfixup.com and their subdomains

1 Needs an API key for this site on the instance. Without one, the URL gets the generic preview.

POST/v1/unfurl

Returns the embeds for url. Fluxer only fetches public HTTP and HTTPS addresses, and a fetch fails after five redirects or on a document larger than 8 MiB.

FieldTypeDescription
urlstringThe HTTP or HTTPS URL to preview (1-2048 characters)
StatusBodyCondition
200array[embed object]Resolution finished, possibly with no embed
403error responseACCESS_DENIED for a bot token or OAuth2 bearer credential
502error responseBAD_GATEWAY when the unfurl service returns an error
503error responseSERVICE_UNAVAILABLE when no unfurl service is answering
504error responseGATEWAY_TIMEOUT when the unfurl service doesn't answer within 12 seconds

The rate limit is 10 requests per minute, on the unfurl:debug bucket.

To preview a fediverse post, the unfurl service fetches the post's ActivityPub object. With FLUXER_ACTIVITYPUB_SIGNING_KEY_BASE64 set, it signs those fetches as the instance actor, and the server it fetches from checks the signature against the actor's public key. Without the key, each actor route returns 404 NOT_FOUND.

The actor's ID is the api_public endpoint followed by /activitypub/actor. Its key ID is the actor ID followed by #main-key.

These routes share a rate limit of 60 requests per minute, on the activity_pub:document bucket.

GET/activitypub/actorUnauthenticated

Returns the instance actor as an application/activity+json document of type Application, with its public key in PEM form. Its preferredUsername is the hostname of the api_public endpoint. Responses may be cached for 5 minutes.

StatusBodyCondition
200ActivityPub actor documentRequest signing is on
404error responseNOT_FOUND when request signing is off
503error responseSERVICE_UNAVAILABLE when no unfurl service is answering
GET/activitypub/actor/outboxUnauthenticated

Returns the actor's outbox as an empty OrderedCollection.

StatusBodyCondition
200ActivityPub collection documentRequest signing is on
404error responseNOT_FOUND when request signing is off
503error responseSERVICE_UNAVAILABLE when no unfurl service is answering
POST/activitypub/actor/inboxUnauthenticated

Accepts any activity and discards it.

StatusBodyCondition
202emptyRequest signing is on
404error responseNOT_FOUND when request signing is off
503error responseSERVICE_UNAVAILABLE when no unfurl service is answering
GET/.well-known/webfingerUnauthenticated

Returns an application/jrd+json document whose self link points to the actor. The edge serves this path at the root of the public origin. Responses may be cached for 5 minutes.

FieldTypeDescription
resourcestringThe actor ID, or acct:{hostname}@{host} for the api_public endpoint

For an api_public endpoint of https://chat.example.com/api, the account is acct:chat.example.com@chat.example.com.

StatusBodyCondition
200WebFinger documentresource is the actor
404error responseNOT_FOUND when request signing is off or resource is anything else
503error responseSERVICE_UNAVAILABLE when no unfurl service is answering