> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usesimple.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Enroll Contacts in Journeys from Your Systems

> Enroll contacts in a Simple AI journey from your CRM or booking system with one API call, pass the record and its date, and cancel when plans change.

Use the API when your own system decides who should be in a journey, such as a CRM that creates leads or a booking system that creates appointments.

## Before You Start

* Publish the journey. Only an active journey accepts enrollments.
* Find the journey's **key** on its Enrollment tab, such as `appointment-confirmations`. The tab also shows a ready-to-copy request.
* Create an [API key](/api-reference/introduction) and send it as `Authorization: Bearer YOUR_API_KEY`.

## Enroll a Contact

```bash theme={null}
curl -X POST https://api.usesimple.ai/api/v1/journeys/appointment-confirmations/enrollments \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotencyKey": "appt-APPT02984416",
    "contact": { "phoneNumber": "+14155550100", "name": "Dana Reyes" },
    "subject": { "appointment_number": "APPT02984416", "status": "Scheduled" },
    "anchorAt": "2026-10-22T14:00:00-04:00"
  }'
```

* **`idempotencyKey`** is your id for this enrollment. Sending the same key again returns the existing enrollment instead of creating a second one, so retries are safe.
* **`contact`** is either an existing contact's `contactId`, or a phone number and details. Simple AI creates or updates the contact from those details.
* **`subject`** is the record the journey is about. Your conditions and texts can use its fields, such as `{{subject.appointment_number}}`, and every call receives them.
* **`anchorAt`** is the date the journey's steps are timed from, such as the appointment time.
* **`notBefore`** is optional. Nothing goes out before this time.
* **`params`** is optional. Extra values passed to every call. They are also added to `subject`.

The response tells you what happened:

```json theme={null}
{
  "enrollmentId": "6c1f2a9e-…",
  "status": "active",
  "endedReason": null,
  "skippedReason": null,
  "created": true,
  "nextTouchAt": null,
  "contact": { "timezone": "America/New_York", "timezoneSource": "area_code" }
}
```

`nextTouchAt` is set when a call or text is going out right away. When the first step is later, such as the day before an appointment, it is `null` and the step is planned when it comes due.

A contact the journey can't take comes back with `"status": "skipped"` and the reason in `skippedReason`. Possible reasons:

* The contact has no phone number
* The anchor field is empty
* No consent for this journey
* Active in another journey
* Test mode is on and the number is not allowlisted

See the [Enroll a Contact in a Journey](/api-reference/journeys/enroll-contact) reference for every field.

## Cancel When Plans Change

```bash theme={null}
curl -X POST https://api.usesimple.ai/api/v1/journeys/appointment-confirmations/enrollments/cancel \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "idempotencyKey": "appt-APPT02984416", "reason": "Appointment cancelled" }'
```

Send the `idempotencyKey` you enrolled with, or an `externalId` if you set one. The contact's journey ends right away and the reason shows in their history. See [Cancel a Journey Enrollment](/api-reference/journeys/cancel-enrollment).

## A Typical Integration

1. **When a record is created** in your system, enroll the contact with your record id as the `idempotencyKey`.
2. **When the record's date changes**, cancel and enroll again with a new key. If the journey enrolls from a custom data table instead, update the row and the journey reschedules on its own.
3. **When the record is cancelled**, cancel the enrollment.
4. **To learn the result**, attach a post-call workflow to the journey. It runs after every journey call with the step, result, contact and record, and can update your system.

<Note>
  Calls placed by a journey are ordinary calls. Your call webhooks keep working as they do today.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.