Enroll contacts

Enroll up to 100 contacts into an active workflow. Enrollment is asynchronous: each contact gets a pending execution that the workflow engine then runs. Running the workflow can send emails and texts and place AI calls, which cost money.

POST https://api.centerfy.ai/webhooks/inbound/workflows/:id/enroll

Headers

HeaderRequiredValueDescription
x-api-keyYesyour sub-account API key (cfy_…)Authenticates the request; or use Authorization: Bearer <key>.

Path parameters

NameTypeRequiredDescription
idstring (uuid)YesThe workflow id.

Body parameters

NameTypeRequiredDefaultDescription
contact_idsstring[] (uuid)Yes—1 to 100 contact ids in this sub-account. Duplicates are ignored.
allow_duplicatesbooleanNo—Enroll contacts even if they are already in this workflow. Defaults to false: contacts with a pending, running, waiting, waiting_for_reply or paused execution are skipped.

Request body

{
  "contact_ids": [
    "3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f",
    "8d4e5f6a-7b8c-4d9e-9f0a-2b3c4d5e6f7a"
  ]
}

Example

curl -X POST "https://api.centerfy.ai/webhooks/inbound/workflows/{id}/enroll" \
  -H "x-api-key: $CENTERFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "contact_ids": [
    "3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f",
    "8d4e5f6a-7b8c-4d9e-9f0a-2b3c4d5e6f7a"
  ]
}'
import { CenterfyClient } from "@centerfy/sdk";

const centerfy = new CenterfyClient({ apiKey: process.env.CENTERFY_API_KEY! });

const result = await centerfy.workflows.enroll("<workflowId>", {
  "contact_ids": [
    "3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f",
    "8d4e5f6a-7b8c-4d9e-9f0a-2b3c4d5e6f7a"
  ]
});
console.log(result);
centerfy workflows enroll <workflowId> '{"contact_ids":["3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f","8d4e5f6a-7b8c-4d9e-9f0a-2b3c4d5e6f7a"]}'

MCP tool: centerfy_workflows_enroll (see MCP server)

Response

{
  "status": "success",
  "enrolled": 1,
  "skipped_contact_ids": [
    "8d4e5f6a-7b8c-4d9e-9f0a-2b3c4d5e6f7a"
  ],
  "executions": [
    {
      "id": "7c3d4e5f-6a7b-4c8d-8e9f-1a2b3c4d5e6f",
      "workflow_id": "5a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
      "contact_id": "3f1c2a9e-7b4d-4c8a-9e2f-1a2b3c4d5e6f",
      "status": "pending",
      "started_at": "2026-10-05T14:00:00.000Z",
      "completed_at": null,
      "error_message": null,
      "current_step_id": null,
      "next_step_at": null
    }
  ]
}

Errors

  • 400 — if a contact id is not a UUID (invalid_contact_ids) or not in this sub-account (missing_contact_ids); nothing is enrolled in that case.
  • 404 — if the workflow is not in this sub-account.
  • 409 — if the workflow is not active.

Notes

Returns 202 (also when every contact was skipped — enrolled is then 0). Skipping already-enrolled contacts makes retries safe.

© 2026 Centerfy AI. All rights reserved.