API-Dokumentation
Eine POST-Anfrage formatiert eine Datei. Kein Schlüssel, kein Konto, keine Signatur — die Adresse und ein Body sind der ganze Vertrag.
Schnellstart
Ein Stylesheet minifizieren und das Ergebnis ausgeben:
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}
Tausche {css} gegen {js} oder {html} und {minify} gegen {beautify}. Jede Kombination funktioniert.
Endpunkte
Die Basisadresse ist {base}. Alles Folgende ist ein POST, sofern nicht anders angegeben.
| Methode | Pfad | Zweck |
|---|---|---|
POST | /api/v1/minify/{lang} | Minifizieren, JSON-Antwort |
POST | /api/v1/minify/{lang}/raw | Minifizieren, Antwort als reiner Text |
POST | /api/v1/beautify/{lang} | Formatieren, JSON-Antwort |
POST | /api/v1/beautify/{lang}/raw | Formatieren, Antwort als reiner Text |
GET | /api/v1/limits | Was dieser IP noch bleibt, ohne eine Anfrage zu verbrauchen |
GET | /api/v1/health | Verfügbarkeitsprüfung, nie ratenbegrenzt |
{lang} ist css, js oder html.
Den Code senden
An jedem Endpunkt werden drei Body-Formate akzeptiert — nimm das, was dein Client dir leicht macht.
Formularkodiert
Ein Feld {input}, {type}. Das ist die Form, die auch die Minifizierer von Toptal erwarten, ein bestehendes Skript ändert also nur seine Adresse.
curl --data-urlencode 'input=body{margin:0;padding:0}' \
https://formatter.nextwell.top/api/v1/beautify/css
JSON
{type} mit einem String {input}.
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
Roher Body
Jeder andere Content-Type: der Body ist der Code. Praktisch für {example}.
curl --data-binary @style.css \
-H 'Content-Type: text/css' \
https://formatter.nextwell.top/api/v1/minify/css
Größe
2 MB pro Anfrage. Alles Größere kommt als 413 zurück, ohne gelesen zu werden.
Query-Parameter
| Name | Werte | Bedeutung |
|---|---|---|
engine |
auto upstream local |
Welche Engine diese Anfrage bearbeitet. {auto} — die Vorgabe — schickt die Minifizierung von CSS und JS nach oben, solange das Kontingent reicht, und fällt sonst auf die lokale Engine zurück. {upstream} verweigert, statt zurückzufallen. {local} verlässt den Server nie. |
indent |
2 4 tab |
Nur beim Formatieren: was eine Einrückungsebene ist. |
curl --data-urlencode 'input=.a{color:red}' \
'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'
Die Antwort
Ein erfolgreicher Aufruf liefert 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}"
}
| Feld | Typ | Bedeutung |
|---|---|---|
ok | boolean | Bei Erfolg immer true. |
action | string | minify oder beautify — was angefordert wurde. |
language | string | css, js oder html. |
engine | string | upstream, wenn Toptal es übernommen hat, local, wenn dieser Server es getan hat. |
input_bytes | number | Größe des Gesendeten, in Bytes. |
output_bytes | number | Größe des Ergebnisses, in Bytes. |
saved_bytes | number | Die Differenz; negativ beim Formatieren. |
saved_percent | number | Dieselbe Differenz als Prozentwert, eine Nachkommastelle. |
duration_ms | number | Dauer der Verarbeitung, Millisekunden. |
output | string | Der formatierte Code. |
Antworten als reiner Text
Hänge {raw} an einen beliebigen Format-Endpunkt an, und der Body ist das Ergebnis und sonst nichts, als {type}. Die Header bleiben gleich. Nützlich, wenn der Aufrufer eine Shell ist:
curl -s --data-binary @app.js \
-H 'Content-Type: text/javascript' \
https://formatter.nextwell.top/api/v1/minify/js/raw > app.min.js
Antwort-Header
| Header | Bedeutung |
|---|---|
X-Formatter-Engine | Welche Engine das Ergebnis erzeugt hat. |
X-Formatter-Duration | Verarbeitungszeit in Millisekunden. |
X-RateLimit-Remaining-Second … -Month | Was dieser IP in jedem Fenster bleibt. |
Retry-After | Bei einem 429: Sekunden, bis sich das engste verbrauchte Fenster wieder öffnet. |
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
https://formatter.nextwell.top/api/v1/minify/css
Fehler
Jeder Fehler ist JSON in derselben Form, die auch die Minifizierer von Toptal verwenden — ein Client, der deren Fehler bereits behandelt, behandelt auch unsere:
{
"errors": [
{ "status": 429, "title": "Too many requests", "detail": "…" }
]
}
| Status | Titel | Wann |
|---|---|---|
400 | Missing input Bad request | Kein Body oder ein leeres Feld input. |
404 | Not found | Diesen Pfad gibt es nicht. |
405 | Method not allowed | Ein Format-Endpunkt wurde mit etwas anderem als POST aufgerufen. |
413 | Payload too large | Der Body ist größer als 2 MB. |
415 | Unsupported language | Die Sprache im Pfad ist nicht css, js oder html. |
422 | Malformed input | Der Formatierer hat die Quelle abgelehnt — meist ein Syntaxfehler. |
429 | Too many requests | Eines der Ratenlimit-Fenster ist verbraucht. Lies Retry-After. |
502 | Upstream failed | Nur mit engine=upstream: Toptal hat nicht geantwortet. Ohne diese Festlegung wäre die Anfrage lokal ausgewichen. |
500 | Internal error | Alles andere. |
Ratenbegrenzung
Pro IP-Adresse, fünf gleitende Fenster, alle zugleich durchgesetzt. Eine Anfrage muss in alle fünf passen.
| Fenster | Limit |
|---|---|
| Pro Sekunde | {n} Anfragen |
| Pro Minute | {n} Anfragen |
| Pro Stunde | {n} Anfragen |
| Pro Tag | {n} Anfragen |
| Pro Monat | {n} Anfragen |
Ist ein Fenster verbraucht, lautet die Antwort 429 mit einem Retry-After-Header, der die Sekunden bis zur Wiederöffnung des engsten Fensters nennt. Nichts wird in eine Warteschlange gestellt.
Die Zähler liegen in einer kleinen Datenbank auf der Platte, ein Neustart des Dienstes schenkt also niemandem einen frischen Tag.
{endpoint} meldet den aktuellen Stand aller fünf Fenster, ohne eines zu verbrauchen.
curl https://formatter.nextwell.top/api/v1/limits
Toptal erlaubt 30 Anfragen pro Minute für diesen gesamten Dienst, nicht pro Besucher. Ein gemeinsamer Token-Bucket führt darüber Buch: Ist er leer, übernimmt die lokale Engine die Minifizierung von CSS und JS, statt zu warten oder zu scheitern. Unter Last kann sich das Feld engine also ändern — die Ausgabe bleibt in beiden Fällen gültig.
Welche Engine die Arbeit macht
Zwei Wege, ein Vertrag.
Toptal — Minifizierung von CSS und JS
Ihre Minifizierer sind schnell und zurückhaltend: Sie entfernen den Whitespace, der weg kann, und behalten den, der bleiben muss, sodass etwa {calc} unversehrt bleibt. Dieser Dienst reicht den Code durch und fügt nichts Eigenes hinzu.
Lokal — alles andere
HTML-Minifizierung, alle drei Formatierer und die Minifizierung von CSS/JS, sobald das gemeinsame Upstream-Kontingent aufgebraucht ist oder der Dienst auf offline gestellt ist. Gebaut auf {tools}, geladen erst dann, wenn eine Anfrage sie braucht, damit ein untätiger Prozess klein bleibt.
Setze {param}, um eine Anfrage auf einen Weg festzulegen.
Was gespeichert wird
Nichts. Der Code liegt für die Dauer der Anfrage im Speicher und wird danach verworfen. Er wird nicht auf die Platte geschrieben und taucht nie in einem Log auf. Was die Logs sehr wohl enthalten: einen gekürzten Hash der IP, die Sprache, die Aktion, die Byte-Anzahl, die Engine und die Dauer.
Fragen
Brauche ich einen Schlüssel?
Nein. Der Dienst ist offen und wird stattdessen pro IP-Adresse begrenzt.
Wird mein Code irgendwohin geschickt?
Die Minifizierung von CSS und JavaScript wird an die Minifizierer von Toptal weitergereicht, dieser Code erreicht also deren Server. Das Formatieren und die gesamte HTML-Arbeit erledigt dieser Server. Setze engine=local, um alles hier zu behalten.
Kann ich es in einem Build-Skript verwenden?
Ja, dafür sind die raw-Endpunkte da. Bleib innerhalb der Limits und bedenke, dass die Engine unter Last zurückfallen kann.
Warum ist mein minifiziertes JavaScript umbenannt?
Der Upstream-Minifizierer kürzt lokale Variablennamen, was sicher ist und den größten Teil der Ersparnis ausmacht. Formatieren holt die ursprünglichen Namen nicht zurück — das kann nichts.
Wie groß darf die Datei höchstens sein?
2 MB in einer Anfrage. Größere Dateien werden mit 413 abgelehnt, statt gekürzt zu werden.