ReWords.AI API

Images

How to send images to the ReWords.AI API — URL, base64, data URL or multipart upload — the size and format limits, EXIF and transparency handling, the result files, and how boxes map to pixels.

What you can send

Limit
FormatsJPEG, PNG, WebP. Detected from the file's bytes, not its name or Content-Type.
File sizeUp to 20 MB (20 × 1024 × 1024 bytes; the 28 MB JSON body limit is counted the same way).
DimensionsLongest side up to 8000 px; shortest side at least 32 px.
ColourRGB or greyscale. CMYK JPEGs are rejected with 400 invalid_image.
AnimationAnimated WebP: only the first frame is used.

A file that breaks these rules is rejected with 400 invalid_image before anything is charged.

Four ways to send an image

Use exactly one per request. Sending none, or more than one, returns 400 invalid_request.

1. image_url

A public http(s) link. We download it once, while handling your request, so a signed link only has to stay valid until we answer. We follow up to 3 redirects and give up after 15 seconds; if the file cannot be downloaded the request returns 400 invalid_image. Links that need cookies or a login do not work, and neither do addresses on a private network, such as localhost, 10.x.x.x or 192.168.x.x.

{ "image_url": "https://example.com/banner.png" }

2. image_base64

The file's bytes in standard base64 (A–Z a–z 0–9 + /, padding optional), or the same as a data URL with any media type, such as data:image/png;base64, or the data:application/octet-stream;base64, a browser's FileReader may produce — the format is detected from the bytes. Spaces and line breaks are ignored, so the 76-character lines of base64 on Linux or Python's base64.encodebytes work. Base64 makes the file about a third larger, so the whole JSON body may be up to 28 MB; a larger body returns 400 invalid_image. Text that is not valid base64 returns 400 invalid_request; valid base64 of a file that is not a supported image returns 400 invalid_image.

{ "image_base64": "iVBORw0KGgoAAAANSUhEUgAA..." }
{ "image_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." }

3. multipart file upload

Send multipart/form-data with the file in the image field. For POST /edits, put the replacements array in a form field as a JSON string; match, language and callback_url are plain form fields.

curl https://api.rewords.ai/v1/edits \
  -H "Authorization: Bearer $REWORDS_API_KEY" \
  -F [email protected] \
  -F 'replacements=[{"from":"SALE","to":"HOT DEAL"}]'
upload.mjs — Node.js 18+
import crypto from 'node:crypto';
import fs from 'node:fs';

const form = new FormData();
form.append('image', new Blob([await fs.promises.readFile('banner.png')]), 'banner.png');
form.append('replacements', JSON.stringify([{ from: 'SALE', to: 'HOT DEAL' }]));
const res = await fetch('https://api.rewords.ai/v1/edits', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.REWORDS_API_KEY}`, // let fetch set the multipart Content-Type
    'Idempotency-Key': crypto.randomUUID(), // a new key per job; reuse it only to resend this same job
  },
  body: form,
});
const job = await res.json();
if (!res.ok) throw new Error(`${res.status} ${job.error.code}: ${job.error.message}`);
console.log(job.id, job.status);

4. image_id

POST /ocr returns an image_id. Pass it to POST /edits within 24 hours to reuse the uploaded image instead of sending it again. It only works on the account that created it; an unknown, expired or other account's id returns 400 invalid_request. Each OCR call returns a new image_id, even for an image you sent before — including when you send an image_id to POST /ocr, which gives you a fresh 24 hours.

How we read your image

  • EXIF orientation is applied first. A phone photo stored sideways is turned upright, and every width, height and box refers to the upright image — what you see in an image viewer.
  • Transparent areas become white. PNG and WebP transparency is flattened onto a white background, because results are JPEG.

Results

  • results.A.url, results.B.url and results.C.url are JPEG files at public links: download them with a plain GET, no API key needed. Treat the links as private — anyone who has one can open it.
  • Send a User-Agent header when you download. Python urllib's default one is refused with 403; requests, curl, browsers and Node fetch work as they are.
  • Links are kept for at least 7 days. Download what you need to keep.
  • Result files are stored upright with no EXIF orientation, so the size in the file is the size you see.
  • B is your original image with the new text blended in. A is the AI's redraw of the whole image and keeps your image's aspect ratio. Read the pixel size from the file rather than assuming it matches your upload.
  • C (4K) is up to about 8.3 megapixels (3840 × 2160 worth), longest side at most 3840 px, same aspect ratio. It is skipped for images wider or taller than 3:1.

Boxes and pixels

Boxes are [x, y, width, height], whole numbers on a 0–1000 scale of the upright image, measured from the top-left corner. width and height are at least 1; x + width and y + height are never more than 1000.

pixel left   = x      / 1000 * imageWidth
pixel top    = y      / 1000 * imageHeight
pixel width  = width  / 1000 * imageWidth
pixel height = height / 1000 * imageHeight

Example: box [120, 80, 300, 60] on a 1080 × 1350 image is left 130, top 108, 324 × 81 px (rounded). To send your own box, convert the other way and round to whole numbers.

On this page