Référence API

API REST JSON, une clé API suffit pour démarrer. Deux modes : hébergé (Shotbot stocke les images) ou callback (images livrées sur votre serveur, marque blanche). Termes obscurs ? Le glossaire les définit.

Envie de jouer avec l'API avant de coder ? Le terrain de jeu en direct génère la requête HTTP et le code dans 6 langages, au fur et à mesure que vous modifiez les paramètres. Tester l'API →
Les captures sont décomptées à la création. L'affichage d'une capture existante est gratuit et non limité.

Par où commencer ?

Shotbot génère et héberge la capture. Vous recevez un token permettant de suivre le statut et de récupérer l'URL directe de l'image.

1. Soumettre une capture

POST https://api.shotbot.net/capture
POST https://api.shotbot.net/capture
Content-Type: application/json

{
  "key":            "votre_clé_api",
  "url":            "https://test.shotbot.fr",
  "format":         "webp",
  "viewport_width": 1280,
  "ratio":          "16:9",
  "wait_time":      15
}

Réponse

JSON 202
{
  "token":      "4XyZaB…32 caractères alphanumériques [A-Za-z0-9]",
  "status":      "queued",
  "eta_seconds": 20
}

Si le quota mensuel et les crédits sont épuisés, la réponse sera {"status":"waitlisted"} sans token. La capture reste en file d'attente jusqu'à ce que le compte dispose à nouveau de captures disponibles (remise à zéro mensuelle ou ajout de crédits).

2. Interroger le statut

GET https://api.shotbot.net/capture/{token}
GET https://api.shotbot.net/capture/a3f1c9…

// En attente
{ "token": "a3f1c9…", "status": "queued", "eta_seconds": 18 }

// Terminé
{
  "token":           "a3f1c9…",
  "status":           "done",
  "image":            "https://static.shotbot.net/a/a3/a3f1c9….webp",
  "preview":          "https://static.shotbot.net/a/a3/a3f1c9…_p.webp",
  "format":           "webp",
  "url":              "https://test.shotbot.fr",
  "meta_http_status": 200,
  "meta_final_url":   "https://test.shotbot.fr/",
  "meta_page_title":  "Example Domain",
  "file_hash":        "sha256:e3b0c44298fc1c149afb…",
  "captured_at":      1746268800
}

// Échec
{
  "token":     "a3f1c9…",
  "status":     "failed",
  "error_code": "nav_timeout",
  "url":        "https://test.shotbot.fr",
  "image":      "https://static.shotbot.net/a/a3/a3f1c9….jpg",
  "partial":    true
}

Le token donne accès au statut et aux URLs de la capture. Conservez-le comme un secret.

3. Paramètres disponibles

ChampTypeDéfautDescription
Essentiels
keystring·Clé API (obligatoire)
urlstring·URL à capturer, http ou https (obligatoire)
Image & rendu
formatstringjpgjpg · png · webp · avif · pdf (voir Sortie PDF). Sans Shotbot Pro : jpg uniquement.
viewport_widthint1280Viewport : mobile (360 · 375 · 390 · 414 · 430) · tablette (768 · 1024) · desktop (1280 · 1440 · 1920). Sans Shotbot Pro, limité à 390, 768, 1280. Shotbot Pro peut aussi passer n'importe quelle largeur personnalisée de 280 à 3840 px (tests CSS / responsive).
output_sizeint= viewportLargeur de l'image de sortie : 120 · 160 · 240 · 320 · 390 · 480 · 640 · 768 · 1024 · 1200 · 1280 · 1440 · 1920
ratiostring16:9Rapport hauteur/largeur de la capture (voir tableau ci-dessous)
crop_heightint·Hauteur de sortie en pixels (remplace ratio). Fixe la hauteur du viewport et capture cette zone depuis le haut de la page, donc les éléments ancrés en bas restent en bas. Maximum : 30 000 px. Pro uniquement.
fullpageboolfalseCapture la page en hauteur totale (scroll entier, max 30 000 px), ignore ratio
hidpiboolfalseMode HiDPI / Retina (résolution ×2)
color_schemestring·Impose le jeu de couleurs avant capture : "dark" · "light" · omis = défaut du navigateur
prefers_reduced_motionboolfalseÉmule la media query CSS prefers-reduced-motion: reduce. Les sites bien faits désactivent ou raccourcissent leurs animations (framer-motion, GSAP, AOS, IntersectionObserver) : captures plus propres, sans frame intermédiaire. Sans effet sur les sites qui n'écoutent pas la media query. Disponible pour tous les comptes.
selectorstring·Sélecteur CSS de l'élément à capturer. Seul cet élément est extrait, renvoyé à sa taille naturelle. output_size, ratio et crop_height ne sont pas appliqués (ni rognage ni redimensionnement). Ignoré si format: "pdf". Échoue avec nav_error si le sélecteur ne correspond à aucun élément. Pro uniquement.
Comportement
nojsboolfalseDésactive JavaScript, contourne les pop-ups, bannières cookies et overlays de consentement
waitint5Secondes d'attente avant capture, 0-30. Augmentez pour les SPAs React/Vue/Angular et le lazy-loading. Le timeout de navigation s'aligne automatiquement.
dismiss_cookiesstring""Ferme automatiquement les bannières CMP (OneTrust, Cookiebot, Didomi, TCF…). Valeurs : "" (laisse visible) · "reject" (refuse de préférence) · "accept" (accepte pour fermer). Pro uniquement pour les valeurs non vides.
scroll_before_captureboolfalseForce le défilement complet de la page avant capture. Déclenche les images loading="lazy" et les pipelines IntersectionObserver, utile combiné à fullpage. Pro uniquement.
scroll_offset_pxint0Fait défiler la page de N px (0 à 30 000) avant capture, pour cadrer plus bas. S'applique après scroll_before_capture. Mutuellement exclusif avec scroll_to (envoyer les deux renvoie 400 invalid_scroll_combo). Ignoré pour fullpage, PDF et selector. Pro uniquement.
scroll_tostring·Sélecteur CSS amené dans le viewport (en haut du cadre) avant capture. Contrairement à selector, il ne rogne pas la sortie, il positionne seulement la page. Mutuellement exclusif avec scroll_offset_px (400 invalid_scroll_combo). Un sélecteur sans correspondance est sans effet (la capture réussit). Ignoré pour fullpage, PDF et selector. Pro uniquement.
block_adsboolfalseBloque les requêtes vers les régies publicitaires et trackers les plus connus, capture plus rapide et plus nette. Pro uniquement.
autoplay_videosboolfalseLance Chromium avec --autoplay-policy=no-user-gesture-required : les balises <video autoplay>, y compris non muettes, démarrent sans interaction utilisateur. Utile pour les pages avec vidéo de fond ou hero vidéo qui afficheraient sinon leur poster figé. Sans effet sur les captures PDF. Pro uniquement.
omit_backgroundboolfalseFond de viewport transparent (option omitBackground de Chromium). La couleur de fond définie par la page reste intacte ; seul le backdrop blanc par défaut devient transparent. Visible sur PNG/WebP/AVIF ; JPG aplatit l'alpha en noir (sans effet). Aucun effet sur les PDF. Pro uniquement.
emulate_print_mediaboolfalseApplique la feuille de style @media print de la page avant capture (page.emulateMediaType('print')). Utile pour capturer en image une mise en page print-only. Sans effet supplémentaire sur les PDF (déjà en mode print). Pro uniquement.
render_regionstringfr-parisRégion de rendu : fr-paris (défaut, gratuit) · ca-montreal · sg-singapore · au-sydney · vn-hanoi. La capture est routée via un point de sortie réseau dans le pays choisi, locale et fuseau horaire émulés. Voir captures géolocalisées. Pro uniquement hors fr-paris.
Auth / Session
http_authobject·Authentification HTTP Basic (voir ci-dessous). Pro uniquement.
cookiesarray·Cookies à injecter avant navigation (voir ci-dessous). Utile pour capturer des pages authentifiées sans HTTP Basic Auth. Max 50 cookies. Pro uniquement.
Confidentialité
privateboolfalseCapture privée : l'image n'est pas uploadée sur le CDN. La réponse de GET /capture/{token} contient "download" (URL vers /capture/{token}/file) au lieu de "image"/"preview". Le fichier est récupérable autant de fois que voulu jusqu'à son expiration automatique, puis purgé. Déduplication désactivée. Disponible pour tous les comptes.

Ces options en images : viewports · presets · pleine page · cadres · bannières cookies · thème clair/sombre.

Ratios disponibles

ValeurOrientationUsage type
16:9PaysageÉcran HD, vidéo (défaut)
4:3PaysageStandard historique
16:10PaysageMoniteurs PC
3:2PaysagePhotographie
2:1PaysagePanoramique, hero
1:1CarréRéseaux sociaux
9:16PortraitMobile, stories
3:4PortraitStandard portrait
10:16PortraitTablette portrait
2:3PortraitPhoto portrait
1:2PortraitPortrait long

Sortie PDF (format: "pdf")

Avec format: "pdf", Shotbot produit un document PDF au lieu d'une image raster. Les options image-spécifiques (output_size, ratio, crop_height, fullpage) sont ignorées : la mise en page est régie par la taille de page, l'orientation et l'échelle. Une vignette WebP 640 px est générée en parallèle pour le tableau de bord et les liens d'aperçu.

ChampTypeDéfautDescription
pdf_page_sizestringA4A4 · A3 · A5 · Letter · Legal · Tabloid
pdf_margin_mmint10Marge uniforme appliquée aux 4 côtés (0-50 mm)
pdf_scalefloat1.00Facteur d'échelle du rendu (0.10-2.00)
pdf_landscapeboolfalseOrientation paysage si true, portrait sinon
JSON
{
  "key":          "VOTRE_CLÉ_API",
  "url":          "https://test.shotbot.fr/facture/12345",
  "format":       "pdf",
  "pdf_page_size":"A4",
  "pdf_margin_mm": 12,
  "pdf_scale":     1.00,
  "pdf_landscape": false
}

Le PDF est servi à https://static.shotbot.net/{t1}/{t2}/{token}.pdf avec Content-Type: application/pdf. La vignette WebP reste accessible à https://cache.shotbot.net/t/{token}/preview.

Authentification HTTP Basic (http_auth)

Pour capturer des pages protégées par mot de passe (HTTP 401) :

JSON
{
  "key": "votre_clé",
  "url": "https://test.shotbot.fr/page-privee",
  "http_auth": {
    "user": "login",
    "pass": "mot_de_passe"
  }
}

Les identifiants sont effacés de la base de données dès la capture terminée. Si la capture reste en attente plus de 2 heures, ils sont supprimés automatiquement. Ils ne sont jamais retournés dans les réponses API.

Injection de cookies (cookies) Pro

Injectez des cookies avant la navigation pour capturer des pages authentifiées (sessions, tokens JWT, préférences…) sans passer par HTTP Basic Auth.

JSON
{
  "key": "votre_clé",
  "url": "https://test.shotbot.fr/dashboard",
  "cookies": [
    { "name": "session_id", "value": "abc123xyz" },
    { "name": "lang",       "value": "fr", "domain": "test.shotbot.fr", "path": "/" }
  ]
}
ChampTypeDescription
namestringNom du cookie (obligatoire, max 255 car.)
valuestringValeur du cookie (obligatoire, max 4096 car.)
domainstringDomaine du cookie (optionnel, défaut : domaine de l'URL cible, max 255 car.)
pathstringChemin du cookie (optionnel, défaut : "/", max 255 car.)

Exemple PHP : APIv2 hébergé

PHP
<?php
$api_key = "VOTRE_CLÉ_API";
$url     = "https://test.shotbot.fr";

// 1. Soumettre la capture
$ch = curl_init("https://api.shotbot.net/capture");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS     => json_encode([
        "key"            => $api_key,
        "url"            => $url,
        "format"         => "webp",
        "viewport_width" => 1280,
        "ratio"          => "16:9",
    ]),
]);
$res    = json_decode(curl_exec($ch), true);
curl_close($ch);

$token = $res["token"] ?? null;
if (!$token) { echo "Erreur : " . ($res["error"] ?? "inconnue"); exit; }

// 2. Attendre le résultat (polling)
do {
    sleep(3);
    $status = json_decode(file_get_contents(
        "https://api.shotbot.net/capture/" . $token
    ), true);
} while (($status["status"] ?? "") !== "done");

echo "<img src=\"" . htmlspecialchars($status["image"]) . "\" loading=\"lazy\">";
Exemple avec options supplémentaires (ratio, HiDPI, blocage des pubs, lazy-load, HTTP auth)…
<?php
$ch = curl_init("https://api.shotbot.net/capture");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS     => json_encode([
        "key"                   => "VOTRE_CLÉ_API",
        "url"                   => "https://test.shotbot.fr",
        "format"                => "avif",
        "viewport_width"        => 390,       // iPhone 14 / 15
        "output_size"           => 390,
        "ratio"                 => "9:16",    // portrait mobile
        "hidpi"                 => true,
        "color_scheme"          => "dark",    // force prefers-color-scheme: dark
        "block_ads"             => true,      // bloque régies + trackers
        "dismiss_cookies"       => "reject",  // ferme les bannières CMP
        "scroll_before_capture" => true,      // déclenche le lazy-load
        "wait_time"             => 20,
        "http_auth"             => ["user" => "admin", "pass" => "s3cr3t"],
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $res["token"];

4. Informations du compte

GET https://api.shotbot.net/account
GET https://api.shotbot.net/account?key={VOTRE_CLE}

// Ou avec le header Authorization
GET https://api.shotbot.net/account
Authorization: Bearer {VOTRE_CLE}

Réponse

JSON
{
  "plan":            "free",     // "free" | "pro"
  "pro_until":       null,       // Timestamp Unix (Pro uniquement)
  "credit":          50,         // Crédits supplémentaires hors quota mensuel
  "quota_used":      12,         // Captures consommées ce mois-ci
  "quota_total":     200,        // Plafond du quota mensuel
  "quota_remaining": 188,        // Captures encore disponibles
  "inflight":        1,          // Captures actuellement en file ou en traitement
  "inflight_cap":    3           // Plafond de concurrence pour ce type de compte
}

Utilisez shotbot status dans le CLI pour une version lisible de cet endpoint.

Shotbot génère la capture et la pousse vers votre serveur en une seule requête multipart. Aucun hébergement de notre côté, les images atterrissent directement chez vous, sans aucune mention Shotbot. Inclus dans le compte gratuit.

Soumettre une capture callback

POST https://api.shotbot.net/capture/callback
POST https://api.shotbot.net/capture/callback
Content-Type: application/json

{
  "key":             "votre_clé_api",
  "url":             "https://test.shotbot.fr",
  "callback_url":    "https://votre-site.com/shotbot-callback.php",
  "callback_secret": "un-secret-aléatoire",
  "format":          "webp",
  "viewport_width":  1280,
  "ratio":           "16:9"
}

Réponse immédiate

JSON 202
{ "token": "a3f1c9…", "status": "queued", "eta_seconds": 20 }

Réception sur votre serveur

Dès la capture terminée, Shotbot envoie un POST multipart/form-data à votre callback_url :

Champs reçus
$_POST["token"]          → token 32 chars alphanumériques (identifiant unique de la capture)
$_POST["url"]             → URL originale capturée
$_POST["status"]          → "OK" | "ERR"
$_POST["format"]          → format de l'image (jpg, webp, etc.)
$_POST["callback_secret"] → secret renvoyé tel quel (uniquement si fourni à la création)
$_FILES["file"]           → image binaire (taille et format demandés)

// Pas d'aperçu en mode callback, une seule image au format choisi.

Contraintes sur callback_url

  • HTTPS obligatoire.
  • L'URL ne doit pas résoudre vers une adresse IP privée (protection SSRF).
  • Les requêtes proviennent de l'IP 163.172.105.112 | à whitelister dans votre firewall si nécessaire. Liste JSON à jour.

Paramètres spécifiques au callback

Identiques à l'APIv2 hébergée, plus :

ChampTypeDescription
callback_urlstringURL HTTPS de réception (obligatoire pour ce mode)
callback_secretstringSecret partagé optionnel (≤ 255 car.) renvoyé tel quel dans le POST de réception (champ callback_secret) ; permet de vérifier que la requête provient bien de Shotbot

Exemple PHP : mode callback

PHP, envoi
<?php
// submit-capture.php, côté client
$ch = curl_init("https://api.shotbot.net/capture/callback");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS     => json_encode([
        "key"             => "VOTRE_CLÉ_API",
        "url"             => "https://test.shotbot.fr",
        "callback_url"    => "https://votre-site.com/shotbot-callback.php",
        "callback_secret" => "un-secret-aléatoire",
        "format"          => "webp",
        "viewport_width"  => 1280,
        "ratio"           => "16:9",
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Capture : " . $res["token"];
PHP, réception (votre serveur)
<?php
// shotbot-callback.php, reçoit la capture
$EXPECTED_SECRET = "un-secret-aléatoire"; // identique à callback_secret envoyé

if (!hash_equals($EXPECTED_SECRET, $_POST["callback_secret"] ?? "")) {
    http_response_code(403);
    exit;
}

if (($_POST["status"] ?? "") !== "OK") {
    http_response_code(200);
    exit;
}

$token = preg_replace("/[^A-Za-z0-9]/", "", $_POST["token"] ?? "");
$format = in_array($_POST["format"] ?? "", ["jpg","png","webp","avif"])
        ? $_POST["format"] : "jpg";

if (!$token || !isset($_FILES["file"])) {
    http_response_code(400);
    exit;
}

$dest = __DIR__ . "/shots/" . $token . "." . $format;
move_uploaded_file($_FILES["file"]["tmp_name"], $dest);

http_response_code(200);
echo "OK";
Marque blanche : les images sont hébergées sur votre serveur. Aucune URL Shotbot n'est exposée à vos utilisateurs. Inclus gratuitement dans tous les comptes.

Soumettez jusqu'à 500 URLs en une seule requête. Mêmes options que l'APIv2 standard, applicables globalement ou URL par URL. Utile pour l'e-commerce (catalogues produits), l'archivage légal (snapshots immuables horodatés, chaque capture reste accessible indéfiniment sans être écrasée), et les pipelines de monitoring visuel.

Limite : 500 URLs/requête (Shotbot Pro : 5 000).

Vous prévoyez un volume inhabituel (500 000 captures d'un coup, par exemple) ? Prévenez-nous avant le lancement - on prépare la capacité de votre côté.

Soumettre un batch

POST https://api.shotbot.net/capture/batch
POST https://api.shotbot.net/capture/batch
Content-Type: application/json

{
  "key":  "votre_clé_api",

  "jobs": [
    { "url": "https://test.shotbot.fr" },
    { "url": "https://other.com", "format": "png", "viewport_width": 390 }
  ],

  // Options globales, appliquées à toutes les captures, surchargeables individuellement
  "format":         "webp",
  "viewport_width": 1280,
  "ratio":          "16:9"
}

Réponse (HTTP 202)

JSON 202
{
  "submitted":    2,
  "waitlisted":   0,
  "deduplicated": 0,
  "errors":       0,
  "jobs": [
    { "index": 0, "url": "https://test.shotbot.fr", "token": "a3f1c9…", "status": "queued" },
    { "index": 1, "url": "https://other.com",   "token": "b7e2d4…", "status": "queued" }
  ]
}

Statuts possibles par capture

StatutSignification
queuedCapture créée, interroger GET /capture/{token} pour le résultat
queued + "deduplicated":trueURL déjà soumise récemment (60 s) ou deux fois dans le même batch, token existant réutilisé, pas de décompte supplémentaire
waitlistedQuota mensuel et crédits épuisés, traité au prochain reset
errorURL invalide ou paramètre incorrect, les autres captures du batch ne sont pas affectées

Paramètres

ChampNiveauDescription
keyRacineClé API (obligatoire)
jobsRacineTableau d'objets capture, max 500 (obligatoire)
jobs[n].urlPar captureURL à capturer, http ou https (obligatoire)
format, viewport_width, output_size, ratio, crop_height, fullpage, hidpi, color_scheme, prefers_reduced_motion, nojs, wait, dismiss_cookies, scroll_before_capture, scroll_offset_px, scroll_to, block_ads, autoplay_videos, omit_background, emulate_print_media, http_auth, cookies, selector, private, pdf_page_size, pdf_margin_mm, pdf_scale, pdf_landscapeRacine ou par captureOptions de capture (voir onglet Hébergé pour les valeurs autorisées), la valeur par capture prend la priorité sur le défaut global. private désactive la déduplication : deux URLs identiques dans le même batch produisent deux tokens distincts.
callback_urlRacineSi présent (HTTPS, non-privée) : toutes les captures passent en mode callback, les images sont poussées vers cette URL à la fin de chaque capture
callback_secretRacineSecret partagé optionnel renvoyé tel quel dans le POST de réception, utile pour vérifier l'origine de la requête (uniquement si callback_url est défini)
idempotency_keyRacineClé d'idempotence optionnelle (16-128 caractères [A-Za-z0-9_.-]). Si vous renvoyez le même batch avec la même clé dans les 24h depuis le même compte, le serveur renvoie la réponse originale (header X-Idempotent-Replay: true) sans créer de nouveaux jobs ni décompter la quota. Recommandé : générez un UUID avant le premier appel, réutilisez-le sur les retries transitoires, jetez-le après succès.

Erreurs globales

Code HTTPErreurCause
400missing_jobsChamp jobs absent
400jobs_not_arrayjobs n'est pas un tableau
400too_many_jobs + "max":500Plus de 500 URLs
400invalid_callback_urlURL callback invalide, non-HTTPS ou adresse privée
400invalid_idempotency_keyClé d'idempotence hors format (16-128 caractères [A-Za-z0-9_.-])
401invalid_keyClé API incorrecte

Exemple PHP : mode batch

PHP
<?php
$api_key = "VOTRE_CLÉ_API";

$urls = [
    "https://test.shotbot.fr",
    "https://github.com",
    "https://wikipedia.org",
    // ... jusqu'à 500
];

// Soumettre le batch
$ch = curl_init("https://api.shotbot.net/capture/batch");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS     => json_encode([
        "key"            => $api_key,
        "format"         => "webp",
        "viewport_width" => 1280,
        "ratio"          => "16:9",
        "jobs"           => array_map(fn($u) => ["url" => $u], $urls),
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);

echo "Soumis : {$res['submitted']} · File d'attente : {$res['waitlisted']}\n";

// Collecter les tokens des captures créées
$tokens = [];
foreach ($res["jobs"] as $capture) {
    if (isset($capture["token"])) {
        $tokens[$capture["url"]] = $capture["token"];
    }
}

// Attendre et afficher les résultats
foreach ($tokens as $url => $token) {
    do {
        sleep(3);
        $status = json_decode(file_get_contents(
            "https://api.shotbot.net/capture/" . $token
        ), true);
    } while (($status["status"] ?? "") !== "done");

    echo $url . " → " . $status["image"] . "\n";
}
Batch callback, images livrées sur votre serveur…
<?php
// Toutes les captures du batch sont poussées vers votre callback_url
$ch = curl_init("https://api.shotbot.net/capture/batch");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS     => json_encode([
        "key"          => "VOTRE_CLÉ_API",
        "callback_url" => "https://votre-site.com/shotbot-callback.php",
        "format"       => "webp",
        "jobs"         => [
            ["url" => "https://test.shotbot.fr"],
            ["url" => "https://other.com", "ratio" => "1:1"],
        ],
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
// Pas besoin de polling, chaque image sera POST-ée à votre callback_url
echo "Captures créées : " . $res["submitted"];
Déduplication automatique. Si la même URL apparaît deux fois dans le batch, ou a déjà été soumise dans les 60 dernières secondes, le token existant est réutilisé sans décompte supplémentaire sur votre quota.
Une URL, c'est tout. L'API legacy fonctionne avec un simple GET HTTP, aucune lib, aucun JSON, aucun polling. Intégrée en 30 secondes dans n'importe quel langage ou script shell. Elle est maintenue et continuera à fonctionner indéfiniment. Les nouvelles intégrations peuvent aussi utiliser l'onglet APIv2, Hébergé pour des options supplémentaires.

Mode Hébergé Legacy

Requête

HTTP GET
https://add.shotbot.net/k={CLÉ}/{URL}

// Avec options
https://add.shotbot.net/k={CLÉ}/format/webp/w/1280/fullpage/1/{URL}

Afficher la capture

HTML
<!-- Format : https://static.shotbot.net/{md5[0]}/{md5[0:2]}/{md5}/{taille}.jpg -->
$md5 = md5($url);
$img = "https://static.shotbot.net/{$md5[0]}/{$md5[0]..$md5[1]}/{$md5}/120.jpg";

Tailles de sortie (ratio 4:3 fixe)

TailleDimensions
320320×240
240240×180
160160×120
120120×90
9292×69
8080×60

Options

ParamètreValeurs
/nojs/1/Désactive JavaScript
/format/webp/jpg · png · webp · avif
/w/1280/768 · 1024 · 1280 · 1600
/fullpage/1/Page entière
/hidpi/1/Retina ×2
/darkmode/1/Dark mode

Codes de retour

CodeSignification
OKCapture créée ou en queue
OK waitlistQuota dépassé, file d'attente
ERR keyClé invalide
ERR argsParamètres incorrects

Actualiser une capture (update)

HTTP GET
https://update.shotbot.net/k={CLÉ}/[options/]{URL}
// Mêmes paramètres que add | re-capture sans déduplication

Mode Callback Legacy

Les captures sont générées puis livrées sur votre serveur via HTTP POST.

Requête (votre serveur → Shotbot)

HTTP POST
POST https://add.shotbot.net/callback.php

k={CLÉ}&uri={URL_ENCODÉE}&s=120&t=10&uri_callback={URL_CALLBACK}&nojs=0

Réponse : OK {id}. En cas d'erreur : codes retour standards.

Réception (votre serveur ← Shotbot)

POST reçu
$_POST["id"]      → identifiant du job
$_POST["uri_md5"] → MD5 de l'URL capturée
$_POST["uri"]     → URL capturée
$_POST["width"]   → taille demandée (ex. 120)
$_POST["status"]  → OK | ERR
$_FILES["file_120"] → image JPEG (nom selon taille demandée)

Tailles disponibles : 80 · 92 · 120 · 160 · 240 · 320. Votre script de callback doit répondre dans un délai de 30 secondes.

Vérifier le quota (legacy)

GET
https://status.shotbot.net/k={CLÉ}
// → "OK 500:327:5000"  (quota:utilisé:réserve)
Indépendant depuis 2008, hébergé en France. Vos données restent stockées en France : conformité RGPD, droit français, rendu par défaut en France.

Une question avant d'intégrer ?

Quotas, formats, ratios, callbacks, batch, planification : la FAQ couvre les questions les plus fréquentes posées par les développeurs avant de poser leur première requête.

Questions fréquentes