Skip to main content
When a request fails, the API returns a consistent JSON error body with an HTTP status code. This page covers every error you might encounter, what causes it, and how to handle it.

Error shape

Every error response has the same structure:
{
  "error": "error_code",
  "message": "Human-readable description"
}
The error field is a stable, machine-readable code you can match on in your code. The message field is a human-readable explanation that may change over time, so don’t parse it programmatically.

Error codes

Client errors (4xx)

These indicate a problem with the request. Fix the issue before retrying.
HTTP statusCodeDescriptionCommon cause
400bad_requestInvalid request body or parametersMalformed JSON, missing required fields, coordinates outside valid range
401unauthorizedMissing or malformed API keyNo x-api-key header, or key doesn’t match the sk_live_* format
403forbiddenInvalid, suspended, or revoked API keyKey was deleted, suspended by admin, or doesn’t exist
404not_foundEndpoint does not existTypo in the URL path, or using an unsupported HTTP method
408request_timeoutRequest took too long to processVery long routes, complex optimisation problems, or temporary server load
429too_many_requestsRate limit exceededToo many requests in a short window. Back off and retry

Server errors (5xx)

These indicate a problem on our side. They are usually transient and safe to retry.
HTTP statusCodeDescriptionCommon cause
502bad_gatewayUpstream service unreachableThe routing engine is starting up or temporarily unreachable
503service_unavailableRouting engine temporarily unavailableMaintenance or deployment in progress
504gateway_timeoutUpstream service timed outThe routing engine took too long to respond

Handling errors in code

Check the HTTP status code first, then read the error field for specifics:
const response = await fetch("https://api.footstep.ai/v1/routing/route", {
  method: "POST",
  headers: {
    "x-api-key": process.env.FOOTSTEP_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ locations }),
});

if (!response.ok) {
  const { error, message } = await response.json();

  switch (error) {
    case "bad_request":
      // Fix the request — don't retry
      console.error("Invalid request:", message);
      break;
    case "unauthorized":
    case "forbidden":
      // Check your API key
      console.error("Auth failed:", message);
      break;
    case "too_many_requests":
      // Back off and retry
      break;
    default:
      // Server error — retry with backoff
      break;
  }
}

Retry strategy

Some errors are transient and safe to retry. Use exponential backoff with jitter to avoid thundering herd problems, where all your retries hit the server at the same time:
async function fetchWithRetry(url, options, maxRetries = 3) {
  const retryable = new Set([408, 429, 502, 503, 504]);

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.ok || !retryable.has(response.status)) {
      return response;
    }

    if (attempt < maxRetries) {
      // Exponential backoff: 1s, 2s, 4s... capped at 30s
      const delay = Math.min(1000 * 2 ** attempt, 30000);
      // Add random jitter (50-100% of delay) to spread out retries
      const jitter = delay * (0.5 + Math.random() * 0.5);
      await new Promise((resolve) => setTimeout(resolve, jitter));
    }
  }
}
Safe to retryDo not retry
408 429 502 503 504400 401 403 404

Common mistakes

Make sure you’re using the x-api-key header (not Authorization or api-key), and that your key starts with sk_live_. Keys passed as query parameters or in the request body are not recognised.
Check that latitude is between -90 and 90, and longitude is between -180 and 180. A common mistake is swapping lat/lon. If your latitude is something like 51.5 but your longitude is 151.2, the coordinates may point to an area with no road network data.
The routing engine may be restarting during a deployment. These are transient. Retry with backoff and they’ll resolve within a few seconds. If 503 errors persist for more than a minute, contact support@footstep.ai.