Skip to main content

Users & Participants

Several different things could reasonably be called “a user” in Cortex, and they mean different things. Getting them straight prevents identity confusion and accidental data leakage.

The identities

IdentityWhat it isIdentified by
Dashboard user (users)Someone who logs into the Cortex dashboarduserId (internal) + email
Participant (participants)A per-project identity for someone who appears in your roomsexternalUserId (your value)
ODIN peerAn ephemeral connection to a Voice roompeerId (assigned by Voice) + userId (your value)

The two you’ll work with as an integrator are participants and the externalUserId.

externalUserId: the value that ties it together

When a client joins an ODIN Voice room, it passes a userId to the ODIN SDK. Cortex persists that value as a participant’s externalUserId. It’s how Cortex maps an audio stream to a stable identity:

ODIN peer (peerId, userId)  ──►  participant (externalUserId == userId)  ──►  attributed transcript

A participant is unique per project by externalUserId. The same person who plays two of your games is two participants (one per project), even with the same externalUserId string — because identity is scoped to the project.

const participant = await project.participants.create({
externalUserId: "user-123", // the value your client passes to ODIN
displayName: "Alice",
});
userId is a hint, not an identity

ODIN Voice does not validate the userId a client claims. Two clients can claim the same userId. For trustworthy identity, authenticate your own users in your backend and pass a value you control. Never treat the reported userId as proof of who someone is.

A participant is not a dashboard user

Most participants are not dashboard users — they’re just “someone with this externalUserId who showed up in a room.” A participant only gains a link to a users row if that same person also logs into the Cortex dashboard. So:

  • Use participants to attribute transcripts, track gathering membership, apply sanctions and store per-speaker metadata.
  • Use dashboard users only for “who created this resource” attribution in the dashboard.

One human, many rows

If Alice plays your game from two devices in the same session, Voice assigns two different peerIds — but both carry the same externalUserId, so they resolve to the same participant and her transcript is attributed correctly.

Anonymous participants and cross-session bans

In ODIN Rooms, users are often anonymous (a random id per device). You can still:

  • Attribute transcripts to whatever externalUserId is present.
  • Ban across sessions by applying a sanction keyed on externalUserId rather than on a single participant row — your enforcement code can then look it up on every join, even if the participant record changes.