Schnellstart
Alle Endpunkte verwenden https://api.ironfang.uk/render als Basis-URL. Der Produktname steht im Pfad, weil api.ironfang.uk alle Ironfang-APIs bereitstellt. Der ältere Pfad ohne Präfix, https://api.ironfang.uk/v1/, wird für Endpunkte, die früher dort veröffentlicht wurden, weiterhin unterstützt. Neue Endpunkte verwenden die Basis-URL des Produkts. Erstellen Sie einen API-Schlüssel im Portal und rendern Sie dann Ihren ersten Screenshot:
curl -X POST https://api.ironfang.uk/render/v1/screenshot \
-H "Authorization: Bearer if_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "width": 1280}' \
--output shot.pngErfolgreiche Render-Anfragen liefern die Binärdatei direkt als image/png, image/jpeg oder application/pdf. Clips liefern video/mp4. Website-Vorschauen liefern eine Multipart-Antwort mit einem JPEG-Posterbild und einem MP4-Video. Alle anderen erfolgreichen Endpunkte und alle Fehlerantworten liefern JSON.
Client-Bibliotheken
Offizielle Clients kapseln dieselbe API, einschließlich typisierter Anfragen, der Webhook-Prüfung und des Herunterladens von Ergebnissen:
npm install @ironfang/renderwolf # TypeScript, Node 20+
pip install ironfang-renderwolf # PythonAußerdem gibt es eine eigenständige CLI: einzelne Binärdateien für Linux, macOS und Windows mit Prüfsummen, erhältlich unter github.com/ironfang-ltd/cli.
Postman
Jeder Endpunkt ist in einer öffentlichen Postman-Collection enthalten, die aus dem OpenAPI-Vertrag erzeugt wird. Sie enthält einen Ordner "Getting started", dessen erste Anfrage keinen Schlüssel benötigt.
Authentifizierung
Senden Sie Ihren API-Schlüssel bei jeder Anfrage als Bearer-Token: Authorization: Bearer if_live_.... Schlüssel erstellen und widerrufen Sie im Portal. Das Secret wird beim Erstellen des Schlüssels einmal angezeigt und als Hash gespeichert. Ein fehlender oder unbekannter Schlüssel ergibt 401 invalid_api_key.
Berechtigungen
Ein Ironfang-API-Schlüssel kann Zugriff auf mehrere Produkte gewähren. Wählen Sie seine Berechtigungen beim Erstellen aus. Berechtigungen lassen sich später nicht erweitern; erstellen Sie daher einen neuen Schlüssel, wenn Sie weitergehenden Zugriff benötigen. Eine Anfrage außerhalb der Berechtigungen des Schlüssels ergibt 403 insufficient_scope und nennt die fehlende Berechtigung.
render:renderScreenshots, PDFs, Bilder, Clips und Website-Vorschauenrender:signSignierte Render-URLs erstellenrender:templates:readGespeicherte Vorlagen lesenrender:templates:writeVorlagen erstellen, bearbeiten und löschenrender:usage:readNutzung im Verhältnis zum Kontingent lesen
Schlüssel, die vor der Einführung von Berechtigungen erstellt wurden, haben keine zugewiesenen Berechtigungen und behalten aus Gründen der Abwärtskompatibilität vollen Zugriff. Neue Schlüssel werden immer mit ausdrücklichen Berechtigungen erstellt.
POST /v1/screenshot
Nimmt eine URL oder rohes HTML mit einer vorgewärmten Chromium-Instanz auf. Verbraucht 1 Credit.
| Feld | Typ | Hinweise |
|---|---|---|
url | string | Aufzunehmende Seite. Geben Sie url oder html an, nicht beides. Ziele in privaten Netzwerken werden blockiert. |
html | string | Rohes HTML, das anstelle einer URL gerendert wird. |
width | int | Breite des Viewports. Standard: 1280. |
height | int | Höhe des Viewports. Standard: 800. |
device | string | desktop, tablet oder mobile. Jede Voreinstellung legt Viewport, Pixeldichte und User-Agent fest. Siehe Geräte. |
full_page | bool | Nimmt die gesamte Scrollhöhe statt nur des Viewports auf. |
selector | string | CSS-Selektor, um ein einzelnes Element aufzunehmen. |
dark_mode | bool | Emuliert prefers-color-scheme: dark. |
format | string | png (Standard), jpeg oder webp. WebP kann für dieselbe Aufnahme eine kleinere Datei als PNG ergeben. |
quality | int | JPEG- und WebP-Qualität von 1 bis 100. Standard: 85. |
delay_ms | int | Zusätzliche Wartezeit nach dem Laden für Inhalte, die spät gerendert werden. |
no_cache | bool | Erzwingt eine neue Aufnahme und ignoriert gecachte Renderings. Wird auf Ihr Kontingent angerechnet. Siehe Caching. |
clip | object | { x, y, width, height } in CSS-Pixeln ab der oberen linken Ecke. Das Feld wird ignoriert, wenn selector gesetzt ist, weil dann der Selektor den Aufnahmebereich festlegt. |
omit_background | bool | Verwendet einen transparenten Hintergrund statt des Seitenhintergrunds. Bei jpeg wird das Feld ignoriert, da JPEG keinen Alphakanal hat. |
full_page_max_height | int | Begrenzt eine full_page-Aufnahme. Ohne diese Grenze hat eine Seite mit endlosem Scrollen kein natürliches Ende. |
Vor der Aufnahme wartet Ironfang Render auf Webfonts, setzt CSS-Animationen und -Übergänge auf ihren Endzustand und blendet Scrollbalken aus. Endlos laufende Animationen laufen weiter.
Websites mit Bot-Schutz liefern automatisierten Browsern möglicherweise eine Verifizierungsseite. Ironfang Render gibt den Inhalt zurück, den die Website liefert, und versucht nicht, die Verifizierung zu umgehen.
Verwenden Sie delay_ms, wenn Inhalte nach dem üblichen Warten auf eine ruhige Seite noch weiter gerendert werden. Typische Beispiele sind Dashboards, die ihre Daten erst nach dem Laden abrufen, und Seiten, die mit JavaScript-Bibliotheken wie GSAP animiert werden.
Fehlen Elemente in Ihrer Aufnahme oder sind sie nur halb eingeblendet, versuchen Sie delay_ms zwischen 500 und 1500.
curl -X POST https://api.ironfang.uk/render/v1/screenshot \
-H "Authorization: Bearer if_live_..." \
-d '{"url": "https://example.com", "full_page": true, "dark_mode": true}' \
--output page.pngGeräte
Das Feld device legt Viewport, Pixeldichte, mobile Kennung und User-Agent gemeinsam fest. Das emuliert ein Gerät genauer, als nur die Breite des Viewports zu ändern.
| Gerät | Viewport | Pixelverhältnis | Bildgröße |
|---|---|---|---|
desktop | 1280 × 800 | 1× | 1280 × 800 |
tablet | 820 × 1180 | 2× | 1640 × 2360 |
mobile | 390 × 844 | 3× | 1170 × 2532 |
Viewport-Maße sind CSS-Pixel. Ein ausdrücklich angegebenes width oder height überschreibt den jeweiligen Wert der Voreinstellung. Ein unbekannter Gerätename ergibt einen Validierungsfehler.
Die Voreinstellungen nutzen die Geräte-Emulation von Chromium. Sie umgehen keinen Bot-Schutz; eine Website kann also trotzdem eine Verifizierungsseite liefern.
curl -X POST https://api.ironfang.uk/render/v1/screenshot \
-H "Authorization: Bearer if_live_..." \
-d '{"url": "https://example.com", "device": "mobile", "format": "webp"}' \
--output phone.webpOptionen für jedes Rendering
Diese Optionen gelten für Screenshots, PDFs und Website-Vorschauen. Lassen Sie eine Option weg, bleibt das Standardverhalten der Antwort erhalten.
Blockieren
Werbung und Tracker werden als Netzwerkanfragen blockiert, bevor sie geladen werden. Consent-Banner sind Seitenelemente, die von Skripten eingefügt werden; Ironfang Render blendet unterstützte Banner daher nach dem Laden der Seite per CSS aus.
| Feld | Typ | Hinweise |
|---|---|---|
block_ads | bool | Verhindert Anfragen an bekannte Werbe- und Tracking-Netzwerke. Ironfang Render nutzt eine gezielte Sperrliste, um das Risiko zu verringern, dass Ressourcen entfernt werden, die die Seite braucht. |
block_cookie_banners | bool | Blendet unterstützte Consent-Frameworks aus und hebt deren Scroll-Sperren auf. So können full_page-Aufnahmen über einen Viewport hinausreichen. Ironfang Render klickt keine Zustimmungsschaltfläche an und speichert keine Einwilligung. |
hide_selectors | string[] | Auszublendende CSS-Selektoren. Sie werden nach dem Laden angewendet und erfassen so auch Elemente, die per Skript eingefügt werden. |
Eigenes CSS, JavaScript und Seitenaktionen
Blenden Sie ein Widget aus, passen Sie Druckstile an, wählen Sie einen Tab aus oder klappen Sie Inhalte auf, bevor ein Screenshot oder PDF entsteht. Diese Optionen funktionieren mit einer URL oder mit übergebenem HTML, auch in Jobs und Batches aus der Warteschlange.
Nach dem normalen Laden der Seite und den Wartebedingungen wendet Ironfang Render zuerst das eingebaute Ausblenden an, dann Ihr css, wartet auf Ihr script und führt anschließend die actions der Reihe nach aus. Danach wartet Ironfang Render, bis die Seite zur Ruhe kommt, und nimmt sie auf. Ein wait_for_selector auf oberster Ebene läuft vor diesen Steuerungen; um auf Inhalte zu warten, die durch eine Interaktion entstehen, verwenden Sie eine Selektor-Aktion.
| Feld | Typ | Grenzen und Verhalten |
|---|---|---|
css | string | Ein Stylesheet mit bis zu 65.536 UTF-8-Bytes. Unterstützt Layout-Anpassungen, ausgeblendete Elemente, deaktivierte Animationen und @media print. Fehlerhafte Syntax ergibt 400 bad_request, bevor gerendert wird. Welche Eigenschaftsnamen und Werte unterstützt werden, bestimmt Chromium. |
script | string | JavaScript mit bis zu 16.384 UTF-8-Bytes, ausgeführt im Kontext des Hauptframes der Zielseite als Rumpf einer async-Funktion. Verwenden Sie await oder geben Sie ein Promise zurück, um asynchron zu arbeiten. Die Ausführung ist auf fünf Sekunden oder das verbleibende Render-Timeout begrenzt, je nachdem, was kürzer ist. Rückgabewerte werden verworfen. |
actions | object[] | Bis zu 20 geordnete Aktionen, die sich das verbleibende Budget von timeout_ms teilen. Selektoren treffen das erste passende Element der Hauptseite und sind auf 1.024 UTF-8-Bytes begrenzt. |
| Aktionstyp | Pflichtfeld | Verhalten |
|---|---|---|
click | selector | Wartet auf ein bedienbares, aktiviertes Element und klickt es an. |
hover | selector | Wartet auf ein bedienbares Element und bewegt den Zeiger darüber. |
wait_for_selector | selector | Wartet, bis ein Element existiert; es darf verborgen sein. |
delay | duration_ms | Wartet 0 bis 10.000 ms. Alle Verzögerungen der Aktionen zusammen dürfen höchstens 10.000 ms betragen. |
Dieses in sich geschlossene Beispiel blendet ein Widget aus, ändert die Überschrift und klappt vor der Aufnahme die Preisdetails auf. Ersetzen Sie html durch url und verwenden Sie die Selektoren Ihrer Website, um eine bestehende Seite aufzunehmen.
curl https://api.ironfang.uk/render/v1/screenshot \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H 'Content-Type: application/json' \
--output expanded.png --data-binary @- <<'JSON'
{
"html": "<h1 id='title'>Plans</h1><div class='chat-widget'>Chat widget</div><details id='details'><summary id='show-more'>Show pricing</summary><p>Expanded pricing details</p></details>",
"css": ".chat-widget { display: none !important; }",
"script": "document.querySelector('#title').textContent = 'Pricing';",
"actions": [
{ "type": "click", "selector": "#show-more" },
{ "type": "wait_for_selector", "selector": "#details[open]" }
]
}
JSONVerwenden Sie /v1/pdf und --output expanded.pdf, um denselben Seitenzustand als PDF zu erhalten. Für asynchrones JavaScript verwenden Sie eine Operation mit await, zum Beispiel await new Promise(resolve => setTimeout(resolve, 250));. Für Oberflächen, die erst später erscheinen, lassen Sie auf die Interaktion eine Selektor-Aktion folgen.
Ungültige Eingaben ergeben 400 bad_request. Syntaxfehler im Skript, Ausführungsfehler und Timeouts ergeben 422 render_failed mit einer bereinigten Meldung. Fehler in Aktionen nennen den nullbasierten Index und den Typ, etwa actions[0] (click), und brechen die Liste ab. Fehlgeschlagene Renderings werden erstattet; Jobs aus der Warteschlange wiederholen diese Interaktionsfehler nicht.
Diese Optionen und die Reihenfolge der Aktionen sind Teil des Cache-Schlüssels für Screenshots. Ein Cache-Treffer liefert das vorherige Bild, ohne die Steuerungen erneut auszuführen; setzen Sie no_cache: true für einen frischen Durchlauf. Skripte und Klicks können den Zustand der Zielanwendung verändern. Die API bietet Code-Schnipsel im Seitenkontext und diese vier Aktionen; Browser-Sitzungen oder die APIs von Playwright/Puppeteer stellt sie nicht bereit.
Header, Cookies und Zugangsdaten
Ironfang Render setzt Header, Cookies und Zugangsdaten vor der Navigation, damit sie schon bei der ersten Anfrage an die Zielseite vorhanden sind.
| Feld | Typ | Hinweise |
|---|---|---|
headers | object | Zusätzliche HTTP-Header, die mit jeder Anfrage der Seite gesendet werden. |
authorization | string | Setzt den Header Authorization. Ein ausdrücklicher Eintrag Authorization in headers hat Vorrang. |
cookies | object[] | { name, value, domain, path }. domain ist erforderlich, weil Chromium ein vor der Navigation gesetztes Cookie ohne Domain verwirft. |
user_agent | string | Überschreibt den User-Agent, auch einen durch device gesetzten. |
Ziele in privaten Netzwerken bleiben auch mit Zugangsdaten blockiert. Der SSRF-Schutz greift, bevor Authentifizierungsdaten angewendet werden.
Warten
| Feld | Typ | Hinweise |
|---|---|---|
wait_until | string | load (Standard), domcontentloaded oder networkidle. networkidle wartet, bis der Netzwerkverkehr aufhört, und ist durch das Render-Timeout begrenzt, weil eine Seite, die regelmäßig Daten abfragt, nie wirklich zur Ruhe kommt. |
wait_for_selector | string | Wartet vor der Aufnahme auf dieses Element. Die Anfrage schlägt fehl, wenn das Element nicht vor dem Timeout erscheint. |
timeout_ms | int | Timeout pro Rendering. Werte über dem Maximum des Dienstes werden auf dieses Maximum begrenzt. |
device_scale_factor | number | Pixeldichte, 1 bis 3. 2 entspricht Retina: dieselbe CSS-Größe mit doppelt so vielen Pixeln. |
curl -X POST https://api.ironfang.uk/render/v1/screenshot \
-H "Authorization: Bearer if_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"block_ads": true,
"block_cookie_banners": true,
"wait_for_selector": "#main",
"device_scale_factor": 2
}' \
--output shot.pngPOST /v1/pdf
Druckt eine URL oder rohes HTML als PDF. Jedes erfolgreiche PDF verbraucht 2 Credits.
| Feld | Typ | Hinweise |
|---|---|---|
url | string | Zu druckende Seite. Geben Sie url oder html an. |
html | string | Rohes HTML, das anstelle einer URL gedruckt wird. |
landscape | bool | Querformat. |
print_background | bool | CSS-Hintergründe einschließen. |
header_html | string | Chromium-Vorlage für die Kopfzeile. Sobald eine der beiden Vorlagen gesetzt ist, sind Kopf- und Fußzeilen aktiv. Wenn Sie nur eine Fußzeile senden, senden Sie deshalb eine leere Kopfzeile wie <span></span>; andernfalls druckt Chromium seine Standard-Kopfzeile mit Datum und Titel. |
footer_html | string | Chromium-Vorlage für die Fußzeile. Die Klassen pageNumber, totalPages, date, title und url werden ausgefüllt. Vorlagen übernehmen die Stile der Seite nicht; legen Sie daher in jeder eine Schriftgröße fest. |
scale | float | Druckmaßstab. Standard: 1,0. |
no_cache | bool | Wird angenommen, hat hier aber keine Wirkung: PDFs werden nie gecacht, jede Anfrage rendert das Dokument neu. |
paper_format | string | a3, a4, a5, letter, legal oder tabloid. Ohne Angabe gilt der Standard von Chromium, Letter. Die Formate sind Hochformat; landscape dreht sie. |
margin | object | { top, right, bottom, left } in Zoll. Weggelassene Seiten behalten den Standardrand von Chromium. |
curl -X POST https://api.ironfang.uk/render/v1/pdf \
-H "Authorization: Bearer if_live_..." \
-d '{"html": "<h1>Invoice #42</h1>", "print_background": true}' \
--output invoice.pdfPOST /v1/qr
Erzeugt gestaltete QR-Codes, die vor der Auslieferung geprüft werden. Ironfang Render dekodiert jedes fertige Bild und vergleicht es mit den übergebenen Daten. Schlägt die Prüfung fehl, lautet die Antwort 422 unscannable. QR-Anfragen sind in jedem Tarif kostenlos, auch innerhalb von Vorlagen. Sie erscheinen in den Nutzungsdaten, verbrauchen aber keine Credits und bleiben auch nach Erreichen der Obergrenze des Tarifs verfügbar.
| Feld | Typ | Hinweise |
|---|---|---|
data | string | Pflichtangabe: die Nutzdaten, etwa eine URL, ein WLAN-String oder Text mit bis zu 1 KB. |
size | int | Quadratische Ausgabegröße von 64 bis 2048 Pixeln. Standard: 512. Nur PNG. |
ecc | string | Fehlerkorrektur: L, M, Q oder H. Standard: M. Mit einem Logo wird automatisch H gewählt, um die vom Logo verdeckten Module auszugleichen. |
dark / light | string | Hex-Farben. dark muss dunkler als light sein und den Mindestkontrast erfüllen. Ungültige Kombinationen ergeben eine 400-Antwort. light akzeptiert auch transparent. Platzieren Sie transparente Codes auf einem hellen Hintergrund. |
dots | string | square oder circle. Die Suchmuster werden immer vollflächig gezeichnet, damit ihre vorgeschriebene Struktur erhalten bleibt. |
eyes | string | square oder rounded. Standardmäßig passend zu dots. |
margin | int | Ruhezone von 0 bis 8 Modulen. Standard: 4. |
invert | bool | Erzeugt helle Module auf dunklem Hintergrund. Moderne Handykameras lesen invertierte Codes oft, viele eingebettete Scanner und Scanner in Apps jedoch nicht. Mit dieser Option muss dark heller als light sein. Ironfang Render prüft das Ergebnis anhand seines Negativs. |
logo | string | Logo in der Mitte als base64-data:-URI, PNG oder JPEG. Schließt logo_url aus. |
logo_url | string | Logo in der Mitte, per URL angegeben. Für die URL gelten derselbe Zielschutz und dieselben Ratenlimits wie für eine Screenshot-Anfrage. |
logo_size | float | Größe der Logofläche als Anteil des Symbols, von 0,12 bis 0,30. Standard: 0,22. |
logo_pad | bool | Legt eine freigestellte Fläche hinter das Logo, um es von den QR-Modulen abzusetzen. Standard: true. |
curl -X POST https://api.ironfang.uk/render/v1/qr \
-H "Authorization: Bearer if_live_..." \
-d '{"data": "https://example.com/menu", "dots": "rounded",
"logo_url": "https://example.com/logo.png"}' \
--output qr.pngUm einen QR-Code in eine gespeicherte Vorlage einzubinden, verwenden Sie das Objekt qr bei Vorlagen-Renderings. QR-Ausgaben tragen kein Badge des kostenlosen Tarifs, weil eine zusätzliche Markierung das Scannen beeinträchtigen könnte.
POST /v1/video
Ein Clip: ein Hintergrund, Texteinblendungen nach Zeitplan, ein optionales Wasserzeichen und eine optionale Tonspur. Liefert video/mp4.
Ironfang Render erzeugt kurze Clips aus strukturierten Daten für automatisierte Content-Workflows. Anfragen nutzen denselben API-Schlüssel, dasselbe Kontingent und dieselben Integrationen wie andere Render-Typen.
| Feld | Typ | Hinweise |
|---|---|---|
size | string | vertical 1080×1920 (Standard), square 1080×1080, landscape 1920×1080, 720p 1280×720. |
duration | number | Länge der Ausgabe in Sekunden, 1 bis 60. Standard: 15. |
captions | array | Bis zu 12 Einblendungen der Form {text, from, to}, in Sekunden. Der Text darf Anführungszeichen, Doppelpunkte und Klammern enthalten. |
colour | string | Hintergrundfarbe als Hex-Wert, verwendet, wenn kein background angegeben ist. Standard: #101820. |
background | string | URL eines Bildes oder Videos, zugeschnitten auf die gesamte Fläche. |
watermark | string | URL eines PNG, unten rechts platziert. |
audio | string | URL einer Tonspur, auf die Länge des Clips gekürzt. |
font_size | int | Schriftgröße der Einblendungen in Pixeln. Standardmäßig ein Fünfzehntel der Breite. |
curl -X POST https://api.ironfang.uk/render/v1/video \
-H "Authorization: Bearer if_live_..." \
-d '{
"size": "vertical",
"duration": 15,
"captions": [
{"text": "Ship it on Friday", "from": 0, "to": 5},
{"text": "Find out on Monday", "from": 5, "to": 10},
{"text": "Or gate the deploy", "from": 10, "to": 15}
]
}' --output clip.mp4Credit-Verbrauch
Hochformat- und Querformat-Clips verbrauchen einen Credit pro Sekunde. Quadratische Clips verbrauchen 0,6 Credits pro Sekunde, 720p-Clips 0,5 Credits pro Sekunde. Die Summe wird auf den nächsten ganzen Credit gerundet, mindestens aber auf einen. Ein Hochformat-Clip von 15 Sekunden verbraucht 15 Credits, derselbe Clip in 720p 8. Credits für fehlgeschlagene Arbeit werden erstattet, und identische Anfragen aus dem Cache verbrauchen keine Credits.
Betriebsgrenzen
Clips werden innerhalb der Anfrage gerendert und sind auf 60 Sekunden begrenzt. Referenzierte Dateien durchlaufen dieselben URL-Prüfungen wie Screenshot-Ziele und sind auf je 64 MB begrenzt. Hintergrunddateien müssen aus dem öffentlichen Internet erreichbar sein.
Clips sind auf 60 Sekunden begrenzt. /v1/video rendert einen Clip innerhalb der Anfrage; um ihn stattdessen in die Warteschlange zu stellen und per Webhook über das Ende informiert zu werden, senden Sie ihn als Job, wie unten beschrieben. Längere Clips werden derzeit nicht unterstützt.
POST /render/v1/site-preview
Macht aus einer öffentlichen Webseite eine Vorschau von oben bis unten. Wählen Sie einen durchgehenden Schwenk oder viewportgroße Schritte mit Schwung, die jeweils in eine kurze Lesepause übergehen. Eine Anfrage liefert ein JPEG-Posterbild aus dem ersten Frame und ein im Browser aufgezeichnetes H.264-MP4. Fixierte und klebende (sticky) Elemente verhalten sich wie beim echten Scrollen.
Dieser Endpunkt ist nur unter https://api.ironfang.uk/render/v1/site-preview verfügbar.
| Feld | Typ | Hinweise |
|---|---|---|
url | string | Öffentliche HTTP- oder HTTPS-Seite, die aufgezeichnet wird. Pflichtfeld. |
width | int | Gerade Ausgabebreite von 320 bis 1280. Standard: 672. |
height | int | Gerade Ausgabehöhe von 240 bis 1200. Standard: 494. Ein Frame hat höchstens 1.200.000 Pixel. |
motion | string | per_page für viewportgroße Schritte mit Pausen oder single_sweep für einen durchgehenden Durchlauf. Standard: per_page. |
device | string | desktop, tablet oder mobile. |
dark_mode | bool | Zeichnet mit dem dunklen Farbschema der Seite auf. Standard: false. |
no_cache | bool | Erzwingt eine neue Aufzeichnung. Standard: false. |
Rufen Sie diesen Endpunkt von Ihrem Server aus auf, nie aus Browser-Code: Die Anfrage enthält Ihren API-Schlüssel, und alles, was an einen Browser ausgeliefert wird, ist öffentlich. Für eine Vorschau, die ein Besucher auslöst, erzeugen Sie stattdessen serverseitig eine signierte URL.
const response = await fetch(
'https://api.ironfang.uk/render/v1/site-preview',
{
method: 'POST',
headers: {
Authorization: 'Bearer if_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://example.com',
motion: 'per_page'
})
}
);
const output = await response.formData();
const poster = output.get('poster'); // poster.jpg, image/jpeg
const video = output.get('video'); // preview.mp4, video/mp4Ausgabe und Credits
Die Antwort ist multipart/form-data mit den benannten Teilen poster und video. Das Video ist ein H.264-MP4 mit 60 fps und einem JPEG-Posterbild aus dem ersten Frame. Ironfang Render berechnet die Dauer aus der Seitenhöhe und der Bewegung, mit einer serverseitigen Obergrenze von 60 Sekunden. Website-Vorschauen verbrauchen einen Credit pro Ausgabesekunde, aufgerundet. Das Posterbild ist inbegriffen. Credits für fehlgeschlagene Arbeit werden erstattet, und identische Anfragen aus dem Cache verbrauchen keine Credits.
Vorlagen
Speichern Sie wiederverwendbares HTML und rendern Sie es mit unterschiedlichen Variablen, etwa für Open-Graph-Bilder, Social Cards und andere dynamische Assets. Variablen verwenden Platzhalter der Form {{name}}. Eingesetzte Werte werden HTML-maskiert, damit kein Markup eingeschleust werden kann. Die Verwaltung von Vorlagen ist kostenlos; jedes erfolgreich gerenderte Bild verbraucht einen Credit. IDs sind UUIDv7 und nach Erstellungszeit sortierbar.
| Endpunkt | Zweck |
|---|---|
POST /v1/templates | Erstellen. Body: name, html (max. 256 KB), width, height (Standard 1200×630, höchstens 4096). |
GET /v1/templates | Ihre Vorlagen auflisten. |
GET /v1/templates/{id} | Eine Vorlage abrufen. |
PUT /v1/templates/{id} | Aktualisieren. Änderungen machen den Render-Cache automatisch ungültig. |
DELETE /v1/templates/{id} | Löschen. |
curl -X POST https://api.ironfang.uk/render/v1/templates \
-H "Authorization: Bearer if_live_..." \
-d '{
"name": "og-card",
"html": "<div class=\"card\"><h1>{{title}}</h1><p>{{author}}</p></div>",
"width": 1200,
"height": 630
}'POST /v1/image/{id}
Rendert eine gespeicherte Vorlage mit den übergebenen Variablen als Bild. Jedes erfolgreiche Bild verbraucht 1 Credit. Identische Anfragen aus dem Cache verbrauchen keine Credits.
| Feld | Typ | Hinweise |
|---|---|---|
vars | object | String-Map, die die {{placeholders}} der Vorlage füllt. Fehlende Variablen bleiben leer. |
no_cache | bool | Erzwingt eine neue Aufnahme und ignoriert gecachte Renderings. Wird auf Ihr Kontingent angerechnet. Siehe Caching. |
format | string | png (Standard), jpeg oder webp. WebP kann für dieselbe Ausgabe eine kleinere Datei als PNG ergeben. |
qr | object | Benannte QR-Angaben, bis zu 4, jeweils in der Form des Bodys von /v1/qr. Jeder Eintrag wird gerendert, auf Lesbarkeit geprüft und als Variable {{qr.<name>}} eingesetzt, die eine Data-URI für ein <img>-Element enthält. Eingebettete QR-Codes verursachen keine zusätzlichen Kosten für das Bild. |
curl -X POST https://api.ironfang.uk/render/v1/image/0198c9f1-5b7a-7c2e-9f1d-3a8b2c4d5e6f \
-H "Authorization: Bearer if_live_..." \
-d '{"vars": {"title": "Hello from Ironfang Render", "author": "Rick"}}' \
--output og.pngFür einen QR-Platz fügen Sie <img src="{{qr.pay}}" width="150"> in die Vorlage ein:
curl -X POST https://api.ironfang.uk/render/v1/image/0198c9f1-5b7a-7c2e-9f1d-3a8b2c4d5e6f \
-H "Authorization: Bearer if_live_..." \
-d '{"vars": {"invoice": "INV-2041"},
"qr": {"pay": {"data": "https://pay.example/INV-2041", "size": 300}}}' \
--output invoice-card.pngSignierte URLs
Erstellen Sie eine stabile GET-URL für ein <img>-Element oder ein og:image-Meta-Tag. Die URL legt den API-Schlüssel nicht offen und braucht keinen Proxy in Ihrer Anwendung. Ihre Signatur deckt jeden Parameter und das abgerechnete Konto ab, sodass nach dem Signieren nichts mehr geändert werden kann.
POST /v1/sign mit:
| Feld | Typ | Hinweise |
|---|---|---|
kind | string | screenshot oder image. |
url | string | Zielseite (kind: screenshot). |
template | string | Vorlagen-ID (kind: image). |
vars | object | Vorlagenvariablen (kind: image). |
width / height | int | Optionale Abmessungen. |
full_page | bool | Nur für Screenshots. |
ttl_hours | int | Ablauf. 0 = läuft nie ab. |
Die Antwort enthält die vollständige url (und ihren path). Ein Abruf rendert bei Bedarf und wird Ihrem Konto berechnet. Wiederholte Abrufe eines identischen Ergebnisses aus dem Cache verbrauchen keine Credits.
curl -X POST https://api.ironfang.uk/render/v1/sign \
-H "Authorization: Bearer if_live_..." \
-d '{"kind": "image", "template": "0198c9f1-5b7a-7c2e-9f1d-3a8b2c4d5e6f", "vars": {"title": "My post"}, "ttl_hours": 0}'
{"url": "https://api.ironfang.uk/v1/r/0/a1b2c3...?kind=image&template=0198c9f1-5b7a-7c2e-9f1d-3a8b2c4d5e6f&v.title=My+post"}Jobs
Jedes der obigen Renderings kann auch als dauerhafter Job laufen: Sie reichen ihn ein, erhalten sofort ein 202, fragen den Status ab, bis er fertig ist, und holen dann das Ergebnis ab. Verwenden Sie Jobs für Clips, langsame Seiten und überall dort, wo Sie keine Verbindung offen halten möchten. Die synchronen Endpunkte bleiben unverändert.
POST /render/v1/jobs
Idempotency-Key: catalogue-42-v1
{
"kind": "screenshot",
"request": { "url": "https://example.com", "full_page": true },
"external_id": "catalogue-42"
}kind ist screenshot, pdf, qr, image, clip oder site_preview, und request ist genau der Body dieses Endpunkts (ein image-Job nennt sein template innerhalb von request). Die Einreichung wird so validiert, wie der synchrone Endpunkt sie validieren würde, bevor etwas berechnet wird.
Statusabfrage und Ergebnisse
GET /render/v1/jobs/{id} liefert den Job mit dem status queued, running, cancellation_requested, succeeded, failed oder cancelled. Ein erfolgreicher Job enthält result (Content-Type, Größe, SHA-256, Ablauf) und eine signierte url, die keinen API-Schlüssel braucht und 15 Minuten lang gültig ist; GET .../result leitet auf eine neue weiter. Das gehostete Ergebnis wird nach dem Erfolg 24 Stunden lang privat aufbewahrt und dann entfernt: Das ist ein Zeitfenster zum Abholen, kein Asset-Hosting. Speichern Sie, was Sie brauchen, auf Ihrer Seite.
Idempotenz, Abbruch und Credits
Senden Sie bei jeder Einreichung einen Idempotency-Key. Derselbe Idempotenzschlüssel mit derselben Anfrage liefert den bestehenden Job; derselbe Idempotenzschlüssel mit einer anderen Anfrage ergibt 409 idempotency_conflict. DELETE .../jobs/{id} bricht ab: Ein wartender Job stoppt sofort, ein laufender am nächsten sicheren Punkt.
Die maximalen Kosten eines Jobs werden bei der Annahme reserviert und bei Abschluss abgerechnet. Eine Website-Vorschau reserviert die Obergrenze von 60 Sekunden und gibt die Differenz frei, sobald die Seite vermessen ist. Credits für fehlgeschlagene Arbeit werden erstattet. Ein wartender Job lässt sich kostenlos abbrechen; ein laufender wird nur berechnet, wenn er eine brauchbare Ausgabe erzeugt hat. Vorübergehende Fehler werden bis zu dreimal mit Backoff wiederholt; eine Seite, die sich nicht rendern lässt, schlägt sofort mit Angabe des Grundes fehl.
Batches
Bis zu 100 Jobs in einer Einreichung: eine gemeinsame default-Anfrage plus items, die Teile davon überschreiben. Nützlich, wenn Sie eigentlich eine Liste von URLs und einen Satz Optionen haben.
POST /render/v1/batches
Idempotency-Key: nightly-2026-08-28
{
"kind": "screenshot",
"default": { "full_page": true, "block_ads": true },
"external_id": "nightly",
"items": [
{ "request": { "url": "https://example.com/a" }, "external_id": "a" },
{ "request": { "url": "https://example.com/b" }, "external_id": "b" },
{ "kind": "pdf", "request": { "url": "https://example.com/terms" } }
]
}Das Zusammenführen geht eine Ebene tief: Das Feld eines Eintrags gewinnt, alles andere kommt aus dem Standard. Ein Eintrag kann außerdem kind überschreiben und eine eigene delivery mitbringen.
Ein Batch wird als Ganzes angenommen oder abgelehnt. Jeder Eintrag wird validiert, bevor irgendeiner gespeichert wird, und die Credits für alle werden in einer Transaktion reserviert. Ein Batch, der Ihre monatlichen Credits überschreiten würde, kommt daher als 429 quota_exhausted zurück, ohne etwas zu berechnen und ohne Jobs zu hinterlassen. Ein Validierungsfehler nennt den Eintrag, aus dem er stammt.
Einträge sind gewöhnliche Jobs: Fragen Sie jeden einzeln ab, oder fragen Sie GET /render/v1/batches/{id} nach den counts je Status, nach done und nach der vollständigen Job-Ressource jedes Eintrags. Ein ZIP mit den Ergebnissen gibt es nicht. Richten Sie ein Speicherziel ein, wenn die Ausgaben an einem Ort gesammelt werden sollen; das ist auch die einzige Variante, die bei einem Batch aus 100 Clips funktioniert.
Zustellung
Ein Job kann mehr, als nur darauf zu warten, abgeholt zu werden. Registrieren Sie ein Ziel, also einen Webhook-Endpunkt oder Ihren eigenen S3-kompatiblen Bucket, und nennen Sie es in einem beliebigen Job über seine ID. Zugangsdaten senden Sie uns einmal, beim Anlegen des Ziels; sie stehen nie in einem Job-Body.
POST /render/v1/destinations
{ "type": "webhook", "name": "Production", "url": "https://hooks.example.com/render" }
→ 201 { "id": "0198f0a1...", "signing_secret": "...", "signing_secret_note": "store this now; it is not shown again" }Das Signatur-Secret wird genau einmal angezeigt. Wir bewahren nur eine verschlüsselte Kopie auf; es gibt also keinen Endpunkt, der es Ihnen später zurückgeben kann. Wenn Sie es verlieren, legen Sie ein neues Ziel an. Für die Verwaltung von Zielen ist die Berechtigung render:destinations erforderlich.
POST /render/v1/jobs
{
"kind": "screenshot",
"request": { "url": "https://example.com" },
"external_id": "catalogue-42",
"delivery": {
"webhook_destination": "0198f0a1...",
"storage_destination": "0198f0b2...",
"storage_key": "captures/{date}/{external_id}.png"
}
}Signierte Webhooks
Ein Webhook-Ziel wird bei render.job.succeeded, render.job.failed und render.job.cancelled aufgerufen. Der Body enthält den Job, seine Credits und bei Erfolg den Content-Type, die Größe und den SHA-256 des Ergebnisses sowie eine signierte url, die 15 Minuten ab dem Versand gültig ist, nicht ab dem Ende des Jobs.
Prüfen Sie die Signatur über die empfangenen Rohbytes, nicht über etwas, das Sie geparst und erneut serialisiert haben:
expected = "v1=" + hmac_sha256(secret, timestamp + "." + raw_body).hexdigest()
compare(expected, headers["Renderwolf-Signature"]) # constant timeRenderwolf-Timestamp enthält Unix-Sekunden; weisen Sie alles ab, was älter als wenige Minuten ist, um Replays zu verhindern. Renderwolf-Event-Id bleibt über Wiederholungen derselben Zustellung gleich; nutzen Sie die ID, um Ihren Handler idempotent zu machen.
Wiederholungen folgen einer Staffel von einer Minute bis zu einem Tag, mit Jitter, und beachten ein begrenztes Retry-After. Wir wiederholen bei 408, 429 und 5xx; andere 4xx beenden die Zustellung sofort, weil Ihr Endpunkt damit sagt, dass eine Wiederholung nicht hilft. Nach 10 aufeinanderfolgenden Fehlschlägen wird das Ziel deaktiviert, bis Sie es im Portal wieder aktivieren.
Zustellung in Ihren eigenen Bucket
Ein s3-Ziel nimmt einen Bucket, eine Region, Zugangsdaten und optional einen endpoint und ein prefix. Alles S3-Kompatible funktioniert: AWS, Cloudflare R2, MinIO, Ceph. Beschränken Sie die Zugangsdaten auf das Präfix, das Sie uns nennen; sie müssen nur dorthin schreiben.
storage_key ist der Objektschlüssel relativ zu diesem Präfix. Er besteht aus festem Text plus {job_id}, {external_id} und {date} (YYYY/MM/DD); andere Felder sind nicht möglich, und nichts wird ausgewertet. Standard ist renderwolf/{date}/{job_id}. Ein Schlüssel, der aus dem Präfix herausführen würde, wird schon beim Einreichen des Jobs abgelehnt, statt stillschweigend in einen anderen Schlüssel umgeschrieben zu werden.
Ein Upload wird mit einer Prüfsumme versehen und nach dem Schreiben geprüft. Ein bereits vorhandenes Objekt mit derselben Prüfsumme bleibt unangetastet; eine wiederholte Zustellung ändert also nichts, statt ein zweites Mal zu schreiben.
Die Zustellung ändert nie ein Rendering
Darauf können Sie sich verlassen. Ein gerenderter Job ist succeeded, was auch immer Ihr Endpunkt danach getan hat: Ein nicht erreichbarer Webhook verbraucht keinen Render-Versuch, belegt keinen Render-Platz und macht aus einem erfolgreichen Job keinen fehlgeschlagenen. Zustellungen werden nach ihrer eigenen Staffel wiederholt, und GET /render/v1/deliveries zeigt, wie weit jede gekommen ist.
Gibt eine Speicherzustellung auf, erfährt das Webhook-Ziel davon über ein Ereignis render.delivery.failed, das das Ziel und den Fehler nennt. So bemerken Sie, dass ein Bucket keine Uploads mehr annimmt, ohne nach fehlenden Dateien suchen zu müssen.
Anleitungen
Diese durchgehenden Anleitungen zeigen gängige Workflows mit Ironfang Render.
- Open-Graph-Bilder aus wiederverwendbaren Vorlagen erzeugen: eine Vorlage speichern, für jede Seite eine signierte URL erstellen und das Design ändern, ohne die URLs zu ersetzen.
- Rechnungs-PDFs aus vorhandenem HTML erzeugen: vorhandenes Rechnungs-HTML und -CSS mit Druckhintergründen, Seitenzahlen, Kopf- und Fußzeilen verwenden.
- Screenshot einer Seite hinter einer Anmeldung: die Sitzung mit der Render-Anfrage übergeben, um die angemeldete Seite aufzunehmen.
- Screenshots ohne Werbung und Cookie-Banner: Netzwerkanfragen blockieren und Consent-Overlays ausblenden, ohne eine Einwilligung zu speichern.
- Screenshots in GitHub Actions erstellen: Vorschauen von Deployments in Pull-Request-Workflows zur Prüfung aufnehmen.
GET /v1/usage
Ihr aktueller Verbrauch im Verhältnis zur festen Obergrenze Ihres Tarifs:
{"period": "2026-08", "credits": 1240, "renders": 1240, "limit": 50000}renders wiederholt credits unter dem Namen, mit dem diese API eingeführt wurde. Das Feld ist veraltet und wird entfernt, sobald die Migration der Konnektoren abgeschlossen ist. Neue Integrationen sollten credits lesen.
Credits
Ein Screenshot oder ein erzeugtes Bild verbraucht einen Credit, ein PDF zwei Credits. Website-Vorschauen verbrauchen einen Credit pro Ausgabesekunde, das Posterbild inbegriffen. Der Verbrauch von Clips hängt von Dauer und Ausgabegröße ab. Die meisten Arbeiten reservieren Credits vor dem Rendern. Die Kosten einer Website-Vorschau werden vor der Videokodierung aus der erfassten Seitenhöhe berechnet. Berechnete Credits werden automatisch zurückgebucht, wenn die Arbeit fehlschlägt. Cache-Treffer und QR-Anfragen verbrauchen keine Credits; QR-Anfragen erscheinen aber weiterhin in den Nutzungsdaten.
| Tarif | Credits pro Monat | Preis | Pro Credit |
|---|---|---|---|
| Free | 250 | Kostenlos | Entfällt |
| Hobby | 5.000 | 9 £ | 0,180 Pence |
| Pro | 15.000 | 19 £ | 0,127 Pence |
| Scale | 50.000 | 49 £ | 0,098 Pence |
Höhere Tarife haben einen niedrigeren Preis pro Einheit. Scale liegt pro Credit 46 % unter Hobby. Ist die Obergrenze erreicht, pausiert die Arbeit mit 429 quota_exhausted; Kosten für Mehrverbrauch entstehen nicht. Bezahlte Konten messen die Nutzung zwischen den Abrechnungsstichtagen, wobei period das Startdatum des Zyklus zeigt. Kostenlose Konten messen die Nutzung pro Kalendermonat.
Badge im kostenlosen Tarif
Screenshots, Vorlagenbilder, PDFs und Clips aus dem kostenlosen Tarif tragen ein kleines Ironfang-Render-Badge in der unteren Ecke. Jeder bezahlte Tarif entfernt es. Kostenlose und bezahlte Tarife nutzen dieselben Endpunkte, dieselbe Render-Infrastruktur und dieselben Produktfunktionen.
Es richtet sich nach Ihrem Tarif; es gibt also kein Anfragefeld, um es ein- oder auszuschalten. Clips setzen es unten links, sodass unten rechts Platz für Ihr eigenes watermark bleibt.
Ratenlimits
Zwei Ratenlimits gelten unabhängig vom monatlichen Kontingent des Tarifs. Jedes Rendering kann mehrere Anfragen an die Zielseite auslösen; diese Limits schützen daher sowohl die Zielwebsite als auch den Dienst Ironfang Render.
- 60 Renderings pro Minute und Ziel-Host, gezählt über alle Kunden. Bei Überschreitung lautet die Antwort
429mittarget_rate_limited. - 120 Renderings pro Minute und Konto. Bei Überschreitung lautet die Antwort
429mitrate_limited.
Cache-Treffer zählen für keines der beiden Limits, weil sie keinen Verkehr zum Ziel erzeugen. Eine durch ein Ratenlimit blockierte Anfrage verbraucht keine Credits. Wenden Sie sich an Ironfang, wenn Sie für eine eigene Website ein höheres Limit brauchen.
Antwort-Header
Jedes gerenderte Asset meldet die Zeiten der Anfrage. X-Renderwolf-Render-Ms enthält die serverseitige Renderzeit, X-Renderwolf-Delay-Ms den angeforderten Anteil von delay_ms. Cache-Treffer tragen X-Renderwolf-Cache: hit, frische Aufnahmen X-Renderwolf-Captured-At.
X-Renderwolf-Credits meldet die Credits, die jeder abgerechnete Endpunkt verbraucht hat. Protokollieren Sie diesen Wert, um die Nutzung pro Anfrage zu verfolgen, ohne /v1/usage abzufragen. Cache-Treffer melden 0.
Caching
Identische Render-Anfragen, die aus dem Cache bedient werden, verbrauchen keine Credits. Cache-Treffer tragen den Header X-Renderwolf-Cache: hit und verringern das Kontingent des Tarifs nicht. Assets werden mit Cache-Control: public, max-age=3600 ausgeliefert, sodass Browser und CDNs sie eine Stunde lang vorhalten können. Das Bearbeiten einer Vorlage macht ihren Cache sofort ungültig.
Setzen Sie "no_cache": true, wenn ein Workflow eine neue Aufnahme braucht, etwa zur Sicherung von Nachweisen, zur Archivierung oder zur Überwachung von Änderungen. Damit wird der Cache umgangen. Die Antwort enthält X-Renderwolf-Captured-At mit dem Aufnahmezeitpunkt in UTC und Cache-Control: no-store, damit nachgelagert nichts gecacht wird. Neue Aufnahmen verbrauchen das normale Credit-Kontingent.
Fehler
Jede Antwort trägt X-Ironfang-Request-ID, und Fehler-Bodys wiederholen sie als request_id. Nennen Sie sie, wenn Sie den Support kontaktieren, dann finden wir genau diese Anfrage. Senden Sie Ihre eigene X-Request-ID (druckbares ASCII ohne Leerzeichen, bis zu 128 Zeichen), wird sie unverändert als separater Korrelationswert zurückgegeben.
Jeder Fehler ist JSON mit einem stabilen, maschinenlesbaren Code:
{
"error": {
"code": "quota_exhausted",
"message": "monthly credits exhausted - upgrade your plan or wait for the period to reset",
"docs": "https://ironfang.uk/render/docs#errors"
},
"request_id": "01a0c375-71de-7a40-8e19-2c7b5d9f0a63"
}docs ist ein Link auf diesen Abschnitt, und request_id ist die X-Ironfang-Request-ID der Antwort, die den Fehler enthielt.
| Status | Code | Bedeutung |
|---|---|---|
| 400 | bad_request | Fehlerhaftes JSON oder ungültige Parameter. |
| 401 | invalid_api_key | Fehlender oder unbekannter API-Schlüssel. |
| 403 | bad_signature | Die signierte URL hat die Prüfung nicht bestanden oder ist abgelaufen. |
| 404 | not_found | Die Vorlage, der Job, der Batch, das Ziel, die Zustellung oder die signierte Route existiert in dieser Organisation nicht. |
| 422 | render_failed | Chromium konnte das Ziel nicht rendern: ungültige URL, blockierte private Adresse oder Timeout beim Warten auf den Selektor. |
| 429 | quota_exhausted | Monatliche Obergrenze erreicht. Wechseln Sie in einen höheren Tarif oder warten Sie, bis der Zeitraum neu beginnt. |
Maschinenschnittstellen
| Schnittstelle | Details |
|---|---|
| Produktseite | https://ironfang.uk/render |
| Dokumentation | https://ironfang.uk/render/docs |
| Basis-URL der API | https://api.ironfang.uk/render |
| OpenAPI-Vertrag | https://api.ironfang.uk/render/openapi.yaml. Derselbe Vertrag wird als JSON unter https://api.ironfang.uk/render/openapi.json bereitgestellt. |
| Authentifizierung | Plattform-API-Schlüssel als Bearer-Token |
| Fehler | https://ironfang.uk/render/docs#errors. Ein JSON-Body mit einem stabilen Code, einer Meldung, diesem Link und der Anfrage-ID. |
| MCP | Verfügbar. Screenshots, PDFs, QR-Codes, Vorlagen-Renderings, Clips, Batches, signierte Render-URLs, Ziele für Webhook-Zustellungen, Jobs und Nutzung. Speicherziele enthalten Zugangsdaten und bleiben im Portal. Die Tools heißen render.*. Referenz des MCP-Servers; jedes Tool und jedes Schema ohne Token unter /.well-known/ironfang-mcp.json |
| Auffindbarkeit | /apis.json, /.well-known/api-catalog und /llms.txt |
Gestartet als Renderwolf. Dieser Name lebt nur in Kompatibilitätskennungen weiter: Der API-Pfad-Alias https://api.ironfang.uk/renderwolf, das Scope-Präfix renderwolf: und die folgenden Kennungen funktionieren weiter und sind Aliasse der aktuellen Namen.
- HTTP-Antwort-Header X-Renderwolf-*
- Webhook-Header Renderwolf-Signature, Renderwolf-Timestamp und Renderwolf-Event-Id
- Standard-Präfix für Speicherschlüssel renderwolf/
- Pakete @ironfang/renderwolf (npm) und ironfang-renderwolf (PyPI)
- Repository ironfang-ltd/renderwolf-action

