Overview & authentication
The StyleRef REST API is plain HTTP over two tiers:
- Anonymous reads — search styles, compile any style to a format, download a STYLE.md, and lint STYLE.md documents. No credentials.
- Authenticated actions — extract a new style from an image you upload, save a gallery style, and read your own library, saved styles, and extraction history. Requires a bearer token; only extraction consumes credits.
Use it from scripts, CI, a backend, or a plugin.
Base URL
https://styleref.io/api/v1The machine-readable contract is at /api/v1/openapi.json.
Anonymous access
Every read endpoint works without credentials against public styles. A minimal call:
curl "https://styleref.io/api/v1/styles?query=warm%20editorial&limit=5"Optional authentication
Pass a StyleRef OAuth 2.1 access token (scope styles:read) to resolve your own private styles. They use the same refs as any other style — a share slug, or the style’s UUID id. URL-encode the whole ref (encodeURIComponent) when it contains / or ::
# By share slug (yours — get it from GET /me/styles)
curl "https://styleref.io/api/v1/styles/7kq2mv0p-9d31ab77c204" \
-H "Authorization: Bearer YOUR_TOKEN"
# By style id (yours) — or paste the builder URL, URL-encoded
curl "https://styleref.io/api/v1/styles/e7c1f2a9-2f65-4f0e-9a3d-2b1c4d5e6f70" \
-H "Authorization: Bearer YOUR_TOKEN"GET /me/styles lists your library and returns a ready-to-use ref for each style.
Get a token through the MCP OAuth flow or npx styleref login (see the CLI). Anonymous requests keep working for public styles.
Required authentication
Some endpoints have no anonymous equivalent — there is no anonymous version of “spend my credits” or “list my styles”. They reject unauthenticated calls with 401 auth_required, a WWW-Authenticate header naming the scope, and a message written for a human to read:
| Endpoint | Scope |
|---|---|
POST /extractions | extract |
GET /extractions/{id} | extract |
POST /styles/{ref}/save | styles:write |
GET /me/styles | styles:read |
GET /me/saved-styles | styles:read |
GET /me/extractions | styles:read |
GET /me/extractions/{id} | styles:read |
Credits
Extraction consumes credits from the same balance as the web app — one credit system across web, MCP, and REST. One extraction currently costs 30 credits on the free plan (unlimited on Pro); the cost is plan configuration rather than a fixed constant, so treat the number in the error message as authoritative. See plans and limits.
POST /extractionsreturnsX-StyleRef-Credits-Remaining(a number, orunlimitedon Pro).- A zero balance returns HTTP 402 with
error: "insufficient_credits", a human-readablemessage, and apricingUrl. Render both verbatim. - A rejected upload is never charged, and a failed extraction is refunded automatically.
{
"error": "insufficient_credits",
"message": "Not enough credits. Need 30, have 0. Upgrade to Pro for unlimited. Credits refill monthly on the free plan; Pro includes unlimited extractions: https://styleref.io/pricing",
"pricingUrl": "https://styleref.io/pricing"
}Identifying your client
Send X-StyleRef-Client with a short slug (comfyui, cli, your integration’s name) so usage is attributable per surface. Optional; defaults to rest.
Rate limits
Responses carry rate-limit headers on every request, success included:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the window |
X-RateLimit-Remaining | Requests left |
X-RateLimit-Reset | Window reset (unix seconds) |
When you exceed the limit, the API returns HTTP 429 with a Retry-After header. Honor it before retrying.
Extraction is metered more tightly than reads: 5 extractions per minute per account, on top of the general per-IP lane.
Calling it from a browser
Every v1 response — errors included — carries Access-Control-Allow-Origin: *, so a browser-based client can call the API directly with no proxy. GET, POST and OPTIONS are allowed, and Content-Type, Authorization and X-StyleRef-Client are accepted request headers.
These response headers are exposed to JavaScript (the rest are hidden by the browser, per CORS):
X-Token-Count, X-StyleRef-Canonical-Url, X-StyleRef-Credits-Remaining,
Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-ResetDon’t ship a bearer token in client-side code — a token in a browser bundle is public. Keep authenticated calls on a server you control.
Errors
Errors return a JSON body with a stable machine-readable code and a message:
{ "error": "not_found", "message": "No public style matched the reference." }Codes: invalid_request, not_found, auth_required, styleref_not_generated, insufficient_credits, plan_limit_reached, payload_too_large, rate_limited, internal_error.
styleref_not_generated (HTTP 409) is specific to your own styles: the API serves what you last generated on styleref.io, so a style you have never generated has no output yet. See Your own styles serve your last generation.
Format and target names
Three surfaces name the same handful of output dialects differently. One table, so you never have to guess:
| You want | REST format= | MCP target (apply_style_to_prompt) | ComfyUI target |
|---|---|---|---|
| ChatGPT, Claude, Gemini | default | chatgpt, claude, gemini | ai_tools |
| Midjourney | midjourney | midjourney | midjourney |
| FLUX | flux | flux | flux |
| Stable Diffusion, DALL·E | diffusion | stable-diffusion, dalle | diffusion |
| A STYLE.md file | stylemd | (use get_style_md) | style_md |
| Structured data | json | json | json |
| Anything else | default | generic | ai_tools |
Next steps
- Endpoints reference — every endpoint with examples.
- OpenAPI specification — the canonical contract.
- MCP server — the same reads plus account-scoped actions.