Back to Blog
integrationworkflowautomation

Integrating BoltShot with Your Workflow

Discover how to integrate BoltShot with custom applications, CI/CD pipelines, and storage solutions.

BoltShot Team
April 17, 2026
Integrating BoltShot with Your Workflow

Integrating BoltShot with Your Workflow

BoltShot can be integrated into various workflows and tools to automate screenshot generation. Pass options as query parameters on /capture.

Errors are always returned as JSON ({ success: false, error: { code, message, details } }), including when the successful response would be a binary file.

Custom Applications

Node.js Example

const axios = require('axios');
const fs = require('fs');

function getApiErrorMessage(error) {
  const data = error.response?.data;
  if (!data) return error.message || 'Screenshot failed';

  if (typeof data === 'object' && data.error?.message) {
    return data.error.message;
  }

  const text = Buffer.isBuffer(data) ? data.toString('utf8') : String(data);
  try {
    const parsed = JSON.parse(text);
    return parsed.error?.message || text;
  } catch {
    return text;
  }
}

// Default: returns binary file
async function captureScreenshot(url) {
  try {
    const response = await axios.get('https://api.boltshot.dev/capture', {
      params: {
        url,
        format: 'png',
        apiKey: process.env.BOLTSHOT_API_KEY,
      },
      responseType: 'arraybuffer',
      validateStatus: (status) => status === 200,
    });

    fs.writeFileSync('screenshot.png', response.data);
    return response.data;
  } catch (error) {
    throw new Error(getApiErrorMessage(error));
  }
}

// JSON response with returnFile=false
async function captureScreenshotJson(url, storageConfigId) {
  try {
    const response = await axios.get('https://api.boltshot.dev/capture', {
      params: {
        url,
        format: 'png',
        returnFile: 'false',
        apiKey: process.env.BOLTSHOT_API_KEY,
        ...(storageConfigId ? { storageConfigId } : {}),
      },
    });

    // { success: true, data: { url?, imageData?, fileName, ... } }
    // imageData is a data URL when no storage URL is returned
    return response.data.data;
  } catch (error) {
    throw new Error(getApiErrorMessage(error));
  }
}

Python Example

import requests
import os

def _raise_api_error(response):
    try:
        payload = response.json()
        message = payload.get('error', {}).get('message', 'Screenshot failed')
    except ValueError:
        message = response.text or 'Screenshot failed'
    raise Exception(message)

def capture_screenshot(url, return_json=False, storage_config_id=None):
    api_key = os.environ['BOLTSHOT_API_KEY']
    params = {
        'url': url,
        'format': 'png',
        'apiKey': api_key,
    }

    if return_json:
        params['returnFile'] = 'false'
    if storage_config_id:
        params['storageConfigId'] = storage_config_id

    response = requests.get('https://api.boltshot.dev/capture', params=params)

    if not response.ok:
        _raise_api_error(response)

    if return_json:
        return response.json().get('data', {})

    with open('screenshot.png', 'wb') as f:
        f.write(response.content)
    return 'screenshot.png'

JavaScript/TypeScript (Fetch) Example

async function parseApiError(response) {
  try {
    const error = await response.json();
    return error.error?.message || `API error: ${response.status}`;
  } catch {
    return `API error: ${response.status}`;
  }
}

// Default: returns binary file
async function captureScreenshot(url, options = {}) {
  const params = new URLSearchParams({
    url,
    format: 'png',
    apiKey: process.env.BOLTSHOT_API_KEY,
    ...options,
  });

  const response = await fetch(`https://api.boltshot.dev/capture?${params}`);

  if (!response.ok) {
    throw new Error(await parseApiError(response));
  }

  return await response.blob();
}

// JSON response with returnFile=false
async function captureScreenshotJson(url, options = {}) {
  const params = new URLSearchParams({
    url,
    format: 'png',
    returnFile: 'false',
    apiKey: process.env.BOLTSHOT_API_KEY,
    ...options,
  });

  const response = await fetch(`https://api.boltshot.dev/capture?${params}`);

  if (!response.ok) {
    throw new Error(await parseApiError(response));
  }

  const result = await response.json();
  return result.data; // { url?, imageData?, fileName, ... }
}

CI/CD Integration

Automate screenshot generation in your CI/CD pipeline. Store your API key as a secret — avoid committing it to source control:

# GitHub Actions example
- name: Generate Screenshots
  run: |
    curl -o screenshot.png "https://api.boltshot.dev/capture?url=https://example.com&format=png&apiKey=${{ secrets.BOLTSHOT_API_KEY }}"

Storage Integration

For production, configure S3-compatible storage in your dashboard at /dashboard/storage:

  1. Add your S3-compatible endpoint, bucket, and credentials
  2. Test the connection and activate the configuration
  3. Set it as the default for your organization

When an active storage configuration exists, captures can upload automatically and JSON responses (returnFile=false) include a permanent url in data.

Reference a saved configuration per request with storageConfigId:

curl "https://api.boltshot.dev/capture?url=https://example.com&format=png&returnFile=false&storageConfigId=your-config-id&apiKey=your-api-key"

For one-off or dynamic buckets, you can pass per-request storage credentials as query parameters (requestStorageEnabled, requestStorageEndpoint, etc.). Avoid putting secrets in URLs in production — prefer dashboard storage configs or server-side proxies.

Authentication Methods

BoltShot supports API key authentication via query parameter or header:

Query parameter:

curl -o screenshot.png "https://api.boltshot.dev/capture?url=https://example.com&format=png&apiKey=your-api-key"

Header (preferred for server-side apps):

curl -o screenshot.png -H "X-API-Key: your-api-key" "https://api.boltshot.dev/capture?url=https://example.com&format=png"

These integrations make it easy to incorporate BoltShot into your existing workflows.