This flow is for partners who need a trusted mapping between an AGG
user.id and their own
internal user ID for rewards, analytics, or reconciliation. The assertion must come from your
backend, not from the browser.externalId is the durable partner user id. It is not the venue externalIdentifier and
not the webhook partner id. See Ids.
How it works
1
Generate the app secret
Generate or rotate the app secret from the AGG admin dashboard, then store it in your backend
secrets manager. Never expose it to the browser. The secret is hex.
2
Sign the assertion on your backend
Sign HMAC-SHA256 over the string
{externalId}:{timestamp}. timestamp is an integer in
milliseconds. The key is that hex secret decoded from hex, not the hex text as UTF-8. Send the
hex digest as hmac. A timestamp more than five minutes off the server clock is rejected.3
Send the assertion to the frontend
Return
{ externalId, timestamp, hmac } from your own API after the user is authenticated in
your app.4
Link it in AGG
Call
client.linkExternalId(assertion) or the useExternalId() hook. AGG returns the updated
UserProfile with externalId populated.Webhook-assisted linking
If your backend needs to connect new AGG users to existing partner users, subscribe toaccounts.created. The event includes the AGG userId and, when available from magic-link or
OAuth sign-in, email.
Use that email to resolve your internal user record, then complete the normal signed assertion flow
for that authenticated user. After client.linkExternalId(assertion) succeeds, AGG emits
accounts.linked with the AGG userId and your externalId.
accounts.created.data.email is null when AGG does not have an email for the principal, such
as wallet-only sign-in or OAuth providers that do not return email.Examples
Backend signing
- Node.js
- Python
Link the user
Send the assertion with the user’s access token. A409 means that external id is already linked
to another user in this app.
externalId is returned on the updated UserProfile and on future
client.getCurrentUser() calls.