PICTOGRAPHIC / IMAGE API
A little color.
One simple URL.
Turn your colors into soft, textured gradients. Choose a seed, pick a size, and use the image wherever you need it.
Make it yours
LIVE PLAYGROUND/api/image?colors=coral,rebeccapurple,royalblue&seed=2000&size=512x320&format=webp01 / GET STARTED
Drop it into your HTML
GET returns the image directly. No API key, token, or JavaScript is needed for an image tag.
/api/image<img
src="https://gradient.pictographic.ai/api/image?colors=red,blue&seed=2000&size=512x320&format=webp"
width="512" height="320"
alt="A red and blue gradient"
>For CSS backgrounds, use the same URL inside background-image: url("…"). Use ordinary & separators in CSS and JavaScript; & is for HTML attributes.
const query = new URLSearchParams({
colors: ['coral', 'rgb(40, 100, 209)', '#EBC6FF'].join(','),
seed: '2000',
size: '512x320',
format: 'webp',
});
const image = document.querySelector('img');
image.src = `https://gradient.pictographic.ai/api/image?${query}`;02 / THE REQUEST
Four things to send
All four primary parameters are required. Order and repeated colors influence the gradient.
| Parameter | Accepted value | Example |
|---|---|---|
colors | Nonempty list of opaque CSS colors, separated by commas | red,blue |
seed | Integer from 0 to 4294967295 | 2000 |
size | Width × height, each 1–2048 pixels | 512x320 |
format | png or webp | webp |
grain optional | Number from 0 to 6; default 1.8. Use 0 for a smooth image. | 0 |
preview optional | true or false; default false. A preview fits within 384 pixels and always returns PNG. | true |
Successful responses have Content-Type: image/png or image/webp. The body contains image bytes, not JSON or base64.
03 / YOUR PALETTE
Speak in color
Names
coralCSS names such as red, blue, and rebeccapurple. Case-insensitive.
Hex
#663399Short or long hex, with or without #. Encode # as %23 in URLs.
Functions
rgb(40, 100, 209)Opaque rgb() and hsl() work too. Commas inside functions stay together.
Mix formats in one palette. red, #f00, and rgb(255,0,0) resolve to the same color and cache entry. Use URLSearchParams to encode special characters.
Generate with hex colors
For orange #FF7308 and blue #2864D1, the simplest URL omits the # characters:
https://gradient.pictographic.ai/api/image?colors=FF7308,2864D1&seed=2000&size=512x320&format=webpIf you keep #, encode each one as %23. A literal # starts a URL fragment, so everything after it would not reach the API:
https://gradient.pictographic.ai/api/image?colors=%23FF7308,%232864D1&seed=2000&size=512x320&format=webpGenerate with RGB colors
The same orange and blue are rgb(255,115,8) and rgb(40,100,209). Use the complete rgb(r,g,b) function for each color. Commas inside parentheses belong to that color; the comma between the functions separates colors.
https://gradient.pictographic.ai/api/image?colors=rgb%28255%2C115%2C8%29,rgb%2840%2C100%2C209%29&seed=2000&size=512x320&format=webpAll three URLs above generate the same image and share the same server-side cache entry. In JavaScript, let URLSearchParams handle the encoding:
// Either list produces the same gradient:
const hexColors = ['#FF7308', '#2864D1'];
const rgbColors = ['rgb(255,115,8)', 'rgb(40,100,209)'];
const query = new URLSearchParams({
colors: rgbColors.join(','), // Or hexColors.join(',')
seed: '2000',
size: '512x320',
format: 'webp',
});
document.querySelector('img').src =
`https://gradient.pictographic.ai/api/image?${query}`;In the playground, enter one hex or RGB color per line. For POST JSON, send the original strings in the colors array, for example ["#FF7308", "rgb(40,100,209)"]; do not URL-encode JSON values.
Colors must be opaque. transparent, alpha below 1, currentColor, and CSS variables are not supported.
04 / REUSE THE RESULT
Render once. Reuse the URL.
Successful images are cached at the serving Cloudflare location for up to one year. Public GET images also have a one-year browser cache. The immutable directive lets browsers reuse a fresh image without revalidation. Equivalent GET and POST settings share an edge cache entry, including equivalent CSS color values.
- The playground shows
BROWSER CACHEwhen the image is reused locally without a network transfer. A browser-cached response can still contain an oldX-Gradient-Cache: MISSheader from its first download. X-Gradient-Cache: HITmeans the image was reused without rendering it again.MISSmeans it was generated.- Newly generated images include an
ETag. A matching GETIf-None-Matchreturns an empty304 Not Modifiedwhen the image is cached. - Reuse the same seed and settings for repeat visitors. Random seeds create distinct images and cache entries.
- Cache hits do not use the public render allowance. Caches are local to each Cloudflare location and may evict images before expiry; they are not permanent storage.
- POST responses use
Cache-Control: no-storefor clients while still reusing the edge image cache.
This documentation is served as static assets; reading it does not invoke the Rust renderer. The playground makes image requests only when it loads or you select Generate image.
05 / SERVER INTEGRATION
Prefer a JSON request?
POST uses the same endpoint and returns the same image bytes. It requires a bearer token; keep it on your server. For public HTML embedding, use GET.
curl 'https://gradient.pictographic.ai/api/image' \
-H "Authorization: Bearer $GRADIENT_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"colors":["red","blue"],"seed":2000,"size":{"width":512,"height":320},"format":"webp"}' \
--output gradient.webpPOST → get an image URL
Add Accept: application/json to generate the image and receive its public GET URL. Use the returned URL directly in an image tag or CSS background; it needs no token.
curl 'https://gradient.pictographic.ai/api/image' \
-H "Authorization: Bearer $GRADIENT_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data '{"colors":["#FF7308","#2864D1"],"seed":2000,"size":{"width":512,"height":320},"format":"webp"}'{"url":"https://gradient.pictographic.ai/api/image?colors=ff7308%2C2864d1&seed=2000&size=512x320&format=webp&grain=1.8&preview=false"}const response = await fetch('https://gradient.pictographic.ai/api/image', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.GRADIENT_TOKEN}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
colors: ['#FF7308', '#2864D1'],
seed: 2000,
size: { width: 512, height: 320 },
format: 'webp',
}),
});
if (!response.ok) throw new Error(await response.text());
const { url } = await response.json();
console.log(url); // Send this public URL to your frontend.Without this Accept header, POST continues to return image bytes. URL responses support explicit color lists and URLs up to 8 KiB; legacy palette IDs and longer generated URLs return 400. The URL preserves colors, seed, dimensions, format, grain, and preview settings.
The former /api/gradients/render path remains supported and shares the same server-side image cache.
The optional grain and preview fields also work in JSON. The older {config, preview} format remains supported.
06 / GOOD TO KNOW
Limits & errors
Public uncached GET renders are limited to approximately 60 per minute per IP at each Cloudflare location. Shared IPs share the allowance. This is not a global spending cap.
GET queries can be up to 8 KiB; POST bodies up to 1 MiB. There is no fixed color-count cap, but a render work budget applies: field pixels × effective colors must not exceed 25 million. A 384 × 384 field permits up to 169 colors; large images and large palettes cost more to render. Colors are never silently removed.
| Status | Meaning | What to do |
|---|---|---|
| 400 | Invalid, missing, duplicate, or unknown input | Check colors and parameter ranges. |
| 401 | Missing or invalid POST token | Send a valid bearer header, or use public GET. |
| 413 / 414 | Body / query is too large | Shorten the list; use POST for long queries. |
| 422 | Render work budget exceeded | Reduce color count or image size. |
| 429 | Too many uncached GET renders | Respect Retry-After: 60 and reuse URLs. |
| 500 / 503 | Rendering failed / temporarily unavailable | Retry later. |
Errors return JSON, for example {"error":"Invalid color…"}. Unsupported methods return 405. Check availability at /api/gradients/health.