Reference

Errors and limits

Failures are worth designing for, because in printing they are not rare. Here is every status the API returns and what to do when you see it.

The error shape

Errors return a JSON body with an error string describing what went wrong. Handle on the HTTP status; log the message.

400 Bad Request
{
  "error": "contentType must be one of raw_base64, pdf_base64, text"
}

HTTP statuses

StatusWhat it meansWhat to do
400Validation failed — a missing field, an unknown content type, or a URI type that is disabled.Fix the request. This will not succeed on retry.
401Missing, malformed, or revoked API key.Check the X-API-Key header. Revoked keys fail permanently — issue a new one.
404No such resource, or it belongs to another organization.Confirm the ID and that the key belongs to the same organization.
409Conflict — an idempotency key reused with different input, or a cancel on an already-dispatched job.For idempotency, use a new key for genuinely new content. For cancel, the job is already on its way.
413The request body exceeds 14 MiB, or content exceeds 10 MiB.Send smaller content. Labels are kilobytes; if you are near the limit, something is wrong upstream.
429Rate limited — more than 300 requests per minute on this key.Back off for the number of seconds in the Retry-After header, then retry.
5xxSomething failed on our side.Retry with the same Idempotency-Key. That is exactly what it is for.

Job failures are not HTTP errors

A job that is accepted and later fails to print returns 201 at creation. The failure appears on the job itself: status becomes failed and the error field carries the reason the print system gave.

  • The print queue rejected the job or is paused.
  • The printer was unreachable from the station.
  • The format is not supported on that device — for example raw content on Windows.
  • The station lost its connection mid-print and reported the outcome on reconnect.

Alert on failed jobs by source. That is the signal that a bench has a real problem, and it is much earlier than a customer telling you.

Limits

LimitValueBehavior at the edge
Requests300 per minute per API key, burst 30429 with Retry-After
Content size10 MiB413
Request body14 MiB413
Idempotency key200 characters400
List page size50 default, 200 maximumClamped to the maximum

How to retry safely

Send an Idempotency-Key on every job creation, derived from your own identifier. Then retry freely on 429 and 5xx — a duplicate request returns the original job rather than printing a second label.

node — retry with backoff
async function printWithRetry(body, idempotencyKey, attempts = 4) {
  for (let attempt = 1; attempt <= attempts; attempt++) {
    const res = await fetch("https://rocketprint.io/api/v1/print-jobs", {
      method: "POST",
      headers: {
        "X-API-Key": process.env.ROCKETPRINT_KEY,
        "Idempotency-Key": idempotencyKey,     // same key on every attempt
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });

    if (res.ok) return res.json();            // 200 replay or 201 created
    if (res.status === 429) {
      await sleep(Number(res.headers.get("retry-after") ?? 1) * 1000);
      continue;
    }
    if (res.status >= 500) { await sleep(2 ** attempt * 250); continue; }

    throw new Error(`print failed: ${res.status} ${await res.text()}`);
  }
  throw new Error("print failed after retries");
}

Do not retry 400, 401, 404, or 409 — they will not succeed without a change.

The full failure model

Offline queueing, ordering, and the failures we cannot detect at all.

Read the reliability page