Aller au contenu

Ironfang Render

Référence de l'API

Retrouvez les endpoints, les paramètres de requête, l'authentification, les quotas, les en-têtes de réponse et les codes d'erreur de l'API Ironfang Render.

Démarrage rapide

Tous les endpoints utilisent https://api.ironfang.uk/render comme URL de base. Le nom du produit figure dans le chemin parce que api.ironfang.uk héberge toutes les API Ironfang. L'ancien chemin sans préfixe, https://api.ironfang.uk/v1/, reste pris en charge pour les endpoints qui y ont été publiés auparavant. Les nouveaux endpoints utilisent l'URL de base du produit. Créez une clé API dans le portail, puis réalisez votre première capture d'écran :

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.png

Les requêtes de rendu réussies renvoient directement le fichier binaire en image/png, image/jpeg ou application/pdf. Les clips renvoient video/mp4. Les aperçus de site renvoient une réponse multipart contenant une affiche JPEG et une vidéo MP4. Les autres endpoints, en cas de succès, et toutes les réponses d'erreur renvoient du JSON.

Bibliothèques clientes

Des clients officiels encapsulent la même API, avec requêtes typées, vérification des webhooks et téléchargement des résultats :

npm install @ironfang/renderwolf    # TypeScript, Node 20+
pip install ironfang-renderwolf     # Python

Il existe aussi une CLI autonome : des binaires uniques pour Linux, macOS et Windows, avec sommes de contrôle, disponibles sur github.com/ironfang-ltd/cli.

Postman

Chaque endpoint figure dans une collection Postman publique générée à partir du contrat OpenAPI, avec un dossier "Getting started" dont la première requête ne nécessite aucune clé.

Exécuter dans PostmanVoir la collection

Authentification

Envoyez votre clé API comme jeton bearer avec chaque requête : Authorization: Bearer if_live_.... Créez et révoquez vos clés dans le portail. Le secret est affiché une seule fois, à la création de la clé, et il est stocké sous forme de hachage. Une clé absente ou inconnue renvoie 401 invalid_api_key.

Portées

Une clé API Ironfang peut donner accès à plusieurs produits. Choisissez ses portées lors de sa création. Les portées ne peuvent pas être étendues par la suite : créez une nouvelle clé lorsqu'un accès plus large est nécessaire. Une requête hors des portées de la clé renvoie 403 insufficient_scope et indique la portée manquante.

  • render:renderCaptures d'écran, PDF, images, clips et aperçus de site
  • render:signCréer des URL de rendu signées
  • render:templates:readLire les modèles enregistrés
  • render:templates:writeCréer, modifier et supprimer des modèles
  • render:usage:readLire l'utilisation par rapport au quota

Les clés créées avant l'introduction des portées n'en ont aucune et conservent un accès complet, par souci de rétrocompatibilité. Les nouvelles clés sont toujours créées avec des portées explicites.

POST /v1/screenshot

Capture une URL ou du HTML brut avec une instance Chromium déjà démarrée. Consomme 1 crédit.

ChampTypeRemarques
urlstringPage à capturer. Fournissez url ou html, pas les deux. Les cibles situées sur un réseau privé sont bloquées.
htmlstringHTML brut à capturer à la place d'une URL.
widthintLargeur du viewport. Par défaut : 1280.
heightintHauteur du viewport. Par défaut : 800.
devicestringdesktop, tablet ou mobile. Chaque préréglage applique un viewport, une densité de pixels et un user agent. Voir Appareils.
full_pageboolCapture toute la hauteur de défilement au lieu du seul viewport.
selectorstringSélecteur CSS pour capturer un seul élément.
dark_modeboolÉmule prefers-color-scheme: dark.
formatstringpng (par défaut), jpeg ou webp. WebP peut produire un fichier plus léger que PNG pour la même capture.
qualityintQualité JPEG et WebP de 1 à 100. Par défaut : 85.
delay_msintTemps d'attente supplémentaire après le chargement, pour les contenus affichés tardivement.
no_cacheboolForce une nouvelle capture en ignorant tout rendu en cache. Décompté de votre quota. Voir Cache.
clipobject{ x, y, width, height } en pixels CSS depuis le coin supérieur gauche. Ce champ est ignoré lorsque selector est défini, car le sélecteur détermine alors la zone capturée.
omit_backgroundboolUtilise un fond transparent au lieu du fond de la page. Ce champ est ignoré pour jpeg, qui n'a pas de canal alpha.
full_page_max_heightintLimite une capture full_page. Sans cette limite, une page à défilement infini n'a pas de fin naturelle.

Avant la capture, Ironfang Render attend les polices web, amène les animations et transitions CSS à leur état final et masque les barres de défilement. Les animations en boucle continuent de tourner.

Les sites protégés contre les robots peuvent servir une page de vérification aux navigateurs automatisés. Ironfang Render renvoie le contenu fourni par le site et ne tente pas de contourner la vérification.

Utilisez delay_ms lorsque le contenu continue de s'afficher après la stabilisation habituelle de la page. Exemples courants : les tableaux de bord qui chargent leurs données après le chargement de la page et les pages animées par des bibliothèques JavaScript comme GSAP.

Si des éléments manquent ou sont à moitié estompés dans votre capture, essayez delay_ms entre 500 et 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.png

Appareils

Le champ device applique ensemble un viewport, une densité de pixels, une identité mobile et un user agent. L'émulation de l'appareil est ainsi plus fidèle qu'en modifiant seulement la largeur du viewport.

AppareilViewportDensité de pixelsTaille de l'image
desktop1280 × 8001×1280 × 800
tablet820 × 11802×1640 × 2360
mobile390 × 8443×1170 × 2532

Les dimensions du viewport sont en pixels CSS. Un width ou un height explicite remplace la valeur correspondante du préréglage. Un nom d'appareil inconnu renvoie une erreur de validation.

Les préréglages utilisent l'émulation d'appareils de Chromium. Ils ne contournent pas les protections contre les robots : un site peut donc toujours renvoyer une page de vérification.

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.webp

Options communes à tous les rendus

Ces options s'appliquent aux captures d'écran, aux PDF et aux aperçus de site. Omettre une option conserve le comportement par défaut de la réponse.

Blocage

Les publicités et les traqueurs sont bloqués en tant que requêtes réseau, avant leur chargement. Les bannières de consentement sont des éléments insérés dans la page par des scripts : Ironfang Render masque donc les bannières prises en charge en CSS, après le chargement de la page.

ChampTypeRemarques
block_adsboolEmpêche les requêtes vers les réseaux publicitaires et de suivi connus. Ironfang Render utilise une liste de blocage ciblée pour limiter le risque de supprimer des ressources nécessaires à la page.
block_cookie_bannersboolMasque les frameworks de consentement pris en charge et lève leurs blocages du défilement. Les captures full_page peuvent ainsi dépasser un viewport. Ironfang Render ne clique sur aucun bouton d'acceptation et n'enregistre aucun consentement.
hide_selectorsstring[]Sélecteurs CSS des éléments à masquer. Appliqués après le chargement, ils couvrent aussi les éléments injectés par script.

CSS, JavaScript et actions de page personnalisés

Masquez un widget, ajustez les styles d'impression, sélectionnez un onglet ou dépliez un contenu avant une capture d'écran ou un PDF. Ces options fonctionnent avec une URL ou avec du HTML fourni, y compris dans les tâches en file d'attente et les lots.

Après le chargement normal de la page et les conditions d'attente, Ironfang Render applique le masquage intégré, puis votre css, attend votre script et exécute les actions dans l'ordre. La stabilisation et la capture viennent ensuite. Le wait_for_selector de premier niveau s'exécute avant ces contrôles ; utilisez une action de sélecteur pour attendre un contenu produit par une interaction.

ChampTypeLimites et comportement
cssstringUne feuille de style d'au plus 65 536 octets UTF-8. Prend en charge les ajustements de mise en page, les éléments masqués, les animations désactivées et @media print. Une syntaxe incorrecte renvoie 400 bad_request avant le rendu. Chromium détermine les noms et valeurs de propriétés pris en charge.
scriptstringDu JavaScript d'au plus 16 384 octets UTF-8, exécuté dans le contexte du cadre principal de la page cible comme corps d'une fonction async. Utilisez await ou renvoyez une promesse pour un travail asynchrone. L'exécution est limitée à cinq secondes ou au délai de rendu restant, selon le plus court. Les valeurs renvoyées sont ignorées.
actionsobject[]Jusqu'à 20 actions ordonnées, qui se partagent le budget restant de timeout_ms. Les sélecteurs ciblent la première correspondance dans la page principale et sont limités à 1 024 octets UTF-8.
Type d'actionChamp requisComportement
clickselectorAttend un élément interactif et activé, puis clique dessus.
hoverselectorAttend un élément interactif et place le pointeur dessus.
wait_for_selectorselectorAttend qu'un élément existe ; il peut être masqué.
delayduration_msAttend de 0 à 10 000 ms. Au total, les délais de toutes les actions ne peuvent pas dépasser 10 000 ms.

Cet exemple autonome masque un widget, modifie le titre et déplie le détail des tarifs avant la capture. Remplacez html par url et utilisez les sélecteurs de votre site pour capturer une page existante.

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]" }
  ]
}
JSON

Utilisez /v1/pdf et --output expanded.pdf pour obtenir le même état de page en PDF. Pour du JavaScript asynchrone, utilisez une opération attendue avec await, par exemple await new Promise(resolve => setTimeout(resolve, 250));. Pour une interface qui apparaît plus tard, faites suivre l'interaction d'une action de sélecteur.

Les entrées non valides renvoient 400 bad_request. Les erreurs de syntaxe du script, les échecs d'exécution et les dépassements de délai renvoient 422 render_failed avec un message nettoyé. Les erreurs d'action indiquent l'index (à partir de zéro) et le type, par exemple actions[0] (click), et interrompent la liste. Les rendus échoués sont remboursés ; les tâches en file d'attente ne réessaient pas ces échecs d'interaction.

Ces options et l'ordre des actions font partie de la clé de cache des captures d'écran. Une réponse servie depuis le cache renvoie l'image précédente sans exécuter à nouveau les contrôles ; définissez no_cache: true pour une nouvelle exécution. Les scripts et les clics peuvent modifier l'état de l'application cible. L'API expose des extraits de code exécutés dans le contexte de la page et ces quatre actions ; elle ne fournit ni sessions de navigateur ni API Playwright/Puppeteer.

En-têtes, cookies et identifiants

Ironfang Render applique les en-têtes, les cookies et les identifiants avant la navigation, afin qu'ils soient présents dès la première requête vers la page cible.

ChampTypeRemarques
headersobjectEn-têtes HTTP supplémentaires, envoyés avec chaque requête de la page.
authorizationstringDéfinit l'en-tête Authorization. Une entrée Authorization explicite dans headers est prioritaire.
cookiesobject[]{ name, value, domain, path }. domain est obligatoire, car Chromium ignore un cookie sans domaine défini avant la navigation.
user_agentstringRemplace le user agent, y compris celui défini par device.

Les cibles situées sur un réseau privé restent bloquées lorsque des identifiants sont fournis. La protection contre la SSRF s'exécute avant l'application des données d'authentification.

Attente

ChampTypeRemarques
wait_untilstringload (par défaut), domcontentloaded ou networkidle. networkidle attend la fin du trafic et est borné par le délai de rendu, car une page qui interroge régulièrement le serveur n'est jamais vraiment inactive.
wait_for_selectorstringAttend cet élément avant la capture. La requête échoue si l'élément n'apparaît pas avant l'expiration du délai.
timeout_msintDélai par rendu. Les valeurs supérieures au maximum du service sont ramenées à ce maximum.
device_scale_factornumberDensité de pixels, de 1 à 3. 2 correspond au retina : la même taille CSS avec deux fois plus de pixels.
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.png

POST /v1/pdf

Imprime une URL ou du HTML brut en PDF. Chaque PDF généré avec succès consomme 2 crédits.

ChampTypeRemarques
urlstringPage à imprimer. Fournissez url ou html.
htmlstringHTML brut à imprimer à la place d'une URL.
landscapeboolOrientation paysage.
print_backgroundboolInclure les arrière-plans CSS.
header_htmlstringModèle d'en-tête Chromium. Définir l'un ou l'autre modèle active les en-têtes et les pieds de page : si vous n'envoyez qu'un pied de page, envoyez donc un en-tête vide, par exemple <span></span> ; sinon, Chromium imprime son en-tête par défaut avec la date et le titre.
footer_htmlstringModèle de pied de page Chromium. Les classes pageNumber, totalPages, date, title et url sont remplies. Les modèles n'héritent pas des styles de la page : définissez une taille de police dans chacun.
scalefloatÉchelle d'impression. Par défaut : 1,0.
no_cacheboolAccepté, sans effet ici : les PDF ne sont jamais mis en cache, chaque requête génère donc le document à nouveau.
paper_formatstringa3, a4, a5, letter, legal ou tabloid. En l'absence de valeur, Chromium utilise son format par défaut, Letter. Les formats sont en portrait ; landscape les fait pivoter.
marginobject{ top, right, bottom, left } en pouces. Les côtés omis conservent la marge par défaut de 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.pdf

POST /v1/qr

Générez des QR codes personnalisés vérifiés avant livraison. Ironfang Render décode chaque image terminée et la compare aux données fournies. Un échec de vérification renvoie 422 unscannable. Les requêtes QR sont gratuites dans toutes les offres, y compris dans les modèles. Elles apparaissent dans les relevés d'utilisation, mais ne consomment aucun crédit et restent disponibles une fois la limite de l'offre atteinte.

ChampTypeRemarques
datastringDonnées obligatoires : une URL, une chaîne WiFi ou un texte d'au plus 1 Ko.
sizeintTaille de sortie carrée de 64 à 2048 pixels. Par défaut : 512. PNG uniquement.
eccstringCorrection d'erreurs : L, M, Q ou H. Par défaut : M. L'ajout d'un logo sélectionne automatiquement H pour compenser les modules couverts par le logo.
dark / lightstringCouleurs hexadécimales. dark doit être plus foncée que light et respecter le contraste minimal requis. Les combinaisons non valides renvoient une réponse 400. light accepte aussi transparent. Placez les codes transparents sur un fond clair.
dotsstringsquare ou circle. Les motifs de repérage sont toujours dessinés pleins afin de préserver leur structure obligatoire.
eyesstringsquare ou rounded. Par défaut, identique à dots.
marginintZone de silence de 0 à 8 modules. Par défaut : 4.
invertboolCrée des modules clairs sur un fond sombre. Les appareils photo des téléphones récents lisent souvent les codes inversés, mais beaucoup de lecteurs embarqués ou intégrés aux applications ne les lisent pas. Avec cette option, dark doit être plus claire que light. Ironfang Render vérifie le résultat à partir de son négatif.
logostringLogo central sous forme d'URI data: en base64, png ou jpeg. Incompatible avec logo_url.
logo_urlstringLogo central fourni par URL. L'URL est soumise à la même protection des cibles et aux mêmes limites de débit qu'une requête de capture d'écran.
logo_sizefloatTaille de la zone du logo, en fraction du symbole, de 0,12 à 0,30. Par défaut : 0,22.
logo_padboolAjoute une zone de réserve derrière le logo pour le séparer des modules du QR code. Par défaut : 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.png

Pour inclure un QR code dans un modèle enregistré, utilisez l'objet qr des rendus de modèles. Les QR codes ne portent pas le badge de l'offre gratuite, car une marque ajoutée pourrait gêner la lecture.

POST /v1/video

Un clip : un arrière-plan, des textes qui apparaissent selon un calendrier, un filigrane facultatif et une piste audio facultative. Renvoie video/mp4.

Ironfang Render génère de courts clips à partir de données structurées pour les processus de contenu automatisés. Les requêtes utilisent la même clé API, le même quota et les mêmes intégrations que les autres types de rendu.

ChampTypeRemarques
sizestringvertical 1080×1920 (par défaut), square 1080×1080, landscape 1920×1080, 720p 1280×720.
durationnumberDurée de la sortie en secondes, de 1 à 60. Par défaut : 15.
captionsarrayJusqu'à 12 cartons de la forme {text, from, to}, en secondes. Le texte peut contenir des guillemets, des deux-points et des parenthèses.
colourstringCouleur de fond hexadécimale, utilisée lorsqu'aucun background n'est fourni. Par défaut : #101820.
backgroundstringURL d'une image ou d'une vidéo, recadrée pour remplir le cadre.
watermarkstringURL d'un PNG, placé en bas à droite.
audiostringURL d'une piste audio, coupée à la durée du clip.
font_sizeintTaille des textes en pixels. Par défaut, un quinzième de la largeur.
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.mp4

Consommation de crédits

Les clips verticaux et paysage consomment un crédit par seconde. Les clips carrés consomment 0,6 crédit par seconde, et les clips 720p 0,5 crédit par seconde. Le total est arrondi au crédit entier le plus proche, avec un minimum d'un crédit. Un clip vertical de 15 secondes consomme 15 crédits, et le même clip en 720p en consomme 8. Le travail échoué est remboursé, et les requêtes identiques servies depuis le cache ne consomment aucun crédit.

Limites de fonctionnement

Les clips sont générés pendant la requête et limités à 60 secondes. Les fichiers référencés passent par les mêmes contrôles d'URL que les cibles de capture d'écran et sont limités à 64 Mo chacun. Les fichiers d'arrière-plan doivent être accessibles depuis l'internet public.

Les clips sont limités à 60 secondes. /v1/video génère un clip dans la requête ; pour le mettre plutôt en file d'attente et être prévenu par webhook quand il est prêt, soumettez-le comme tâche, comme décrit plus bas. Les clips plus longs ne sont pas pris en charge pour le moment.

POST /render/v1/site-preview

Transformez une page web publique en aperçu du haut vers le bas. Choisissez un balayage continu ou des étapes de la taille du viewport, avec un mouvement vif qui se pose sur une courte pause de lecture. Une requête renvoie une affiche JPEG tirée de la première image et une vidéo MP4 H.264 enregistrée dans le navigateur. Les éléments fixes et collants (sticky) se comportent comme lors d'un vrai défilement.

Cet endpoint est disponible uniquement à l'adresse https://api.ironfang.uk/render/v1/site-preview.

ChampTypeRemarques
urlstringPage HTTP ou HTTPS publique à enregistrer. Obligatoire.
widthintLargeur de sortie paire, de 320 à 1280. Par défaut : 672.
heightintHauteur de sortie paire, de 240 à 1200. Par défaut : 494. L'image est limitée à 1 200 000 pixels.
motionstringper_page pour des étapes de la taille du viewport avec pauses, ou single_sweep pour un seul passage continu. Par défaut : per_page.
devicestringdesktop, tablet ou mobile.
dark_modeboolEnregistre avec le jeu de couleurs sombre de la page. Par défaut : false.
no_cacheboolForce un nouvel enregistrement. Par défaut : false.

Appelez cet endpoint depuis votre serveur, jamais depuis du code exécuté dans le navigateur : la requête contient votre clé API, et tout ce qui est envoyé à un navigateur est public. Pour un aperçu déclenché par un visiteur, créez plutôt une URL signée côté serveur.

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/mp4

Sortie et crédits

La réponse est en multipart/form-data, avec les parties nommées poster et video. La vidéo est un MP4 H.264 à 60 images par seconde, avec une affiche JPEG tirée de la première image. Ironfang Render calcule la durée à partir de la hauteur de la page et du mouvement, dans la limite de 60 secondes fixée par le serveur. Les aperçus de site consomment un crédit par seconde de sortie, arrondi au supérieur. L'affiche est incluse. Le travail échoué est remboursé, et les requêtes identiques servies depuis le cache ne consomment aucun crédit.

Modèles

Enregistrez du HTML réutilisable et générez-en des images avec différentes variables : images Open Graph, cartes pour les réseaux sociaux et autres ressources dynamiques. Les variables utilisent des espaces réservés {{name}}. Les valeurs substituées sont échappées en HTML pour empêcher toute injection de balisage. La gestion des modèles est gratuite ; chaque image générée avec succès consomme un crédit. Les identifiants sont des UUIDv7 et se trient par date de création.

EndpointObjet
POST /v1/templatesCréer. Corps : name, html (256 Ko max.), width, height (par défaut 1200×630, au plus 4096).
GET /v1/templatesLister vos modèles.
GET /v1/templates/{id}Récupérer un modèle.
PUT /v1/templates/{id}Mettre à jour. Les modifications invalident automatiquement le cache de rendu.
DELETE /v1/templates/{id}Supprimer.
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}

Génère une image à partir d'un modèle enregistré et des variables fournies. Chaque image générée avec succès consomme 1 crédit. Les requêtes identiques servies depuis le cache ne consomment aucun crédit.

ChampTypeRemarques
varsobjectTable de chaînes qui remplit les {{placeholders}} du modèle. Les variables manquantes restent vides.
no_cacheboolForce une nouvelle capture en ignorant tout rendu en cache. Décompté de votre quota. Voir Cache.
formatstringpng (par défaut), jpeg ou webp. WebP peut produire un fichier plus léger que PNG pour le même résultat.
qrobjectSpécifications de QR codes nommées, jusqu'à 4, chacune de la forme du corps de /v1/qr. Chaque entrée est générée, vérifiée par lecture et injectée comme variable {{qr.<name>}} contenant une URI data à utiliser dans un élément <img>. Les QR codes intégrés n'ajoutent aucun coût à l'image.
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.png

Pour un emplacement de QR code, placez <img src="{{qr.pay}}" width="150"> dans le modèle :

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.png

URL signées

Créez une URL GET stable à utiliser dans un élément <img> ou une balise meta og:image. L'URL n'expose pas la clé API et ne nécessite pas de proxy applicatif. Sa signature couvre chaque paramètre et le compte utilisé pour la facturation, ce qui empêche toute modification après la signature.

POST /v1/sign avec :

ChampTypeRemarques
kindstringscreenshot ou image.
urlstringPage cible (kind: screenshot).
templatestringIdentifiant du modèle (kind: image).
varsobjectVariables du modèle (kind: image).
width / heightintDimensions facultatives.
full_pageboolCaptures d'écran uniquement.
ttl_hoursintExpiration. 0 = n'expire jamais.

La réponse contient l'url complète (et son path). L'appeler déclenche le rendu à la demande, décompté sur votre compte. Les appels répétés d'un résultat identique en cache ne consomment aucun crédit.

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"}

Tâches

Chaque rendu ci-dessus peut aussi s'exécuter sous forme de tâche durable : vous la soumettez, recevez aussitôt un 202, interrogez son état jusqu'à ce qu'elle se termine, puis récupérez le résultat. Utilisez les tâches pour les clips, les pages lentes et partout où vous préférez ne pas garder une connexion ouverte. Les endpoints synchrones restent inchangés.

POST /render/v1/jobs
            Idempotency-Key: catalogue-42-v1

            {
              "kind": "screenshot",
              "request": { "url": "https://example.com", "full_page": true },
              "external_id": "catalogue-42"
            }

kind vaut screenshot, pdf, qr, image, clip ou site_preview, et request est exactement le corps de l'endpoint correspondant (une tâche image nomme son template dans request). La soumission est validée comme l'endpoint synchrone la validerait, avant toute facturation.

Suivi et résultats

GET /render/v1/jobs/{id} renvoie la tâche avec un status parmi queued, running, cancellation_requested, succeeded, failed ou cancelled. Une tâche réussie contient result (type de contenu, taille, SHA-256, expiration) et une url signée qui ne nécessite pas de clé API et reste valable 15 minutes ; GET .../result redirige vers une nouvelle URL. Le résultat hébergé est conservé en privé pendant 24 heures après le succès, puis supprimé : il s'agit d'une fenêtre de récupération, pas d'un hébergement de ressources. Conservez de votre côté ce dont vous avez besoin.

Idempotence, annulation et crédits

Envoyez Idempotency-Key à chaque soumission. La même clé avec la même requête renvoie la tâche existante ; la même clé avec une requête différente produit 409 idempotency_conflict. DELETE .../jobs/{id} annule : une tâche en attente s'arrête aussitôt, une tâche en cours à son prochain point sûr.

Le coût maximal d'une tâche est réservé lorsqu'elle est acceptée et réglé lorsqu'elle se termine. Un aperçu de site réserve le plafond de 60 secondes et libère la différence une fois la page mesurée. Le travail échoué est remboursé. Une tâche en attente s'annule gratuitement ; une tâche en cours n'est facturée que si elle a produit un résultat utilisable. Les échecs temporaires sont réessayés jusqu'à trois fois avec un délai croissant ; une page dont le rendu est impossible échoue aussitôt, avec la raison.

Lots

Jusqu'à 100 tâches en une seule soumission : une requête default commune et des items qui en remplacent certaines parties. Pratique lorsque vous disposez en fait d'une liste d'URL et d'un seul jeu d'options.

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" } }
              ]
            }

La fusion se fait sur un seul niveau : le champ d'un élément l'emporte, tout le reste provient de la valeur par défaut. Un élément peut aussi remplacer kind et porter sa propre delivery.

Un lot est accepté ou refusé en entier. Chaque élément est validé avant qu'aucun ne soit enregistré, et les crédits de tous les éléments sont réservés en une seule transaction. Un lot qui dépasserait vos crédits mensuels revient donc avec 429 quota_exhausted, sans rien facturer et sans laisser de tâche derrière lui. Une erreur de validation nomme l'élément dont elle provient.

Les éléments sont des tâches ordinaires : interrogez-les une par une, ou interrogez GET /render/v1/batches/{id} pour obtenir les counts par état, done et la ressource complète de chaque tâche. Il n'existe pas d'archive ZIP des résultats : configurez une destination de stockage si vous voulez réunir les sorties au même endroit, ce qui est aussi la seule solution qui fonctionne lorsque le lot compte 100 clips.

Livraison

Une tâche peut faire plus qu'attendre d'être récupérée. Enregistrez une destination, c'est-à-dire un endpoint de webhook ou votre propre bucket compatible S3, et désignez-la par son identifiant depuis n'importe quelle tâche. Les identifiants d'accès nous sont envoyés une seule fois, à la création de la destination, et ne transitent jamais dans le corps d'une tâche.

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" }

Le secret de signature n'est affiché qu'une seule fois. Nous n'en conservons qu'une copie chiffrée : aucun endpoint ne peut donc vous le renvoyer plus tard ; si vous le perdez, créez une nouvelle destination. La gestion des destinations nécessite la portée render:destinations.

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"
              }
            }

Webhooks signés

Une destination de webhook est appelée lors de render.job.succeeded, render.job.failed et render.job.cancelled. Le corps contient la tâche, ses crédits et, en cas de succès, le type de contenu, la taille et le SHA-256 du résultat ainsi qu'une url signée, valable 15 minutes à compter de l'envoi, et non de la fin de la tâche.

Vérifiez la signature sur les octets bruts reçus, et non sur ce que vous avez analysé puis sérialisé à nouveau :

expected = "v1=" + hmac_sha256(secret, timestamp + "." + raw_body).hexdigest()
            compare(expected, headers["Renderwolf-Signature"])   # constant time

Renderwolf-Timestamp est exprimé en secondes Unix ; rejetez tout ce qui date de plus de quelques minutes pour empêcher un rejeu. Renderwolf-Event-Id reste identique d'une tentative à l'autre pour une même livraison : utilisez-le pour rendre votre gestionnaire idempotent.

Les nouvelles tentatives suivent une progression d'une minute jusqu'à un jour, avec une variation aléatoire, et respectent un Retry-After borné. Nous réessayons en cas de 408, 429 et 5xx ; les autres 4xx arrêtent immédiatement les tentatives, car votre endpoint indique ainsi qu'une nouvelle tentative ne servirait à rien. Après 10 échecs consécutifs, la destination est désactivée jusqu'à ce que vous la réactiviez dans le portail.

Livraison dans votre propre bucket

Une destination s3 prend un bucket, une région, des identifiants d'accès et, en option, un endpoint et un prefix. Tout service compatible S3 fonctionne : AWS, Cloudflare R2, MinIO, Ceph. Limitez les identifiants d'accès au préfixe que vous nous indiquez : ils n'ont besoin d'écrire que là.

storage_key est la clé d'objet relative à ce préfixe. Elle accepte du texte fixe ainsi que {job_id}, {external_id} et {date} (YYYY/MM/DD), aucun autre champ, et rien n'est évalué. Par défaut, elle vaut renderwolf/{date}/{job_id}. Une clé qui sortirait du préfixe est refusée dès la soumission de la tâche, plutôt que d'être discrètement réécrite en une autre clé.

Chaque envoi reçoit une somme de contrôle et est vérifié après l'écriture ; un objet déjà présent avec la même somme de contrôle est laissé tel quel. Une livraison réessayée ne change donc rien, au lieu d'écrire une seconde fois.

La livraison ne modifie jamais un rendu

C'est sur ce point que vous pouvez compter. Une tâche dont le rendu a abouti est succeeded, quoi que votre endpoint ait fait ensuite : un webhook injoignable ne consomme pas de tentative de rendu, n'occupe pas d'emplacement de rendu et ne transforme pas une tâche réussie en échec. Les livraisons sont réessayées selon leur propre progression, et GET /render/v1/deliveries montre où en est chacune.

Si une livraison vers le stockage abandonne, la destination de webhook en est informée par un événement render.delivery.failed qui nomme la destination et l'erreur. C'est ainsi que vous apprenez qu'un bucket n'accepte plus les envois, sans devoir guetter des fichiers manquants.

Guides pratiques

Ces guides de bout en bout couvrent les processus courants avec Ironfang Render.

Choisissez un démarrage rapide pour Python, Node.js, PHP ou Go.

GET /v1/usage

Votre consommation actuelle par rapport à la limite stricte de votre offre :

{"period": "2026-08", "credits": 1240, "renders": 1240, "limit": 50000}

renders reprend credits sous le nom avec lequel cette API a été lancée. Ce champ est obsolète et sera supprimé une fois les migrations des connecteurs terminées. Les nouvelles intégrations doivent lire credits.

Crédits

Une capture d'écran ou une image générée consomme un crédit, un PDF deux crédits. Les aperçus de site consomment un crédit par seconde de sortie, affiche comprise. La consommation des clips dépend de leur durée et de leur taille de sortie. La plupart des travaux réservent des crédits avant le rendu. Le coût d'un aperçu de site est calculé à partir de la hauteur de page capturée, avant l'encodage vidéo. Les crédits facturés sont restitués automatiquement si le travail échoue. Les réponses servies depuis le cache et les requêtes QR ne consomment aucun crédit, mais les requêtes QR apparaissent toujours dans les relevés d'utilisation.

OffreCrédits par moisPrixPar crédit
Free250GratuitSans objet
Hobby5 0009 £0,180 pence
Pro15 00019 £0,127 pence
Scale50 00049 £0,098 pence

Les offres supérieures ont un coût unitaire plus bas. Par crédit, Scale coûte 46 % de moins que Hobby. Atteindre la limite met le travail en pause avec 429 quota_exhausted et n'entraîne aucun dépassement facturé. Les comptes payants mesurent l'utilisation entre deux dates anniversaires de facturation, period indiquant la date de début du cycle. Les comptes gratuits mesurent l'utilisation par mois civil.

Badge de l'offre gratuite

Les captures d'écran, images de modèles, PDF et clips créés avec l'offre gratuite portent un petit badge Ironfang Render dans le coin inférieur. Toutes les offres payantes le retirent. Les offres gratuite et payantes utilisent les mêmes endpoints, la même infrastructure de rendu et les mêmes fonctionnalités.

Il dépend de votre offre : aucun champ de requête ne permet donc de l'ajouter ou de le retirer. Les clips le placent en bas à gauche, ce qui laisse le coin inférieur droit à votre propre watermark.

Limites de débit

Deux limites de débit s'appliquent indépendamment du quota mensuel de l'offre. Chaque rendu peut générer plusieurs requêtes vers la page cible : ces limites protègent donc à la fois le site cible et le service Ironfang Render.

  • 60 rendus par minute et par hôte cible, tous clients confondus. Au-delà, la réponse est 429 avec target_rate_limited.
  • 120 rendus par minute et par compte. Au-delà, la réponse est 429 avec rate_limited.

Les réponses servies depuis le cache ne comptent pour aucune des deux limites, car elles n'envoient aucun trafic vers la cible. Une requête bloquée par une limite de débit ne consomme pas de crédits. Contactez Ironfang si vous avez besoin d'une limite plus élevée pour un site qui vous appartient.

En-têtes de réponse

Chaque ressource rendue indique les temps de la requête. X-Renderwolf-Render-Ms contient le temps de rendu côté serveur, et X-Renderwolf-Delay-Ms la part demandée via delay_ms. Les réponses servies depuis le cache portent X-Renderwolf-Cache: hit, et les nouvelles captures X-Renderwolf-Captured-At.

X-Renderwolf-Credits indique les crédits consommés par chaque endpoint facturé. Journalisez cette valeur pour suivre l'utilisation par requête sans interroger /v1/usage. Les réponses servies depuis le cache indiquent 0.

Cache

Les requêtes de rendu identiques servies depuis le cache ne consomment aucun crédit. Elles portent l'en-tête X-Renderwolf-Cache: hit et ne réduisent pas le quota de l'offre. Les ressources sont renvoyées avec Cache-Control: public, max-age=3600, afin que les navigateurs et les CDN puissent les conserver une heure. Modifier un modèle invalide immédiatement son cache.

Définissez "no_cache": true lorsqu'un processus exige une nouvelle capture, par exemple pour la collecte de preuves, l'archivage ou la surveillance des modifications. Le cache est alors contourné. La réponse contient X-Renderwolf-Captured-At avec l'heure de capture en UTC et Cache-Control: no-store pour empêcher toute mise en cache en aval. Les nouvelles captures consomment le quota de crédits normal.

Erreurs

Chaque réponse porte X-Ironfang-Request-ID, et les corps d'erreur le reprennent dans request_id. Indiquez-le lorsque vous contactez le support : nous pourrons retrouver la requête exacte. Si vous envoyez votre propre X-Request-ID (ASCII imprimable sans espaces, jusqu'à 128 caractères), il est renvoyé tel quel comme valeur de corrélation distincte.

Chaque erreur est un JSON avec un code stable, lisible par une machine :

{
  "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 est un lien vers cette section, et request_id est le X-Ironfang-Request-ID de la réponse qui contenait l'erreur.

StatutCodeSignification
400bad_requestJSON mal formé ou paramètres non valides.
401invalid_api_keyClé API absente ou inconnue.
403bad_signatureLa vérification de l'URL signée a échoué, ou l'URL a expiré.
404not_foundLe modèle, la tâche, le lot, la destination, la livraison ou la route signée n'existe pas dans cette organisation.
422render_failedChromium n'a pas pu générer le rendu de la cible en raison d'une URL non valide, d'une adresse privée bloquée ou d'un délai dépassé pour le sélecteur.
429quota_exhaustedLimite mensuelle atteinte. Passez à une offre supérieure ou attendez la réinitialisation de la période.

Interfaces pour machines

InterfaceDétails
Page produithttps://ironfang.uk/render
Documentationhttps://ironfang.uk/render/docs
URL de base de l'APIhttps://api.ironfang.uk/render
Contrat OpenAPIhttps://api.ironfang.uk/render/openapi.yaml. Le même contrat est servi en JSON à https://api.ironfang.uk/render/openapi.json.
AuthentificationClé API de la plateforme comme jeton bearer
Erreurshttps://ironfang.uk/render/docs#errors. Un corps JSON avec un code stable, un message, ce lien et l'identifiant de la requête.
MCPDisponible. Captures d'écran, PDF, QR codes, rendus de modèles, clips, lots, URL de rendu signées, destinations de livraison par webhook, tâches et utilisation. Les destinations de stockage contiennent des identifiants et restent dans le portail. Les outils sont nommés render.*. Référence du serveur MCP ; chaque outil et chaque schéma, sans jeton, à /.well-known/ironfang-mcp.json
Découverte/apis.json, /.well-known/api-catalog et /llms.txt

Lancé sous le nom Renderwolf. Ce nom ne subsiste que dans des identifiants de compatibilité : l'alias de chemin d'API https://api.ironfang.uk/renderwolf, le préfixe de scope renderwolf: et les identifiants ci-dessous continuent de fonctionner et sont des alias des noms actuels.

  • En-têtes de réponse HTTP X-Renderwolf-*
  • En-têtes de webhook Renderwolf-Signature, Renderwolf-Timestamp et Renderwolf-Event-Id
  • Préfixe par défaut des clés de stockage renderwolf/
  • Paquets @ironfang/renderwolf (npm) et ironfang-renderwolf (PyPI)
  • Dépôt ironfang-ltd/renderwolf-action