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

# Subscription Lifecycle

> States, transitions, and how spans determine what you can export

# Subscription Lifecycle

A subscription tells Ticksupply to record a specific datastream for your account. Once active, it produces the data you can later pull through the Exports API. This guide explains the subscription state machine, what each transition does, and how a subscription's history of active periods ("spans") determines what is exportable.

## States

A subscription is always in exactly one of three states:

| State     | Meaning                                                                                                     |
| --------- | ----------------------------------------------------------------------------------------------------------- |
| `active`  | Data is being recorded. Exports for this subscription work within its recorded spans.                       |
| `paused`  | Recording is stopped. Data captured in earlier spans remains exportable; no new data is collected.          |
| `deleted` | Terminal. The subscription is no longer visible in `GET /v1/subscriptions` and its recorded spans are gone. |

## Transitions

Each state change maps to a dedicated endpoint:

| From → To            | Endpoint                                               | Effect on spans                                                                                         | Billing-gated |
| -------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | ------------- |
| *(new)* → `active`   | `POST /v1/subscriptions`                               | Opens a new span starting now.                                                                          | Yes           |
| `active` → `paused`  | `POST /v1/subscriptions/{id}/pause`                    | Closes the current span (`ended_at = now`).                                                             | No            |
| `paused` → `active`  | `POST /v1/subscriptions/{id}/resume`                   | Opens a new span starting now.                                                                          | Yes           |
| any → `deleted`      | `DELETE /v1/subscriptions/{id}`                        | **All spans are removed.**                                                                              | No            |
| `deleted` → `active` | `POST /v1/subscriptions` with the same `datastream_id` | Reuses the same subscription ID, resets `created_at`, opens a fresh span. Prior spans are not restored. | Yes           |

<Note>
  `pause`, `resume`, and `delete` are idempotent. Calling `pause` on an already-paused subscription (or `resume` on an already-active one) returns `204 No Content` without changing anything. `delete` on an already-deleted subscription also succeeds without side effects.
</Note>

Billing-gated transitions can return `402 payment_required` — see [Billing interactions](#billing-interactions).

## State diagram

```mermaid theme={"system"}
stateDiagram-v2
    [*] --> active: create
    active --> paused: pause
    paused --> active: resume
    active --> deleted: delete
    paused --> deleted: delete
    deleted --> active: recreate (same datastream_id)
```

## Spans drive exportable time ranges

A span is a single `[started_at, ended_at]` window during which the subscription was recording. Exports are always clipped to the intersection of their requested time range with your subscription's spans.

| State     | Current spans                                                                              |
| --------- | ------------------------------------------------------------------------------------------ |
| `active`  | One open span (`ended_at` is `null`) plus any closed spans from prior pause/resume cycles. |
| `paused`  | All spans are closed; the most recent `ended_at` marks when recording stopped.             |
| `deleted` | No spans exist.                                                                            |

A subscription that has been paused and resumed will have multiple spans. Retrieve them in chronological order with [`GET /v1/subscriptions/{id}/spans`](/api-reference/subscriptions/get-subscription-spans):

```bash cURL theme={"system"}
curl -H "X-Api-Key: $TICKSUPPLY_API_KEY" \
  "https://api.ticksupply.com/v1/subscriptions/sub_019d5faefcce7d218eb2c52037ddb44d/spans"
```

```json theme={"system"}
[
  { "id": "spn_019c2a1b0f3b7abc9d4e5f6a7b8c9d0e1", "started_at": "2024-12-20T12:00:00Z", "ended_at": "2024-12-21T09:30:00Z" },
  { "id": "spn_019c4e8d1234abcd5678ef90123456789", "started_at": "2024-12-22T08:00:00Z", "ended_at": null }
]
```

<Note>
  The `spans` array on the `POST /v1/subscriptions` response is always `[]`. Use `GET /v1/subscriptions/{id}/spans` right after creation to retrieve the initial open span.
</Note>

## Billing interactions

Three lifecycle-related endpoints can return `402 payment_required`:

* `POST /v1/subscriptions` — your plan has no room for another subscription, or the trial stream cap has been reached.
* `POST /v1/subscriptions/{id}/resume` — resuming would re-enable recording on a plan that currently disallows it (for example, a suspended or past-due plan).
* `POST /v1/exports` — billing rules deny the export (for example, the trial export cap has been reached).

`pause` and `delete` never return `402`. See [Error Handling](/guides/error-handling) for the full list of error codes.

## Common questions

<AccordionGroup>
  <Accordion title="Can I export from a deleted subscription?">
    No. Deletion removes the subscription's spans, and `POST /v1/exports` returns `403 permission_denied` with the message `"Subscription has been deleted"`. If you want to stop collection but keep the data exportable, pause the subscription instead.
  </Accordion>

  <Accordion title="Can I undo a deletion?">
    The recorded history cannot be recovered. You can start a new recording for the same datastream by calling `POST /v1/subscriptions` with the original `datastream_id` — the API reuses the subscription's ID, resets `created_at`, and opens a fresh span. Data captured before deletion is not accessible from the restored subscription.
  </Accordion>

  <Accordion title="What happens to data during the gap between pause and resume?">
    Nothing is recorded. Pause closes the active span at the moment the call lands; resume opens a brand-new span. Exports that cross the gap skip that interval.
  </Accordion>

  <Accordion title="What if I try to create a duplicate subscription for the same datastream?">
    If an `active` or `paused` subscription already exists for that `datastream_id`, the API returns `409 already_exists`. Only `deleted` subscriptions can be recreated through this path — that is the "restore" flow described above.
  </Accordion>

  <Accordion title="Does a paused subscription count against my plan limits?">
    No. Only `active` subscriptions count toward stream quota. Resuming a paused subscription is subject to billing and trial-limit checks at the moment of resumption.
  </Accordion>
</AccordionGroup>

## Related

* [Create a subscription](/api-reference/subscriptions/create-subscription)
* [List subscription spans](/api-reference/subscriptions/get-subscription-spans)
* [Create an export](/api-reference/exports/create-export)
* [Error handling](/guides/error-handling)
