Plan CRUD
The Public API exposes operations on the plan entity. A plan is the pricing template applied to a product; it is referenced by planId on subscriptions and one-time orders.
For the concept (categories of plans, the relationship to products), see Products and plans.
Create a plan
curl -X POST \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/plans" \
-H 'Content-Type: application/json' \
-H "Authorization: ApiKey ${API_KEY}" \
-d '{
"name": "Monthly Pro",
"currency": "USD",
"productId": "prod_xxx",
"pricing": {
"price": 29,
"formula": "fixed-fee"
},
"description": "Monthly Pro subscription",
"isActive": true,
"isTrialOnly": false
}'
Request fields
| Field | Notes |
|---|---|
name | Display name of the plan. |
currency | CurrencyCodesEnum (USD, EUR, etc.). |
productId | The product this plan applies to. |
pricing | Object with price and formula (fixed-fee, flat-rate, tiered, volume, stairstep). See Pricing. |
description | Plain-text description. |
richDescription | Long-form description. |
isActive | false hides the plan from new subscriptions but does not affect existing ones. |
isTrialOnly | true for trial-only plans (no recurring cadence after the trial). |
Advanced fields
These fields are present on the plan schema and accepted by the API. Behavior of productOptions and recognition is implementation-specific — confirm before relying on them.
| Field | Notes |
|---|---|
productOptions | Free-form object. Defined as an empty schema in the API spec — verify the expected shape with the engineering team before use. |
currencySign | String. The display sign for currency (for example, $). |
setup | Object with approvalLink and price. Setup fee or approval URL applied on the first charge. |
revision | Number. Internal revision marker. |
List plans
curl -X GET \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/plans?limit=20&offset=0&sortBy=createdAt&sortDirection=desc" \
-H "Authorization: ApiKey ${API_KEY}"
| Query parameter | Type | Notes |
|---|---|---|
limit | integer 0–100, default 20 | Pagination page size. |
offset | integer ≥0 | Pagination offset. |
sortBy | enum | createdAt or updatedAt. |
sortDirection | enum | asc or desc. |
search | string | Free-text search. |
updatedFrom / updatedTo | date-time | Filter by last-update timestamp range. |
Response: paginated list with { type: "list", totalCount, paginationMeta, data: [Plan, ...] }.
Retrieve a plan
curl -X GET \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/plans/${PLAN_ID}" \
-H "Authorization: ApiKey ${API_KEY}"
Upsert a plan
Create the plan at the given planId if it does not exist, or replace the full resource if it does. The API does not expose a separate PATCH endpoint — use Create (POST) for new plans and Upsert (PUT) when you need to replace an existing one in full.
curl -X PUT \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/plans/${PLAN_ID}" \
-H 'Content-Type: application/json' \
-H "Authorization: ApiKey ${API_KEY}" \
-d '{
"name": "Updated Monthly Pro",
"currency": "USD",
"productId": "prod_xxx",
"pricing": {
"price": 39,
"formula": "fixed-fee"
},
"description": "Updated plan"
}'
Body fields are the same as Create. Returns 201 Plan upserted.
To move customers to different pricing, see Upgrade and downgrade.
Delete a plan
curl -X DELETE \
"https://staging-api.payments.ai/v1/public-api/organizations/${ORGANIZATION_ID}/plans/${PLAN_ID}" \
-H "Authorization: ApiKey ${API_KEY}"
Returns 204 on success.
May return 409 Conflict with a generic message ("Conflict with the current state of the target resource"). The exact condition that triggers 409 on plan deletion is not documented in the API spec — verify with the engineering team if you hit it in practice.
Related pages
- Products and plans
- Pricing
- Recurring interval — note: recurring interval is a subscription cadence concept, not a field on
Plan(see related notes in this document). - Trial
- Product CRUD
- Create a subscription
- Upgrade and downgrade