Concepts
Campaign code, API key, launch key, deviceId, userId, tokens and workspace scope.
On this page
Keys: what is public and what is secret
| Name | Public? | What it is for | Where it lives |
|---|---|---|---|
| Campaign code | Public (a publishable key) | Names one feedback topic. Apps use it to register and to open the page. It can be re-issued; the old one can be disabled. | In your app |
API key (wtn_<prefix>_<secret>) | Secret | Authenticates your server to /api/v1/channel/*. Carries scopes and a workspace allowlist. Shown once when it is created. | Your server's secrets manager |
| Launch key | Secret | Signs a launch token (HS256) and computes userHash. A campaign has two active slots (current and next) so rotation never breaks a live app. Shown once. | Your server only |
| Webhook secret | Secret | Verifies the signature on webhook deliveries. Shown once when you register the endpoint. | Your server only |
Anything inside an app binary can be extracted, so a secret never ships in an app.
Identity: device and user
deviceId: one app install. Issued by WTN as a UUID, unique within a workspace andappId. The app stores it (Keychain on iOS, EncryptedSharedPreferences on Android).userId: one person. Issued by WTN, only when the app sendsuser.externalId,emailorphone. It links one person's devices, so changing phones keeps the history.identitysays how much WTN can trust the user:anonymous: no user fields were sent.self_declared: the app named the user but did not prove it.verified: your server computeduserHash(HMAC-SHA256 ofexternalIdwith a launch-key secret) and the app sent it. A wrong hash is refused with401 USER_HASH_INVALID.
Email and phone are stored encrypted and are never returned.
Tokens
refreshToken: proves the app owns itsdeviceId. Opaque, per device, long-lived (180 days by default) and renewed on every heartbeat. Store it securely.accessToken: short-lived (24 hours by default). It travels in the page link's fragment so the feedback is linked to the device and user. Keep it in memory only.
If the refresh token is unknown, revoked or expired, the heartbeat answers 401 DEVICE_AUTH_INVALID: call register again (the same user fields give back the same userId). An expired access token never blocks the person; the feedback is just kept anonymous.
Workspaces
Your API key belongs to a business that may run several client workspaces. If the key reaches exactly one, it is used automatically. If it reaches more than one, send X-WTN-Workspace: <workspace-id> on every data call, otherwise you get 400 WORKSPACE_REQUIRED. GET /api/v1/channel/orgs lists the workspaces your key may act on.
Open and signed access
By default a campaign is open: anyone with the link can leave feedback, protected by abuse limits. A campaign can instead require a signed launch: your server signs a short-lived, single-use token or asks the API for a one-time link, and an unsigned visit sees "open this from the app". See Server integration.