The gateway
convention

One host, one header, the provider’s own paths. Learn it once and every service on Squiid works the same way.

One rule

Every service on Squiid is reached the same way:

The convention
https://api.squiid.io/v1/<service>/<the provider's own path>

Authorization: Bearer $SQUIID_API_KEY

The service segment is the service slug, for example supabase, resend, openai or twilio. Everything after it is the provider's own path, unchanged. Request bodies, response bodies, status codes and error shapes are the provider's own, which means provider documentation stays correct and your agent already knows how to use it.

Why it is shaped this way

A coding agent that has to learn a new abstraction per service is slower and wronger than one that learns a single rule. By keeping the provider path and payloads intact, the only thing an agent must know is the host and the header. Everything it already knows about the Supabase client or the OpenAI SDK remains true.

Raw passthrough

Every catalog service is reachable at /v1/{service}/… with the provider's own request and response shapes. Provider SDKs work by overriding their base URL.

Passthrough
# anthropic, native messages api
curl https://api.squiid.io/v1/anthropic/v1/messages \
  -H "Authorization: Bearer $SQUIID_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{ "model": "claude-sonnet-5", "max_tokens": 1024, "messages": [...] }'

# resend
curl https://api.squiid.io/v1/resend/emails \
  -H "Authorization: Bearer $SQUIID_API_KEY" \
  -d '{ "from": "you@app.dev", "to": ["…"], "subject": "…", "html": "…" }'
// provider sdks work by overriding the base url
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({
  baseURL: "https://api.squiid.io/v1/anthropic",
  apiKey: process.env.SQUIID_API_KEY,
});

import { Resend } from "resend";
const resend = new Resend(process.env.SQUIID_API_KEY, {
  baseUrl: "https://api.squiid.io/v1/resend",
});
# provider sdks work by overriding the base url
from anthropic import Anthropic
anthropic = Anthropic(
    base_url="https://api.squiid.io/v1/anthropic",
    api_key=os.environ["SQUIID_API_KEY"],
)

import httpx
httpx.post("https://api.squiid.io/v1/resend/emails",
    headers={"Authorization": f"Bearer {KEY}"},
    json={"from": "you@app.dev", "to": ["…"], "subject": "…"})

With an SDK

Base URL swaps
// OpenAI
const ai = new OpenAI({
  baseURL: 'https://api.squiid.io/v1/openai',
  apiKey: process.env.SQUIID_API_KEY,
});

// Anthropic
const claude = new Anthropic({
  baseURL: 'https://api.squiid.io/v1/anthropic',
  apiKey: process.env.SQUIID_API_KEY,
});

// Supabase
const db = createClient('https://api.squiid.io/v1/supabase', process.env.SQUIID_API_KEY);

With plain fetch

fetch
const res = await fetch('https://api.squiid.io/v1/resend/emails', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SQUIID_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    from: 'hello@yourdomain.com',
    to: 'someone@example.com',
    subject: 'Sent through Squiid',
    html: '<p>One key.</p>',
  }),
});

With curl

curl
curl https://api.squiid.io/v1/openai/chat/completions \
  -H "Authorization: Bearer $SQUIID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4.1-mini","messages":[{"role":"user","content":"ping"}]}'

Put it in your agent rules

Paste this into whichever file your agent reads as project context:

Agent rules
# Services
All third-party calls go through the Squiid gateway.
Base URL: https://api.squiid.io/v1/<service>/
Header:   Authorization: Bearer $SQUIID_API_KEY
Never add provider-specific API keys to this repo.

That is CLAUDE.md for Claude Code, AGENTS.md for Codex, .cursor/rules for Cursor, .windsurf/rules/ for Windsurf, .clinerules for Cline, GEMINI.md for Gemini CLI and .github/copilot-instructions.md for GitHub Copilot. Agent-specific notes are on each agent page, and agent setup covers the endpoint that generates the block.

Errors

The gateway returns the provider status and body wherever it can, and provider errors are never billed. Where the problem is on the Squiid side you get a clear status instead: 401 for a missing or revoked key, 402 when the balance or the key's cap cannot cover the call, 403 when the key is not scoped to this service, and 404 when the service segment names something you have not added. Headers and errors has the full list and the body shape.

Keys

Keys are prefixed sq_live_. You can hold several, scoped per project or per agent, so the console shows which key made which call. Rotating a key is a click and does not touch upstream provider credentials, which is the whole point: a leaked gateway key is worth nothing outside the gateway and costs you one click, not an afternoon.

Questions people ask

What is the Squiid gateway convention?

Every service is called at https://api.squiid.io/v1/<service>/ with the header Authorization: Bearer $SQUIID_API_KEY. The path after the service name matches the provider’s own API, so provider documentation stays accurate.

Do I have to learn a new API for each service?

No. The gateway passes the request through to the provider, so the request and response bodies are the provider’s own. Only the host and the auth header change, which is why the switch is usually a one line change per client.

What happens to rate limits?

Provider rate limits still apply, and the gateway surfaces the provider response rather than hiding it. If a provider returns 429, so does the gateway, with the provider headers where they exist and x-sq-limit-source saying whose limit it was.

Is the gateway a single point of failure?

It is a dependency, like any provider. It is also what makes one key and one bill possible. If that trade is unacceptable for a particular critical path, keep that one service direct and run the rest through Squiid.

Can I use webhooks with services behind the gateway?

Yes. Webhooks are inbound from the provider and are configured in the console for the service, so the signing secret is held the same way the API credential is.

One convention.
Every service.

Point your SDK base URL at the gateway and give every agent the same single credential.