RoomagenDevelopersGet API key

Guide

Errors & limits

Every error code, the response envelope, and rate limit headers.

Every non-2xx response has the same shape:

json
{
  "error": {
    "code": "invalid_tool",
    "message": "Unknown tool \"virtual-stagng\". See GET /v1/tools.",
    "doc_url": "https://developers.roomagen.com/docs/errors#invalid_tool"
  }
}

Branch on code. It is stable. message is human-facing and may change without notice, so never parse it — and doc_url always points at the matching anchor on this page.

Error codes

CodeStatusDescription
invalid_api_key401

The X-Api-Key header is missing, malformed, or does not match a key. Check the header name and that you sent the whole key including the rmg_live_ prefix.

key_revoked401

The key was revoked, or the account behind it is disabled. Create a new key in the portal — a revoked key never becomes valid again.

api_disabled404

The API is switched off server-side. Every route answers this, including requests carrying a valid key, so there is nothing to retry. Email support if you expected access.

invalid_request400

The request failed validation: a malformed field, an out-of-range value for an option the tool knows, an Idempotency-Key over 128 characters, or an option that virtual-staging does not accept. The message names what was wrong.

invalid_tool400

The tool value is not a slug this API accepts. Read GET /v1/tools — the marketing names used on roomagen.com are not slugs.

invalid_image400

Neither image_url nor image_base64 was supplied, or both were. Send exactly one of them.

image_fetch_failed400

Roomagen could not fetch image_url: a non-2xx status, a non-image content type, a timeout, a refused private or loopback host, or more than 3 redirects. Confirm the URL is public and serves the image directly.

insufficient_credits402

The image balance behind the key cannot cover the job, so no job is created. Top up and retry — see Pricing & credits.

rate_limited429

Too many requests in the sliding 60-second window. Wait the number of seconds in Retry-After and retry; a caller that holds a steady rate under the limit never sees this.

idempotency_conflict409

The same Idempotency-Key was reused with a different body. Resend the original body to replay the first job, or pick a new key for a genuinely new request.

job_not_found404

No job with that id belongs to your account. A job that belongs to someone else reports the same code — the API never confirms that another account’s id exists.

webhook_url_rejected400

The webhook_url is not a public https URL. Private, loopback and link-local hosts are refused.

payload_too_large413

The request body is over the parser limit — 30 MB with X-Api-Key, 1 MB without. Send a smaller image, or switch to image_url. If the body was well under 30 MB, check that the key header was actually sent.

generation_failed422

The model could not produce a result. Credits for the job are refunded automatically, and the failure shows on the job as status: failed with a reason in error. Retry once; if it repeats, the input image is usually the cause.

internal_error500

Something failed on Roomagen’s side. Retry with the same Idempotency-Key: in normal operation the retry will not double-charge. If in doubt, check GET /v1/account before retrying. If it persists, email support with the time and the request details.

Rate limits

EndpointPer minute
POST /v1/jobs60 req/min
GET /v1/jobs/{id}300 req/min
GET /v1/tools, GET /v1/account120 req/min

Per API key, in a sliding 60-second window, counted separately per route group. Counters live in the API process, so they reset on deploy.

IP backstop

600 req/min

Per client IP across all /v1 routes, applied before the key is identified. A fleet behind one NAT egress IP shares this budget; contact support if you need it raised.

HeaderDescription
X-RateLimit-Limit

Requests allowed in the current window for this route and key.

X-RateLimit-Remaining

Requests left in the current window.

Retry-After

Seconds to wait, sent only with a 429.

When exceeded

429 · rate_limited

Retry after Retry-After seconds. The window slides rather than resetting on a fixed boundary, so a caller that keeps a steady rate under the limit never sees a 429.

Retry-After

A 429 carries Retry-After with whole seconds to wait. Honour it rather than backing off on your own schedule: the window slides instead of resetting on a fixed boundary, so a steady rate recovers without backing off further.

X-RateLimit-Limit and X-RateLimit-Remaining are sent on successful responses too, so you can slow down before you hit the limit rather than after.

Next step

Pricing & credits — what an image costs and how to buy more.