AI API

Org-scoped AI provider management and a pass-through proxy: configure provider credentials once per org, then call any provider's native API through Kapable without shipping provider keys to clients.

Token tier: API keys work here

The AI module is scope-gated: an sk_live_ key with the right scope gets 200 (verified live — it's one of the surfaces in the SDK's golden-path smoke test).

Providers

MethodPathSDK (client.ai)
GET/v1/providerslistProviders
GET/v1/providers/{id}getProvider
POST/v1/providers/{id}/configureconfigureProvider
DELETE/v1/providers/{id}/configureremoveProviderConfig

Provider proxy

POST /v1/proxy/{provider}/{path} forwards the request to the configured provider with the org's stored credentials. The SDK returns the raw Response so you keep full control over streaming bodies.

SDK Examples

// List providers and their configuration state
const { providers } = await client.ai.listProviders();

// Point the provider at a strongbox secret holding the org's upstream key —
// the raw key never travels through this SDK (store it via client.secrets first)
await client.ai.configureProvider('anthropic', { key_name: 'anthropic-api-key' });

// Call the provider's native API through the proxy
const res = await client.ai.proxy('anthropic', '/v1/messages', {
  body: {
    model: 'claude-sonnet-4-6',
    max_tokens: 256,
    messages: [{ role: 'user', content: 'Hello from Kapable' }],
  },
});
const completion = await res.json();
let providers = client.ai().list_providers(ListProvidersParams::default()).await?;

let payload = serde_json::json!({
    "model": "claude-sonnet-4-6",
    "max_tokens": 256,
    "messages": [{"role": "user", "content": "Hello from Kapable"}]
});
let res = client.ai().proxy("anthropic", "/v1/messages", ProxyRequest {
    body: Some(serde_json::to_vec(&payload)?),
    ..ProxyRequest::post()
}).await?;