# Subscriptions

Recurring plans, billed as one invoice per cycle.

## List subscriptions

`GET /v1/subscriptions`

### Responses

#### `200`: The merchant's subscriptions, newest first.

Body (`application/json`):

- `id` `string` _(required)_
- `subscriber` `object` _(required)_
  - `customerId` `string` _(required)_: The merchant's customer, found or created by email.
  - `name` `string` _(required)_
  - `email` `string | null` _(required)_
- `description` `string` _(required)_
- `amount` `object` _(required)_
  - `amount` `string` _(required)_: Exact minor units. Calculate with this value.
  - `asset` `string` _(required)_: ISO asset code, e.g. IDR, USD, USDC.
  - `formatted` `string` _(required)_: Machine decimal; ungrouped and dot-separated.
  - `display` `string` _(required)_: Localized display text. Never parse this value.
- `interval` `string` _(required)_
- `state` `string` _(required)_
- `billedCycles` `integer` _(required)_: Cycles invoiced so far.
- `daysUntilDue` `integer` _(required)_: Each cycle's invoice falls due this many days after issue.
- `anchorAt` `string` _(required)_: The first billing date; every later date derives from it.
- `nextBillingAt` `string | null` _(required)_: Only an active subscription has one. Null while paused or once cancelled.
- `createdAt` `string` _(required)_
- `cancelledAt` `string | null` _(required)_

#### `401`: Missing or unknown API key.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

### Example request

```bash
curl https://api.mayarin.xyz/v1/subscriptions
```

```ts
fetch('https://api.mayarin.xyz/v1/subscriptions')
```

## Create a subscription

`POST /v1/subscriptions`

Puts a customer on a recurring plan. Send-to-pay: every cycle Mayarin issues the subscriber an invoice and emails its pay link; they pay it on any rail. Payments on a cycle carry `metadata.subscriptionId` into the `payment.*` webhooks. The merchant's customer with the given email is reused, or created. Needs `catalog:manage`.

### Request body (`application/json`)

- `customer` `object` _(required)_
  - `name` `string` _(required)_
  - `email` `string <email>` _(required)_
- `description` `string` _(required)_
- `amount` `object` _(required)_
  - `amount` `string` _(required)_
  - `asset` `string` _(required)_
- `interval` `string` _(required)_
- `startAt` `string <date-time>`
- `daysUntilDue` `integer`

### Responses

#### `201`: Subscription created, active.

Body (`application/json`):

- `id` `string` _(required)_
- `subscriber` `object` _(required)_
  - `customerId` `string` _(required)_: The merchant's customer, found or created by email.
  - `name` `string` _(required)_
  - `email` `string | null` _(required)_
- `description` `string` _(required)_
- `amount` `object` _(required)_
  - `amount` `string` _(required)_: Exact minor units. Calculate with this value.
  - `asset` `string` _(required)_: ISO asset code, e.g. IDR, USD, USDC.
  - `formatted` `string` _(required)_: Machine decimal; ungrouped and dot-separated.
  - `display` `string` _(required)_: Localized display text. Never parse this value.
- `interval` `string` _(required)_
- `state` `string` _(required)_
- `billedCycles` `integer` _(required)_: Cycles invoiced so far.
- `daysUntilDue` `integer` _(required)_: Each cycle's invoice falls due this many days after issue.
- `anchorAt` `string` _(required)_: The first billing date; every later date derives from it.
- `nextBillingAt` `string | null` _(required)_: Only an active subscription has one. Null while paused or once cancelled.
- `createdAt` `string` _(required)_
- `cancelledAt` `string | null` _(required)_

#### `400`: Validation error.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

#### `403`: The key does not grant catalog:manage.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

### Example request

```bash
curl https://api.mayarin.xyz/v1/subscriptions \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "customer": {
    "name": "string",
    "email": "string"
  },
  "description": "string",
  "amount": {
    "amount": "string",
    "asset": "IDR"
  },
  "interval": "week",
  "startAt": "1970-01-01T00:00:00.000Z",
  "daysUntilDue": 7
}'
```

```ts
fetch('https://api.mayarin.xyz/v1/subscriptions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    customer: {
      name: 'string',
      email: 'string'
    },
    description: 'string',
    amount: {
      amount: 'string',
      asset: 'IDR'
    },
    interval: 'week',
    startAt: '1970-01-01T00:00:00.000Z',
    daysUntilDue: 7
  })
})
```

## Get a subscription and its cycles

`GET /v1/subscriptions/{id}`

### Path parameters

- `id` `string` _(required)_

### Responses

#### `200`: The subscription and every cycle's invoice.

Body (`application/json`):

- `subscription` `object` _(required)_
  - `id` `string` _(required)_
  - `subscriber` `object` _(required)_
    - `customerId` `string` _(required)_: The merchant's customer, found or created by email.
    - `name` `string` _(required)_
    - `email` `string | null` _(required)_
  - `description` `string` _(required)_
  - `amount` `object` _(required)_
    - `amount` `string` _(required)_: Exact minor units. Calculate with this value.
    - `asset` `string` _(required)_: ISO asset code, e.g. IDR, USD, USDC.
    - `formatted` `string` _(required)_: Machine decimal; ungrouped and dot-separated.
    - `display` `string` _(required)_: Localized display text. Never parse this value.
  - `interval` `string` _(required)_
  - `state` `string` _(required)_
  - `billedCycles` `integer` _(required)_: Cycles invoiced so far.
  - `daysUntilDue` `integer` _(required)_: Each cycle's invoice falls due this many days after issue.
  - `anchorAt` `string` _(required)_: The first billing date; every later date derives from it.
  - `nextBillingAt` `string | null` _(required)_: Only an active subscription has one. Null while paused or once cancelled.
  - `createdAt` `string` _(required)_
  - `cancelledAt` `string | null` _(required)_
- `cycles` `object & object[]` _(required)_: Every cycle's invoice, newest first, each with its pay `url` and status.

#### `404`: No subscription with that id, or not this merchant's.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

### Example request

```bash
curl https://api.mayarin.xyz/v1/subscriptions/string
```

```ts
fetch('https://api.mayarin.xyz/v1/subscriptions/string')
```

## Pause a subscription

`POST /v1/subscriptions/{id}/pause`

Stops billing. Nothing is billed while paused.

### Path parameters

- `id` `string` _(required)_

### Responses

#### `200`: The subscription after the transition.

Body (`application/json`):

- `id` `string` _(required)_
- `subscriber` `object` _(required)_
  - `customerId` `string` _(required)_: The merchant's customer, found or created by email.
  - `name` `string` _(required)_
  - `email` `string | null` _(required)_
- `description` `string` _(required)_
- `amount` `object` _(required)_
  - `amount` `string` _(required)_: Exact minor units. Calculate with this value.
  - `asset` `string` _(required)_: ISO asset code, e.g. IDR, USD, USDC.
  - `formatted` `string` _(required)_: Machine decimal; ungrouped and dot-separated.
  - `display` `string` _(required)_: Localized display text. Never parse this value.
- `interval` `string` _(required)_
- `state` `string` _(required)_
- `billedCycles` `integer` _(required)_: Cycles invoiced so far.
- `daysUntilDue` `integer` _(required)_: Each cycle's invoice falls due this many days after issue.
- `anchorAt` `string` _(required)_: The first billing date; every later date derives from it.
- `nextBillingAt` `string | null` _(required)_: Only an active subscription has one. Null while paused or once cancelled.
- `createdAt` `string` _(required)_
- `cancelledAt` `string | null` _(required)_

#### `404`: No subscription with that id, or not this merchant's.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

#### `409`: The transition is not allowed from the current state.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

### Example request

```bash
curl https://api.mayarin.xyz/v1/subscriptions/string/pause \
  --request POST
```

```ts
fetch('https://api.mayarin.xyz/v1/subscriptions/string/pause', {
  method: 'POST'
})
```

## Resume a subscription

`POST /v1/subscriptions/{id}/resume`

Billing restarts from the next period; every period missed while paused is skipped, not back-billed.

### Path parameters

- `id` `string` _(required)_

### Responses

#### `200`: The subscription after the transition.

Body (`application/json`):

- `id` `string` _(required)_
- `subscriber` `object` _(required)_
  - `customerId` `string` _(required)_: The merchant's customer, found or created by email.
  - `name` `string` _(required)_
  - `email` `string | null` _(required)_
- `description` `string` _(required)_
- `amount` `object` _(required)_
  - `amount` `string` _(required)_: Exact minor units. Calculate with this value.
  - `asset` `string` _(required)_: ISO asset code, e.g. IDR, USD, USDC.
  - `formatted` `string` _(required)_: Machine decimal; ungrouped and dot-separated.
  - `display` `string` _(required)_: Localized display text. Never parse this value.
- `interval` `string` _(required)_
- `state` `string` _(required)_
- `billedCycles` `integer` _(required)_: Cycles invoiced so far.
- `daysUntilDue` `integer` _(required)_: Each cycle's invoice falls due this many days after issue.
- `anchorAt` `string` _(required)_: The first billing date; every later date derives from it.
- `nextBillingAt` `string | null` _(required)_: Only an active subscription has one. Null while paused or once cancelled.
- `createdAt` `string` _(required)_
- `cancelledAt` `string | null` _(required)_

#### `404`: No subscription with that id, or not this merchant's.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

#### `409`: The transition is not allowed from the current state.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

### Example request

```bash
curl https://api.mayarin.xyz/v1/subscriptions/string/resume \
  --request POST
```

```ts
fetch('https://api.mayarin.xyz/v1/subscriptions/string/resume', {
  method: 'POST'
})
```

## Cancel a subscription

`POST /v1/subscriptions/{id}/cancel`

Terminal. A cancelled subscription cannot be resumed.

### Path parameters

- `id` `string` _(required)_

### Responses

#### `200`: The subscription after the transition.

Body (`application/json`):

- `id` `string` _(required)_
- `subscriber` `object` _(required)_
  - `customerId` `string` _(required)_: The merchant's customer, found or created by email.
  - `name` `string` _(required)_
  - `email` `string | null` _(required)_
- `description` `string` _(required)_
- `amount` `object` _(required)_
  - `amount` `string` _(required)_: Exact minor units. Calculate with this value.
  - `asset` `string` _(required)_: ISO asset code, e.g. IDR, USD, USDC.
  - `formatted` `string` _(required)_: Machine decimal; ungrouped and dot-separated.
  - `display` `string` _(required)_: Localized display text. Never parse this value.
- `interval` `string` _(required)_
- `state` `string` _(required)_
- `billedCycles` `integer` _(required)_: Cycles invoiced so far.
- `daysUntilDue` `integer` _(required)_: Each cycle's invoice falls due this many days after issue.
- `anchorAt` `string` _(required)_: The first billing date; every later date derives from it.
- `nextBillingAt` `string | null` _(required)_: Only an active subscription has one. Null while paused or once cancelled.
- `createdAt` `string` _(required)_
- `cancelledAt` `string | null` _(required)_

#### `404`: No subscription with that id, or not this merchant's.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

#### `409`: The transition is not allowed from the current state.

Body (`application/json`):

- `error` `object` _(required)_
  - `code` `string` _(required)_
  - `message` `string` _(required)_
  - `retryable` `boolean` _(required)_
  - `details` `object`

### Example request

```bash
curl https://api.mayarin.xyz/v1/subscriptions/string/cancel \
  --request POST
```

```ts
fetch('https://api.mayarin.xyz/v1/subscriptions/string/cancel', {
  method: 'POST'
})
```
