Help center

Troubleshooting

Work through these in order. Each step rules out a whole class of cause, so a later step is only worth doing once the earlier ones pass.

1

Can you reach the API at all?

GET /v1/modelsis public, so it separates "cannot reach xKiro" from "credentials are wrong" — the two failures that look identical from a stack trace.

curl -sS -o /dev/null -w "%{http_code}\n" https://api.xkiro.com/v1/models

Anything other than 200 here is network, DNS or a proxy in front of you — not your key and not your request body.

2

Is the key being sent, and accepted?

curl -sS https://api.xkiro.com/v1/chat/completions \
  -H "Authorization: Bearer $XKIRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"openai/gpt-5.6-sol","messages":[{"role":"user","content":"hi"}]}'

401 means the key is missing, malformed or revoked. The most common cause is an environment variable that is empty in the environment that actually runs — print its length (never its value) to confirm it arrived.

3

Read the error type, not the message

Messages are written for people and get reworded. type and code are stable, and they tell you whether retrying can ever help. The table on Error codes maps every status to an action.

4

Reproduce with curl

If curl works and your code does not, the difference is in your client — a wrapper adding headers, a proxy rewriting the body, or an SDK version mismatch. That is a much smaller search space than "the API is broken".

Common symptoms#

404 on every request

  • Model ID missing its vendor prefix. openai/gpt-5.6-sol, not gpt-5.6-sol.
  • Base URL has the wrong number of /v1s. OpenAI SDKs need it; Anthropic SDKs add it themselves. /v1/v1/messages is the giveaway.

Requests hang, then fail around 95 seconds

That is the blocking limit. Switch to stream: true. If a proxy sits in front, also check that it is not buffering the response — see Streaming.

Streaming works in curl but not in my app

  • Response buffering is on somewhere in the middle. In nginx: proxy_buffering off;.
  • Your reader is parsing incomplete events. A chunk boundary can land mid-event; buffer the tail and only parse complete ones.

Charged twice for what looks like one request

Check whether a proxy is retrying POST requests on timeout — that genuinely runs the request twice, and xKiro sees two legitimate calls. In nginx: proxy_next_upstream off;. See Idempotency.

429 that will not clear

A tight retry loop keeps you at the limit permanently — every retry consumes the capacity that would have let the next real request through. Back off exponentially, add jitter, and honour Retry-After. See Rate limits.

Empty or truncated answers

  • Finish reason length — the token budget ran out. Raise max_tokens.
  • Finish reason content_filter — the provider blocked it. Retrying identical input will not help.
  • Streaming that ends without a terminator is a failure, not an empty success. Treat it as retryable.

Never paste a key into a bug report

Share the request ID, the timestamp, the model and the error type. If a key has been exposed anywhere, revoke it first and investigate afterwards.

What to collect before asking for help#

  • The exact model ID.
  • Timestamp with timezone, and roughly how often it happens.
  • The full error body — type, code and message.
  • Whether the same request works with curl.
  • Whether a proxy or gateway sits between you and the API.

With those five, most issues are identifiable in one round trip. See Support.