RGPixelrgpixel

API reference

Convert images from your own app

A small REST API to turn any image into a pixel-perfect SVG (plus PNG/WebP at every size) without opening the studio. Upload an image, poll until it is ready, download the result. Everything the web app does under the hood, driven by your code.

Plan

Business

Quota

5000 / month

Auth

API key

Format

REST · JSON

Base URL

https://rgpixel.com/api/v1

Authentication

Every request carries your API key as a Bearer token. Generate one on your account page — it is shown once, starts with fk_, and can be rotated any time (rotating does not reset your monthly usage). Keep it secret; it is the only thing standing between a caller and your quota.

header
Authorization: Bearer fk_YOUR_KEY

A missing or unknown key returns 401. A valid key whose plan no longer includes API access returns 403 — access follows the live plan, so a lapsed subscription loses the API immediately.

POST/api/v1/convert

Start a conversion

Send the image as multipart/form-data. Returns immediately with an uploadId and a queued status — the conversion runs in the background. This is the only call that spends quota (one call per conversion). A missing file returns 400 and is not charged.

Form fields

filefilerequired

The image to convert (PNG, JP, WebP, …). Its longest side is capped at your plan maximum (4096 px on Business); larger images are downscaled, never upscaled.

removeBackgroundboolean

Pass "true" to strip the background to real transparency before vectorizing. Omit for images that already have clean alpha.

curl
curl -X POST https://rgpixel.com/api/v1/convert \
  -H "Authorization: Bearer fk_YOUR_KEY" \
  -F "file=@logo.png" \
  -F "removeBackground=true"

# → { "uploadId": "u_abc123", "status": "queued" }
GET/api/v1/convert?id={uploadId}

Check status & list files

Poll this until status is done. Polling is free — it never spends quota. When done, engine.variants[] lists every file produced; each entry’s path is what you pass to the download endpoint.

queued · waiting for a workerprocessing · being converteddone · ready to downloadfailed · see engine.error
curl
curl "https://rgpixel.com/api/v1/convert?id=u_abc123" \
  -H "Authorization: Bearer fk_YOUR_KEY"

# → {
#     "uploadId": "u_abc123",
#     "status": "done",
#     "engine": {
#       "status": "done",
#       "imageKind": "flat",
#       "variants": [
#         { "kind": "svg-exact", "path": "vector/u_abc123.exact.svg",
#           "mimeType": "image/svg+xml", "bytes": 11234 },
#         { "kind": "png", "path": "512x512/u_abc123_512.png",
#           "sizePx": 512, "mimeType": "image/png", "bytes": 8765 }
#       ]
#     }
#   }

Each variant has a kind (e.g. svg-exact — the lossless, pixel-perfect SVG; svg-traced — a small scalable trace; and png/webp at each sizePx), a path, its mimeType and bytes.

GET/api/v1/convert/{uploadId}/file/{path}

Download a result file

Stream any file from variants[] by its path. Free (no quota). Returns the raw bytes with the right Content-Type; supports Range requests. Returns 409 if the conversion is not done yet, and 404 for a path that isn’t in the manifest.

curl
# Use a "path" from engine.variants[] above
curl "https://rgpixel.com/api/v1/convert/u_abc123/file/vector/u_abc123.exact.svg" \
  -H "Authorization: Bearer fk_YOUR_KEY" \
  -o logo.svg

Full example (Node.js)

The whole flow — upload, poll, download the exact SVG — with no dependencies.

javascript
import { readFile, writeFile } from "node:fs/promises";

const KEY = process.env.RGPIXEL_API_KEY;
const BASE = "https://rgpixel.com/api/v1/convert";
const headers = { Authorization: `Bearer ${KEY}` };

// 1 — start the conversion
const form = new FormData();
form.set("file", new Blob([await readFile("logo.png")]), "logo.png");
const start = await fetch(BASE, { method: "POST", headers, body: form });
const { uploadId } = await start.json();

// 2 — poll until it is done (or failed)
let engine;
for (;;) {
  const res = await fetch(`${BASE}?id=${uploadId}`, { headers });
  const data = await res.json();
  if (data.status === "done") { engine = data.engine; break; }
  if (data.status === "failed") throw new Error("conversion failed");
  await new Promise((r) => setTimeout(r, 1500));
}

// 3 — download the exact SVG
const svg = engine.variants.find((v) => v.kind === "svg-exact");
const file = await fetch(`${BASE}/${uploadId}/file/${svg.path}`, { headers });
await writeFile("logo.svg", Buffer.from(await file.arrayBuffer()));

Quota & rate limits

Monthly quota

5000 conversions per calendar month (UTC). Only POST /convert counts; status polls and downloads are free. The counter resets on the 1st and lives on your account, so rotating your key does not reset it.

Burst limit

Up to 30 requests per 10 seconds per key. Over that returns 429 with a Retry-After header — back off and retry.

Exhausted quota

Once you reach 5000 for the month, POST /convert returns 429 ("Monthly API quota exceeded") until the next month. Upgrade or wait for the reset.

Errors

Errors are JSON with an error message and the matching HTTP status.

StatusWhenMeaning
400POSTNo file in the request. Not charged.
401anyMissing or unknown API key.
403anyYour plan does not include API access.
404GET fileUpload isn’t yours, or the path isn’t a real variant.
409GET fileThe conversion isn’t done yet — keep polling status.
429POSTMonthly quota reached, or too many requests too fast.
502POSTThe conversion couldn’t be started. Not charged — retry.

Ready to build?

The API ships with the Business plan. Grab a key and make your first call in a minute.