ZeroCredit AI Documentation

Two ways to start: point your existing AI API at ZeroCredit, or connect your provider API keys in the dashboard. Either way you keep your models, prompts and provider billing.

Overview

ZeroCredit is a drop-in AI infrastructure and FinOps layer. It sits underneath your existing AI application: intelligent routing, semantic caching, budget controls, fallback chains and ML-powered cost optimization — with evidence for every dollar saved.

  • ZeroCredit API path — change one base URL in your existing OpenAI-compatible client. No SDK swap, no prompt rewrite.
  • BYOK console path — connect your provider API keys in the dashboard and use the playground, analytics, budgets and optimization tooling directly.

Nothing is applied to your traffic automatically. Optimization recommendations wait for your approval.

Quickstart

  1. Create a ZeroCredit API token in the dashboard under API Keys. It is shown once — store it in your secret manager.
  2. Connect at least one provider API key (OpenAI, Anthropic, Google, xAI, DeepSeek, Kimi, Perplexity, Azure OpenAI) so requests run on your own provider account. Keys come from each provider's developer platform — a consumer subscription (Gemini Advanced, Google One AI, Claude Pro/Max, ChatGPT Plus) is not an API credential and cannot authorize API requests.
  3. Point your client at the ZeroCredit base URL and send a request.
curl
curl https://zerocreditai.com/api/public/v1/chat/completions \
  -H "Authorization: Bearer $ZEROCREDIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "zerocredit-balanced",
    "messages": [
      { "role": "system", "content": "You are concise." },
      { "role": "user", "content": "Summarize our refund policy." }
    ]
  }'
Python (OpenAI SDK)
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZEROCREDIT_API_KEY"],
    base_url="https://zerocreditai.com/api/public/v1",
)

resp = client.chat.completions.create(
    model="zerocredit-balanced",
    messages=[{"role": "user", "content": "Summarize our refund policy."}],
)
print(resp.choices[0].message.content)
Node (openai)
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ZEROCREDIT_API_KEY,
  baseURL: "https://zerocreditai.com/api/public/v1",
});

const resp = await client.chat.completions.create({
  model: "zerocredit-balanced",
  messages: [{ role: "user", content: "Summarize our refund policy." }],
});
LangChain (Python)
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="zerocredit-balanced",
    api_key=os.environ["ZEROCREDIT_API_KEY"],
    base_url="https://zerocreditai.com/api/public/v1",
)

Authentication

Every request carries a ZeroCredit API token as a bearer token. Tokens are prefixed zc_.

Authorization: Bearer zc_your_token_here
  • Tokens are revealed once at creation and can be revoked at any time from the dashboard.
  • Create separate tokens per environment or service so you can revoke one without downtime.
  • Provider API keys you connect are stored encrypted, used only to call that provider on your behalf, and are never returned by any API or shown again in full.
  • Never ship a token in browser or mobile code — call ZeroCredit from your backend.

ZeroCredit AI OpenAPI spec, MCP server & CLI

Everything an AI agent or code generator needs to integrate with ZeroCredit AI is published at predictable URLs and needs no credentials to read.

ResourceWhat it is
https://zerocreditai.com/openapi.jsonOpenAPI 3.1 specification for the ZeroCredit AI API, including security schemes and OAuth scopes.
https://zerocreditai.com/api/openapi.yamlThe same specification in YAML.
https://zerocreditai.com/agents.mdAgent instructions: when to use ZeroCredit AI, how to call it, endpoints and error handling.
https://zerocreditai.com/api/public/v1/statusService status, endpoints, capabilities, onboarding and rate limits. No authentication.
https://zerocreditai.com/api/public/v1/catalogPublic model catalog with providers, context windows and list prices. No authentication.
https://zerocreditai.com/api/public/v1/sandbox/chat/completionsSandbox chat completion returning a deterministic canned response. No authentication, no billing, no provider call.
https://zerocreditai.com/llms.txtPlain-text index of ZeroCredit AI pages and developer resources for LLMs.
https://zerocreditai.com/mcpModel Context Protocol server (OAuth 2.0) exposing usage, spend and provider-key tools.
https://zerocreditai.com/.well-known/oauth-authorization-serverRFC 8414 authorization server metadata: issuer, same-origin OAuth endpoints and the scopes an agent can request.
https://zerocreditai.com/.well-known/openid-configurationThe same metadata at the OpenID Connect discovery location.
https://zerocreditai.com/.well-known/oauth-protected-resourceRFC 9728 protected-resource metadata for the MCP endpoint.

OAuth 2.0 endpoints

Authorization code flow with PKCE and dynamic client registration, served on this domain at /api/public/oauth/authorize, /token, /register, /userinfo, /revoke and /jwks.json. API tokens (zc_...) remain available and are the simplest option for server-to-server agents.

Rate-limit headers

Every API response carries RateLimit-Policy (120 requests per 60 seconds per authenticated caller). Responses for an identified caller also carry RateLimit, RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. A 429 includes Retry-After in seconds.

Unknown paths return HTTP 404 with a structured JSON body under /api/, or a Markdown body when the request sends Accept: text/markdown.

ZeroCredit AI CLI

export ZEROCREDIT_API_KEY=zc_your_token_here
npx @zerocredit/cli status
npx @zerocredit/cli catalog
npx @zerocredit/cli models
npx @zerocredit/cli chat "Summarise our AI spend policy"

Chat completions

POST https://zerocreditai.com/api/public/v1/chat/completions — standard OpenAI chat-completions wire format.

FieldNotes
modelA provider model ID or a ZeroCredit routing alias (see Models & routing).
messagesFull array. system, developer, user, assistant and tool roles; turn structure preserved.
contentString, or an array of parts with text, image_url and file (data: URL) parts for multimodal requests.
modalities["text", "image"] asks for image generation through the chat endpoint; the reply carries the image under zerocredit.images and returns a complete response even when stream is set. Runs on your image-capable provider key.
streamtrue for a Server-Sent Events response.
temperature, top_p, stop, n, seedPassed through to the provider.
max_tokens / max_completion_tokensEither is accepted.
presence_penalty, frequency_penaltyPassed through where the provider supports them.
response_formatJSON / structured output where the provider supports it.
tools, tool_choice, parallel_tool_callsFunction calling on tool-capable providers.
logprobs, top_logprobsPassed through where supported.
metadataFlat string map. customer_ref and feature are used for cost attribution.

Responses are OpenAI-shaped, plus a non-standard `zerocredit` block with cost evidence:

Response
{
  "id": "chatcmpl-zc-...",
  "object": "chat.completion",
  "created": 1767225600,
  "model": "gemini-2.5-flash",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "..." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 218,
    "completion_tokens": 96,
    "total_tokens": 314
  },
  "zerocredit": {
    "provider": "google",
    "cost_usd": 0.00021,
    "savings_usd": 0.0017,
    "cache_hit": false,
    "used_user_key": true,
    "latency_ms": 740,
    "routing_mode": "balanced",
    "plan": { "tier": "free" }
  }
}

Standard clients ignore the extra block, so it is safe to leave in place. Read it when you want per-request cost and savings evidence inside your own logs.

Images and embeddings

Both use the same ZeroCredit token and run on your own provider keys — never on a consumer subscription. If no connected key can perform the capability, the error says so and names the credential that would enable it.

  • POST https://zerocreditai.com/api/public/v1/images/generations — OpenAI-shaped image generation (prompt, optional size; n=1, URL responses). Runs on your OpenAI, Google or xAI key; the reply adds a zerocredit block with provider, model and cost.
  • POST https://zerocreditai.com/api/public/v1/embeddings — OpenAI-shaped embeddings (input string or array, optional model). Runs on your OpenAI or Google key. Embeddings execute on the provider's embeddings endpoint, never through chat.

Streaming

Set "stream": true to receive Server-Sent Events. Chunks are chat.completion.chunk objects and the stream ends with data: [DONE].

SSE
data: {"id":"chatcmpl-zc-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"}}]}

data: {"id":"chatcmpl-zc-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hello"}}]}

data: {"id":"chatcmpl-zc-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
  • Tool calls arrive in the delta as tool_calls, with finish_reason: "tool_calls" on the final chunk.
  • Cached responses stream too, so client behaviour stays identical on a cache hit.
  • Disconnecting mid-stream cancels the request; partial usage is still accounted.

Models & routing

GET https://zerocreditai.com/api/public/v1/models returns the routing aliases plus the models available to your account, in the standard { object: "list", data: [...] } shape.

curl
curl https://zerocreditai.com/api/public/v1/models -H "Authorization: Bearer $ZEROCREDIT_API_KEY"

Send a provider model ID to pin one model, or a routing alias to let ZeroCredit choose:

Model valueBehaviour
zerocredit-cheapestLowest cost model that can handle the request.
zerocredit-fastestLowest observed latency.
zerocredit-balancedWeighted score across cost, latency and quality.
zerocredit-premiumHighest quality model available to you.
zerocredit-autoSame as balanced — the safe default.
<provider model id>Pinned. No cross-model routing; caching, budgets and fallbacks still apply.

Routing only ever considers models your connected providers can actually serve, and requests with images or tools are routed only to models with those capabilities.

Response headers

HeaderMeaning
X-Request-IdUnique request ID. Include it in support requests.
X-ZC-ModelThe model that actually served the request.
X-ZC-Cost-USDCost attributed to this request.
X-ZC-Cachehit or miss for semantic cache.

Logging these four values next to your own request IDs gives you a cost dashboard without parsing response bodies.

Cost attribution

Tag requests so spend rolls up per end customer and per product feature in the Customer Costs and Finance views.

Tagging
# headers
x-zerocredit-customer: acct_10482
x-zc-feature: support-inbox

# or in the request body
{
  "model": "zerocredit-balanced",
  "messages": [ ... ],
  "metadata": {
    "customer_ref": "acct_10482",
    "feature": "support-inbox"
  }
}
  • Use a stable, non-personal identifier as customer_ref — an internal account ID, not an email.
  • Feature labels are normalised to lowercase letters, numbers, hyphens and underscores.
  • Untagged requests still appear in totals, just without a customer or feature breakdown.

Caching, budgets & fallbacks

  • Semantic caching — near-duplicate prompts can be served from cache at near-zero cost. Cache hits are marked in the response and the header, so you always know when an answer was reused. Free plan includes a limited monthly hit allowance; beyond it, requests simply go to the provider as normal.
  • Budget controls and kill-switch — set spend limits per scope in alert-only or hard-stop mode. Hard-stop returns a quota error instead of spending more. Alerts can be delivered by email or webhook.
  • Fallback chains — if the primary provider errors, rate limits or times out, the request is retried on the next capable provider you have connected.
  • Optimization recommendations — cheaper-model and prompt-efficiency opportunities are surfaced with evidence and applied only when you approve them.

Which of these apply to a given request depends on the plan active on the account. Every signed-in account is on Free by default until a paid plan is active, and the applied plan is reported in the zerocredit.plan block.

Errors & retries

Error shape
{
  "error": {
    "message": "Invalid or revoked token",
    "type": "authentication_error",
    "code": null,
    "param": null
  }
}
StatusMeaning and what to do
400invalid_request_error — malformed body or unsupported field. Fix and resend; do not retry blindly.
401authentication_error — missing, invalid or revoked token. Rotate the token.
402insufficient_quota — budget hard-stop or provider credit exhausted. Raise the limit or top up the provider account.
429rate_limit_error — provider or account rate limit. Retry with exponential backoff and jitter.
5xxapi_error — transient upstream failure. Retry a couple of times with backoff; fallback chains already retry across providers.

Errors surface the underlying provider message where one exists, so failures are diagnosable rather than generic.

Limits & not yet supported

  • Supported today: chat completions, streaming, tool calling on capable providers, JSON/structured output, standard sampling parameters, multimodal text + image inputs, inline file parts, image generation (images/generations, or chat with modalities ["text", "image"]), embeddings, web search, model discovery.
  • Web search: send web_search_options: {} (or a { "type": "web_search" } entry in tools) and the request runs on a provider's own search mechanism using your connected key: Google Search grounding, the OpenAI web_search tool, the Anthropic web_search server tool, or Perplexity Sonar (always search-grounded). Sources come back as OpenAI-style url_citation annotations plus azerocredit.web_search block. Provider limits apply: the searching provider bills each search, grounded answers are returned complete rather than streamed, Google cannot combine grounding with your own function tools in one call, and OpenAI does not report the queries it ran. Requests that need search never fall back to a platform model or to model knowledge — if no connected key can search, the call fails with the credential type that would enable it. Wording alone ("search the web…") never switches search on; the parameter does.
  • Not exposed yet: code execution, computer use, browsing agents, audio output, fine-tuning, batch APIs, and provider-specific stateful APIs (assistants, files, threads). Keep those on the provider SDK directly — an explicit request for audio output returns a clear error rather than a silent text answer.
  • Tool calling depends on the provider serving the request — pin a model when your app requires it.
  • Up to 100 messages per request; sampling parameter ranges follow the OpenAI specification.

Security & data handling

  • Provider keys are encrypted at rest and used only to call that provider for your account. They are never returned in an API response.
  • BYOK requests are billed by your provider under your own account, pricing and rate limits.
  • Request telemetry (model, tokens, cost, latency, status) is recorded so analytics and cost evidence work.
  • Prompt and response content is stored only where a feature you enable requires it — for example semantic caching or a prompt you save to the registry. Cached content expires and can be cleared from the dashboard.
  • Your prompt content is never used to train models and is not sold.
  • Full detail in the privacy policy and terms.

FAQ

Do I have to send my traffic through ZeroCredit?

No. You can either point your existing OpenAI-compatible client at the ZeroCredit base URL, or connect your provider API keys in the dashboard and use the console, playground and cost tooling. Most teams do both.

Whose provider account gets billed?

Yours. When you connect your own provider keys (BYOK), calls are made with your key and billed by your provider under your existing pricing, discounts and rate limits.

Does ZeroCredit change my models or prompts automatically?

No. Optimization recommendations are surfaced for review and applied only when you choose to apply them. Routing modes and caching are opt-in settings you control.

Do I need to change my SDK or rewrite my application?

No. The chat completions endpoint speaks the standard OpenAI wire format, so changing the base URL and API key in your existing SDK is enough.