Palettes API

Palettes API

Search the Jinero color palette library — 10,000+ curated palettes with filters by mood, harmony, temperature, tone and tags, plus full color data and SEO meta out of the box.

Read-only API over the Jinero palette library. Search by mood, harmony, temperature, tone, color count and tags; fetch single palettes with full color data, SEO-friendly display names, and related-palette suggestions. Backs both our own UI and any LLM agent that needs curated palette data.

# List 5 most popular palettes
curl "https://jinero.online/api/v1/palettes?per_page=5&order=popular"

# Fetch one palette by id
curl "https://jinero.online/api/v1/palettes/3798"
const r = await fetch("https://jinero.online/api/v1/palettes?mood=pastel&per_page=24");
const { data: palettes, last_page } = await r.json();

All endpoints are public — no key required. Read-only and cheap, so limits are generous.

# Anonymous limits (per IP):
#   GET /palettes        60 req/min
#   GET /palettes/{id}   60 req/min

# Pagination: per_page max 100, default 24

Paginated search. Every filter is optional and combinable. Empty filters return the full library sorted by your choice of order.

GET https://jinero.online/api/v1/palettes
ParameterTypeDescription
name string Fuzzy name match (LIKE). Most palettes are unnamed — combine with other filters instead.
tone string light · dark · mixed.
temperature string warm · cool · neutral.
mood string pastel · muted · earthy · vibrant · monochrome (and more — values are open).
harmony string analogous · complementary · triadic · monochromatic · tetradic · split-complementary.
color_count integer Exact count (2–6) or 7+ for "many colors".
tags[] string[] Tag slugs to require. Repeat the parameter for multiple tags.
order string newest (default) · popular · name.
per_page integer 1–100, default 24.
page integer Page number, default 1.
# Top 10 cool-pastel palettes
curl "https://jinero.online/api/v1/palettes?temperature=cool&mood=pastel&order=popular&per_page=10"
const url = new URL("https://jinero.online/api/v1/palettes");
url.searchParams.set("temperature", "warm");
url.searchParams.set("color_count", "5");
url.searchParams.set("order", "popular");

const r = await fetch(url);
const { data, total, last_page } = await r.json();
$res = Http::get("https://jinero.online/api/v1/palettes", [
    "mood" => "vibrant",
    "harmony" => "triadic",
    "per_page" => 30,
]);
$palettes = $res->json("data");
Example response
{
  "current_page": 1,
  "data": [
    {
      "id": 3798,
      "name": null,
      "display_name": "4-Color Muted Palette",
      "slug": "222831393e4600adb5eeeeee",
      "colors": ["#222831", "#393e46", "#00adb5", "#eeeeee"],
      "color_count": 4,
      "tone": "mixed",
      "temperature": "cool",
      "mood": "muted",
      "harmony": "analogous",
      "source": "imported",
      "source_url": "...",
      "tags": [],
      "likes_count": 71122,
      "views_count": 0,
      "url": "https://jinero.online/colors/palettes/3798"
    }
  ],
  "first_page_url": "...",
  "last_page": 421,
  "per_page": 24,
  "total": 10103
}

Fetch a single palette plus 8 related palettes (same temperature + tone, sorted by popularity). Calling this endpoint also increments views_count.

GET https://jinero.online/api/v1/palettes/{id}
ParameterTypeDescription
id integer (path) Palette ID from the list response.
curl "https://jinero.online/api/v1/palettes/3798"
const r = await fetch("https://jinero.online/api/v1/palettes/3798");
const { palette, related } = await r.json();
document.title = palette.seo_title;
$res = Http::get("https://jinero.online/api/v1/palettes/3798");
$palette = $res->json("palette");
Example response
{
  "success": true,
  "palette": {
    "id": 3798,
    "name": null,
    "display_name": "4-Color Muted Palette",
    "colors": ["#222831", "#393e46", "#00adb5", "#eeeeee"],
    "color_count": 4,
    "tone": "mixed",
    "temperature": "cool",
    "mood": "muted",
    "harmony": "analogous",
    "tags": [],
    "likes_count": 71122,
    "views_count": 1,
    "url": "https://jinero.online/colors/palettes/3798",
    "seo_title": "4-Color Muted Palette — Cool Mixed, Analogous Harmony | Jinero",
    "seo_description": "4-color muted palette with cool temperature and analogous harmony. Hex codes: #222831, #393E46, #00ADB5, #EEEEEE..."
  },
  "related": [
    { "id": 1234, "display_name": "...", "colors": [...] }
  ]
}

About 65% of the imported library has name: null. We derive a human-readable display_name from mood + color_count via a model accessor — for example, an unnamed 4-color muted palette becomes "4-Color Muted Palette". The seo_title and seo_description fields use the same derivation, so links and meta tags stay consistent whether the palette had an editorial name or not.

// Unnamed palette as it appears in the database
{ "id": 3798, "name": null, "mood": "muted", "color_count": 4 }

// What you actually receive from the API
{
  "id": 3798,
  "name": null,
  "display_name": "4-Color Muted Palette",
  "seo_title": "4-Color Muted Palette — Cool Mixed, Analogous Harmony | Jinero"
}

Standard HTTP semantics. Errors return JSON with a "message" field.

// 404 — palette id not found
{ "message": "Palette not found" }

// 422 — invalid filter value (e.g. unknown order)
{ "message": "The selected order is invalid." }

// 429 — rate limit exceeded
{ "message": "Too Many Attempts." }

About the jinero.online Palettes API

Free REST API over a 10,000+ palette library — curated by mood, harmony, temperature and tone, with SEO-ready display names and related-palette suggestions baked in.

10,000+ palettes

Curated and imported palettes with consistent metadata — mood, harmony, temperature, tone. Searchable by every dimension that matters.

Pagination & filters

Standard Laravel pagination contract — current_page, last_page, total, plus typed filter parameters. No custom cursor formats to learn.

SEO-ready out of the box

Each palette ships with derived display_name, seo_title and seo_description — drop them straight into your <title> and meta tags.

Related palettes

Single-palette responses include up to 8 related palettes (same temperature + tone, sorted by popularity) — perfect for "you may also like" rows.

Frequently Asked Questions

No. Both endpoints are public and rate-limited to 60 req/min per IP. Sign up for an API token if you need higher limits for batch work.

The library was bootstrapped by importing from public color-curation sites that mostly publish unnamed palettes. We never invent fake editorial names — instead we derive a stable display_name from mood + color_count via a model accessor, so the API surface stays consistent.

Yes — repeat the tags[] parameter: ?tags[]=warm-tones&tags[]=monochrome. All listed tags must be present (AND semantics). For OR behaviour, fire two separate requests and merge client-side.

likes_count, views_count and saves_count are updated in real time — every /palettes/{id} call increments views_count synchronously. Order=popular sorts by likes_count.

Not in v1. Slugs are deterministic (concatenated hex codes without #), so you can build them client-side, but lookup is by integer id only. Open an issue if you have a use case for slug-based fetching.