> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jojapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Billable Objects

> Define what your API charges for — Credits, AI tokens, compute time, or any resource you meter.

> This article is for API providers. For the consumer view of per-object pricing and usage, see [Credit & Usage](/credit-usage).

Billing on JoJ API is built around **billable objects**: the resources your API charges for. Every API starts with a default **Credits** object, and you can define more — AI tokens, compute time, bandwidth, storage, or anything else you meter. Each endpoint declares how much of each object a request consumes, and each plan declares how much of each object a subscriber gets (or what they pay per unit).

## Objects

Manage your objects in **Studio → your API → Objects**.

* **Name, slug and dimension are set once at creation and cannot be changed.** The slug appears in the per-object [response headers](/consumers/response-headers) (`X-Jojapi-<slug>-Used`), so treat it as part of your API's contract.
* The **Credits** object is created automatically for every API and cannot be deleted. Additional objects can be deleted while no endpoint or plan references them.
* Slugs use lowercase letters, numbers and hyphens. A few platform names are reserved (`credits`, `user-balance`, `spent-balance`, `gateway-response`, `key`).

### Default usage formula

Every object has a **default usage formula** — the metering rule that endpoints inherit when they don't define their own. Set it once on the object instead of repeating it on every endpoint. A plain number works as a constant (for example `1` bills one unit per request); a template computes the amount from the response:

```
{{default(response.headers["x-jojapi-credits-used"], 1)}}
```

The formula is required when you create an object (Studio suggests `1` for the Requests dimension). To bill nothing unless an endpoint sets its own formula, say so explicitly with `0` — the gateway never invents an amount you didn't specify, so an object created before this rule that still has no default bills 0 for those endpoints until you set one.

## Endpoint billing

Each endpoint's **Details** page has a **Billing** section listing the objects the endpoint consumes. Add or remove objects, and give each one a single **cost** input:

| You enter | Meaning |
| - | - |
| A plain number (`5`) | Fixed: the request always bills exactly this many units. The amount is also an upper bound — a response can lower it (see below) but never exceed it. |
| A formula (`{{response.json.usage.total_tokens}}`) | Metered: the amount is computed from the final response on every request. |
| Nothing (empty) | Metered: inherits the object's default formula. With no default either, the object bills 0. |

The optional **Description** is shown to consumers under the cost on your API's documentation page — use it to explain how the metering works in plain words.

To bill many endpoints the same way at once, select them on the **Endpoints** page and choose **Set billing**: pick the object, enter the cost and description, and every selected endpoint gets that element — endpoints already billing the object are updated in place, and their other objects are left unchanged.

The first object in the list is the one that receives the in-band SSE value if you send one (see [Reporting usage from your server](/studio/adjusting-credit-usage)).

Consumers see the **effective** cost for every endpoint — the fixed amount, or the exact formula that applies (their own or the inherited default) — plus a last-month average for metered objects. Transparent pricing is a platform principle: if you meter it, consumers can see how.

## Usage sources on the edge gateway

For APIs served by the **edge gateway** (an *Edge gateway* badge on the Code tab), a metered cost is a structured **usage source** instead of a template. The cost input offers:

| Source | Bills |
| - | - |
| Object default | whatever the object's default source says |
| Fixed amount | this many units per request |
| Response header | the numeric value of a header your server returns, e.g. `x-credits-used` |
| Header key=value | one key of a `k=v; k2=v2` header, e.g. `Images` in `x-billing: Images=3; Videos=1` |
| JSON field | a field of the JSON response body, e.g. `usage.total_tokens` |

Each source takes an optional **default**, billed when the value is missing or not a number; without one, 0 is billed. Formulas written for the classic gateway are converted when the API moves; one that cannot be expressed as a source is shown read-only until you replace it, or you report usage from [custom code](/studio/custom-code) with `ctx.usage()`.

## Formulas

Formulas are template expressions evaluated against the finished request/response. Useful building blocks:

* `response.json.…`, `response.headers["…"]`, `request.json.…` — read the exchange. Your upstream's own `x-jojapi-*` headers are visible to formulas even though the gateway strips them from the client response.
* `default(x, fallback)` — `fallback` when `x` is missing or empty; a real `0` passes through.
* `isNumber(x) ? x : 2` — a stricter fallback: `2` whenever `x` isn't a valid number.
* `min(x, cap)` / `max(x, floor)` — bound a computed amount, e.g. `{{min(response.json.tokens, 10)}}` never bills more than 10.
* Also available: `round`, `floor`, `ceil`, `abs`, `toInt`, `len`, `contains`, `split`, `first`, `last` and more.

**Billing rules the platform always enforces:**

* Responses with a **5xx status, and gateway-generated errors, bill 0 on every object** — no formula, header or SSE value can charge for a failed response.
* A formula that fails to evaluate or produces a non-numeric result bills 0 for that object ("charge nothing you can't compute"). Negative results are clamped to 0.
* On fixed costs, any computed or reported value is capped at the declared amount.

## Plans

Plan pricing is per object. When creating a plan in **Studio → your API → Plans**:

* **Fixed price plans** — set an included quota for each object the plan covers ("5,000 Credits and 100,000 AI Tokens per month"). Quotas reset each period and do not carry over.
* **Pay as you go plans** — define a graduated tier ladder per object. Each unit is billed at the rate of the tier it falls in.

A subscriber's plan must cover **every object an endpoint consumes** — requests to an endpoint whose objects the plan doesn't include are rejected (402 `Plan Does Not Include {Object}`). The plan form warns you when your API's endpoints consume an object the plan leaves out.

### Changing what a plan covers

Plan pricing is immutable per object: a quota or tier ladder can never be edited or removed once it is on the plan. What you **can** do is add a *new* object to an existing plan (**Edit plan → Billable Objects → Add an object**):

* The addition applies to **all current subscribers immediately** and, like the rest of the plan, can never be changed afterwards — pick the quota or tiers carefully.
* **Every subscriber of the plan is automatically notified by email**, with the new object and its quota or pricing spelled out. This notice is mandatory and cannot be turned off: subscribers must know when what their plan bills for changes.
* On a pay as you go plan, a tier priced at 0 covers the object free of charge — the explicit way to grandfather existing subscribers when you start billing a new object on newer plans.

When you introduce a new object to an endpoint that already has subscribers, do it in this order: create the object, add it to every plan that has active subscribers (quota, tiers, or a 0-price tier), and only then attach it to the endpoint. Attaching it first would 402 every subscriber whose plan doesn't cover it yet.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.