Users & Platform Users#
Outeract uses a two-level user model to handle identity across multiple messaging platforms. Understanding this model is key to building effective multi-platform experiences.
The Two-Level Model#
flowchart TB
subgraph User["User (Abstract Identity)"]
PU1["Platform User<br/>(WhatsApp)<br/>+1234567890"]
PU2["Platform User<br/>(Telegram)<br/>@john_doe"]
PU3["Platform User<br/>(Slack)<br/>U12345678"]
endUser#
The abstract identity that represents a person across all platforms. A User can have multiple Platform Users attached.
Platform User#
The concrete identity on a specific platform. Contains the platform-specific identifier (external_id) and is linked to a Platform Connection.
User Model#
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
app_id | UUID | Application this user belongs to |
config.name | string | User’s display name |
config.system_user | boolean | Whether this is a system/bot user |
created_at | datetime | When the user was created |
System Users#
System users represent your application or bot in conversations. They’re automatically created for each platform connection and used as the “sender” for outbound messages.
query {
users(filters: { isSystemUser: true }) {
id
name
platformUsers {
externalId
platformConnectionId
}
}
}Platform User Model#
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
user_id | UUID | Parent User |
platform_connection_id | UUID | Platform connection |
external_id | string | Platform-specific identifier |
config.name | string | Platform-specific display name |
config.profile_picture_url | string | Profile picture URL |
created_at | datetime | When created |
External IDs by Platform#
| Platform | External ID Format | Example |
|---|---|---|
| Phone number (E.164) | +14155551234 | |
| Instagram Scoped User ID | 123456789012345 | |
| Telegram | Telegram User ID | 123456789 |
| Slack | Slack User ID | U0123456789 |
| Discord | Discord User ID | 123456789012345678 |
| SMS | Phone number (E.164) | +14155551234 |
| Email address | user@example.com |
Auto-Creation#
Platform users and users are automatically created when:
- Inbound message - A new person messages you
- Outbound message - You message a new recipient
- Link code activation - A user links their identity
flowchart TB
A["Incoming WhatsApp message<br/>from +14155551234"] --> B{"Check: Does PlatformUser exist?<br/>external_id='+14155551234'<br/>platform_connection_id=whatsapp_conn"}
B -->|Exists| C["Use existing<br/>PlatformUser"]
B -->|Not Found| D["Create new User<br/>Create new PlatformUser"]Querying Users#
Get All Users#
query {
users(first: 20) {
edges {
node {
id
name
isSystemUser
platformUsers {
id
externalId
platformConnection {
platformName
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}Find User by Platform Identity#
query {
users(
filters: {
platformUserId: "pu_abc123"
}
) {
edges {
node {
id
name
}
}
}
}Get Platform Users for a Connection#
query {
platformUsers(
platformConnectionId: "pc_abc123"
first: 50
) {
edges {
node {
id
externalId
name
user {
id
name
}
}
}
}
}Creating Users#
Create a User Manually#
mutation {
createUser(
name: "John Doe"
) {
id
name
}
}Create a Platform User#
mutation {
createPlatformUser(
userId: "user_abc123"
platformConnectionId: "pc_xyz789"
externalId: "+14155551234"
name: "John's WhatsApp"
) {
id
externalId
user {
id
name
}
}
}Linking Users Across Platforms#
When you have a User with multiple Platform Users, you can message them on any platform:
# User has both WhatsApp and Slack identities
query {
user(id: "user_abc123") {
id
name
platformUsers {
id
externalId
platformConnection {
id
platformName
}
}
}
}
# Response
{
"user": {
"id": "user_abc123",
"name": "John Doe",
"platformUsers": [
{
"id": "pu_whatsapp",
"externalId": "+14155551234",
"platformConnection": {
"id": "pc_whatsapp",
"platformName": "WHATSAPP"
}
},
{
"id": "pu_slack",
"externalId": "U12345678",
"platformConnection": {
"id": "pc_slack",
"platformName": "SLACK"
}
}
]
}
}Using Link Codes#
Link codes allow users to connect their identities across platforms:
1. User messages your bot on WhatsApp
2. You generate a link code for that user
3. User enters the code in your Slack bot
4. Outeract links the two Platform Users to the same UserMerging Users#
If you discover two Users are actually the same person, you can merge them:
mutation {
mergeUsers(
sourceUserId: "user_to_merge"
targetUserId: "user_to_keep"
) {
id
platformUsers {
id
externalId
}
}
}This:
- Moves all Platform Users from source to target
- Re-assigns edges (sent_by, sent_to) to target
- Deletes the source User
- Creates a
user.mergedevent
User in Events#
Users appear in events via edges:
query {
event(id: "evt_abc123") {
id
eventType
edges {
edgeType
targetUser {
id
name
}
targetPlatformUser {
id
externalId
}
}
}
}Typical edges:
sent_by- Who sent the messagesent_to- Who received the message
Best Practices#
1. Don’t Create Users Prematurely#
Let Outeract auto-create users from messages. This ensures proper linking.
2. Use Link Codes for Cross-Platform Identity#
Don’t manually merge users. Use link codes for user-initiated linking.
3. Store Your Own User IDs#
Map Outeract User IDs to your internal user database.
4. Handle Platform User Changes#
Users might change phone numbers or usernames. Track changes via events.
5. Respect Privacy#
Users on different platforms may not want their identities linked. Always get consent.
Related Concepts#
- Events - How users relate to events
- Edges - User relationships in the graph
- Link Codes - Cross-platform identity linking