Managing External Reference IDs

An external reference ID is your own identifier for a Fluz user. It lets you operate the Fluz API using the IDs you already have in your system — without storing or passing Fluz's internal userId and accountId for every user.

When a user authorizes your application, you attach your identifier to that grant. Fluz stores the pairing between your identifier and the user's Fluz account, scoped to your application. From that point forward, you can reference the user by your own ID when generating tokens, sending transfers, and matching webhook events.

📘

Where you'll see it

The field appears as external_id in the OAuth authorization URL and as externalReferenceId in the GraphQL API and webhook payloads. They are the same value.

What can it be?

PropertyRule
TypeAny string. Fluz does not impose a format.
UniquenessMust be unique per user within your application. One external reference ID maps to exactly one Fluz user.
ScopeScoped to your OAuth client. The same Fluz user can carry a different external reference ID in another developer's application, and no other application can see or use yours.
StabilityTreat it as immutable. Use a stable identifier from your system — your internal user ID or a UUID.
⚠️

Do not use PII as an external reference ID

Avoid email addresses, phone numbers, or names. These can change over time and would break your mapping, and they unnecessarily transmit personal data in URLs and tokens. A UUID or your database primary key is the right choice.

Where do we use it?

The external reference ID flows through four surfaces:

SurfaceFieldDirection
OAuth authorization URLexternal_id query parameterYou → Fluz
generateUserAccessToken mutationexternalReferenceId argumentYou → Fluz
Wallet transfers (createTransfer)destination.externalReferenceIdYou → Fluz
Webhook event payloadsexternalReferenceIdFluz → You

It is also embedded in the OAuth access token issued for the user, so the association persists across token refreshes.

How do we use it?

1. Assign it during the OAuth authorization flow

When you direct your end user to the authorization URL (see Client facing OAuth grant flow), append your identifier as the external_id query parameter:

https://uni.staging.fluzapp.com/authorize?response_type=code&client_id=<CLIENT_ID>&redirect_uri=<REDIRECT_URI>&scopes=MAKE_DEPOSIT%20LIST_PAYMENT&external_id=usr_8f3d2a91

When the user completes the grant, Fluz records usr_8f3d2a91 against that user's authorization of your application. The same parameter applies when launching an embedded widget — see Widget Overview.

🚧

Required for widget applications

All widget application types (deposit, payouts, payins, virtual card, gift card catalog, bill pay, and external payout widgets) require an external reference ID when establishing a user session. The request will be rejected with External reference ID is required for <type> applications if it is omitted. For standard OAuth applications it is optional, but strongly recommended.

2. Generate user access tokens with it

Once the pairing exists, generateUserAccessToken accepts externalReferenceId in place of userId and accountId:

mutation {
  generateUserAccessToken(
    externalReferenceId: "usr_8f3d2a91"
    scopes: [MAKE_DEPOSIT, LIST_PAYMENT]
  ) {
    token
    refreshToken
    scopes
  }
}

Authenticate this call with your application's Basic credentials as usual — see Generate a User Access Token.

You may pass userId/accountId alongside externalReferenceId, but they must match the user the external reference ID resolves to. If they don't, the request is rejected.

3. Address transfer destinations with it

When creating a wallet transfer to another Fluz account (see Create Wallet Transfer to Another Fluz Account), the destination can be identified by external reference ID instead of a Fluz account ID:

mutation {
  createTransfer(input: {
    idempotencyKey: "1f7c5a2e-9b14-4c6d-8e3f-2a90d4b7c1aa"
    amount: 25.00
    destination: { externalReferenceId: "usr_8f3d2a91" }
  }) {
    transferId
  }
}

Provide either destination.accountId or destination.externalReferenceId — never both. The destination user must have authorized your application; otherwise the transfer is rejected.

4. Match webhook events back to your users

Webhook payloads include externalReferenceId so you can correlate Fluz events to your own user records without maintaining a lookup table of Fluz IDs:

{
  "userId": "5070d5a1-d71a-4190-91b0-f116eec51771",
  "accountId": "9c2e1b44-7a3d-4f08-b6e5-d18a3c7f0e22",
  "externalReferenceId": "usr_8f3d2a91",
  "eventType": "DEPOSIT_COMPLETE",
  "amount": 100.00
}

See Webhooks for the full event catalog and delivery details.

📘

Privacy note

externalReferenceId is omitted from webhook payloads where the user's grant has no external reference ID associated, or where the event is flagged as private.

Validation rules and errors

ScenarioResult
Token request with neither externalReferenceId nor userId + accountIdProvide either externalReferenceId or both userId and accountId.
externalReferenceId not found for your applicationNo user found with externalReferenceId <value>.
userId provided alongside externalReferenceId but pointing to a different userProvided userId does not match the user associated with the externalReferenceId.
accountId provided alongside externalReferenceId but pointing to a different accountProvided accountId does not match the account associated with the externalReferenceId.
Transfer destination with both accountId and externalReferenceIdProvide either destination.accountId or destination.externalReferenceId, not both.
Transfer destination user has not authorized your applicationDestination account has not authorized this application.
Widget session created without an external reference IDExternal reference ID is required for <type> applications

Adding an external reference ID to an existing grant

If a user authorized your application before you adopted external reference IDs, you can supply one on a subsequent authorization or token request and Fluz will backfill it onto the existing grant — provided the grant does not already carry one. An existing external reference ID is never overwritten.

What an external reference ID is not

  • It is not a Fluz userId or accountId. Those are Fluz-issued UUIDs; the external reference ID is issued by you.
  • It is not the external_id or external account identifiers that appear on withdrawal records or linked funding sources elsewhere in the API. Those reference banking and processor records, not users. [TBD: confirm whether any of these are exposed in the public schema and should be cross-referenced here]

Want to learn more? Contact us at [email protected]

Speak with our experts for more info or to request a demo.