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

# Enroll Subscriber

> Enroll a customer into a subscription plan

# Enroll Subscriber

Enrolls a customer into a subscription plan. Call this from your backend when a customer chooses a plan — for example, after they complete your onboarding or sign-up flow.

After enrollment:

* The subscriber's status is set to `pending`
* An invoice is created immediately for the first billing cycle
* A `subscriber.enrolled` webhook is fired to your configured webhook URL
* The subscriber becomes `active` only after their first payment is confirmed on-chain

<Warning>
  Provision access to your product only after you receive the `subscriber.activated` webhook — not immediately on enrollment.
</Warning>

***

## Request

<ParamField body="planId" type="string" required>
  UUID of the subscription plan to enroll the customer into. The plan must belong to your merchant account and must not be archived.

  **Example:** `"a1b2c3d4-e5f6-7890-abcd-ef1234567890"`
</ParamField>

<ParamField body="email" type="string" required>
  The subscriber's email address. Used for billing notifications and to identify the subscriber within a plan.

  A subscriber with the same email can only be enrolled in the same plan once at a time. Attempting to enroll a duplicate returns `409 Conflict`.

  **Example:** `"customer@example.com"`
</ParamField>

<ParamField body="externalId" type="string">
  Your internal customer or user ID. Stored on the subscriber record and returned in webhook payloads. Use this to correlate Settlx subscribers with users in your system.

  Maximum 255 characters.

  **Example:** `"usr_789abc"`
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value pairs to attach to the subscriber. Returned in all webhook events for this subscriber.

  **Example:** `{ "plan": "pro", "signupSource": "checkout" }`
</ParamField>

***

## Response

<ResponseField name="data" type="object">
  <Expandable title="Subscriber object">
    <ResponseField name="id" type="string">UUID of the subscriber</ResponseField>
    <ResponseField name="merchantId" type="string">Your merchant account UUID</ResponseField>
    <ResponseField name="planId" type="string">UUID of the plan they enrolled into</ResponseField>
    <ResponseField name="email" type="string">Subscriber email address</ResponseField>
    <ResponseField name="externalId" type="string | null">Your internal customer ID, if provided</ResponseField>
    <ResponseField name="status" type="string">Always `pending` immediately after enrollment</ResponseField>
    <ResponseField name="currentPeriodStart" type="string">ISO 8601 — start of the current billing period</ResponseField>
    <ResponseField name="currentPeriodEnd" type="string">ISO 8601 — end of the current billing period</ResponseField>
    <ResponseField name="gracePeriodEndsAt" type="string">ISO 8601 — deadline to pay the first invoice before expiry</ResponseField>
    <ResponseField name="cancelAtEnd" type="boolean">Whether the subscription is scheduled to cancel at period end</ResponseField>
    <ResponseField name="metadata" type="object | null">Metadata you attached at enrollment</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 creation timestamp</ResponseField>
  </Expandable>
</ResponseField>

***

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.settlx.io/api/v1/subscriptions/subscribers \
    -H "Authorization: Bearer pk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "planId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "customer@example.com",
      "externalId": "usr_789abc",
      "metadata": {
        "userId": "usr_789abc",
        "signupSource": "checkout"
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.settlx.io/api/v1/subscriptions/subscribers', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.SETTLX_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      planId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
      email: 'customer@example.com',
      externalId: 'usr_789abc',
      metadata: {
        userId: 'usr_789abc',
        signupSource: 'checkout',
      },
    }),
  });

  const { data } = await response.json();
  console.log(data.id);     // subscriber UUID
  console.log(data.status); // "pending"
  ```

  ```python Python theme={null}
  import httpx, os

  client = httpx.Client(headers={"Authorization": f"Bearer {os.environ['SETTLX_API_KEY']}"})

  response = client.post(
      "https://api.settlx.io/api/v1/subscriptions/subscribers",
      json={
          "planId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "email": "customer@example.com",
          "externalId": "usr_789abc",
          "metadata": {"userId": "usr_789abc"},
      }
  )

  subscriber = response.json()["data"]
  print(subscriber["id"])      # subscriber UUID
  print(subscriber["status"])  # "pending"
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "data": {
      "id": "9f1e2d3c-4b5a-6789-abcd-ef0123456789",
      "merchantId": "f9e8d7c6-b5a4-3210-9876-543210fedcba",
      "planId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "customer@example.com",
      "externalId": "usr_789abc",
      "status": "pending",
      "currentPeriodStart": "2026-04-19T00:00:00.000Z",
      "currentPeriodEnd": "2026-05-19T00:00:00.000Z",
      "gracePeriodEndsAt": "2026-04-26T00:00:00.000Z",
      "cancelAtEnd": false,
      "metadata": {
        "userId": "usr_789abc",
        "signupSource": "checkout"
      },
      "createdAt": "2026-04-19T10:00:00.000Z"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "error": "Bad Request",
    "message": "Cannot enroll into an archived plan"
  }
  ```

  ```json 404 theme={null}
  {
    "error": "Not Found",
    "message": "Subscription plan not found"
  }
  ```

  ```json 409 theme={null}
  {
    "error": "Conflict",
    "message": "Subscriber is already enrolled in this plan (status: active)"
  }
  ```

  ```json 401 theme={null}
  {
    "error": "Unauthorized",
    "message": "Invalid API key"
  }
  ```
</ResponseExample>
