Skip to content
Hardcount
Run it locally
Pre-1.0 · one maintainer · Stripe and cards only · no SDKs (client libraries) yet · no production users yet. Docs describe v0.9.1 (29 Oct 2026) · What’s new →

List recipes

GET
/v1/recipes
curl --request GET \
--url 'http://localhost:8080/v1/recipes?limit=50&offset=0' \
--header 'Authorization: Bearer <token>'

Every recipe in the embedded registry, tagged with this tenant’s installation state in the session’s livemode. instantiated present means installed (the dashboard renders an “Installed” badge instead of the Install CTA); re-apply is an idempotent no-op and there is no uninstall (ADR-085).

limit
integer
default: 50 >= 1 <= 100

Rows per page, from 1 to 100. Default 50. Any other value, or one that is not a whole number, is a 422 with param: limit.

offset
integer
0

Rows to skip, 0 or more. Default 0. A negative value, or one that is not a whole number, is a 422 with param: offset.

Recipe catalog with per-tenant install state

Media typeapplication/json
object
data
required
Array
object
key
required
string
version
required
string
name
required
string
summary
required
string
description
string
overridable
required
Array<object>

One override key declared in a recipe’s overridable list. Drives validation at instantiate time and the override form in the dashboard’s preview dialog.

object
key
required
string
type
required
string
Allowed values: string int
default
required

Default value applied when the override is not supplied.

enum
Array<string>
max_length
integer
pattern
string
meters
required
Array<object>
object
event_name
required
string
name
required
string
unit
required
string
aggregation
required
string
plans
required
Array<object>
object
code
required
string
name
required
string
currency
required
string
billing_interval
required
string
Allowed values: monthly yearly
base_amount_cents
required
integer format: int64
base_bill_timing

Optional when the base fee is 0; the plan is then in_arrears (ADR-031).

string
Allowed values: in_advance in_arrears
prices
required

The plan’s usage prices. Each takes the plan’s currency.

Array

One usage price of a recipe plan. It takes the plan’s currency.

object
meter
required

The event_name of the recipe meter the price is on.

string
dimension_match
required
object
key
additional properties
string
mode
required

per_unit bills quantity × unit_amount_cents. graduated bills each tier’s part of the quantity at that tier’s rate. package bills ceil(quantity ÷ package_size) × package_amount_cents: a part package bills as a whole one.

string
Allowed values: per_unit graduated package
unit_amount_cents
required

Price per unit in cents, as a decimal string (e.g. “0.0003” = $3.00 per 1,000,000 units). Used when mode is per_unit. 0 or more, under 10^18, at most 12 decimal places (trailing zeros do not count), and at most 100 characters. A JSON number is also read. A value outside them is refused with 422 and param naming the field. Invoice line amounts round to whole cents.

string
tiers
required

Used when mode is graduated. Each up_to is a whole number above the one before. The last tier has up_to: null (no upper bound), and only the last. Otherwise 422 with param tiers. A tier’s rate takes the limits of unit_amount_cents; a refusal names tiers[i].unit_amount_cents (i counts from 0).

Array<object>
object
up_to
required

The tier’s upper bound in whole units: the tier prices the quantity above the previous tier’s bound, up to this one. null on the last tier, which has no upper bound. Only the last tier is null, and it must be.

integer format: int64
nullable
unit_amount_cents
required

Price per unit in cents in this tier, as a decimal string.

string
package_size
required

Used when mode is package. Must be above 0.

integer format: int64
package_amount_cents
required

Price of one package in cents, as a decimal string (e.g. “0.2” with package_size 1000 = $0.002 per 1,000 units), with the limits of unit_amount_cents. Used when mode is package.

string
creates
required

Per-role count of objects a recipe will produce when instantiated. Recipes create no product entity — there is no products count.

object
meters
required
integer
plans
required
integer
prices
required

The prices the install puts on its plans.

integer
instantiated

Present when this tenant (in the session’s livemode) has installed the recipe; absent otherwise. Drives the “Installed” badge — re-apply is an idempotent no-op and there is no uninstall (ADR-085).

object
id
required
string
tenant_id

Omitted when empty.

string
recipe_key
required
string
recipe_version
required
string
overrides
required
object
key
additional properties
any
created_objects
required

Per-role map of entity IDs a recipe apply produced (including ADOPTED meters — apply reconnects to an existing meter rather than duplicating it, ADR-085). Every field is omitted when empty; clients must guard reads.

object
meter_ids
Array<string>
plan_ids
Array<string>
price_ids
Array<string>
created_at
required
string format: date-time
created_by

Operator email or API key ID. Omitted when empty.

string
total
required

How many rows match the request’s filters, on every page, not only this one. The audit log and the customer list’s search and name or email sort say where they stop counting.

integer

Example

{
"data": [
{
"overridable": [
{
"type": "string"
}
],
"plans": [
{
"billing_interval": "monthly",
"base_bill_timing": "in_advance",
"prices": [
{
"mode": "per_unit"
}
]
}
]
}
]
}

limit or offset is out of range or not a whole number, or the request sends the removed after cursor (param names it)

Media typeapplication/json
object
error
object
type

One of invalid_request_error, authentication_error, rate_limit_error or api_error. Every error the API answers has this shape, including an unknown path (404, code route_not_found) and a method the path does not take (405, code method_not_allowed, with an Allow header). The few exceptions are listed in docs/api-surface.md.

string
code
string
message
string
request_id
string
param

The request field the error is about. Sent only when the error names one. A request body may hold only the fields its operation lists, spelled and cased as listed: any other field, or one the server sets (such as id), is refused with 422 and param naming it. An operation with no request body lists no fields: send no body, {} or null. The Stripe and Postmark webhooks and the LiteLLM callback take their sender’s body as it comes.

string

Example

{
"error": {
"type": "invalid_request_error"
}
}