> ## 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 a Contact in a Journey with the API

> Enroll a contact in an active Simple AI journey by its key, with the record, anchor date and call parameters, using an idempotency key for safe retries.

Re-sending the same `idempotencyKey` returns the existing enrollment with `200` instead of creating a second one. A new enrollment returns `201`.

A contact the journey can't take, such as one already active in another journey or without consent, is returned with `200`, `status: "skipped"` and the reason in `skippedReason`.

See [Enroll contacts from your systems](/journeys/enroll-with-the-api) for a walkthrough.


## OpenAPI

````yaml POST /journeys/{key}/enrollments
openapi: 3.1.0
info:
  title: Public API v1
  description: >-
    Public API v1 requiring API keys.


    **Timestamps:** All datetime fields in API responses are returned in UTC
    using ISO 8601 format (e.g., `2024-01-15T14:30:00Z`). When filtering by date
    parameters, provide timestamps in ISO 8601 format.
  version: 0.1.0
servers:
  - url: https://api.usesimple.ai/api/v1
    description: Production API Server
security: []
paths:
  /journeys/{key}/enrollments:
    post:
      tags:
        - Journeys
      summary: Enroll a Contact in a Journey
      description: >-
        Enroll a contact in an active journey. Re-sending the same
        idempotencyKey returns the existing enrollment instead of creating a
        second one. A contact the journey cannot take is returned with status
        skipped and the reason.
      operationId: enroll_contact_journeys_key_enrollments_post
      parameters:
        - name: key
          in: path
          required: true
          description: >-
            The journey's key, such as `appointment-confirmations`. It is shown
            on the journey's Enrollment tab.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JourneyEnrollRequest'
            example:
              idempotencyKey: appt-APPT02984416
              contact:
                phoneNumber: '+14155550100'
                name: Dana Reyes
              subject:
                appointment_number: APPT02984416
                status: Scheduled
              params:
                store_name: Market Street
              anchorAt: '2026-10-22T14:00:00-04:00'
      responses:
        '200':
          description: >-
            The enrollment already existed for this idempotencyKey, or the
            contact was skipped.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JourneyEnrollmentResult'
        '201':
          description: A new enrollment was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JourneyEnrollmentResult'
        '401':
          description: Authentication failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '404':
          description: No journey with this key, or the contact was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
        '422':
          description: >-
            The request is invalid, or the journey is not active (a draft,
            paused or archived).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
      security:
        - APIKeyHeader: []
components:
  schemas:
    JourneyEnrollRequest:
      type: object
      additionalProperties: false
      required:
        - idempotencyKey
        - contact
      properties:
        idempotencyKey:
          type: string
          maxLength: 255
          description: >-
            Your key for this enrollment, such as a lead or appointment id.
            Sending it again returns the same enrollment.
        externalId:
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
          description: >-
            Another id to cancel by later. Defaults to idempotencyKey. It is
            also used as the contact's external id when the contact is created
            or updated.
        contact:
          description: >-
            An existing contact by id, or contact details that are created or
            updated by phone number.
          oneOf:
            - type: object
              additionalProperties: false
              required:
                - contactId
              properties:
                contactId:
                  type: string
                  format: uuid
                  description: The contact's id.
              title: Existing contact
            - type: object
              additionalProperties: false
              required:
                - phoneNumber
              properties:
                phoneNumber:
                  type: string
                  description: The contact's phone number, ideally in E.164 format.
                name:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: The contact's name.
                email:
                  anyOf:
                    - type: string
                      format: email
                    - type: 'null'
                  description: The contact's email address.
                timezone:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: >-
                    The contact's IANA time zone, such as America/Chicago. Used
                    for calling hours ahead of the address or area code.
                attributes:
                  type: object
                  additionalProperties: true
                  description: Contact fields to set.
              title: Contact details
        subject:
          type: object
          additionalProperties: true
          description: >-
            The record this enrollment is about, such as an appointment. The
            journey's conditions and texts can read these fields, and calls
            receive them.
        params:
          type: object
          additionalProperties: true
          description: >-
            Extra parameters passed to every call the journey places for this
            enrollment. They are also merged into subject.
        subjectKey:
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
          description: Identifies the subject. Defaults to idempotencyKey.
        anchorAt:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          description: >-
            The date the journey's steps are timed from, in ISO 8601 with an
            offset. Overrides the anchor the journey would read from subject.
        notBefore:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          description: >-
            The earliest time the first call or text may go out. Null means as
            soon as calling hours allow.
      title: Enroll in Journey Request
    JourneyEnrollmentResult:
      type: object
      required:
        - enrollmentId
        - status
        - endedReason
        - skippedReason
        - created
        - nextTouchAt
        - contact
      properties:
        enrollmentId:
          type: string
          description: The enrollment's id. Empty when the contact was skipped.
        status:
          type: string
          enum:
            - active
            - ended
            - skipped
          description: >-
            active while the journey is working the contact, ended once it
            finished, skipped when the contact could not be enrolled.
        endedReason:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Why the enrollment ended, such as goal_met, opted_out, cancelled,
            total_cap or exhausted.
        skippedReason:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Why the contact was not enrolled, in words, such as Active in
            another journey.
        created:
          type: boolean
          description: True when this request created the enrollment.
        nextTouchAt:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          description: >-
            When a call or text is going out right away. Null when the next step
            is later; it is planned when it comes due.
        contact:
          anyOf:
            - type: object
              required:
                - timezone
                - timezoneSource
              properties:
                timezone:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: The time zone used for the contact's calling hours.
                timezoneSource:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: >-
                    Where the time zone came from: confirmed, provided, address
                    or area_code.
            - type: 'null'
          description: The contact's time zone, when known.
      title: Journey Enrollment Result
    PublicApiError:
      type: object
      required:
        - status
        - success
        - error
        - errors
      properties:
        status:
          type: string
          const: error
        success:
          type: boolean
          const: false
        error:
          type: string
        errors:
          type: array
          items:
            type: string
      title: Public API Error
  securitySchemes:
    APIKeyHeader:
      type: http
      scheme: bearer
      description: 'Your API key, sent as `Authorization: Bearer YOUR_API_KEY`'

````

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