Referral programs
Connect the referral or affiliate program you already run — Referalli, Rewardful, PartnerStack, FirstPromoter, Tolt, Impact, or one of your own — and your pages, sign-up and community work with it. Every program is the same provider model; the presets only pre-fill where the vendor's tracking script lives, what its link parameter is called and how its API key is checked.
Connect a program
PUT /orgs/{orgId}/referrals/providers/{provider}:
{
"trackingToken": "pub_123",
"apiKey": "sk_…",
"config": { "landingUrl": "https://acme.com/partners" }
}trackingTokenandapiKeyare write-only: a value sets,nullclears, leaving it out keeps. Reads say onlyhasTrackingToken/hasApiKey.A partner link instead of the API key. If the program issues partner links (Referalli does), send
"partnerLink": {"grantId": "pl_…", "secret": "…"}and leaveapiKeyout. We exchange the grant at the program's token endpoint for a short-lived token on each call, so no long-lived key of yours sits with us. Another vendor names its endpoint withtokenUrl. Write-only like the key; reads answerpartnerLink: {grantId, tokenUrl}. See Partner links we hold.config.landingUrlis where:::referrallinks go.config.refParamsoverrides the parameter names the preset keeps.For
custom:config.scriptSrc(https),tokenAttributeandconnectOrigins.
The older preset spelling referally is accepted and stored as referalli.
What your pages do
Keep the partner's parameter. A reader who lands with
?ref=partner42(or the program's own name for it) keeps it on every link inside your site and on the link to your sign-in page, so the partner is still named when they sign up. Nothing is written to cookies or storage for this.Load the program's script only with consent. The tracking script loads once the reader allows the suite's
referralscategory (a consent platform without it answers asmarketing). Its origin is added to the page's content security policy for you.Link to the program. A
:::referralblock anywhere on a page:
:::referral{label="Join the partner program" campaign="docs"}::::::referalli{…}::: is read as the same block (it is written back as :::referral), so a snippet copied from a referral program's own docs works unchanged.
It links to href if you give one, else to the program's landing URL, with campaign= added, marked rel="sponsored". In the editor it is "Referral link" in the slash menu.
Credit a partner's standing
A program can show a partner's tier in your community without knowing their user id here: PUT /orgs/{orgId}/community/reputation/by-subject/external with ?iss=&sub= (their sign-in subject at your identity provider) and {source, label, value}. A subject who has not joined yet is held (202 pending) and applied when they do. A partner link with community:standing:write may call it.
Webhooks topic.solved, post.created and user.joined carry author: {iss, sub, ext} so a program can match the author to its own records.
Your own partner link on "Powered by"
If you are a Forumulate partner yourself, set general.powered_by_referral_url (Settings → General) to your partner link and the "Published with Forumulate" credit points there instead, marked as sponsored. It is off until you set it.
Showing pages to some readers only
Readers who sign in through your identity provider can carry a principal (partner, customer), roles and personal vars. Map where your IdP puts them with the sign-in provider's claimMap.
settings.audienceon a space —{"principals": ["partner"]}— limits the whole space; a collection'snav.audiencelimits one collection;settings.postingAudiencelimits who may post in each forum category ("*"for all). A reader who does not match gets a 404, as if the page did not exist, and these pages stay out of sitemaps andllms.txt.your-programin a page — code samples included — becomes the reader's own value, with the fallback for everyone else.
Personal values: where they are filled
Where the page is read |
|
|---|---|
The page, signed in | The reader's own |
The page's | The reader's own |
The page and its |
|
|
|
| The template itself, unchanged |
A var with no fallback (YOUR_PROGRAM_ID) becomes a placeholder named after it, YOUR_PROGRAM_ID, in every shared copy — the same convention as YOUR_API_KEY in generated code samples. The raw {{…}} template is never served. A page or .md twin that uses reader vars is answered Cache-Control: private, no-store, so no cache in front of us keeps one reader's values for another.
"Try it" starts from the reader's values. On an API reference page, a signed-in reader's vars prefill the console: a var named apiKey (or api_key, apiToken, accessToken, token) becomes the operation's credential, and any other var fills the parameter of the same name (programId → {programId}; case, _ and - are ignored). Fields the reader has typed in are never overwritten. The values come from the reader's own session (GET /public/orgs/{orgId}/spaces/{spaceId}/viewer → vars, answered only to that reader) and stay in their browser.
In the API
Every operation below is also reachable from the other surfaces without a dedicated command. forumulate api <Operation> calls it from the CLI, the JavaScript SDK has a typed method for each one (the last column names it; the Python and Go SDKs are generated from the same spec), and an agent reaches the organization-scoped ones through the MCP agent server — its api_* family tools, or call_api. Where a CLI command or a hand-made MCP tool exists too, the last column names it. Operation names link to the API reference.
Referrals
Operation | Request | What it does | Shortcuts |
|---|---|---|---|
| List referral program presets |
| |
| List connected referral programs |
| |
| Get a connected referral program |
| |
| Connect or update a referral program |
| |
| Change part of a referral program |
| |
| Disconnect a referral program |
| |
| Check a referral program’s API key |
|
Reputation Subject
Operation | Request | What it does | Shortcuts |
|---|---|---|---|
| Set a subject’s external standing |
| |
| Remove a subject’s external standing |
| |
| List standing waiting for its subject |
|
Viewer
Operation | Request | What it does | Shortcuts |
|---|---|---|---|
| Get the viewer in a space |
| |
| A reader’s access to a space |
|