FruxonDocs
Agent NetworkParticipants

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.

POST
/v1/tenants/{tenant}/directory/import
AuthorizationBearer <token>

JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token.

In: header

Path Parameters

tenant*string

The tenant identifier

Query Parameters

integrationConfigId?string

The tenant integration config to import from (e.g. the TexterChat connection).

Formatuuid
provider?string

The provider/integration key to import from. Defaults to texterchat.

Default"texterchat"
targetNetworkId?string

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.

Formatuuid
agentMode?string

Required 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.

Value in"UNSPECIFIED" | "ON" | "OFF_HUMAN_ONLY"
enrollmentScope?string

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.

Value in"UNSPECIFIED" | "ALL_CONTACTS" | "SELECTED_ACCOUNTS"
environmentIds?array<string>

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
}
Empty
Empty
{
  "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
}