Documentation

Keys, hosts, and limits

The key a Journey needs, the host the SDKs call, and the limits a client must respect.

Read this once before you put a Journey in your product. It applies to every Journeys SDK and to a client you write yourself.

Keys

A Journey renders with a publishable key (fhq_pk_XXXX). The key belongs to one brand. It is safe in browsers and in shipped mobile apps: every config fetch, every access check, and every captured event is validated on FounderHQ's servers. Never put a secret key (fhq_sk_XXXX) in a Journey.

Create the key in FounderHQ under Settings → API Keys and pick the Journey embed preset. It gives the key exactly two permissions:

PermissionWhat it allows
journeys:read_publishedRead the published config of a Journey in the key's brand.
journeys:captureRecord step events, answers, and completions.

A Journey embed key needs at least one allowed origin. FounderHQ refuses to create it without one, and refuses a request whose Origin is not on the list. Add the origins your pages are served from — scheme, host, and port, with no path:

https://your-domain.com
https://www.your-domain.com
http://localhost:3000

Native SDKs send no Origin header, so the list does not gate them.

Scope the key to one brand, and to specific Journeys when you can. Do not reuse one key across brands: a key can only read Journeys in the brand it was created for, so a shared key fails the moment you add a second brand.

Where the SDKs connect

Every Journeys SDK talks to https://app.getfounderhq.com, the FounderHQ app host. Analytics use a separate ingest host. You do not configure the production Journey host.

Every SDK takes a base-URL override for local development, and each one guards it:

SDKOptionWhat it accepts
@founderhq/journeys (web)baseUrlA localhost address only. Every other value silently falls back to https://app.getfounderhq.com.
React Native, iOS, AndroidbaseUrl / baseURLAny HTTPS origin. Plain http:// only for a local host, and an invalid value throws.

On the web that fallback means a mistyped baseUrl cannot quietly send responses somewhere else. It also means you cannot point a web embed at a proxy of your own.

Limits and reliability

RuleValue
Events per capture batch50. A larger batch is refused with 400.
Request body64 KiB for a capture or a completion. A larger one is refused with 413.
Over budget429 with a Retry-After header, in whole seconds. The public link and the embed always enforce this: 60 requests a minute for each visitor and Journey.

Budgets are counted per organization. Brands, keys, Journeys, and app installations all spend from the same allowance, so adding a key does not add capacity.

If you write your own client instead of using an SDK:

  • Honor Retry-After on a 429. Do not retry sooner, and do not retry in a tight loop.
  • Give every event a stable id and reuse it on a retry. FounderHQ de-duplicates by event ID, so a replayed batch is safe.
  • Send one clientSessionId for the whole presentation, and keep it on events you deliver late.
  • You may send an X-FounderHQ-Installation-Id header on the load calls (prepare, the published-config GET, and validate). It identifies one app installation for per-client fairness. It is optional, allowed through CORS, and no shipped SDK sends it yet.

AI agent or LLM? Read this page as markdown

On this page