Skip to main content
One client per site. Build it once, and reuse it for every call to that site.
.env
An unset FETCHSKI_ATTRACT_URL throws SiteConfigurationError naming it; a key that is set but empty throws too, never quietly the public.

Options

string
required
The site’s public origin, https:// and the host the site answers on. A trailing /api/v1 is fine; any other path, a query or credentials throw. A redirect is never followed. Plain http:// reaches only localhost or a private service name, so a key never crosses the internet in the clear.
string
fsk_<site>_<key id>_<secret>, as the site showed it. Leave it out to read as the public. Given but empty (an unset environment variable) throws: never quietly the public.
string
fss_…, when the key signs. With a secret, the client signs every request it can, uploads by their SHA-256. Signing requests lists which requests must be signed.
'none' | 'writes' | 'all'
The key’s signing mode, from its Security tab. Name it only to have the client refuse what the key can’t send before it leaves.
number
default:"15000"
Milliseconds per attempt. A route the site marks as slow carries its own (the larger wins).
number
default:"2"
Extra attempts for a call that failed in a way that is safe to repeat. 0 for none, at most 10.
(call) => void
Called once per attempt with { site, method, path, status, ms }: never a header, query or body. A hook that throws or rejects never changes the call.
A bad option throws SiteConfigurationError when the client is built, saying which option and how to fix it. No request is made.

Many sites, by slug

When your app talks to several sites, keep them in one directory and ask for each by the slug in its key.
An entry’s name must be its key’s own slug, the acme in fsk_acme_…. Anything else throws before any request, naming the right one. forSite() with a slug no site has throws UnknownSite.

Next: calling the API

Arguments, models, lists, ids and uploads.