# API Reference

Browse every REST operation, inspect schemas, run requests, and copy generated snippets.

<!-- docs-source -->
Source: https://learning.monetizekit.app/docs/api-reference
<!-- /docs-source -->

Mock API reference used by the interactive docs explorer.

| OpenAPI version | Contract version | REST base path |
| --- | --- | --- |
| 3.1.0 | 2026-03-15 | /api/v1 |

## Servers

| URL | Environment |
| --- | --- |
| `https://app.monetizekit.app/api/v1` | Development environment |
| `https://app.monetizekit.app/api/v1` | Staging environment |
| `https://app.monetizekit.app/api/v1` | Production environment |

## Domains

| Domain | Description |
| --- | --- |
| Catalog | Manage plans, features, and pricing metadata. |
| Customers | Manage customer identities and subscriptions. |
| Entitlements | Resolve access decisions for feature gates. |
| Usage | Ingest and query usage events and counters. |
| Webhooks | Configure and inspect webhook delivery. |
| Integrations | Connect third-party services. |

## Operations

### List plans

`GET /plans` — Returns plans visible to the current workspace.

Operation ID: plans.list.

Required scopes: plans:read.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `page` | query | no | One-based page number. | { "type": "integer" } | 1 |
| `pageSize` | query | no | Number of records per page. | { "type": "integer" } | 20 |

#### Responses

`200` — Success

```json
{
  "type": "object",
  "required": [
    "data",
    "total",
    "page",
    "pageSize",
    "totalPages",
    "hasNext",
    "hasPrev"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "key",
          "name",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "key": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published",
              "archived"
            ]
          }
        }
      }
    },
    "total": {
      "type": "integer"
    },
    "page": {
      "type": "integer"
    },
    "pageSize": {
      "type": "integer"
    },
    "totalPages": {
      "type": "integer"
    },
    "hasNext": {
      "type": "boolean"
    },
    "hasPrev": {
      "type": "boolean"
    }
  }
}
```

```json
{
  "data": [
    {
      "id": "plan_001",
      "key": "starter_monthly",
      "name": "Starter",
      "status": "published"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20,
  "totalPages": 1,
  "hasNext": false,
  "hasPrev": false
}
```

### Create plan

`POST /plans` — Creates a draft plan with entitlements and pricing terms.

Operation ID: createPlan.

Required scopes: plans:write.

#### Request schema

```json
{
  "type": "object",
  "required": [
    "productId",
    "name"
  ],
  "properties": {
    "productId": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    }
  }
}
```

#### Request example

```json
{
  "productId": "prod_saas",
  "name": "Growth",
  "description": "Growth plan"
}
```

#### Responses

`201` — Created

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "status": {
      "type": "string"
    }
  }
}
```

```json
{
  "id": "plan_002",
  "status": "draft"
}
```

### List customers

`GET /customers` — Lists customers in the active workspace.

Operation ID: customers.list.

Required scopes: customers:view.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `page` | query | no | One-based page number. | { "type": "integer" } | 1 |
| `pageSize` | query | no | Number of records per page. | { "type": "integer" } | 25 |

#### Responses

`200` — Success

```json
{
  "type": "object",
  "required": [
    "data",
    "total",
    "page",
    "pageSize",
    "totalPages",
    "hasNext",
    "hasPrev"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "email"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          }
        }
      }
    },
    "total": {
      "type": "integer"
    },
    "page": {
      "type": "integer"
    },
    "pageSize": {
      "type": "integer"
    },
    "totalPages": {
      "type": "integer"
    },
    "hasNext": {
      "type": "boolean"
    },
    "hasPrev": {
      "type": "boolean"
    }
  }
}
```

```json
{
  "data": [
    {
      "id": "cust_001",
      "name": "Acme Corp",
      "email": "ops@acme.test"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 25,
  "totalPages": 1,
  "hasNext": false,
  "hasPrev": false
}
```

### Create customer

`POST /customers` — Creates a customer profile.

Operation ID: customers.create.

Required scopes: customers:create.

#### Request schema

```json
{
  "type": "object",
  "required": [
    "name",
    "email"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "email": {
      "type": "string"
    }
  }
}
```

#### Request example

```json
{
  "name": "Acme Project",
  "email": "ops@acme.test"
}
```

#### Responses

`201` — Created

```json
{
  "type": "object",
  "required": [
    "id",
    "name",
    "email"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "email": {
      "type": "string"
    }
  }
}
```

```json
{
  "id": "cust_445",
  "name": "Acme Project",
  "email": "ops@acme.test"
}
```

### List customer entitlements

`GET /entitlements/{customerId}` — Returns effective entitlements for the customer.

Operation ID: entitlements.list.

Required scopes: entitlements:read.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `customerId` | path | yes | Customer ID | { "type": "string" } | "cust_dev_1001" |

#### Responses

`200` — Success

```json
{
  "type": "array",
  "items": {
    "type": "object",
    "required": [
      "featureKey",
      "type",
      "sources"
    ],
    "properties": {
      "featureKey": {
        "type": "string"
      },
      "type": {
        "type": "string"
      },
      "effectiveValue": {},
      "sources": {
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    }
  }
}
```

```json
[
  {
    "featureKey": "api_access",
    "type": "boolean",
    "effectiveValue": true,
    "sources": [
      "plan"
    ]
  }
]
```

### Check entitlement decision

`GET /entitlements/{customerId}/{featureKey}` — Returns access decision for one feature gate.

Operation ID: entitlements.check.

Required scopes: entitlements:read.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `customerId` | path | yes | Customer ID | { "type": "string" } | "cust_dev_1001" |
| `featureKey` | path | yes | Feature key | { "type": "string" } | "analytics_export" |

#### Responses

`200` — Success

```json
{
  "type": "object",
  "required": [
    "allowed",
    "reason"
  ],
  "properties": {
    "allowed": {
      "type": "boolean"
    },
    "reason": {
      "type": "string"
    }
  }
}
```

```json
{
  "customerId": "cust_dev_1001",
  "featureKey": "analytics_export",
  "allowed": true,
  "type": "boolean",
  "sources": [
    "plan"
  ],
  "reason": "Plan includes feature",
  "reasonCode": "granted"
}
```

### Submit usage event

`POST /usage/events` — Ingests a metered usage event.

Operation ID: usage.submit.

Required scopes: usage:write.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | yes | Client-generated idempotency key | { "type": "string" } | "idem_2f5fd2b7a1" |

#### Request schema

```json
{
  "type": "object",
  "required": [
    "customerId",
    "meterId",
    "value"
  ],
  "properties": {
    "customerId": {
      "type": "string"
    },
    "meterId": {
      "type": "string"
    },
    "value": {
      "type": "number"
    }
  }
}
```

#### Request example

```json
{
  "customerId": "cust_dev_1001",
  "meterId": "api_requests",
  "value": 15,
  "occurredAt": "2026-03-15T12:00:00.000Z"
}
```

#### Responses

`201` — Recorded

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "customerId": {
      "type": "string"
    },
    "meterId": {
      "type": "string"
    },
    "eventName": {
      "type": "string"
    },
    "value": {
      "type": "number"
    },
    "status": {
      "type": "string"
    },
    "occurredAt": {
      "type": "string"
    },
    "createdAt": {
      "type": "string"
    }
  }
}
```

```json
{
  "id": "evt_9012",
  "customerId": "cust_dev_1001",
  "meterId": "api_requests",
  "eventName": "usage.recorded",
  "value": 15,
  "status": "success",
  "occurredAt": "2026-03-15T12:00:00.000Z",
  "createdAt": "2026-03-15T12:00:00.000Z"
}
```

### Submit a batch of usage events

`POST /usage/events/batch` — Ingests up to 500 usage events in one request. Each item carries its own idempotency key, so replaying a window missed during an outage converges without duplicates while preserving each event's original occurredAt. Item-level failures do not fail the batch. Each accepted item names its stored event by eventId; pass ?include=events to receive the full event object per item.

Operation ID: usage.submitBatch.

Required scopes: usage:write.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `include` | query | no | Comma-separated extras to include per result. `events` adds the stored event object (the shape POST /usage/events returns) to every created or duplicate item; omitted by default because a 500-item batch would return roughly 200 KB of copies of the request. | { "type": "string", "enum": [ "events" ] } | "events" |

#### Request schema

```json
{
  "type": "object",
  "required": [
    "events"
  ],
  "properties": {
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "customerId",
          "meterId",
          "value",
          "idempotencyKey"
        ],
        "properties": {
          "customerId": {
            "type": "string"
          },
          "meterId": {
            "type": "string"
          },
          "value": {
            "type": "number"
          },
          "idempotencyKey": {
            "type": "string"
          },
          "occurredAt": {
            "type": "string"
          }
        }
      }
    }
  }
}
```

#### Request example

```json
{
  "events": [
    {
      "customerId": "cust_dev_1001",
      "meterId": "api_requests",
      "value": 15,
      "idempotencyKey": "idem_replay_0001",
      "occurredAt": "2026-03-15T11:00:00.000Z"
    },
    {
      "customerId": "cust_dev_1001",
      "meterId": "api_requests",
      "value": 8,
      "idempotencyKey": "idem_replay_0002",
      "occurredAt": "2026-03-15T11:30:00.000Z"
    }
  ]
}
```

#### Responses

`200` — Batch processed

```json
{
  "type": "object",
  "required": [
    "summary",
    "results"
  ],
  "properties": {
    "summary": {
      "type": "object",
      "required": [
        "total",
        "created",
        "duplicate",
        "errors"
      ],
      "properties": {
        "total": {
          "type": "number"
        },
        "created": {
          "type": "number"
        },
        "duplicate": {
          "type": "number"
        },
        "errors": {
          "type": "number"
        }
      }
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "index",
          "idempotencyKey",
          "status"
        ],
        "properties": {
          "index": {
            "type": "number"
          },
          "idempotencyKey": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "duplicate",
              "error"
            ]
          },
          "eventId": {
            "type": "string",
            "description": "Id of the stored event, on created and duplicate items."
          },
          "event": {
            "type": "object",
            "description": "The stored event, only when the request asked for ?include=events."
          },
          "error": {
            "type": "object",
            "description": "On error items: the same code and message a single-event request would return.",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}
```

```json
{
  "summary": {
    "total": 2,
    "created": 1,
    "duplicate": 1,
    "errors": 0
  },
  "results": [
    {
      "index": 0,
      "idempotencyKey": "idem_replay_0001",
      "status": "created",
      "eventId": "evt_9013"
    },
    {
      "index": 1,
      "idempotencyKey": "idem_replay_0002",
      "status": "duplicate",
      "eventId": "evt_9014"
    }
  ]
}
```

### Get usage counter

`GET /usage/{customerId}/{meterId}` — Returns current counter for a customer and meter.

Operation ID: usage.retrieve.

Required scopes: usage:read.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `customerId` | path | yes | Customer ID | { "type": "string" } | "cust_dev_1001" |
| `meterId` | path | yes | Meter key | { "type": "string" } | "api_requests" |

#### Responses

`200` — Success

```json
{
  "type": "object",
  "properties": {
    "customerId": {
      "type": "string"
    },
    "meterId": {
      "type": "string"
    },
    "current": {
      "type": "number"
    },
    "limit": {
      "type": "number"
    }
  }
}
```

```json
{
  "customerId": "cust_dev_1001",
  "meterId": "api_requests",
  "current": 120,
  "limit": 1000
}
```

### Get usage breakdown

`GET /usage/{customerId}/{meterId}/breakdown` — Returns usage grouped by a required dimension.

Operation ID: usage.breakdown.

Required scopes: usage:read.

#### Parameters

| Name | In | Required | Description | Schema | Example |
| --- | --- | --- | --- | --- | --- |
| `customerId` | path | yes | Customer ID | { "type": "string" } | "cust_dev_1001" |
| `meterId` | path | yes | Meter key | { "type": "string" } | "api_requests" |
| `dimension` | query | yes | Dimension to group usage by | { "type": "string" } | "model" |

#### Responses

`200` — Success

```json
{
  "type": "object",
  "properties": {
    "meterId": {
      "type": "string"
    },
    "dimension": {
      "type": "string"
    },
    "window": {
      "type": "string"
    },
    "total": {
      "type": "number"
    },
    "totalCreditCost": {
      "type": "number"
    },
    "breakdown": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "total": {
            "type": "number"
          },
          "count": {
            "type": "number"
          },
          "creditCost": {
            "type": "number"
          }
        }
      }
    }
  }
}
```

```json
{
  "meterId": "api_requests",
  "dimension": "model",
  "window": "all",
  "total": 120,
  "totalCreditCost": 42,
  "breakdown": [
    {
      "value": "gpt-4.1",
      "total": 120,
      "count": 4,
      "creditCost": 42
    }
  ]
}
```

### List webhook endpoints

`GET /webhooks/endpoints` — Returns configured webhook endpoints.

Operation ID: listWebhookEndpoints.

Required scopes: webhooks:read.

#### Responses

`200` — Success

```json
{
  "type": "object",
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      }
    }
  }
}
```

```json
{
  "data": [
    {
      "id": "wh_001",
      "url": "https://example.local/hooks/monetizekit"
    }
  ]
}
```

### Create webhook endpoint

`POST /webhooks/endpoints` — Registers a new webhook endpoint.

Operation ID: createWebhookEndpoint.

Required scopes: webhooks:write.

#### Request schema

```json
{
  "type": "object",
  "required": [
    "url",
    "events"
  ],
  "properties": {
    "url": {
      "type": "string"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}
```

#### Request example

```json
{
  "url": "https://example.local/hooks/monetizekit",
  "events": [
    "customer.created"
  ]
}
```

#### Responses

`201` — Created

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "secret": {
      "type": "string"
    }
  }
}
```

```json
{
  "id": "wh_002",
  "secret": "whsec_placeholder"
}
```

### Connect Stripe

`POST /integrations/stripe` — Creates a Stripe connect session for workspace setup.

Operation ID: connectStripe.

Required scopes: integrations:manage.

#### Request schema

```json
{
  "type": "object",
  "required": [
    "action"
  ],
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "connect",
        "disconnect",
        "set_webhook_secret"
      ]
    },
    "apiKey": {
      "type": "string"
    },
    "secret": {
      "type": "string"
    }
  }
}
```

#### Request example

```json
{
  "action": "connect",
  "apiKey": "rk_test_placeholder"
}
```

#### Responses

`200` — Success

```json
{
  "type": "object",
  "required": [
    "ok"
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    }
  }
}
```

```json
{
  "ok": true
}
```