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:
| Permission | What it allows |
|---|---|
journeys:read_published | Read the published config of a Journey in the key's brand. |
journeys:capture | Record 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:3000Native 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:
| SDK | Option | What it accepts |
|---|---|---|
@founderhq/journeys (web) | baseUrl | A localhost address only. Every other value silently falls back to https://app.getfounderhq.com. |
| React Native, iOS, Android | baseUrl / baseURL | Any 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
| Rule | Value |
|---|---|
| Events per capture batch | 50. A larger batch is refused with 400. |
| Request body | 64 KiB for a capture or a completion. A larger one is refused with 413. |
| Over budget | 429 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-Afteron a429. Do not retry sooner, and do not retry in a tight loop. - Give every event a stable
idand reuse it on a retry. FounderHQ de-duplicates by event ID, so a replayed batch is safe. - Send one
clientSessionIdfor the whole presentation, and keep it on events you deliver late. - You may send an
X-FounderHQ-Installation-Idheader on the load calls (prepare, the published-configGET, andvalidate). It identifies one app installation for per-client fairness. It is optional, allowed through CORS, and no shipped SDK sends it yet.