Identities
Your organization's directory of people and customers: the one record your dashboard, your apps and your AI agents share for each person.
An identity is one person, group or customer account in your organization's directory. Your team edits it in the dashboard, your apps use it through the SDK, and a customer-facing agent uses it to decide whose data a conversation may read. Data-store tables can reference identities, so an order belongs to a person, not a copy of their name.
Open Identities in the dashboard.
Who's in the directory
Most identities are added for you:
| Source | What gets added |
|---|---|
| Team members | Every member of your organization, linked to their dashboard login |
| People who sign in to apps | Each app user, linked on sign-in |
| Inbound messages | A person for each direct message, or a group for each group chat, on a connected channel |
| Your apps | Anyone an app creates, such as a walk-in customer or a new staff member |
| You | Anyone you create by hand in the dashboard |
- A customer who signs in to two of your apps is one person.
- Sandboxes, previews and stagings add people to the same live directory as production. A person a staging creates is marked with that staging.
- A team member's name and
emailfollow their Stardeck account and are read-only here (and to the SDK) while they are on the team. Other attributes stay editable. - Apps'
listandsearchleave out people who are only team members.
Identity types
| Type | What it is | Nests under | Channel-linked? |
|---|---|---|---|
| Account | The root scope unit: a company or customer | Nothing (it's a root) | No |
| Group | A collective subject, e.g. a LINE group chat | An account or group | Yes |
| Person | An individual | An account or group | Yes |
How scope works
Identities nest into tiers through memberships: an account holds groups, a group holds people. Read scope flows upward. A subject reads its own data plus every ancestor's, and never its members' or its siblings'.
flowchart TD
A["Account: Acme Inc."] --> G["Group: Acme support chat"]
A --> D["Person: Dana"]
G --> S["Person: Sam"]
Sam reads Sam, the support chat and Acme Inc. Dana reads Dana and Acme Inc., not Sam or the chat. Acme Inc. reads only itself.
An identity's Memberships section shows its effective read scope: exactly what a scoped agent can read. Check it before pointing an agent at a customer.
Channel links
A channel link ties an external identifier or login to a person or group, so inbound messages and sign-ins resolve to the right identity. Accounts are never channel-linked.
| Link kind | Typical value |
|---|---|
| LINE | A LINE user id (person) or group id |
| A Facebook page-scoped user id | |
| An Instagram-scoped user id | |
| An email address | |
| Phone | A phone number |
| App login | A person's sign-in to one of your deployed apps |
| Dashboard user | A team member's Stardeck login |
- Verified means proven to belong to that person. Unverified emails and phones can sit on several people (a family sharing a number).
- App logins, dashboard logins and channel ids each belong to one identity only.
- Inbound messages find the sender by channel link or create a person (direct message) or group (group chat). Each web conversation gets its own anonymous person.
Managing identities
- Create: New Identity, pick a type, add a display name and an optional external
reference (your own customer key). Setting a parent needs
identities:govern. - Edit attributes: free-form fields such as position or loyalty tier. Apps read and write the same attributes.
- Channel links: add a kind and external id. Mark it verified only if you're sure.
- Memberships: Belongs to lists parents (widens read scope). Members lists children.
Changing parents needs
identities:govern. - Merge: folds a duplicate into a survivor of the same type, moving links and scope. Needs
identities:govern, is audited and can't be undone automatically. - Archive: retires an identity. It resolves to no read scope, so a conversation pointed at it reads nothing.
To give a login to someone already in the directory, pick them in the Person column of Create accounts. If the login can't be added to the person, the account still works; merge the two people here.
Connecting customers to their profile
A profile connection joins a customer's new login to a profile that already holds their history (a walk-in, a phone booking, an imported list). Your app asks for a link; the customer confirms on a Stardeck-hosted page.
- Email or phone invitation: sent to a contact on the profile. The customer proves they own it.
- Profile invite link: for profiles with no contact, shown in person as a QR code or slip. Nothing is verified: whoever signs in gets the profile. Turn them off in the app's Settings → Authentication, under Sessions → Profile Invite Links; issued links stop working at once.
Stardeck refuses a connection when another login already owns the profile or proved the contact. Your app never merges profiles itself.
Permissions
Identity management is controlled by organization permissions (see Members & Roles):
| Permission | Grants |
|---|---|
identities:manage | View the directory, create and edit identities, and attach channel links |
identities:govern | Actions that move read scope: merge, delete or archive, re-parent, and resolve conflicting channel links |
identities:assist-claim | Pair with a signed-in customer and select which existing profile they connect. The customer still confirms on their device |
identities:transfer-claim | Move a profile already connected to another login. This revokes that login's access, so grant it sparingly |
identities:impersonate | Preview sandbox apps as a specific person from the directory |
identities:manage keeps the directory tidy. Only identities:govern can change what an agent reads.
Using identities with AI agents
Customer-facing agents that read data scoped to an identity are in early access. To try them, email support@stardeck.ai.
Each conversation on the Conversations page carries its identity. To correct it, change the
Person row in the conversation's Customer panel (needs identities:manage). Reads follow
the new identity from the next reply.
Using identities from your app
Apps use integrations.identities from integrations-sdk. Its SKILL.md has the full API.
Attributes live on profile:
const person = await integrations.identities.create({
type: "person",
displayName: "Somchai",
profile: { position: "Head chef", branch: "Silom" },
});update replaces the whole profile. Read, change, write it all back:
const { identity } = await integrations.identities.get(person.id);
await integrations.identities.update(person.id, {
profile: { ...identity.profile, position: "Sous chef" },
});For a current team member, changing the display name or email is refused. Writing them back
unchanged is fine; leaving out email keeps it.
Search by attribute:
const page = await integrations.identities.search({
attributes: { position: "Head chef" },
});- Exact match on every key, by JSON type (
"5"doesn't match5). - Values: string (up to 500 chars), number or boolean. Up to 10 keys, 1–100 chars each.
- Combines with
query(display name or any link's external id). - Paginate with
nextCursor→cursor.limit1–100, default 50.
Keeping internal data private
Scope decides which customer an agent reads, not which fields it may show. A customer-facing agent sees only client-facing data; a staff agent sees the whole record. Enforce this on the data store. A scoped agent reads the store directly and never runs your app code, so hiding fields in the app does nothing.
- Staff-only store: put internal data in its own store and turn on Staff-only store in its General settings. Customer-facing assistants can't be granted it.
- Shared store: turn on Enforce client/internal visibility in General settings, then:
- Column tiers: mark columns Client or Internal. Internal columns are hidden and can't be searched or sorted.
- Row visibility: per table, pick the column that marks a row visible to the customer. Tables left Not configured are hidden from customer-facing agents.
- Default tier: keep it Internal so new columns stay private.