API documentation
One POST request formats a file. No key, no account, no signature — the address and a body are the whole contract.
Quick start
Minify a stylesheet and print the result:
curl --data-urlencode 'input=.card { padding: 8px; margin: 0 auto; }' \
https://formatter.nextwell.top/api/v1/minify/css/raw
# .card{padding:8px;margin:0 auto}
Swap {css} for {js} or {html}, and {minify} for {beautify}. Every combination works.
Endpoints
The base address is {base}. Everything below is a POST unless it says otherwise.
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/minify/{lang} | Minify, JSON response |
POST | /api/v1/minify/{lang}/raw | Minify, plain-text response |
POST | /api/v1/beautify/{lang} | Beautify, JSON response |
POST | /api/v1/beautify/{lang}/raw | Beautify, plain-text response |
GET | /api/v1/limits | What this IP has left, without spending a request |
GET | /api/v1/health | Liveness check, never rate limited |
{lang} is one of css, js or html.
Sending the code
Three body shapes are accepted on every endpoint — pick whichever your client makes easy.
Form encoded
An {input} field, {type}. This is the shape Toptal's own minifiers take, so an existing script only changes its address.
curl --data-urlencode 'input=body{margin:0;padding:0}' \
https://formatter.nextwell.top/api/v1/beautify/css
JSON
{type} with an {input} string.
curl -H 'Content-Type: application/json' \
-d '{"input":"const a=1;const b=a+1;console.log(b)"}' \
https://formatter.nextwell.top/api/v1/beautify/js
Raw body
Any other content type: the body is the code. Convenient for {example}.
curl --data-binary @style.css \
-H 'Content-Type: text/css' \
https://formatter.nextwell.top/api/v1/minify/css
Size
2 MB per request. Anything larger comes back as 413 without being read.
Query parameters
| Name | Values | Meaning |
|---|---|---|
engine |
auto upstream local |
Which engine handles this request. {auto} — the default — sends CSS and JS minification upstream while the budget lasts and falls back locally. {upstream} refuses rather than falls back. {local} never leaves the server. |
indent |
2 4 tab |
Beautify only: what one level of indentation is. |
curl --data-urlencode 'input=.a{color:red}' \
'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'
The response
A successful call returns JSON:
{
"ok": true,
"action": "minify",
"language": "css",
"engine": "upstream",
"input_bytes": 1024,
"output_bytes": 640,
"saved_bytes": 384,
"saved_percent": 37.5,
"duration_ms": 42,
"output": "p{color:red}"
}
| Field | Type | Meaning |
|---|---|---|
ok | boolean | Always true on a success. |
action | string | minify or beautify — what was asked for. |
language | string | css, js or html. |
engine | string | upstream if Toptal handled it, local if this server did. |
input_bytes | number | Size of what was sent, in bytes. |
output_bytes | number | Size of the result, in bytes. |
saved_bytes | number | The difference; negative when beautifying. |
saved_percent | number | The same difference as a percentage, one decimal. |
duration_ms | number | How long the work took, milliseconds. |
output | string | The formatted code. |
Plain-text responses
Append {raw} to any format endpoint and the body is the result and nothing else, as {type}. The headers are the same. Useful when the caller is a shell:
curl -s --data-binary @app.js \
-H 'Content-Type: text/javascript' \
https://formatter.nextwell.top/api/v1/minify/js/raw > app.min.js
Response headers
| Header | Meaning |
|---|---|
X-Formatter-Engine | Which engine produced the result. |
X-Formatter-Duration | Processing time in milliseconds. |
X-RateLimit-Remaining-Second … -Month | What is left in each window for this IP. |
Retry-After | On a 429: seconds until the tightest spent window reopens. |
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
https://formatter.nextwell.top/api/v1/minify/css
Errors
Every error is JSON in the same shape Toptal's minifiers use, so a client that already handles theirs handles ours:
{
"errors": [
{ "status": 429, "title": "Too many requests", "detail": "…" }
]
}
| Status | Title | When |
|---|---|---|
400 | Missing input Bad request | No body, or an empty input field. |
404 | Not found | No such path. |
405 | Method not allowed | A format endpoint was called with something other than POST. |
413 | Payload too large | The body is over 2 MB. |
415 | Unsupported language | The language in the path is not css, js or html. |
422 | Malformed input | The formatter refused the source — usually a syntax error. |
429 | Too many requests | One of the rate-limit windows is spent. Read Retry-After. |
502 | Upstream failed | Only with engine=upstream: Toptal did not answer. Without that override the request would have fallen back locally. |
500 | Internal error | Anything else. |
Rate limits
Per IP address, five rolling windows, all enforced at once. A request has to fit in all five.
| Window | Limit |
|---|---|
| Per second | {n} requests |
| Per minute | {n} requests |
| Per hour | {n} requests |
| Per day | {n} requests |
| Per month | {n} requests |
When a window is spent the answer is 429 with a Retry-After header giving the seconds until the tightest one reopens. Nothing is queued.
The counters live in a small database on disk, so restarting the service does not hand anyone a fresh day.
{endpoint} reports the current state of all five windows without spending one.
curl https://formatter.nextwell.top/api/v1/limits
Toptal allows 30 requests a minute for this whole service, not per visitor. A shared bucket tracks that: when it is empty, CSS and JS minification is served by the local engine instead of waiting or failing. You may see the engine field change under load — the output stays valid either way.
Which engine does the work
Two paths, one contract.
Toptal — CSS and JS minification
Their minifiers are fast and conservative: they drop the whitespace that can go and keep the whitespace that cannot, so things like {calc} survive intact. This service passes the code through and adds nothing of its own.
Local — everything else
HTML minification, all three beautifiers, and CSS/JS minification whenever the shared upstream budget is gone or the service is set to stay offline. Built on {tools}, loaded only when a request needs them so an idle process stays small.
Set {param} to pin a request to one path.
What is kept
Nothing. The code is held in memory for the length of the request and dropped. It is not written to disk and never appears in a log. What the logs do carry: a truncated hash of the IP, the language, the action, the byte count, the engine and the duration.
Questions
Do I need a key?
No. The service is open and limited by IP address instead.
Is my code sent anywhere?
CSS and JavaScript minification is proxied to Toptal's minifiers, so that code reaches their servers. Beautifying and all HTML work is done on this server. Set engine=local to keep everything here.
Can I use it in a build script?
Yes, that is what the raw endpoints are for. Keep within the limits and mind that the engine may fall back under load.
Why is my minified JavaScript renamed?
The upstream minifier shortens local variable names, which is safe and is where most of the saving comes from. Beautifying will not bring the original names back — nothing can.
What is the largest file I can send?
2 MB in one request. Larger files are refused with 413 rather than truncated.