go2llm API documentation

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).

MethodEndpointAuthPurpose
GET/statusnonegateway status
GET/v1/modelsnonepublished models, modalities and endpoints
GET/v1/models/{id}nonea single model, in the same shape as an element of /v1/models
GET/api/pricingnonepublic prices and the catalog version
POST/v1/messagesAPI keyAnthropic Messages, SSE and tools
POST/v1/messages/count_tokensAPI keyinput size estimate, no reservation and no charge
POST/v1/chat/completionsAPI keyOpenAI Chat Completions, SSE and tools
POST/v1/responsesAPI keyOpenAI Responses API, an adapter on top of chat.completions
POST/v1/images/generationsAPI keyimage generation for published image models
POST/v1/images/editsAPI keyimage-to-image: edit or combine up to 4 source images
GET/v1/meAPI keykey 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_found with the list of published routes in error.message;
  • known path with a different method → 405 method_not_allowed and an allow header 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.