# API overview

Source: https://docs.orbytelabs.com/api

Call the Credit HTTP API from any server-side language.

The Credit API manages your credit types, features, wallets, deposits, usage, and subscriptions. Each secret API key belongs to one application. Requests use that application's data and permissions.

The [TypeScript SDK](/sdk) handles authentication and amount conversion. Use the HTTP API when integrating another language or building your own client.

## Base URL [#base-url]

All requests use this base URL:

```text
https://api.orbytelabs.com
```

All resource paths start with `/v1`. Development and Production use the same address; your API key selects the application. The SDK supplies the base URL automatically. For HTTP calls, use the full URLs below and set `ORBYTE_API_KEY` to your secret key.

```sh
curl "https://api.orbytelabs.com/v1/application" \
  -H "Authorization: Bearer $ORBYTE_API_KEY"
```

This request returns the application, organization, environment, and permissions associated with the key. It requires `credits:read`.

## Authentication and request format [#authentication-and-request-format]

Send a secret API key in the `Authorization: Bearer` header. Keep it on your server. Publishable keys cannot call these endpoints. See [API keys](/authentication) for permission setup.

Send `Content-Type: application/json` with JSON request bodies. Bodies must be no larger than 16 KiB. Unknown fields and repeated query parameters are rejected. Encode resource keys and wallet identities when placing them in URLs.

## Amounts and timestamps [#amounts-and-timestamps]

The HTTP API represents credit amounts as decimal strings of nanocredits. One credit equals `1,000,000,000` nanocredits.

| Credits | JSON amount      |
| ------- | ---------------- |
| 0.001   | `"1000000"`      |
| 1       | `"1000000000"`   |
| 100     | `"100000000000"` |

Keep these values as strings or use an integer type that preserves precision. Do not send a JSON number or a string with a decimal point. Amounts must fit in a nonnegative signed 64-bit integer. Deposits must be greater than zero.

Plan and checkout `amountCents` values are JSON integers in Stripe currency minor units, such as 2000 for $20 USD. They are separate from nanocredits.

`quantity` is a positive safe integer and defaults to `1`. Timestamp fields such as `createdAt`, `anchor`, `periodStart`, and `periodEnd` use Unix milliseconds.

Plan and checkout prices use a separate `amountCents` integer in the currency's smallest unit, plus a three-letter lowercase `currency`. For USD, `1000` means $10. These monetary prices are separate from credit balances.

## Check and track [#check-and-track]

Call [`POST /v1/check`](/api-reference/events/checkUsage) before work to read the current charge, balance, and any subscription limit. It returns `allowed: false` with HTTP `200` when access is denied. A check neither reserves usage nor deducts credits.

```sh
curl "https://api.orbytelabs.com/v1/check" \
  -H "Authorization: Bearer $ORBYTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"identity":"customer_123","feature":"api-call","quantity":1}'
```

Call [`POST /v1/events`](/api-reference/events/ingestEvent) to record usage and deduct any credit charge. This is the HTTP endpoint behind the SDK's `track` function. Credit enforces the current subscription allowance and balance again when it records usage.

```sh
curl "https://api.orbytelabs.com/v1/events" \
  -H "Authorization: Bearer $ORBYTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id":"request_123","identity":"customer_123","feature":"api-call","quantity":1}'
```

Use a stable event `id` for retries. Newly recorded usage returns HTTP `201` with `status: "accepted"`. An exact retry returns HTTP `200` with `status: "duplicate"`. A use already covered by a feature's deduplication period returns HTTP `200` with `status: "deduplicated"`. Insufficient balance, an exhausted blocking allowance, or an inactive subscription returns HTTP `409`.

Callback-priced features require `amountNanocredits` and `quantity: 1`. Your server must calculate the amount. Fixed-price features reject an amount override. See [feature pricing](/pricing) and [checking and tracking usage](/checking-and-tracking).

## Subscriptions and payments [#subscriptions-and-payments]

Use [subscriptions and payments](/subscriptions) to configure Stripe Connect, plan prices, and feature allowances. `POST /v1/plans` creates a plan and queues Stripe synchronization. `POST /v1/checkout` returns a subscription checkout link; `POST /v1/topup-checkout` returns a paid credit checkout link. Both collect payment on the application's connected account.

Verified Stripe events update subscription state and credit top-ups. A success URL is not payment confirmation. Create billing portal links with `POST /v1/billing-portal`, and read or manage the subscription at `/v1/subscriptions/{identity}`.

Use `POST /v1/deposits` for a direct credit grant that does not collect payment.

Read the current subscription with `GET /v1/subscriptions/{identity}`. It returns `null` when the wallet has no subscription. The change and cancel endpoints require stable idempotency keys. Plan changes invoice prorations immediately; when payment needs customer action, the old plan remains until payment completes. The billing portal gives customers a hosted page for billing management.

Stripe sends signed payment updates to `POST /stripe/webhook`. This integration endpoint authenticates the Stripe signature rather than an API key. See [subscriptions](/subscriptions) for the Stripe setup and payment flow.

## Pagination [#pagination]

List endpoints return a `data` array and a `cursor`. Pass a non-null cursor into the next request with the same filters. Stop when it is `null`.

```sh
curl "https://api.orbytelabs.com/v1/deposits?identity=customer_123&limit=10" \
  -H "Authorization: Bearer $ORBYTE_API_KEY"
```

The default limit is `10`. Credits, features, deposits, and plans accept up to `100` items per page. Wallets accept up to `25`. Treat cursors as opaque strings and URL-encode them.

## Endpoints and permissions [#endpoints-and-permissions]

| Endpoint                                                                                       | Permission            |
| ---------------------------------------------------------------------------------------------- | --------------------- |
| [`POST /v1/check`](/api-reference/events/checkUsage)                                           | `events:ingest`       |
| [`POST /v1/events`](/api-reference/events/ingestEvent)                                         | `events:ingest`       |
| [`POST /v1/wallets`](/api-reference/wallets/createWallet)                                      | `wallets:write`       |
| [`GET /v1/wallets`](/api-reference/wallets/listWallets)                                        | `wallets:read`        |
| [`GET /v1/wallets/{identity}`](/api-reference/wallets/getWallet)                               | `wallets:read`        |
| [`PATCH /v1/wallets/{identity}/billing-period`](/api-reference/wallets/setWalletBillingPeriod) | `wallets:write`       |
| [`POST /v1/deposits`](/api-reference/deposits/createDeposit)                                   | `deposits:write`      |
| [`GET /v1/deposits`](/api-reference/deposits/listDeposits)                                     | `deposits:read`       |
| [`POST /v1/credits`](/api-reference/credits/createCredit)                                      | `credits:write`       |
| [`GET /v1/credits`](/api-reference/credits/listCredits)                                        | `credits:read`        |
| [`GET /v1/credits/{key}`](/api-reference/credits/getCredit)                                    | `credits:read`        |
| [`PATCH /v1/credits/{key}`](/api-reference/credits/updateCredit)                               | `credits:write`       |
| [`POST /v1/features`](/api-reference/features/createFeature)                                   | `features:write`      |
| [`GET /v1/features`](/api-reference/features/listFeatures)                                     | `features:read`       |
| [`GET /v1/features/{key}`](/api-reference/features/getFeature)                                 | `features:read`       |
| [`PATCH /v1/features/{key}`](/api-reference/features/updateFeature)                            | `features:write`      |
| [`POST /v1/plans`](/api-reference/plans/createPlan)                                            | `plans:write`         |
| [`GET /v1/plans`](/api-reference/plans/listPlans)                                              | `plans:read`          |
| [`GET /v1/plans/{key}`](/api-reference/plans/getPlan)                                          | `plans:read`          |
| [`PATCH /v1/plans/{key}`](/api-reference/plans/updatePlan)                                     | `plans:write`         |
| [`POST /v1/checkout`](/api-reference/subscriptions/createSubscriptionCheckout)                 | `subscriptions:write` |
| [`POST /v1/topup-checkout`](/api-reference/subscriptions/createTopupCheckout)                  | `subscriptions:write` |
| [`POST /v1/billing-portal`](/api-reference/subscriptions/createBillingPortal)                  | `subscriptions:write` |
| [`GET /v1/subscriptions/{identity}`](/api-reference/subscriptions/getSubscription)             | `subscriptions:read`  |
| [`POST /v1/subscriptions/{identity}/change`](/api-reference/subscriptions/changeSubscription)  | `subscriptions:write` |
| [`POST /v1/subscriptions/{identity}/cancel`](/api-reference/subscriptions/cancelSubscription)  | `subscriptions:write` |
| [`GET /v1/application`](/api-reference/application/getApplicationContext)                      | `credits:read`        |

## Plan catalog [#plan-catalog]

The plan endpoints define subscription prices and feature limits. Create the referenced features before adding them to a plan. Each limit chooses a `month` or `billing` period and either blocks overage or charges credits. See [subscriptions and limits](/subscriptions).

Creating or updating a plan queues its Stripe synchronization. Inspect `syncStatus` in the plan response or read the plan again. A `201` response confirms that Credit created the plan; `syncStatus: "synced"` confirms that Stripe synchronization completed. Plan updates revise terms for new subscriptions. Existing subscriptions keep their terms.

## Errors and retries [#errors-and-retries]

Errors use an HTTP status and a JSON body with `error` and `message` fields. A check denied for low balance is a successful check response, so inspect `allowed` as well as the HTTP status.

```json
{
  "error": "insufficient_balance",
  "message": "This wallet does not have enough credits."
}
```

For an uncertain usage or deposit response, retry with the same event `id` or deposit `idempotencyKey`. Reusing a key with different input returns an idempotency conflict. Respect the `Retry-After` header on HTTP `429` responses. See [errors and retries](/errors) for the status codes and recovery guidance.

## OpenAPI schema [#openapi-schema]

The endpoint reference comes from Credit's HTTP routes and their shared validation schemas. [Download the documentation's OpenAPI 3.1 schema](/openapi.json) to generate a client or inspect complete request and response definitions.

Your deployment also serves its current schema at `GET /v1/openapi.json`. This endpoint does not require an API key.