Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kynasmith.dev/llms.txt

Use this file to discover all available pages before exploring further.

Authentication

Kynasmith uses short-lived bearer access tokens for API calls. The SDKs handle token management for you.

Server-side authentication

Use your project-bound API key to initialize the Python SDK. The SDK automatically exchanges your credentials for a short-lived access token and refreshes it as needed.
from kynasmith import KynasmithClient

client = KynasmithClient(
    api_key="ks_key_123:secret_123",
)
The api_key value combines your key ID and secret in the format key_id:key_secret. You can find both values in the portal under Settings > API Keys.
You can also bootstrap with separate key ID and secret fields, or with a service account:
# Separate key fields
client = KynasmithClient(
    api_key_id="key_123",
    api_key_secret="secret_123",
)

# Service account
client = KynasmithClient(
    service_account_id="svc_123",
    service_account_secret="svc_secret_123",
)

Browser authentication

Do not embed long-lived API keys or service-account secrets in the browser. Instead, expose a backend endpoint that exchanges your API key for a short-lived Kynasmith access token, then pass it through a tokenProvider:
import { createClient } from "@kynasmith/web-sdk";

const client = createClient({
  tokenProvider: async () => {
    const response = await fetch("/api/kynasmith/token", { method: "POST" });
    const { access_token } = await response.json();
    return access_token;
  },
});

Backend token endpoint example

Your backend endpoint should call the Kynasmith token exchange API:
# Example backend endpoint (using any Python web framework)
import httpx

async def exchange_token():
    """Mint a short-lived Kynasmith access token for the browser client."""
    async with httpx.AsyncClient() as http:
        resp = await http.post(
            "https://api.kynasmith.dev/api/auth/access-tokens",
            json={
                "api_key_id": "key_123",
                "api_key_secret": "secret_123",
                "scopes": ["sessions:write"],
            },
        )
        resp.raise_for_status()
        return resp.json()
The response contains an access_token field with the short-lived bearer token your frontend needs.
If you already have a short-lived bearer token, you can pass it directly instead of a tokenProvider:
const client = createClient({
  accessToken: "ks_at_...",
});
When using a static accessToken, you are responsible for refresh and rotation.

Access token scopes

When minting an access token, you can restrict its capabilities with scopes. If no scopes are specified, the token inherits the full scope of the credential that minted it.
ScopeDescription
movespecs:readRead MoveSpec resources, drafts, versions, and validation results
movespecs:writeCreate, update, validate, version, release, and fork MoveSpecs
sessions:readRead detection session status and results
sessions:writeCreate detection sessions and connect to realtime streams
tokens:readList and inspect access tokens
tokens:writeCreate and revoke access tokens
Use the narrowest scope set that your integration requires. Browser integrations typically need only sessions:write (and optionally movespecs:read).

Token lifetime notes

  • Browser integrations should treat tokenProvider as a refresh hook, not as one-time bootstrap. The SDK may call it before each authenticated request.
  • The Python SDK automatically refreshes access tokens as they approach expiry.
  • If you pass a bearer token directly through accessToken or access_token, you are responsible for refresh and rotation.

Direct API integration

If you are integrating without an official SDK, use:
  1. POST /api/auth/access-tokens to mint a bearer access token
  2. Authorization: Bearer <access_token> header on all subsequent API calls
  3. POST /api/detection/sessions to create a session
See the API reference for the full endpoint documentation. If token exchange, scopes, or bearer auth fail, see Authentication troubleshooting.