Exemples d'intégration

Copiez-collez le code dans votre langage. Remplacez VOTRE_CLÉ_API par votre clé API (12 caractères, gratuite).

Créez un compte gratuit ou connectez-vous pour voir votre clé API pré-remplie dans les exemples.
Préférez-vous voir le code se construire en direct ? Le terrain de jeu génère ces snippets au fur et à mesure que vous ajustez l'URL et les options. Tester l'API →
Langages
Fonctionnalités
Outils

PHP

Capture simple (hébergée)

PHP
<?php
$api_key = "VOTRE_CLÉ_API";
$url     = "https://example.com";

// 1. Soumettre
$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",
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);

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

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

// 3. Utiliser l'image
echo "<img src=\"" . htmlspecialchars($status["image"]) . "\" loading=\"lazy\">";

Carte sociale en 1 ligne (preset)

Le paramètre preset remplit automatiquement viewport_width, output_size et crop_height. Presets disponibles : og (1200×630), mobile (390×844), youtube_thumbnail (1280×720), square (1080×1080), reel (1080×1920), pinterest (1000×1500), tablet (768×1024), desktop_hd, twitter_header, linkedin_banner, hero_banner (4 derniers réservés Pro).

PHP
<?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://example.com",
        "preset" => "og",   // 1200×630, carte OpenGraph
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $res["token"];

Capture avec options supplémentaires

PHP
<?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://example.com",
        "format"         => "webp",
        "viewport_width" => 1280,
        "output_size"    => 640,
        "ratio"          => "16:9",
        "hidpi"          => true,
        "color_scheme"   => "dark",
        "render_region"  => "ca-montreal", // Pro : fr-paris (défaut) | ca-montreal | sg-singapore | au-sydney | vn-hanoi
        "fullpage"       => false,
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $res["token"]; // token pour suivre le statut

Mode Callback (marque blanche)

Pour vérifier que le POST entrant provient bien de Shotbot, fournissez un callback_secret à la soumission : Shotbot le renverra tel quel dans le POST de réception (champ callback_secret).

PHP, soumission
<?php
// Soumettre une capture callback
$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://example.com",
        "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);
// $res["token"] disponible pour suivi optionnel
PHP, réception (shotbot-callback.php)
<?php
// Shotbot envoie un POST multipart quand la capture est prête.
// Champs disponibles : token, url, status, format, callback_secret
// Fichier : $_FILES["file"] contient l'image

$EXPECTED_SECRET = "un-secret-aléatoire"; // identique à callback_secret envoyé
if (!hash_equals($EXPECTED_SECRET, $_POST["callback_secret"] ?? "")) {
    http_response_code(403);
    exit("Forbidden");
}

if (($_POST["status"] ?? "") !== "OK" || !isset($_FILES["file"])) {
    http_response_code(400);
    exit;
}

$token = preg_replace("/[^A-Za-z0-9]/", "", (string)($_POST["token"] ?? ""));
$ext   = preg_replace("/[^a-z]/", "", (string)($_POST["format"] ?? "webp"));

if ($token === "") {
    http_response_code(400);
    exit;
}

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

// Enregistrer en base, notifier un webhook, etc.
http_response_code(200);
echo "OK";

Python

Capture simple

Python
import requests, time

API_KEY = "VOTRE_CLÉ_API"
url     = "https://example.com"

# 1. Soumettre
res = requests.post("https://api.shotbot.net/capture", json={
    "key": API_KEY, "url": url, "format": "webp",
    "viewport_width": 1280, "ratio": "16:9",
})
res.raise_for_status()
token = res.json()["token"]

# 2. Attendre
while True:
    time.sleep(2)
    status = requests.get(f"https://api.shotbot.net/capture/{token}").json()
    if status["status"] == "done":
        print(status["image"])
        break

Carte sociale en 1 ligne (preset)

Python
import requests

res = requests.post("https://api.shotbot.net/capture", json={
    "key": "VOTRE_CLÉ_API",
    "url": "https://example.com",
    "preset": "og",   # 1200x630, carte OpenGraph
})
token = res.json()["token"]

Télécharger la capture

Python
import requests, time

API_KEY = "VOTRE_CLÉ_API"
url     = "https://example.com"

res   = requests.post("https://api.shotbot.net/capture", json={"key": API_KEY, "url": url})
token = res.json()["token"]

while True:
    time.sleep(2)
    s = requests.get(f"https://api.shotbot.net/capture/{token}").json()
    if s["status"] == "done": break

img_data = requests.get(s["image"]).content
with open("capture.webp", "wb") as f:
    f.write(img_data)
print("Capture enregistrée.")

Node.js

Capture et polling (ESM)

Node.js (ESM)
const API_KEY = "VOTRE_CLÉ_API";
const url     = "https://example.com";

// 1. Soumettre
const res = await fetch("https://api.shotbot.net/capture", {
  method:  "POST",
  headers: { "Content-Type": "application/json" },
  body:    JSON.stringify({ key: API_KEY, url, format: "webp", viewport_width: 1280 }),
});
const { token } = await res.json();

// 2. Attendre
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
let image;
while (true) {
  await wait(2000);
  const s = await fetch(`https://api.shotbot.net/capture/${token}`).then((r) => r.json());
  if (s.status === "done") { image = s.image; break; }
}
console.log(image);

Carte sociale en 1 ligne (preset)

Node.js (ESM)
const res = await fetch("https://api.shotbot.net/capture", {
  method:  "POST",
  headers: { "Content-Type": "application/json" },
  body:    JSON.stringify({
    key:    "VOTRE_CLÉ_API",
    url:    "https://example.com",
    preset: "og",   // 1200×630, carte OpenGraph
  }),
});
const { token } = await res.json();

Polling côté navigateur

HTML + JS
<!-- Votre backend soumet la capture et stocke le token.
     Ce script surveille le statut et met à jour l'image quand c'est prêt. -->
<script>
async function waitForCapture(token, imgEl) {
  while (true) {
    await new Promise((r) => setTimeout(r, 2000));
    const s = await fetch(`https://api.shotbot.net/capture/${token}`).then((r) => r.json());
    if (s.status === "done") { imgEl.src = s.image; return; }
  }
}
const img = document.getElementById("shot");
if (img) waitForCapture(img.dataset.capture, img);
</script>
<img id="shot" data-capture="a3f1c9…" alt="Screenshot" loading="lazy">

Go

Capture simple

Go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

const apiKey = "VOTRE_CLÉ_API"

func main() {
	// 1. Soumettre
	payload, _ := json.Marshal(map[string]any{
		"key":    apiKey,
		"url":    "https://example.com",
		"format": "webp",
	})
	resp, _ := http.Post("https://api.shotbot.net/capture",
		"application/json", bytes.NewReader(payload))
	defer resp.Body.Close()

	var capture struct {
		Token string `json:"token"`
	}
	json.NewDecoder(resp.Body).Decode(&capture)

	// 2. Attendre
	for {
		time.Sleep(2 * time.Second)
		r, _ := http.Get("https://api.shotbot.net/capture/" + capture.Token)
		body, _ := io.ReadAll(r.Body)
		r.Body.Close()

		var s map[string]any
		json.Unmarshal(body, &s)
		if s["status"] == "done" {
			fmt.Println(s["image"])
			return
		}
	}
}

Mode Callback

Go, soumission
payload, _ := json.Marshal(map[string]any{
	"key":             apiKey,
	"url":             "https://example.com",
	"callback_url":    "https://votre-site.com/shotbot-callback",
	"callback_secret": "un-secret-aléatoire",
	"format":          "webp",
	"ratio":           "16:9",
})
http.Post("https://api.shotbot.net/capture/callback",
	"application/json", bytes.NewReader(payload))
Go, réception
const expectedSecret = "un-secret-aléatoire"

http.HandleFunc("/shotbot-callback", func(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(32 << 20) // 32 MB max

	// Vérification du secret partagé
	if subtle.ConstantTimeCompare(
		[]byte(r.FormValue("callback_secret")),
		[]byte(expectedSecret),
	) != 1 {
		http.Error(w, "forbidden", http.StatusForbidden)
		return
	}

	if r.FormValue("status") != "OK" {
		http.Error(w, "not OK", http.StatusBadRequest)
		return
	}
	token := r.FormValue("token")
	ext   := r.FormValue("format")

	file, _, err := r.FormFile("file")
	if err != nil {
		http.Error(w, "no file", http.StatusBadRequest)
		return
	}
	defer file.Close()

	dst, _ := os.Create("shots/" + token + "." + ext)
	defer dst.Close()
	io.Copy(dst, file)

	fmt.Fprintln(w, "OK")
})

cURL

Capture simple

Shell
# 1. Soumettre (retourne le token)
curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com","format":"webp"}'
# {"token":"a3f1c9...","status":"queued","eta_seconds":20}

# 2. Vérifier le statut
curl -s "https://api.shotbot.net/capture/a3f1c9..."
# {"status":"done","image":"https://static.shotbot.net/..."}

# 3. Télécharger
curl -o capture.webp "https://static.shotbot.net/a/a3/a3f1c9….webp"

Carte sociale en 1 ligne (preset)

Shell
# preset=og remplit automatiquement viewport_width / output_size / crop_height (1200×630).
curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com","preset":"og"}'

Cadre décoratif autour de l'image (frame)

Paramètre frame | composite un cadre côté serveur autour de l'image. Variantes : brackets, shadow, browser_chrome, mobile (mockup smartphone), tablet, shotbot_brand. Ignoré pour PDF. Les comptes gratuits reçoivent une marque shotbot.fr en bas à droite (sauf shotbot_brand, intrinsèquement marqué) | retirée avec Shotbot Pro.

Shell
# Carte OG (1200×630) avec ombre portée
curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com","preset":"og","frame":"shadow"}'

# Capture mobile dans un mockup smartphone (idéal pour landings d'app mobile)
curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com","preset":"mobile","frame":"mobile"}'

Avec options supplémentaires

Shell
curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com",
       "format":"avif","viewport_width":390,"ratio":"9:16",
       "hidpi":true,"color_scheme":"dark",
       "block_ads":true,"dismiss_cookies":"reject","scroll_before_capture":true,
       "scroll_offset_px":600,"wait_time":25}'

Mode Callback

Shell
curl -s -X POST https://api.shotbot.net/capture/callback \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com",
       "callback_url":"https://votre-site.com/callback",
       "callback_secret":"un-secret-aléatoire",
       "format":"webp","ratio":"16:9"}'

Sortie PDF

Shell
# Document PDF A4 portrait, marge 10 mm
curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://example.com/facture/12345",
       "format":"pdf","pdf_page_size":"A4","pdf_margin_mm":10,
       "pdf_scale":1.00,"pdf_landscape":false}'

# Récupérer le PDF une fois prêt :
# https://static.shotbot.net/{t1}/{t2}/{token}.pdf

Capture privée (jamais sur le CDN)

Passez "private":true quand la page capturée est sensible (intranet, espaces clients, tableaux de bord). Le résultat n'est pas publié sur static.shotbot.net : la réponse de statut expose une URL download qui diffuse le fichier. Vous pouvez le récupérer autant de fois que voulu jusqu'à son expiration automatique, après quoi l'URL retourne 410 Gone.

Shell
# 1. Soumettre avec private:true
TOKEN=$(curl -s -X POST https://api.shotbot.net/capture \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","url":"https://intranet.example.com",
       "format":"webp","private":true}' | jq -r .token)

# 2. Polling | la réponse "done" contient `download`, pas `image`/`preview`
curl -s "https://api.shotbot.net/capture/$TOKEN"
# {"status":"done","private":true,
#  "download":"https://api.shotbot.net/capture/.../file", ...}

# 3. Récupérer les octets (répétable jusqu'à l'expiration automatique côté serveur)
curl -o capture.webp "https://api.shotbot.net/capture/$TOKEN/file"

Batch : jusqu'à 500 URLs en une requête

L'endpoint batch traite jusqu'à 500 URLs en une seule requête (5 000 avec Shotbot Pro). Les options globales s'appliquent à toutes les captures ; chaque URL peut y définir ses propres options. La déduplication automatique évite de recompter deux fois la même URL soumise dans le même batch.

Équité entre clients : la file batch (Q3) utilise un planificateur fair-share : à chaque slot libre, le worker choisit le job le plus ancien parmi le client avec le moins de captures en cours. Un grand batch ne monopolise pas tous les workers ; les autres clients continuent d'avancer en parallèle. Pour une file réservée sans partage, voir Shotbot Dédié.

Limite de taille de page : les pages dont le document HTML dépasse 10 Mo (20 Mo avec Shotbot Pro) sont automatiquement rejetées avec le code response_too_large. Le job échoue en quelques secondes plutôt qu'après 30 s de timeout, préservant les ressources des workers.

PHP : batch simple

PHP
<?php
$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",
        "format"         => "webp",     // défaut pour toutes les captures
        "viewport_width" => 1280,
        "ratio"          => "16:9",
        "jobs"           => [
            ["url" => "https://example.com"],
            ["url" => "https://example.org"],
            ["url" => "https://example.net"],
        ],
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);

echo "Soumis : " . $res["submitted"] . "\n";
echo "Dédupliqués : " . $res["deduplicated"] . "\n";
echo "En attente : " . $res["waitlisted"] . "\n";

foreach ($res["jobs"] as $capture) {
    echo $capture["url"] . " → " . $capture["token"] . "\n";
}

PHP : avec options par capture et callback

PHP
<?php
$urls = [
    ["url" => "https://boutique.example.com/produit-1"],
    ["url" => "https://boutique.example.com/produit-2", "viewport_width" => 390, "ratio" => "9:16"],
    ["url" => "https://boutique.example.com/produit-3", "format" => "avif"],
    // ... jusqu'à 500
];

$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",
        "format"          => "webp",        // défaut surchargeable par capture
        "callback_url"    => "https://votre-site.com/batch-callback",
        "callback_secret" => "un-secret-aléatoire",
        "jobs"            => $urls,
    ]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
// Shotbot notifie callback_url pour chaque capture terminée.
// Le champ callback_secret est renvoyé tel quel pour vérifier l'origine.

Python : batch

Python
import requests

res = requests.post("https://api.shotbot.net/capture/batch", json={
    "key":    "VOTRE_CLÉ_API",
    "format": "webp",
    "jobs": [
        {"url": "https://example.com"},
        {"url": "https://example.org", "viewport_width": 390},
        {"url": "https://example.net", "hidpi": True},
    ],
})
data = res.json()
print(f"Soumis : {data['submitted']} | Dédupliqués : {data['deduplicated']}")
for capture in data["jobs"]:
    print(capture["url"], "→", capture["token"])

cURL : batch

Shell
curl -s -X POST https://api.shotbot.net/capture/batch \
  -H "Content-Type: application/json" \
  -d '{"key":"VOTRE_CLÉ_API","format":"webp","jobs":[
    {"url":"https://example.com"},
    {"url":"https://example.org"},
    {"url":"https://example.net"}
  ]}'
# {"submitted":3,"waitlisted":0,"deduplicated":0,"errors":[],"jobs":[...]}

Format de réponse batch

JSON
{
  "submitted":    3,
  "waitlisted":   0,
  "deduplicated": 0,
  "errors":       [],
  "jobs": [
    { "index": 0, "url": "https://example.com",  "token": "a3f1c9…", "status": "queued" },
    { "index": 1, "url": "https://example.org",  "token": "b7e2d1…", "status": "queued" },
    { "index": 2, "url": "https://example.net",  "token": "c8f4a0…", "status": "queued" }
  ]
}

Les captures du batch partent en file dédiée (Queue 3), isolée des captures unitaires. Avec un callback_url, chaque capture terminée notifie votre serveur individuellement. Sans callback, interrogez chaque token via GET /capture/{token}.

Vous voulez que chaque capture atterrisse directement dans votre bucket ? Voir le guide Export vers S3 / Scaleway / R2.

Ruby

Capture simple

Ruby
require "net/http"
require "json"

API_KEY = "VOTRE_CLÉ_API"
url     = "https://example.com"

# 1. Soumettre
uri = URI("https://api.shotbot.net/capture")
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
req.body = { key: API_KEY, url: url, format: "webp", viewport_width: 1280 }.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
token = JSON.parse(res.body)["token"]

# 2. Attendre
loop do
  sleep 2
  s = JSON.parse(Net::HTTP.get(URI("https://api.shotbot.net/capture/#{token}")))
  break puts s["image"] if s["status"] == "done"
end

CLI

Installation

Python
pip install shotbot
Node.js
npm install -g shotbot

Capture simple

CLI
shotbot capture --url=https://example.com   # privée + enregistrée dans le dossier courant

Avec options

CLI
shotbot capture --url=https://example.com --format=webp --viewport=1440 --full-page
shotbot capture --url=https://example.com --output=capture.png   # choisir le nom du fichier
shotbot capture --url=https://example.com --cdn                 # URL CDN publique, sans fichier local
shotbot capture --url=https://example.com --color-scheme=dark --wait=5

Sans installation (npx)

Node.js
npx shotbot capture --url=https://example.com

CI / scripts

Shell
export SHOTBOT_API_KEY=

shotbot capture --url=https://example.com --output=avant.png
# déploiement…
shotbot capture --url=https://example.com --output=apres.png

Documentation complète du CLI →

Serveur MCP

Shotbot expose un serveur MCP (Model Context Protocol) que Claude Code, Claude Desktop, Cursor et Windsurf reconnaissent nativement. Demandez vos captures en langage naturel, sans écrire de code.

Installation

Shell
claude mcp add --scope user shotbot --transport http "https://api.shotbot.net/mcp?key="

Outils disponibles

MCP
capture        — capture une URL (format, viewport, frame, région…)
batch          — soumet jusqu'à 5 000 URLs en une requête
get_status     — interroge l'état d'une capture par token
account_status — quota restant, statut Pro, limite batch

Exemple d'usage (Claude Code)

Prompt
Fais une capture de https://www.permalink.fr/ en format WebP, viewport 1280, avec le cadre browser_chrome.

Documentation complète du serveur MCP →

Export vers S3

Envoyez chaque capture directement dans votre bucket via le mécanisme de callback. Shotbot poste le fichier à votre endpoint dès que le rendu est prêt. Compatible AWS S3, Scaleway, OVH, Cloudflare R2, Backblaze B2.

Soumettre avec callback_url

PHP, soumission
<?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"             => "",
        "url"             => "https://example.com",
        "format"          => "webp",
        "callback_url"    => "https://votreapp.com/callback-s3.php",
        "callback_secret" => "votre_secret_ici",
    ]),
]);
$res = json_decode(curl_exec($ch), true);

Handler de réception (PHP)

PHP, réception
<?php
require 'vendor/autoload.php'; // composer require aws/aws-sdk-php
use Aws\S3\S3Client;

if (!hash_equals('votre_secret_ici', $_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'] ?? '');
$fmt   = $_POST['format'] ?? 'jpg';

$s3 = new S3Client(['version'=>'latest','region'=>'fr-par',
      'endpoint'=>'https://s3.fr-par.scw.cloud', // null pour AWS S3
      'credentials'=>['key'=>getenv('S3_KEY'),'secret'=>getenv('S3_SECRET')]]);

$s3->putObject(['Bucket'=>'mon-bucket',
    'Key'         => 'screenshots/' . date('Y/m/d/') . $token . '.' . $fmt,
    'Body'        => fopen($_FILES['file']['tmp_name'], 'rb'),
    'ContentType' => 'image/' . $fmt]);

http_response_code(200);

Guide complet + Python + tous les providers →

Cadres décoratifs

Le paramètre frame habille la capture d'un cadre ou d'un mockup appareil (format image, ignoré en PDF). Valeurs disponibles, groupées par usage :

Navigateur
browser_chromeTutoriels, captures de page
browser_chrome_darkTutoriels sur fond sombre
Appareils
mobileAperçu responsive mobile
mobile_lightSmartphone, châssis clair
tabletAperçu responsive tablette
tablet_lightTablette, châssis clair
laptopPrésentations, hero produit
Décoratifs
roundedCoins adoucis, taille inchangée
shadowArticles de blog, documentation
polaroidTémoignages, ambiance rétro
gradientCartes sociales, images OG
Marque
shotbot_brandImage de marque Shotbot

Disponible sur tous les comptes. Cadres sans watermark avec Shotbot Pro.

JSON{
  "url": "https://example.com",
  "format": "png",
  "frame": "browser_chrome"
}

Galerie de rendus réels : cadres sur captures réelles →

Vous utilisez l'API legacy (add.shotbot.net) ? Les exemples v1 sont dans l'onglet API Legacy de la documentation.