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.
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 enumerate (e.g. the TexterChat connection).
uuidThe provider/integration key to import from. Defaults to texterchat.
"texterchat"Ask the dry run about the enrollment half too: how many of the swept contacts would start being served in this application, how many it already serves, how many are blocked or ineligible, and how many fall outside the selected accounts. Omit for a Directory-only preview.
uuidAs on the import: ALL_CONTACTS (default) or SELECTED_ACCOUNTS.
"UNSPECIFIED" | "ALL_CONTACTS" | "SELECTED_ACCOUNTS"The accounts, repeated. Required with SELECTED_ACCOUNTS.
Response Body
curl -X GET "https://api.fruxon.com/v1/tenants/string/directory/importPreview"{
"provider": "string",
"totalContacts": 0,
"contactsWithEnvironment": 0,
"contactsUnaffiliated": 0,
"contactsWithStableId": 0,
"distinctEnvironments": 0,
"standaloneEnvironments": 0,
"chainedEnvironments": 0,
"distinctChains": 0,
"slotPresence": {},
"labelCounts": {},
"sampleUnaffiliatedAddresses": [
"string"
],
"contactsNew": 0,
"contactsToUpdate": 0,
"contactsUnchanged": 0,
"contactsWithWithheldValues": 0,
"changesByField": {},
"withheldByField": {},
"sampleChanges": [
{
"address": "string",
"changes": [],
"withheld": []
}
],
"enrollment": {
"networkId": "00000000-0000-0000-0000-000000000000",
"scope": "ALL_CONTACTS",
"wouldGrant": 0,
"wouldRevive": 0,
"alreadyServed": 0,
"blocked": 0,
"ineligible": 0,
"outOfScope": 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
}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.
Lists the tenant's directory sync jobs, newest first — imports and the undos of their enrollment.
The history behind the wizard: what each sync created, refreshed and enrolled, and whether its enrollment has since been reversed (an undo row carries `sourceRunId`). It is what makes `POST directory/importRuns/{importRun}:undoEnrollment` reachable at all once the wizard is closed — a mis-scoped sync is usually noticed hours later, not on the completion screen.