How it works
Your backend calls the endpoint
Your server computes a shared-secret HMAC over the customer’s email and calls
POST /api/auth/externalMagicLink with a valid Omneo bearer token.Omneo verifies the request
Omneo checks the bearer token, confirms the calling origin is allow-listed, and matches the request to your configured app entry using the supplied secret.
Omneo mints a token and emails the link
When the profile exists, Omneo mints a profile-scoped ID token, renders your link template with the token and expiry, and emails the link to the customer.
Endpoint
Headers
| Header | Required | Notes |
|---|---|---|
Authorization | Yes | Bearer <omneo-token>. Validated against the Omneo auth service. |
Origin | Yes | Your calling origin must be allow-listed by Omneo. |
Body
| Field | Required | Description |
|---|---|---|
email | Yes | Email of the profile to authenticate. |
appUrl | Yes | Your app base URL (origin). Must match a configured app entry. |
secret | Yes | HMAC-SHA256 of the email, keyed with your shared secret. See Computing the secret. |
redirect | No | In-app redirect hint. Defaults to /home. |
Responses
| Status | Meaning |
|---|---|
200 | { data: { type: 'existing', id, email } } when the profile exists; the link is emailed. { data: { type: 'new', email } } when no profile matches the email. |
400 | Missing email, appUrl, or secret. |
401 | Missing Authorization header. |
403 | Invalid or expired bearer token, a disallowed Origin, or an appUrl/secret that does not match a configured app. |
502 | Token generation failed upstream. |
Computing the secret
The bearer token alone does not authorise the call. You are also issued a shared secret and must prove you hold it on every request. Compute the value you send like this:secret body field. Omneo recomputes the same HMAC over the email it received and accepts the request only if the two match. Binding the HMAC to the email stops a captured secret from being replayed to request a link for a different profile.
Use the exact email string you send in the payload, with the same casing and trimming:
Configuration
Your app entry is configured by Omneo during onboarding. You provide your app origin and a Branch.io link template, and Omneo issues you the shared secret. Each entry has three values:| Value | Description |
|---|---|
baseUrl | The origin you send as appUrl. Requests are matched to an entry by comparing origins. |
linkTemplate | The full template used to build the emailed link. Omneo controls this, so you only send your origin. |
secret | The shared secret (HMAC key) issued to you. |
token, expiry, and redirect. The example above renders to:
token and redirect values are URL-encoded (or use a base64url-safe token) so characters like +, /, and = survive query-string parsing. Use double braces, for example {{token}}, in the template. A template with no placeholders falls back to appending ?token=...&expiry=....
Validating the ID token on app open
Thetoken query parameter is a base64-encoded JWT. When the customer opens the link, your app should:
- Base64-decode the
tokenvalue, then JWT-decode it. - Read the
pid(profile ID) andexp(unix expiry) claims. - Reject the link if
expis in the past. Links are valid for about 24 hours. - Use the decoded JWT as a bearer token against the Omneo ID service, for example
GET https://api.[tenant].getomneo.com/id/api/v1/profiles/me.