API Errors — What Each Code Means and How to Fix It

FastOG returns machine-readable error codes when an OG image request fails. Every error response includes:

  • code — a stable, documented error code (table below).
  • hint — a short plain-language description of what went wrong.
  • request_id — correlates this HTTP failure to a row in the dashboard Render Logs table (also returned in the X-Request-ID response header).

Reading an error response

json
{
  "error": "Unauthorized",
  "code": "invalid_signature",
  "hint": "The signature did not match. Re-sign with your HMAC secret after every param change.",
  "request_id": "5f2a9c1e-..."
}

If you get a response you don't understand, the fastest path is:

  1. Note the code.
  2. Check your URL builder — most failures are signing bugs, not account issues.
  3. Match the code below for the exact cause and fix.
  4. In the dashboard, open Render Logs and filter by the same error_code — each row shows the requested params so you can reproduce (and confirm request_id matches).

Signing & authentication

missing_signature

Your request is missing the key and/or s (signature) query parameters.

Fix: ensure your URL includes both key=<api-key> and s=<hmac-signature>. Use the SDK or the /docs/hmac-signature-guide walkthrough to build it.

invalid_signature

The s value did not match what your HMAC secret produces for this URL.

Fix: the signature covers every query param except s, with keys sorted. Changing any param — including reordering, URL-encoding differences, or adding whitespace — invalidates the signature. Re-sign after every change. Confirm your secret is the same one shown when the API key was created.

invalid_signature_format

The s value is not a 64-character hex string.

Fix: the signature must be raw SHA-256 hex (lowercase a-f0-9). If you're base64-encoding or truncating the output, use plain hex.

expired_timestamp

The t timestamp you supplied is more than 5 minutes old.

Fix: regenerate the timestamp each time you build a URL. This code applies to the legacy signed-URL flow; the current HMAC v2 flow has no timestamp.

invalid_api_key

The key you passed does not exist.

Fix: copy the full API key from the dashboard — it's the public identifier starting with sk_. It is public and safe in URLs; the secret (never in URLs) is what proves possession.

missing_hmac_secret

The API key has no HMAC secret configured.

Fix: create a new API key in the dashboard — the HMAC secret is generated and shown once at creation.


Parameter / input

invalid_image_url

A URL-bearing prop (image, brand_logo, logo, avatar, background_image, ...) is not a public http(s) URL.

Fix: pass a publicly fetchable https://... URL. Localhost, private IPs, and bare paths are rejected to prevent server-side request forgery.


Credits

insufficient_credits

Your balance reached zero before the render was charged.

Fix: top up in the dashboard. The response includes credits_remaining and a top_up_url for a direct link. Note: when the render service is down or the image fails, no credit is charged — credits are only deducted after a successful render.


Render service

render_unreachable

The render service could not be reached (brief restart window).

Fix: retry in a few seconds. No credit was charged for this attempt.

render_failed

The render service returned an error for your request.

Fix: verify your template props — long/malformed values, unsupported fields, or an unreachable upstream image. The response includes the underlying status. No credit was charged.


Still stuck?

  • Open the dashboard Render Logs page — every outcome (success + rejection) is listed with its error_code, HTTP status, and the requested params.
  • Run php artisan og:diagnose on a signed URL to walk the whole pipeline and see which stage fails.
  • Check the docs in the sidebar for the framework you're using (Next.js, Express, SvelteKit, ...).

Try it free — no signup required

Preview and test dynamic OG images in seconds.

Open the Free OG Image Tester