Get started
Integrate Cran into your app
Your product never holds provider keys. It authenticates to Cran with a connection token (cran_…), and the dashboard controls which model, prompt, and parameters each call uses.
Native SDK (recommended)
The cran-sdk client has no runtime dependencies and returns the resolved model alongside the content. model: "auto" applies whatever you publish in the dashboard.
import { createCran } from "cran-sdk";
const { content, model } = await createCran().chat(
[{ role: "user", content: "Summarize this ticket…" }],
{ model: "auto" } // applies your published architecture
);OpenAI-compatible (drop-in)
Already using the OpenAI SDK? Change two values - the base URL and the key - and keep your code. The key is your Cran connection key (the optional cran link routing key, separate from the cran login MCP connection), not a real OpenAI key.
from openai import OpenAI
client = OpenAI(
base_url="https://trycran.in/api/v1",
api_key="cran_…", # your Cran token, NOT an sk-… key
)
client.chat.completions.create(model="auto", messages=[...])Embeddings & images
The same token and base URL work for the other modalities. Send model: "auto" or a catalog id (e.g. openai/text-embedding-3-small, openai/gpt-image-1):
curl https://trycran.in/api/v1/embeddings \
-H "Authorization: Bearer cran_…" -H "Content-Type: application/json" \
-d '{ "model": "auto", "input": "text to embed" }'Why traffic must go through Cran
Spend tracking, workflow discovery, live architecture editing, and model comparison all require requests to pass through Cran’s API. Calls that bypass Cran and hit a provider directly are invisible to the dashboard - there is no out-of-band reconciliation.