You receive
Only core’s external id, an opaque UUID. Never a name, email, Keycloak id or app token.
The engagement partner runs the fun part of the membership program: rewards, raffles, games and campaigns. Members meet it as widgets inside the FINNS app, and every point it gives or takes goes through core’s Points API, so there is one balance wherever the member looks.
| Core decides who | The partner decides how |
|---|---|
| Who is a member, and their external id | Which widgets each member sees |
| Each member’s balance: the system of record | Rewards, raffles, draws, prizes, campaigns |
| Points earned at FINNS (check-ins, bookings, staff adjustments) | Points earned or spent in its own mechanics |
| Signing members in and out | Its own short sessions, bound by core’s |
flowchart TB
classDef ours fill:#13686C,stroke:#0B4A4D,color:#ffffff
classDef ext fill:#F3ECDF,stroke:#B9A88B,color:#12191B
classDef person fill:#E9724C,stroke:#C55A37,color:#ffffff
g(["Member"]):::person
subgraph appbox["FINNS app"]
app["App<br/>widget host"]:::ours
page["<b>Your widget page</b><br/>in a WebView / iframe"]:::ext
end
be["<b>Your backend</b>"]:::ext
core["Trident core"]:::ours
g --> app
app -- "1 · launch with one-time code" --> be
be -- "2 · redeem code → extId" --> core
app <-- "3 · protocol v1 messages<br/>(token in memory)" --> page
page -- "4 · your API, widget token" --> be
be -- "5 · Points API:<br/>credit, debit, refund, feed" --> core
core -- "6 · member signed out" --> be
You receive
Only core’s external id, an opaque UUID. Never a name, email, Keycloak id or app token.
You build
A widget page that speaks protocol v1, and a backend with a launch API, your widget API, and /auth/revoke.
You call
Core’s Points API: balances, credits, debits, refunds, the event feed, daily reconciliation, and launch-code redeem.
You hold
Two secrets from FINNS: the Points API token (you → core) and a revoke token (core → you).
Internal and confidential. Share partner sections only as partner builds (pnpm build:partner).