# Subscriptions

A subscription generates a regular invoice every `interval`, starting on
`start_date`. Generated invoices are normal invoices and appear in
`GET /invoices`.

Statuses: `draft` (never generates invoices), `active`, `paused`. Status
can't be set through update. Use `/activate` and `/pause` instead. A
subscription with `number_of_invoices` set is paused automatically once
`invoices_generated` reaches it.

Invoices are generated when `next_invoice_at` is today or earlier. If
several billing periods are already due (e.g. a past `start_date`), one
invoice is generated per missed period: the first right away, the rest
roughly one per hour after that.

`pay` and `send` are attempts made for each generated invoice, payment
first. `pay` tries to charge the client's default saved card; a failed
charge leaves that invoice unpaid and, if the client has a saved card,
notifies the account. `send` tries to email the invoice to the client;
if it can't be sent, the invoice is still generated with
`sent_at: null`. Neither ever fails the request that generated the
invoice.

A subscription's client and `start_date` can't be changed. To move the
schedule, change `next_invoice_at` instead. Deleted subscriptions are
hidden until you restore them.

## The subscription object

- `id` (string): Example: `0abcDEF1234567890xyzAB`.
- `status` (string): One of `draft`, `active`, `paused`.
- `client_id` (string): Example: `0abcDEF1234567890xyzAB`.
- `client` (object): The client embedded in invoices and subscriptions, without `payment_methods`.
- `client.id` (string): Example: `0abcDEF1234567890xyzAB`.
- `client.name` (string)
- `client.emails` (array of string): Min 1 items.
- `client.address` (string or null)
- `client.currency` (string): Three-letter currency code, in lowercase. Example: `usd`.
- `client.language` (string): Two-letter language code, in lowercase. One of `da`, `en`, `fr`, `de`, `it`, `no`, `pt`, `es`.
- `client.default_payment_method_id` (string or null): The card `POST /invoices/{id}/pay` uses when no `payment_method_id` is sent. Null when the client has no card on file. Example: `0abcDEF1234567890xyzAB`.
- `client.created_at` (timestamp): Date and time in UTC. Example: `2024-06-15T12:00:00.000000Z`.
- `client.updated_at` (timestamp): Date and time in UTC. Example: `2024-06-15T12:00:00.000000Z`.
- `client.is_deleted` (boolean)
- `currency` (string): Three-letter currency code, in lowercase. Example: `usd`.
- `language` (string): Two-letter language code, in lowercase. One of `da`, `en`, `fr`, `de`, `it`, `no`, `pt`, `es`.
- `notes` (string or null)
- `items` (array of object)
- `items[].description` (string)
- `items[].amount` (integer): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `items[].quantity` (string): Quantity as a decimal string, without trailing zeros. Example: `1`.
- `items[].total` (integer): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `items[].one_time` (boolean): Billed on the next generated invoice only, then removed from the subscription.
- `discounts` (array of object)
- `discounts[].amount` (integer or null): Fixed amount off, in cents. Example: `10000`. Min 0.
- `discounts[].percent` (string or null): Percent off the subtotal, as a decimal string without trailing zeros. Example: `12.5`.
- `discount_amount` (integer): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `taxable_amount` (integer): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `tax_rates` (array of object)
- `tax_rates[].id` (string): The tax rate's ID. Use it in `tax_rates`. Example: `0abcDEF1234567890xyzAB`.
- `tax_rates[].name` (string): Example: `TPS`.
- `tax_rates[].percentage` (string): Percentage as a decimal string, without trailing zeros. Example: `5`.
- `tax_rates[].amount` (integer): Tax amount for this rate. Example: `10000`. Min 0.
- `tax_amount` (integer): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `subtotal` (integer): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `total` (integer): Total of the next generated invoice. Example: `10000`. Min 0.
- `accept_cards` (boolean): Whether generated invoices can be paid by card online.
- `interval` (string): How often to bill. `biweekly` is every 2 weeks, `four_weeks`, `eight_weeks`, and `twelve_weeks` are every 4, 8, and 12 weeks, and `biannual` is every 6 months. One of `weekly`, `biweekly`, `four_weeks`, `monthly`, `eight_weeks`, `twelve_weeks`, `quarterly`, `biannual`, `yearly`.
- `start_date` (date): Example: `2024-06-15`.
- `next_invoice_at` (date): Date the next invoice will be generated. Example: `2024-07-15`.
- `number_of_invoices` (integer or null): Number of invoices to generate before the subscription pauses automatically. `null` means no limit. Min 1.
- `invoices_generated` (integer): Number of invoices generated so far, not counting deleted ones.
- `send` (boolean): Email each generated invoice to the client.
- `pay` (boolean): Attempt to charge the client's default saved card for each generated invoice.
- `created_at` (timestamp): Date and time in UTC. Example: `2024-06-15T12:00:00.000000Z`.
- `updated_at` (timestamp): Date and time in UTC. Example: `2024-06-15T12:00:00.000000Z`.
- `is_deleted` (boolean)

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## List subscriptions

`GET /subscriptions`

### Query parameters

- `search` (string): Matches notes, client name and emails, and item descriptions. Not case-sensitive. Example: `retainer`.
- `status` (string): One of `draft`, `active`, `paused`.
- `client_id` (string): The client ID. Example: `0abcDEF1234567890xyzAB`.
- `limit` (integer): Number of results per page. Default: `10`. Min 1. Max 100.
- `cursor` (string): To get the next page, pass the `next_cursor` from the previous response.
- `created_at` (object): Keys `gt`, `gte`, `lt`, `lte`. Example: `created_at[gt]=2024-06-15T12:00:00.000000Z`.
- `updated_at` (object): Keys `gt`, `gte`, `lt`, `lte`. Example: `updated_at[gt]=2024-06-15T12:00:00.000000Z`.

### Response

- `200`: Paginated subscriptions. Returns a [paginated list](/docs/pagination) of [subscription objects](#the-subscription-object).

### Errors

- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `404`: The record doesn't exist or was deleted.
- `422`: The request body or query parameters are invalid.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl https://api.tallymark.com/subscriptions \
  -H "Authorization: Bearer $TALLYMARK_API_KEY"
```

### Example response

```json
{
  "data": [
    {
      "id": "0abcDEF1234567890xyzAB",
      "status": "active",
      "client_id": "0abcDEF1234567890xyzAB",
      "client": {
        "id": "0abcDEF1234567890xyzAB",
        "name": "Jane Doe",
        "emails": [
          "jane@example.com"
        ],
        "address": "1 Main St",
        "currency": "usd",
        "language": "en",
        "default_payment_method_id": "0abcDEF1234567890xyzAB",
        "created_at": "2024-06-15T12:00:00.000000Z",
        "updated_at": "2024-06-15T12:00:00.000000Z",
        "is_deleted": false
      },
      "currency": "usd",
      "language": "en",
      "notes": null,
      "items": [
        {
          "description": "Monthly retainer",
          "amount": 10000,
          "quantity": "1",
          "total": 10000,
          "one_time": false
        }
      ],
      "discounts": [],
      "discount_amount": 0,
      "taxable_amount": 10000,
      "tax_rates": [],
      "tax_amount": 0,
      "subtotal": 10000,
      "total": 10000,
      "accept_cards": true,
      "interval": "monthly",
      "start_date": "2024-06-15",
      "next_invoice_at": "2024-07-15",
      "number_of_invoices": null,
      "invoices_generated": 1,
      "send": true,
      "pay": true,
      "created_at": "2024-06-15T12:00:00.000000Z",
      "updated_at": "2024-06-15T12:00:00.000000Z",
      "is_deleted": false
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

## Create a subscription

`POST /subscriptions`

Creates a `draft` subscription, or an `active` one with
`activate: true`. Pass `client_id` for an existing client, or a
`client` object to create one, but not both.

When activated with a `start_date` of today or earlier, the first
invoice is generated immediately (and sent / paid per `send` and
`pay`). A failed payment does not fail the request. A past
`start_date` also generates one invoice per missed period after
that, roughly one per hour.

### Request body

Send exactly one of `client_id` (an existing client) or `client` (a
new client).

- `client_id` (string): Example: `0abcDEF1234567890xyzAB`.
- `client` (object): A new client. If a non-deleted client with exactly these emails (same order) already exists, it is reused and updated: its name, its address (cleared when `address` is omitted), and its currency and language (set to this request's).
- `client.name` (string, required): Max length 255.
- `client.email` (string or array of string, required): One email address, or a list of up to 4. Example: `jane@example.com`.
- `client.address` (string or null)
- `start_date` (date, required): Date of the first invoice.
- `number_of_invoices` (integer or null): Number of invoices to generate before the subscription pauses automatically. Omit it or send `null` for no limit. Min 1.
- `activate` (boolean): Create the subscription `active` instead of `draft`. Default: `false`.
- `items` (array of object, required): Min 1 items.
- `items[].description` (string, required): Max length 255.
- `items[].amount` (integer, required): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `items[].quantity` (number, required): Rounded to 4 decimals. Example: `1`. Min 0.
- `items[].one_time` (boolean): Bill this item on the next generated invoice only (e.g. a setup fee). At least one item must be recurring. Default: `false`.
- `discounts` (array of object): Max 1 items.
- `discounts[].amount` (integer or null): Fixed amount off, in cents. Example: `10000`. Min 0.
- `discounts[].percent` (number or null): Percent off the subtotal, up to 4 decimals. Example: `12.5`. Min 0. Max 100.
- `interval` (string, required): How often to bill. `biweekly` is every 2 weeks, `four_weeks`, `eight_weeks`, and `twelve_weeks` are every 4, 8, and 12 weeks, and `biannual` is every 6 months. One of `weekly`, `biweekly`, `four_weeks`, `monthly`, `eight_weeks`, `twelve_weeks`, `quarterly`, `biannual`, `yearly`.
- `currency` (string, required): Three-letter currency code, in lowercase. Example: `usd`.
- `language` (string, required): Two-letter language code, in lowercase. One of `da`, `en`, `fr`, `de`, `it`, `no`, `pt`, `es`.
- `tax_rates` (array of string): Tax rate IDs belonging to the account. Deleted tax rates cannot be added, but ones already on the subscription can be kept.
- `include_default_tax_rates` (boolean): Adds the account's default tax rates on top of `tax_rates`. On update, if `tax_rates` is omitted, the defaults are added to the tax rates already on the subscription. A tax rate is never applied twice. Default: `false`.
- `accept_cards` (boolean, required)
- `send` (boolean): Email each generated invoice to the client. Default: `false`.
- `pay` (boolean): Attempt to charge the client's default saved card for each generated invoice. A failed charge leaves that invoice unpaid. Default: `false`.
- `notes` (string or null)

### Response

- `201`: Created subscription. Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `403` `api_key_read_only`: This API key is read-only and cannot make write requests.
- `404`: The record doesn't exist or was deleted.
- `422`: The request body or query parameters are invalid.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl -X POST https://api.tallymark.com/subscriptions \
  -H "Authorization: Bearer $TALLYMARK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "client": {
    "name": "Jane Doe",
    "email": "jane@example.com"
  },
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": 1
    },
    {
      "description": "Setup fee",
      "amount": 5000,
      "quantity": 1,
      "one_time": true
    }
  ],
  "interval": "monthly",
  "start_date": "2027-01-01",
  "currency": "usd",
  "language": "en",
  "accept_cards": true,
  "activate": true,
  "send": true,
  "pay": true
}'
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## Show a subscription

`GET /subscriptions/{id}`

### Path parameters

- `id` (string, required): The subscription ID. Example: `0abcDEF1234567890xyzAB`.

### Response

- `200`: Subscription. Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `404`: The record doesn't exist or was deleted.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl https://api.tallymark.com/subscriptions/0abcDEF1234567890xyzAB \
  -H "Authorization: Bearer $TALLYMARK_API_KEY"
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## Update a subscription

`POST /subscriptions/{id}/update`

Updates a subscription in any status. Only the fields you send are
changed; omitted fields keep their current value. Send `notes: null`
to clear the notes, `number_of_invoices: null` for no limit, and
`discounts: []` or `tax_rates: []` to remove them. Changes apply to
invoices generated from now on, not to invoices already generated.
The client and `start_date` can't be changed.

If the subscription is `active` and the new `next_invoice_at` is
today or earlier, the next invoice is generated immediately, and any
other missed periods after that, roughly one per hour.

### Path parameters

- `id` (string, required): The subscription ID. Example: `0abcDEF1234567890xyzAB`.

### Request body

Send at most one discount.

- `next_invoice_at` (date): Date the next invoice will be generated.
- `number_of_invoices` (integer or null): Number of invoices to generate before the subscription pauses automatically. Send `null` for no limit; omit it to keep the current value. Min 1.
- `items` (array of object): Min 1 items.
- `items[].description` (string, required): Max length 255.
- `items[].amount` (integer, required): Amount in the smallest currency unit (cents). Example: `10000`. Min 0.
- `items[].quantity` (number, required): Rounded to 4 decimals. Example: `1`. Min 0.
- `items[].one_time` (boolean): Bill this item on the next generated invoice only (e.g. a setup fee). At least one item must be recurring. Default: `false`.
- `discounts` (array of object): Max 1 items.
- `discounts[].amount` (integer or null): Fixed amount off, in cents. Example: `10000`. Min 0.
- `discounts[].percent` (number or null): Percent off the subtotal, up to 4 decimals. Example: `12.5`. Min 0. Max 100.
- `interval` (string): How often to bill. `biweekly` is every 2 weeks, `four_weeks`, `eight_weeks`, and `twelve_weeks` are every 4, 8, and 12 weeks, and `biannual` is every 6 months. One of `weekly`, `biweekly`, `four_weeks`, `monthly`, `eight_weeks`, `twelve_weeks`, `quarterly`, `biannual`, `yearly`.
- `currency` (string): Three-letter currency code, in lowercase. Example: `usd`.
- `language` (string): Two-letter language code, in lowercase. One of `da`, `en`, `fr`, `de`, `it`, `no`, `pt`, `es`.
- `tax_rates` (array of string): Tax rate IDs belonging to the account. Deleted tax rates cannot be added, but ones already on the subscription can be kept.
- `include_default_tax_rates` (boolean): Adds the account's default tax rates on top of `tax_rates`. On update, if `tax_rates` is omitted, the defaults are added to the tax rates already on the subscription. A tax rate is never applied twice. Default: `false`.
- `accept_cards` (boolean)
- `send` (boolean): Email each generated invoice to the client. Default: `false`.
- `pay` (boolean): Attempt to charge the client's default saved card for each generated invoice. A failed charge leaves that invoice unpaid. Default: `false`.
- `notes` (string or null)

### Response

- `200`: Updated subscription. Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `403` `api_key_read_only`: This API key is read-only and cannot make write requests.
- `404`: The record doesn't exist or was deleted.
- `422`: The request body or query parameters are invalid.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl -X POST https://api.tallymark.com/subscriptions/0abcDEF1234567890xyzAB/update \
  -H "Authorization: Bearer $TALLYMARK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 12000,
      "quantity": 1
    }
  ],
  "next_invoice_at": "2024-08-01"
}'
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## Pause a subscription

`POST /subscriptions/{id}/pause`

Pauses an `active` subscription: no invoices are generated until it
is activated again.

### Path parameters

- `id` (string, required): The subscription ID. Example: `0abcDEF1234567890xyzAB`.

### Response

- `200`: Paused subscription. Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `subscription_draft`: This subscription is a draft and cannot be paused. Only active subscriptions can be paused.
- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `403` `api_key_read_only`: This API key is read-only and cannot make write requests.
- `404`: The record doesn't exist or was deleted.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl -X POST https://api.tallymark.com/subscriptions/0abcDEF1234567890xyzAB/pause \
  -H "Authorization: Bearer $TALLYMARK_API_KEY"
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## Activate a subscription

`POST /subscriptions/{id}/activate`

Activates a `draft` or resumes a `paused` subscription. If
`next_invoice_at` is today or earlier, the next invoice is generated
immediately (and sent / paid per `send` and `pay`), and any other
missed periods after that, roughly one per hour. Check
`next_invoice_at` before resuming a subscription paused for longer
than a billing period.

To resume a subscription that has generated all of its
`number_of_invoices`, raise `number_of_invoices` first.

### Path parameters

- `id` (string, required): The subscription ID. Example: `0abcDEF1234567890xyzAB`.

### Response

- `200`: Active subscription. Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `subscription_ended`: This subscription has generated all of its invoices and cannot be activated. Increase number_of_invoices first.
- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `403` `api_key_read_only`: This API key is read-only and cannot make write requests.
- `404`: The record doesn't exist or was deleted.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl -X POST https://api.tallymark.com/subscriptions/0abcDEF1234567890xyzAB/activate \
  -H "Authorization: Bearer $TALLYMARK_API_KEY"
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## Delete a subscription

`POST /subscriptions/{id}/delete`

Deletes a subscription. An `active` subscription is paused first.
Invoices it already generated are not affected. You can restore it
later.

### Path parameters

- `id` (string, required): The subscription ID. Example: `0abcDEF1234567890xyzAB`.

### Response

- `200`: Deleted subscription (`is_deleted` true). Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `403` `api_key_read_only`: This API key is read-only and cannot make write requests.
- `404`: The record doesn't exist or was deleted.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl -X POST https://api.tallymark.com/subscriptions/0abcDEF1234567890xyzAB/delete \
  -H "Authorization: Bearer $TALLYMARK_API_KEY"
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```

## Restore a deleted subscription

`POST /subscriptions/{id}/restore`

Restores a deleted subscription. It keeps its status (a deleted
active subscription comes back `paused`). Activate it to resume.

### Path parameters

- `id` (string, required): The subscription ID. Example: `0abcDEF1234567890xyzAB`.

### Response

- `200`: Restored subscription (`is_deleted` false). Returns a [subscription object](#the-subscription-object).

### Errors

- `400` `request_failed`: Your request could not be processed.
- `400` `api_version_unsupported`: The requested API version is not supported. Current version: 2026-08-21
- `401` `api_key_missing`: The API key is missing.
- `401` `api_key_invalid`: The API key is invalid or has been revoked.
- `403` `api_key_read_only`: This API key is read-only and cannot make write requests.
- `404`: The record doesn't exist or was deleted.
- `429`: Too many requests. The limit is 300 requests per 5 minutes.

### Example request

```bash
curl -X POST https://api.tallymark.com/subscriptions/0abcDEF1234567890xyzAB/restore \
  -H "Authorization: Bearer $TALLYMARK_API_KEY"
```

### Example response

```json
{
  "id": "0abcDEF1234567890xyzAB",
  "status": "active",
  "client_id": "0abcDEF1234567890xyzAB",
  "client": {
    "id": "0abcDEF1234567890xyzAB",
    "name": "Jane Doe",
    "emails": [
      "jane@example.com"
    ],
    "address": "1 Main St",
    "currency": "usd",
    "language": "en",
    "default_payment_method_id": "0abcDEF1234567890xyzAB",
    "created_at": "2024-06-15T12:00:00.000000Z",
    "updated_at": "2024-06-15T12:00:00.000000Z",
    "is_deleted": false
  },
  "currency": "usd",
  "language": "en",
  "notes": null,
  "items": [
    {
      "description": "Monthly retainer",
      "amount": 10000,
      "quantity": "1",
      "total": 10000,
      "one_time": false
    }
  ],
  "discounts": [],
  "discount_amount": 0,
  "taxable_amount": 10000,
  "tax_rates": [],
  "tax_amount": 0,
  "subtotal": 10000,
  "total": 10000,
  "accept_cards": true,
  "interval": "monthly",
  "start_date": "2024-06-15",
  "next_invoice_at": "2024-07-15",
  "number_of_invoices": null,
  "invoices_generated": 1,
  "send": true,
  "pay": true,
  "created_at": "2024-06-15T12:00:00.000000Z",
  "updated_at": "2024-06-15T12:00:00.000000Z",
  "is_deleted": false
}
```
