Guarantees

Errors

When something goes wrong, the API responds with an appropriate HTTP status and a consistent JSON body. This page lists every code, its cause, and how to handle it in your code.

Error format

Unlike a success (which returns the binary), errors always come back as JSON in the format { error: { code, message } }. The code is stable and machine-readable — branch your logic on it, not on the message (which is for humans and may change).

error body
{
  "error": {
    "code": "template_not_found",
    "message": "Template \"invoice\" not found."
  }
}
HTTP status + code
The HTTP status gives the category (4xx = problem with the request, 5xx = problem with the render). The code gives the exact cause. Use them together.

All codes

HTTPcodeMeaningWhat to do
401missing_api_keyNo authentication header was sent.Send Authorization: Bearer or X-API-Key.
401invalid_api_keyKey does not exist, is malformed, or has been revoked.Check the key; generate a new one in the Dashboard if needed.
402quota_exceededThe organization's monthly render quota has run out.Reach out to us (support@renderly.dev) to unlock more, or wait for the start of the next month.
404template_not_foundThe slug provided in template does not exist in the organization.Check the template slug in the Dashboard (the slug is assigned when you save).
422invalid_bodyInvalid body: missing template/html, wrong type, invalid enum, etc.Fix the JSON according to the endpoint reference.
422template_emptyThe template exists, but has no content to render.Add at least one block to the template and save it in the editor.
500render_failedRender failure (invalid HTML, unreachable external resource, internal timeout).Review the content; apply retry with backoff (it may be transient).
Malformed JSON error
If the request body is not valid JSON, the API responds before schema validation with a parse error (400 invalid_json). Make sure you send a Content-Type: application/json and a well-formed body.

How to interpret by category

CategoryCodesNatureRetry?
Authentication (401)missing / invalid_api_keyCredential missing or invalid.No — fix the key first.
Quota (402)quota_exceededPlan limit reached.No — only after an upgrade or the start of the month.
Request (404 / 422)template_not_found, invalid_body, template_emptySomething in the request is wrong.No — retrying as-is gives the same error.
Render (500)render_failedFailure generating the document.Maybe — it may be transient; exponential backoff.

Recommended handling

Branch on the code and separate client errors (do not retry) from transient ones (retry):

node — handling by code
const res = await fetch("https://api.renderly.dev/v1/render", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.RENDERLY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ template: "invoice", data }),
})

if (!res.ok) {
  const { error } = await res.json()
  switch (error.code) {
    case "quota_exceeded":
      // pause the queue / alert billing
      throw new QuotaError(error.message)
    case "template_not_found":
    case "template_empty":
    case "invalid_body":
      // client error: retrying without fixing it won't help
      throw new BadRequest(error.code, error.message)
    case "render_failed":
      // may be transient: retry with backoff
      throw new RetryableError(error.message)
    default:
      throw new Error(`${res.status} ${error.code}: ${error.message}`)
  }
}

Retry policy

SituationStrategy
render_failedRetry with exponential backoff (e.g. 1s, 2s, 4s), at most 3 attempts.
quota_exceededDo not retry; alert billing and pause the queue.
client 4xxDo not retry; log it and fix the request.
network timeoutIdempotent retry — the same body produces the same document.
Render is idempotent for you
The same body produces the same document. On a network timeout, retrying is safe in terms of the result — but remember that each successful render counts against your quota.

The relationship between quota and the 402 is detailed in Limits & quota.

Next
Limits & quota
Monthly quota per organization, supported formats and sizes.