Enqueues a real directory import and returns the job to poll
A full import can sweep up to 100k contacts (each creating a participant + environment), which far exceeds a single HTTP request budget — so this does not run the sweep inline. It enqueues a job and returns `202 Accepted` with the run; a background worker then enumerates the integration's contacts, gets-or-creates each contact's environment, and creates a participant (External audience) where none already exists at its address — so a re-run is safe and creates no duplicates. Poll `GET directory/importRuns/{importRun}` for progress and the final counters. Only one import per `(provider, integrationConfigId)` may be in flight; a second request returns `409 Conflict` until the first finishes. Run the dry-run preview first and review the report before importing.
Authorization
Bearer JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token.
In: header
Path Parameters
The tenant identifier
Query Parameters
The tenant integration config to import from (e.g. the TexterChat connection).
uuidThe provider/integration key to import from. Defaults to texterchat.
"texterchat"Optional enrollment target: grant every imported (or re-synced existing) participant Served
access in this application during the same sweep, replacing the manual per-person enrollment step.
Existing access rows are never modified, so a re-import can't clobber operator decisions. Use
GET directory/importTarget to pre-answer this from the config's entry points.
uuidRequired with targetNetworkId, and rejected without one: ON = enroll
now (the agent answers, and transports needing a provider-side flip — TexterChat — are actuated per
newly granted participant); OFF_HUMAN_ONLY = staged import (grants exist but the agent stays
silent until enabled from the roster — the bakery-by-bakery migration path). Deliberately has no
default: an import sweeps the provider's entire contact base, so switching the agent live for all of
it must be something a caller asked for, never what an omitted parameter does.
"UNSPECIFIED" | "ON" | "OFF_HUMAN_ONLY"With targetNetworkId: ALL_CONTACTS (default) enrolls every contact the
sweep touches; SELECTED_ACCOUNTS enrolls only those resolving to
environmentIds — the wave-by-wave onboarding path — and imports the rest without
a grant. SELECTED_ACCOUNTS with no accounts is rejected rather than widened.
"UNSPECIFIED" | "ALL_CONTACTS" | "SELECTED_ACCOUNTS"The accounts (environments) to enroll, repeated: environmentIds=…&environmentIds=….
Required with SELECTED_ACCOUNTS, rejected otherwise. A contact affiliated with no account is
outside every selection.
Response Body
curl -X POST "https://api.fruxon.com/v1/tenants/string/directory/import"{
"id": "00000000-0000-0000-0000-000000000000",
"kind": "IMPORT",
"sourceRunId": "00000000-0000-0000-0000-000000000000",
"provider": "string",
"integrationConfigId": "00000000-0000-0000-0000-000000000000",
"scheduleId": "00000000-0000-0000-0000-000000000000",
"targetNetworkId": "00000000-0000-0000-0000-000000000000",
"targetAgentMode": "ON",
"enrollmentScope": "ALL_CONTACTS",
"enrollmentEnvironmentIds": [
"00000000-0000-0000-0000-000000000000"
],
"status": "PENDING",
"participantsCreated": 0,
"participantsUpdated": 0,
"participantsExisting": 0,
"participantsFailed": 0,
"contactsUnaffiliated": 0,
"valuesWithheld": 0,
"sampleFailures": [
{
"address": "string",
"reason": "string"
}
],
"accessGranted": 0,
"accessAlreadyGranted": 0,
"accessSkipped": 0,
"accessOutOfScope": 0,
"channelsActuated": 0,
"channelsNotActuated": 0,
"accessWithdrawn": 0,
"accessLeftAlone": 0,
"channelsReleased": 0,
"channelsNotReleased": 0,
"errorMessage": "string",
"createdAt": 0,
"modifiedAt": 0,
"startedAt": 0,
"completedAt": 0
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"property1": null,
"property2": null
}Lists participants in the tenant
Returns participants ordered by display name, each with its inline channels and current agent bindings. Pass `agentId` to narrow the result to the participants bound to a single agent — the Agent Network UI uses this to render an agent's contact list. Always paged (an agent's roster can run to thousands): each response carries `nextPageToken` and `totalCount`, and an omitted `pageSize` takes the server default rather than returning everything. Consumers that need the whole roster page through `nextPageToken`.
Dry-runs a directory import — enumerates the integration's contacts and returns an aggregate report, writing nothing.
Reads the whole contact base of the given integration config through its `IParticipantDirectorySource`, runs each contact through the same environment resolver the live approve gate uses, and aggregates the result — how many contacts would affiliate with an environment, the standalone-vs-chain split, per-attribute coverage (e.g. how many carry a branch), and a sample of contacts that would stay unaffiliated. Use it to gauge data quality before running a real import.