Knowledge and production

Errors, retries and usage

Handle failures, recover interrupted requests, and reconcile usage and credits.

Know the pricing and credit policy

All model aliases and routing modes use one fixed 5% markup on the configured provider cost. Exact aliases and Kendr managed routing do not have different markup percentages. Credits added by a completed paid package purchase never expire; promotional grants can have a grant-specific expiration.

  • Use the public catalog's pricing_policy and per-model pricing fields for public quotes.
  • Use authenticated GET /v1/models for models and rates available to the current account.
  • Use kendr_usage.credits_charged_micros as the authoritative settled model charge.
  • Use the wallet activity or billing summary to distinguish non-expiring purchased lots from expiring promotional lots.

See Credits and billing for package and lot behavior.

Fetch surfaces, packages, and current credits

Use the public catalog to discover what is available, then use the customer dashboard to read the live wallet balance and package state for the authenticated user.

Public catalog

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

Dashboard balance

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

The dashboard response includes user.credit_balance, packages, api_keys, purchases, ledger, and surfaces.

Read the model response envelope

Successful model responses add three Kendr blocks next to the compatibility-format fields. A trimmed /v1/responses result:

{
  "id": "0887c41b-5285-409d-ad04-b900b9a258c3",
  "model": "kendr-intelligent",
  "status": "completed",
  "output_text": "Hello! How can I help?",
  "usage": { "input_tokens": 36, "output_tokens": 25, "total_tokens": 61 },
  "kendr_usage": {
    "credits_charged": "0.01165",
    "credits_charged_micros": 11650,
    "remaining_credits": "49886.925505",
    "request_id": "0887c41b-5285-409d-ad04-b900b9a258c3",
    "pricing_version": "cloud-v1"
  },
  "kendr_routing": {
    "receipt_id": "kr_86f82eb4d7a54fa2b30d8ce43e7d5f72",
    "request_id": "0887c41b-5285-409d-ad04-b900b9a258c3",
    "policy_version": "balanced-v1",
    "catalog_version": "catalog-2026-08-12",
    "pricing_version": "cloud-v1",
    "rate_card_version": "2026-08-12T00:00:00Z",
    "requested_model": "kendr-intelligent",
    "selected_model_alias": "kc-llama-4-scout",
    "task_category": "flash",
    "reason_code": "trivial_greeting_cheapest_fast",
    "confidence": "0.95",
    "tools": [],
    "latency_ms": 842,
    "attempted_candidates": [
      {"attempt": 1, "selected_model_alias": "kc-llama-4-scout", "status": "succeeded", "latency_ms": 842}
    ],
    "usage": {
      "input_tokens": 36,
      "cached_input_tokens": 0,
      "cache_write_tokens": 0,
      "output_tokens": 25,
      "reasoning_tokens": 0,
      "total_tokens": 61
    },
    "cost": {
      "currency": "credits",
      "credits_charged_micros": 11650,
      "credits_charged": "0.01165"
    }
  },
  "kendr_optimization": {
    "enabled": true,
    "requested_mode": "balanced",
    "resolved_mode": "balanced",
    "engine": "kendr_optimizer",
    "estimated_input_tokens_avoided": 24,
    "estimated_credits_saved_micros": 4000,
    "estimated_credits_without_optimization_micros": 15650,
    "shadow": false
  }
}
BlockWhat it tells you
kendr_usageExact settlement for this request: credits charged (also as integer microcredits), remaining wallet balance, token counts, and the idempotent request_id. Retrying with the same idempotency key replays this settled response instead of charging again.
kendr_routingPresent on Kendr managed routing requests. It identifies the requested route product, selected public alias, decision category/reason/confidence, sanitized attempt and fallback outcomes, latency, policy/catalog/pricing versions, settled token or billing-unit usage, and settled credit cost. Store receipt_id for support or audit correlation, but treat it as opaque and never parse its current kr_... form. Provider identities, router-model internals, and raw provider errors are not public.
kendr_optimizationOptimizer receipt: requested and resolved mode, engine, compression ratio, estimated input tokens avoided, estimated credits saved, comparable unoptimized cost, quality checks, and fallback state. shadow: true is preview-only; resolved_mode: "off" means the request was sent unmodified.
Receipt behavior on errors

A failed managed-route request can return sanitized routing identifiers, versions, selected alias, attempts, and outcome metadata in its error details. It does not claim settled usage or cost when the request was not settled successfully.

Keep API keys out of client code

Store Kendr API keys in a server-side secret manager or protected environment variable. Never place a live key in browser JavaScript, a mobile bundle, a public repository, logs, analytics events, or support screenshots.

# Local development only
KENDR_API_KEY=kndr_live_replace_with_your_key

# Application configuration
KENDR_BASE_URL=https://api.kendr.org/v1
KENDR_MODEL=kendr-intelligent
  • Create separate keys for development and production so one environment can be revoked without interrupting the other.
  • Use the narrowest scopes your integration needs. Model listing needs models:read; generation needs models:invoke; usage reads need usage:read.
  • Rotate a key by creating its replacement, updating callers, confirming traffic on the new key, and then revoking the old key.
  • Proxy browser and mobile requests through your backend when your product cannot safely hold a server credential.

Kendr configuration reference

Use environment variables or protected deployment secrets for service configuration. Client applications normally need only KENDR_API_KEY, KENDR_BASE_URL, and the selected model alias.

ConfigurationPurpose
KENDR_API_KEYServer-side API key used by your integration.
KENDR_BASE_URLClient SDK base URL, usually https://api.kendr.org/v1.
KENDR_MODELDefault model alias, for example kendr-intelligent.
KENDR_PUBLIC_BASE_URLPublic origin used in generated links and callbacks.
KENDR_ALLOWED_ORIGINSComma-separated origins allowed to call browser-facing JSON routes.
KENDR_DATABASE_URL or DATABASE_URLPostgreSQL connection string.
KENDR_REDIS_URLRedis connection string for shared runtime state.
KENDR_INTERNAL_JWT_SECRETSecret used to authenticate Kendr service-to-service calls.
KENDR_CREDENTIAL_ENCRYPTION_KEYEncryption key for stored connector and MCP credentials.
KENDR_USER_REQUESTS_PER_MINUTEPer-user model request rate limit. The implementation default is 60 when Redis-backed rate-limit state is available; the same limit is enforced per replica from in-process state when that shared state is unavailable. Deployment and account limits can differ, and a 429 response is authoritative.
KENDR_SES_FROM_EMAIL, KENDR_SES_REGIONEmail sender and region for sign-in messages.
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKENAWS credentials when the deployment uses AWS-backed capabilities.
AWS_REGION, AWS_DEFAULT_REGIONDefault AWS region for general AWS SDK calls.
BEDROCK_MODEL_REGIONRegion used for Bedrock model invocation. This can differ from the default AWS region.
Managed web-search gatewayCross-provider web search is configured on the Kendr side through the managed gateway; deployments enable it during setup and applications need no additional configuration.
OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, XAI_API_KEYProvider credentials for native model routes.
DEEPSEEK_API_KEY, ZAI_API_KEY, QWEN_API_KEY or DASHSCOPE_API_KEY, BYTEPLUS_API_KEY or ARK_API_KEY, KIMI_API_KEY, MISTRAL_API_KEY, SARVAM_API_KEY, TOKENRA_API_KEYAdditional provider credentials for enabled native routes. QWEN_API_KEY and BYTEPLUS_API_KEY take precedence over their provider-native fallback names.
KENDR_FREE_ACCOUNT_CREDITS, KENDR_REFERRAL_REWARD_CREDITS, KENDR_REFERRAL_JOIN_BONUS_CREDITS, KENDR_PROMOTIONAL_CREDIT_EXPIRATION_DAYSPromotional grant amounts and the default promotional-grant expiry window. The older KENDR_CREDIT_EXPIRATION_DAYS name remains a compatibility fallback. Neither setting applies to completed paid purchases; purchased credit lots have no expiry.
RAZORPAY_KEY_ID, RAZORPAY_KEY_SECRETPayment provider credentials for credit purchases.

Retries, timeouts, and idempotency

Idempotency-Key is optional — Kendr generates one per request when absent. Supplying your own key is recommended for production retry safety: reuse the same key only when retrying the same logical operation, and create a new key for a new user request.

StatusWhat it meansRecommended action
400The request is invalid or uses an unsupported field.Do not retry unchanged. Validate the body against OpenAPI and correct it.
401 / 403The key is missing, invalid, revoked, or lacks the required scope.Do not loop. Check the credential and scopes.
402The shared wallet cannot cover the request.Ask the account owner to add credits, then retry as a new attempt.
408 / 429The call timed out or traffic is being limited.Retry with exponential backoff and jitter. Honor Retry-After if a gateway includes it, but do not require that header.
500 / 502 / 503The request could not be completed by the service or selected route.Retry a small number of times with the same idempotency key, then surface a recoverable error.
Timeout budget

Model calls can take longer than normal JSON APIs, especially for intelligent routing or tool use. Before the first streamed answer delta, a disconnect may cancel the request. After output starts, Kendr finishes and settles the server-owned request. To recover without any chance of starting a second generation, send an authenticated, empty-body POST /api/v1/llm/responses/replay with the original Idempotency-Key. This actor- and wallet-scoped lookup never plans, reserves credits, or invokes a provider, and a settled replay retains its optimizer and web-search receipts. Compatibility clients may instead resend the exact original body and key with X-Kendr-Idempotency-Replay-Only: true.

Track usage without recording sensitive prompts

Record your own request identifier, idempotency key, selected Kendr alias, status, latency, token totals, and returned credit charge. Avoid logging authorization headers or full prompts unless your own privacy policy explicitly requires and protects that data.

Account usage

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

Available models

curl https://api.kendr.org/v1/models \
  -H "Authorization: Bearer $KENDR_API_KEY"

Build authenticated model selection from GET /v1/models at runtime. Use unauthenticated GET /api/public/models for public directories or pre-login discovery; its versioned response exposes public capabilities, availability, and credit rates but deliberately omits private provider routes and account-specific aliases. An alias can become temporarily unavailable, so avoid hardcoding assumptions about every account or environment.

Production checklist

  • Create a production key with only the scopes the service requires and store it outside source control.
  • Use TLS and the exact https://api.kendr.org API base domain.
  • Generate an idempotency key for every chargeable operation and preserve it across retries.
  • Handle 400, 401, 402, 429, and 5xx responses deliberately; cap retry attempts.
  • Set connect, read, and overall deadlines appropriate to model latency.
  • Read the model catalog at runtime and provide a graceful fallback when the preferred alias is unavailable.
  • Monitor latency, failures, token usage, and credits charged without logging secrets.
  • Test key rotation, low-credit behavior, duplicate retries, streaming disconnects, and revoked credentials before launch.