Kendr.org

Make real queries against https://kendr.org.

This guide is the fastest path from zero to a working Kendr integration. It covers the base domain, the supported auth modes, the request body for POST /api/v1/query, and working curl, JavaScript, Python, .NET, Java, and Go examples for catalog reads, credits, API keys, and live query execution.

Base URL: https://kendr.org Query route Catalog and dashboard

Integration rules

Item Value
Base domain https://kendr.org
Public discovery GET /api/catalog and GET /api/openapi.json
Query execution POST /api/v1/query
Primary server auth Authorization: Bearer kndr_live_... or X-API-Key: kndr_live_...
Customer state GET /api/me/dashboard returns user, packages, api_keys, purchases, ledger, and surfaces

Quickstart flow

1
Discover surfaces and packages
Call GET /api/catalog to see the current surfaces, packages, providers, and docs metadata.
2
Authenticate
Use an API key for backend code, or use X-Kendr-Session or OAuth when the request is directly tied to a customer session.
3
Fetch credits and wallet state
Call GET /api/me/dashboard to read the credit balance, packages, purchases, ledger, and enabled surfaces.
4
Run a query
Send the surface key, query string, and optional params to POST /api/v1/query.

Auth headers accepted by the query route

Mode Header When to use it
API key Authorization: Bearer kndr_live_... Best for server-to-server integrations and background jobs.
API key X-API-Key: kndr_live_... Alternative header when bearer auth is not convenient.
App session X-Kendr-Session: SESSION_TOKEN Best when your app just authenticated the user through Kendr.
OAuth bearer Authorization: Bearer kndr_oat_... Best for Kendr Desktop or CLI flows using PKCE or device code with the app scope.
Browser cookie kendr_session cookie Works for browser-origin requests after /api/auth/login.

Query request body

Field Required Meaning
surface Yes The Kendr surface key, such as google_search, google_images, google_maps, google_flights, or google_hotels.
query Yes The primary query string.
params No An object for optional values such as gl, hl, page, location, or travel fields.
Top-level extras No Optional params can also be sent beside surface and query. Kendr merges them with params.
{
  "surface": "google_search",
  "query": "best llm observability tools",
  "params": {
    "gl": "us",
    "hl": "en",
    "page": 1
  }
}

Query examples

Kendr is a plain HTTPS and JSON API. The same request contract works from JavaScript, Python, .NET, Java, and Go, so you can use whichever runtime already exists in your stack.

API key auth

curl https://kendr.org/api/v1/query \
  -X POST \
  -H "Authorization: Bearer $KENDR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "surface": "google_search",
    "query": "best llm observability tools",
    "params": {
      "gl": "us",
      "hl": "en",
      "page": 1
    }
  }'

App session auth

curl https://kendr.org/api/v1/query \
  -X POST \
  -H "X-Kendr-Session: $KENDR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "surface": "google_maps",
    "query": "coworking spaces in austin",
    "params": {
      "gl": "us",
      "hl": "en"
    }
  }'
Switch languages

Kendr currently ships helper clients for JavaScript and Python. Use the tabs to switch between Curl, JavaScript, Python, .NET, Java, and Go for the same query contract.

Server-side fetch request to POST /api/v1/query

const response = await fetch('https://kendr.org/api/v1/query', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.KENDR_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    surface: 'google_search',
    query: 'best llm observability tools',
    params: { gl: 'us', hl: 'en', page: 1 }
  })
});

const payload = await response.json();
console.log(payload.data, payload.remaining_credits);

Official helper clients

Kendr currently publishes helper clients for JavaScript and Python. Use these when you want a thinner call surface around the raw HTTP routes, or call the HTTPS endpoints directly from any other runtime.

JavaScript SDK

import { KendrClient } from './sdk/javascript/index.js';

const client = new KendrClient({
  apiKey: process.env.KENDR_API_KEY,
  baseUrl: 'https://kendr.org'
});

const response = await client.query({
  surface: 'google_search',
  query: 'best llm observability tools',
  params: { gl: 'us', hl: 'en', page: 1 }
});

console.log(response.data);

Python SDK

from kendr import KendrClient

client = KendrClient(
    api_key='YOUR_KENDR_API_KEY',
    base_url='https://kendr.org',
)

response = client.query(
    surface='google_search',
    query='best llm observability tools',
    params={'gl': 'us', 'hl': 'en', 'page': 1},
)

print(response['data'])

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://kendr.org/api/catalog

Dashboard balance

curl https://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.

Create and use API keys

API keys are customer-scoped credentials. They are created after a customer logs in through a browser session, app session, or OAuth bearer token, and the raw key is returned only once.

Create a key

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

List keys

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

The create response includes raw_token once. Persist it immediately and use the returned api_key.id later for revocation.

Successful response and errors

Successful query response

{
  "ok": true,
  "surface": "google_search",
  "provider": "searchapi",
  "credits_charged": 1,
  "remaining_credits": 249,
  "data": {
    "...": "provider payload"
  },
  "provider_attempts": []
}

Errors to handle

  • 400: invalid payload, missing surface, unsupported surface, or invalid JSON.
  • 401: no valid API key, session, or OAuth bearer token was supplied.
  • 402: the wallet does not have enough credits for the requested surface.
  • 502: every configured provider failed.
Charging rule

Kendr charges credits after a provider succeeds. Failed fallback attempts are exposed in provider_attempts for debugging but do not directly consume credits.