API endpoints
The base URL for OpenAI-compatible clients is https://go2llm.tech/v1; for the Anthropic SDK and Claude Code it is https://go2llm.tech (no /v1).
| Method | Endpoint | Auth | Purpose |
|---|---|---|---|
| GET | /status | none | gateway status |
| GET | /v1/models | none | published models, modalities and endpoints |
| GET | /v1/models/{id} | none | a single model, in the same shape as an element of /v1/models |
| GET | /api/pricing | none | public prices and the catalog version |
| POST | /v1/messages | API key | Anthropic Messages, SSE and tools |
| POST | /v1/messages/count_tokens | API key | input size estimate, no reservation and no charge |
| POST | /v1/chat/completions | API key | OpenAI Chat Completions, SSE and tools |
| POST | /v1/responses | API key | OpenAI Responses API, an adapter on top of chat.completions |
| POST | /v1/images/generations | API key | image generation for published image models |
| POST | /v1/images/edits | API key | image-to-image: edit or combine up to 4 source images |
| GET | /v1/me | API key | key quota, remaining balance and limits |
Account, key, balance and payment routes under /api/ use the browser session of the dashboard and are not a replacement for the model API.
Embeddings, video and audio are not published at the moment.
Picking the route for a model
The endpoints field in GET /v1/models lists what is sold on the model: messages, chat.completions, images.generations, images.edits. A mismatched model ID and endpoint returns 400 model_protocol_mismatch.
responses will not show up in that list, and that is not an oversight: endpoints describes what is sold on a model, not which dialects you can speak to us in. POST /v1/responses serves exactly the same models as POST /v1/chat/completions — details on the Responses API page.
A single model: GET /v1/models/{id}
curl https://go2llm.tech/v1/models/claude-sonnet-4-5
No key needed. Aliases resolve, but the id in the response is the canonical one: a request for claude-sonnet-5 returns "id": "claude-sonnet-4-5", so you see the substitution right away instead of inside an error message on your first paid request. An unknown ID gives 404 model_not_found with the same text as a rejection on /v1/messages.
Estimating the input: POST /v1/messages/count_tokens
The body matches POST /v1/messages (model, messages, system, tools). A key is required — otherwise this is free CPU for anyone — but there is no reservation and no charge: the call costs nothing. It has its own limit of 60 RPM per key, independent of the main one.
curl https://go2llm.tech/v1/messages/count_tokens \
-H "x-api-key: YOUR_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-haiku-4-5","messages":[{"role":"user","content":"Reply: OK"}]}'
{
"input_tokens": 14,
"go2llm": { "exact": false, "method": "byte_estimate", "typical_error_pct": null }
}
This is a byte-based estimate, not a vendor tokenizer, and the go2llm block says so out loud: exact: false. The gateway sizes the reservation for a request with the same estimator. It is good enough to decide whether your context fits the window and to ballpark the cost; for the real token count and the real price, read usage in the model's actual response.
typical_error_pct comes back as null: we have not measured the typical deviation of the estimate from the fact, so we do not publish it. Once the estimator is calibrated against accumulated spend, the field will carry a number.
Request ID
Every /v1/* response — successful, streamed or failed — carries an x-go2llm-request-id header. On errors the same identifier is duplicated in the body as error.request_id. That is the value a support request needs; never send your full API key.
curl -sD - -o /dev/null https://go2llm.tech/v1/models | grep -i x-go2llm-request-id
An unknown route under /v1/
A miss on the route returns JSON in the same shape as the rest of the gateway's errors, not plain text:
- unknown path →
404 endpoint_not_foundwith the list of published routes inerror.message; - known path with a different method →
405 method_not_allowedand anallowheader with the accepted method.
curl -i https://go2llm.tech/v1/embeddings # 404 endpoint_not_found
curl -i -X GET https://go2llm.tech/v1/messages # 405, allow: POST
The codes are explained on the API errors page.
CORS: reading from a browser is fine, spending is not
Access-Control-Allow-Origin: * sits on exactly four public read routes: GET /v1/models, GET /v1/models/{id}, GET /api/pricing, GET /status. You can call those from browser code — to build a model picker with live prices, for example.
On routes that take an API key there is deliberately no CORS. A key in a browser bundle is readable by every visitor to your site, and the rule "don't put the key in client-side JavaScript" should be enforceable, not just written in the docs. OPTIONS on those routes answers with a 405 and an explanation rather than silence: call go2llm from your own server.
Current model IDs and prices are in the model catalog and on the pricing page. Get a key and make your first request at go2llm.tech.