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

# Create Recurrence

> Attach a schedule to an experience so it produces bookable slots

# Create Recurrence

Attaches a schedule to an existing experience. The experience template
itself must already exist (create it first via [Create Experience](/api-reference/experiences/create-experience)).

The recurrence defines a **cadence** (how often), an **end condition**
(when to stop), and one or more **session templates** (what time each
day, with what capacity and provider). Once an active recurrence
exists, the public booking page expands its rules on-the-fly into the
date/time grid — no separate "publish slots" step is required.

Requires the `experiences:write` scope.

## Idempotency

Pass an `Idempotency-Key` header (max 255 chars) to make POST retries safe. The first request executes the create; subsequent requests with the same key within 24 hours replay the original response verbatim — including the original status code — and add an `Idempotent-Replay: true` response header. Keys are scoped per API key, so two integrations can use the same key value without collision.

Two concurrent requests with the same key return `409 idempotent_request_in_progress` to the second caller.

## Path Parameters

<ParamField path="experience_id" type="string" required>
  Parent experience ID. Must belong to the API key's organization.
</ParamField>

## Request Body

<ParamField body="provider_id" type="string" required>
  Default provider (SpaceMember) for this recurrence. Used by session templates that don't specify their own `provider_id`.
</ParamField>

<ParamField body="timezone" type="string" required>
  IANA timezone the schedule is anchored to (e.g. `America/New_York`). Session start times are interpreted in this zone.
</ParamField>

<ParamField body="start_date" type="string" required>
  First date the recurrence is active. Accepts an ISO-8601 datetime or a `YYYY-MM-DD` date string.
</ParamField>

<ParamField body="cadence" type="object" required>
  <Expandable>
    <ParamField body="frequency" type="enum" required>`daily`, `weekly`, or `monthly`.</ParamField>
    <ParamField body="interval" type="integer" required>Every-N (1..52). `interval: 2` with `frequency: "weekly"` = every other week.</ParamField>
    <ParamField body="days_of_week" type="array<integer>">Active weekdays for `weekly` cadence. 0=Sun..6=Sat.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="end_condition" type="object" required>
  Discriminated union, one of:

  <Expandable>
    <ParamField body="type=date" type="object">`{ type: "date", until: "<ISO datetime or YYYY-MM-DD>" }`</ParamField>
    <ParamField body="type=count" type="object">`{ type: "count", occurrences: <1..500> }`</ParamField>
    <ParamField body="type=never" type="object">`{ type: "never" }`</ParamField>
  </Expandable>
</ParamField>

<ParamField body="session_templates" type="array<object>" required>
  At least one template, up to 336. Each template materializes into one
  session per occurrence date.

  <Expandable>
    <ParamField body="start_time_of_day" type="string" required>`HH:mm` 24-hour, local to `timezone`.</ParamField>
    <ParamField body="capacity" type="integer" required>Seats per occurrence (1..10000).</ParamField>
    <ParamField body="provider_id" type="string" required>SpaceMember ID hosting this slot.</ParamField>
    <ParamField body="days_of_week" type="array<integer>">Optional per-template filter (0=Sun..6=Sat). When omitted, the template runs on every active day of the recurrence — letting you mix different hours per day (e.g. Mon–Fri 9–5 + Sat 10–14).</ParamField>
  </Expandable>

  Two templates can share a `start_time_of_day` only if their `days_of_week` are disjoint.
</ParamField>

<ParamField body="status" type="enum">
  `active` or `paused`. Defaults to `active`.
</ParamField>

## Response

Returns the created recurrence with `201 Created`.

<ResponseField name="data" type="object">
  Same schema as [Get Recurrence](/api-reference/recurrences/get-recurrence).
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST \
    -H "X-API-KEY: your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "provider_id": "prov_xyz",
      "timezone": "America/New_York",
      "start_date": "2026-09-01",
      "cadence": { "frequency": "weekly", "interval": 1, "days_of_week": [1, 3] },
      "end_condition": { "type": "never" },
      "session_templates": [
        { "start_time_of_day": "09:00", "capacity": 12, "provider_id": "prov_xyz" },
        { "start_time_of_day": "17:00", "capacity": 12, "provider_id": "prov_xyz" }
      ]
    }' \
    "https://www.gomry.com/api/v1/experiences/AbCdEfGhIjKlMnOpQrSt/recurrences"
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "data": {
      "id": "rec_AbCdEfGh",
      "service_id": "AbCdEfGhIjKlMnOpQrSt",
      "provider_id": "prov_xyz",
      "timezone": "America/New_York",
      "start_date": "2026-09-01",
      "cadence": { "frequency": "weekly", "interval": 1, "days_of_week": [1, 3] },
      "end_condition": { "type": "never" },
      "session_templates": [
        { "start_time_of_day": "09:00", "capacity": 12, "provider_id": "prov_xyz", "days_of_week": null },
        { "start_time_of_day": "17:00", "capacity": 12, "provider_id": "prov_xyz", "days_of_week": null }
      ],
      "status": "active",
      "created_at": "2026-05-25T10:00:00.000Z",
      "updated_at": "2026-05-25T10:00:00.000Z"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "error": "Validation failed",
    "details": {
      "fieldErrors": { "session_templates": ["At least one start time required"] }
    }
  }
  ```

  ```json 404 theme={null}
  { "error": "Experience not found" }
  ```

  ```json 403 theme={null}
  {
    "error": "insufficient_scope",
    "message": "This API key does not have 'write' access to 'experiences'.",
    "required_scope": "experiences:write"
  }
  ```
</ResponseExample>
