Skip to content
Chessglance
Open app
Menu
d1 — Errors and limits

Errors and limits

Status codes, error bodies, monthly quotas, per-minute limits and how to retry the API safely.

Errors return a JSON body with a human-readable message, and the request id when there is one.

{ "error": "No chessboard was detected in the image.", "requestId": "4b2c5e1a-8d0f-4f1e-9a53-0b6c2f7d1a90" }

Status codes

Status Meaning What to do
200 Recognized.
400 No image in the request, or the file cannot be decoded. Fix the request.
401 Missing, invalid or revoked API key. Send X-API-Key; create a new key if needed.
413 The file is over 12 MB, or the image is over 40 megapixels. Downscale and resend. A board only needs about 20 px per square.
415 The upload is not an image. Send PNG, JPEG or WebP.
422 No chessboard was found in the image. Crop closer, or pass bbox if you know where the board is.
429 Monthly quota used up, or too many requests per minute. Wait for the reset in X-RateLimit-Reset, or upgrade.
503 Workers are starting or the queue is full. Retry with backoff.
504 Recognition timed out (30 s). Retry once; send a smaller image.

Quotas

Quota is per account, counted per calendar month in UTC, and shared by all your keys. Every authenticated request that carries an image counts as one, including a request that then fails with 422 or a 5xx. Requests rejected for a bad key, a missing file or a file that is too large or not an image do not count.

Plan Requests a month
API Free 500
API Starter 10,000
API Growth 100,000
API Scale 1,000,000

At the limit the API answers 429 with the quota in the body and in the X-RateLimit-* headers. Nothing is billed beyond your plan.

On top of the monthly quota there is a burst limit per client IP address, currently 60 requests a minute. It returns 429 with Too many requests; slow down. If you need more throughput, write to us.

Retrying

Retry 503 and 504 with exponential backoff. Do not retry 400, 401, 413, 415 or 422: the same request fails the same way.

Retry with backoff
async function recognize(form, tries = 4) {
  for (let attempt = 0; attempt < tries; attempt++) {
    const response = await fetch('https://api.chessglance.com/v1/recognize', { method: 'POST', headers: { 'X-API-Key': process.env.API_KEY }, body: form });
    if (response.ok) return response.json();
    // 503 and 504 are safe to retry; everything else needs a fix on your side.
    if (![503, 504].includes(response.status)) throw new Error((await response.json()).error);
    await new Promise((resolve) => setTimeout(resolve, 500 * 2 ** attempt));
  }
  throw new Error('Recognizer unavailable');
}

Data handling

Uploaded images are deleted when the request finishes. We log the request id, status, number of boards, time taken and size, not the image. See the privacy policy.

Fair play

Recognition works on any page, but the API is for study, publishing and analysis. API customers agree not to use it to assist in a live game, and to pass the same rule on to their users. See the terms.