Creates a participant and optionally binds it to a set of agents atomically.
Creates the participant together with its channels and any initial agent bindings supplied in the request — all in one transaction, so a participant is never persisted half-bound. `Kind` is fixed at creation: switching a participant between Person, Group, and AI Agent requires recreating it.
Authorization
Bearer JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token.
In: header
Path Parameters
The tenant identifier
What sort of entity a Fruxon.Model.Participants.Participant represents. The Agent Network treats all three uniformly — they're the "things that talk to agents" — but the kind disambiguates UX and downstream routing rules.
"UNSPECIFIED" | "PERSON" | "GROUP" | "AI_AGENT"Trust boundary a Fruxon.Model.Participants.Participant sits on (design participant-audience-and-roles.md §1) —
a platform-owned, security-relevant axis distinct from Fruxon.Model.Participants.ParticipantTier (how it was admitted)
and the tenant's own Segment directory. A customer and a support operator are both
Fruxon.Model.Participants.ParticipantTier.Curated; only Audience separates them.
Gates the operator-eligibility predicate (only an Fruxon.Model.Participants.ParticipantAudience.Internal + Fruxon.Model.Participants.ParticipantTier.CuratedFruxon.Model.Participants.ParticipantKind.Person may be an escalation operator), which fixes "a customer can be selected as an operator." Defaults Fruxon.Model.Participants.ParticipantAudience.Unknown on existing rows so eligibility is fail-closed; the I4 backfill promotes participants already wired as operators to Fruxon.Model.Participants.ParticipantAudience.Internal so live escalation is not stranded.
"UNSPECIFIED" | "UNKNOWN" | "INTERNAL" | "EXTERNAL"1 <= length <= 150length <= 4000Operator-uploaded avatar file id (in platform storage). Optional; AI-agent participants without one fall back to the backing agent's avatar at projection time.
Identity addresses (provider + address) the participant can be reached at. The bot/app is derived from the bound agents' endpoints, not picked here.
Agents to bind to this participant on creation. May be empty.
Whether the initial bindings also place this participant on each agent's consult roster. Defaults false so binding a customer for conversation access does not inject peer-network tools. Advisor creation must opt in explicitly.
Consult advisor identity (PLAN-consult-roster): a free-text description of what this participant can help with, plus the capability names they carry (the expertise the consult resolver matches).
length <= 4000Profile (PLAN-identity-normalization, Phase 0): area of work (or role), a longer bio, and working-preference tags — distinct from the consult Fruxon.Model.Participants.CreateParticipantRequest.Description/Fruxon.Model.Participants.CreateParticipantRequest.Expertise above.
length <= 150length <= 4000Optional preferred language (ISO 639-1, e.g. "en", "he") for platform-authored notices sent to this participant — set on an operator so bridge notices render in their language, not the customer's.
length <= 16Optional environment (served end-customer / account) this contact belongs to — the unified grouping (docs/design/environments-directory-unification.md). A logical reference (no FK, partition-friendly), null = unaffiliated. Set at onboarding by the per-provider environment resolver, or by an operator picking one on approve.
uuidNon-routing external account links (github, jira, gitlab, …) — correlation keys, never routed. Kept separate from Fruxon.Model.Participants.CreateParticipantRequest.Addresses on purpose.
Response Body
curl -X POST "https://api.fruxon.com/v1/tenants/string/participants" \ -H "Content-Type: application/json" \ -d '{ "displayName": "string" }'{
"id": "00000000-0000-0000-0000-000000000000",
"kind": "PERSON",
"tier": "CURATED",
"audience": "UNKNOWN",
"displayName": "string",
"email": "string",
"relatedAgentId": "string",
"description": "string",
"expertise": [
"string"
],
"area": "string",
"bio": "string",
"preferredLanguage": "string",
"environmentId": "00000000-0000-0000-0000-000000000000",
"preferences": [
"string"
],
"accounts": [
{
"provider": "string",
"identifier": "string",
"handle": "string",
"profileUrl": "string",
"source": "MANUAL",
"verifiedAt": 0
}
],
"addresses": [
{
"provider": "string",
"address": "string",
"priority": 0,
"label": "string",
"disabled": false
}
],
"isDebugOnly": false,
"agentIds": [
"string"
],
"disabledAt": 0,
"health": {
"reachable": false,
"channels": [
{
"address": "string",
"reason": null,
"keyStatus": "UNSPECIFIED",
"keyPrefix": "string",
"lastMessageAt": null
}
],
"reason": "INVALID_FORMAT"
},
"channelActivations": [
{
"agentId": "string",
"bindingId": "00000000-0000-0000-0000-000000000000",
"integrationConfigId": "00000000-0000-0000-0000-000000000000",
"provider": "string",
"address": "string",
"webhookUrl": "string",
"webhookUrlTemplate": "string",
"webhookKeyPrefix": "string",
"scope": "PER_BINDING"
}
],
"avatarFileId": "string",
"avatarSource": "UPLOADED",
"avatarSourceConfigId": "00000000-0000-0000-0000-000000000000",
"avatarSourceAddress": "string",
"avatarSyncedAt": 0,
"avatarAutoSync": {
"synced": false,
"provider": "string",
"address": "string"
},
"createdAt": 0,
"modifiedAt": 0
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}Partial update
Applies a partial update: only the non-null fields of the request are written, so callers can patch a single property without resending the whole resource. Supplying `Channels` replaces the channel list wholesale. `Kind` cannot be changed here. Agent bindings are managed through the nested `bindings` sub-resource, not this endpoint.
Smoke-tests the outbound dispatch pipeline — picks a channel via the channel selector, decrypts the integration config, and routes through the per-provider sender (currently a logging stub for every provider — real senders land in Phase 3d.3)
Smoke-tests the outbound dispatch pipeline end to end: the channel selector picks a channel for the participant, the integration config is decrypted, and the message is handed to the per-provider sender. Use it to confirm a participant is reachable before relying on it in a flow. Returns 404 when the participant does not exist.