Kendr.org

Fetch credits, inspect the wallet, and buy packages.

Kendr’s billing model is wallet-based. The current balance lives on the customer account, active packages come from the live catalog, purchases credit the wallet, and successful queries deduct credits after the provider returns a successful response.

Dashboard balance Package discovery Purchase flow

Where credits live

Balance

The live balance is exposed as user.credit_balance inside GET /api/me/dashboard.

Packages

Active packages are available in both GET /api/catalog and GET /api/me/dashboard.

Purchases

Customer purchase history is returned as purchases on the dashboard payload.

Usage

Wallet debits are exposed through ledger entries and query responses such as remaining_credits.

Fetch the current credit balance

The dashboard endpoint is the main place to fetch credits. It returns the user record plus packages, purchases, ledger, API keys, and enabled surfaces in one call.

Curl with app session

curl https://kendr.org/api/me/dashboard \
  -H "X-Kendr-Session: $KENDR_SESSION"

Curl with OAuth bearer

curl https://kendr.org/api/me/dashboard \
  -H "Authorization: Bearer $KENDR_OAUTH_ACCESS_TOKEN"

JavaScript fetch

const response = await fetch('https://kendr.org/api/me/dashboard', {
  headers: {
    'X-Kendr-Session': process.env.KENDR_SESSION
  }
});

const payload = await response.json();
console.log(payload.user.credit_balance);
console.log(payload.packages);

Python requests

import os
import requests

payload = requests.get(
    'https://kendr.org/api/me/dashboard',
    headers={'X-Kendr-Session': os.environ['KENDR_SESSION']},
    timeout=30,
).json()

print(payload['user']['credit_balance'])
print(payload['packages'])
{
  "ok": true,
  "user": {
    "id": 12,
    "email": "user@example.com",
    "full_name": "Example User",
    "credit_balance": 250
  },
  "packages": [...],
  "api_keys": [...],
  "purchases": [...],
  "ledger": [...],
  "surfaces": [...]
}

Discover active packages before purchase

Do not hardcode package IDs or prices. Load them from the live catalog or dashboard payload before constructing a purchase request.

Curl

curl https://kendr.org/api/catalog

JavaScript

const catalog = await fetch('https://kendr.org/api/catalog').then(res => res.json());
console.log(catalog.packages);
Package fields

Each package includes id, slug, name, description, credits, price_cents, currency, and sort metadata.

Purchase credits

Purchases are made through POST /api/me/purchases. The route accepts either package_id or package_slug. It returns the new balance and the purchased package metadata.

Curl by package ID

curl https://kendr.org/api/me/purchases \
  -X POST \
  -H "X-Kendr-Session: $KENDR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "package_id": 3
  }'

Curl by package slug

curl https://kendr.org/api/me/purchases \
  -X POST \
  -H "X-Kendr-Session: $KENDR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "package_slug": "starter-250"
  }'

JavaScript fetch

const purchase = await fetch('https://kendr.org/api/me/purchases', {
  method: 'POST',
  headers: {
    'X-Kendr-Session': process.env.KENDR_SESSION,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ package_id: 3 })
}).then(res => res.json());

console.log(purchase.balance_after);

Python requests

import os
import requests

purchase = requests.post(
    'https://kendr.org/api/me/purchases',
    headers={
        'X-Kendr-Session': os.environ['KENDR_SESSION'],
        'Content-Type': 'application/json',
    },
    json={'package_id': 3},
    timeout=30,
).json()

print(purchase['balance_after'])
{
  "ok": true,
  "purchase_id": 18,
  "balance_after": 250,
  "package": {
    "id": 3,
    "slug": "starter-250",
    "name": "Starter 250",
    "credits": 250,
    "price_cents": 2500,
    "currency": "USD"
  },
  "created_at": "2026-04-24T00:00:00Z"
}

Ledger and purchase history

The dashboard response exposes both purchases and ledger. Purchase entries describe package top-ups. Ledger entries describe both top-ups and usage debits.

Field Where it appears Meaning
credits_delta ledger Positive for purchases, negative for usage.
balance_after ledger The wallet balance after the ledger entry was applied.
entry_type ledger Examples include purchase and usage.
external_reference purchases Purchase identifier recorded by the backend.
package_slug and package_name purchases The package that produced the credit top-up.

When credits are charged

  • Credits are deducted after POST /api/v1/query succeeds against a provider.
  • The successful response includes credits_charged and remaining_credits.
  • Provider fallback failures can appear in provider_attempts, but failed attempts do not directly charge the wallet.
  • If the balance is below the surface cost, the query returns 402 and no charge is made.

Next steps