Skip to content

Build Your Own Vizzly SDK

You do not need a complex SDK to integrate with Vizzly.

When vizzly run or vizzly tdd is active, the CLI starts a local HTTP server. Your code only needs to find that server and POST screenshots to it.

What your client needs to do

  1. Discover the local server URL.
  2. Send screenshots to POST /screenshot.

Find the server

Option 1: VIZZLY_SERVER_URL

If this environment variable is present, use it.

import os
server_url = os.getenv("VIZZLY_SERVER_URL")

Option 2: .vizzly/server.json

If the env var is missing, look for .vizzly/server.json in the current directory or a parent directory.

import json
import os
def find_server():
directory = os.getcwd()
root = os.path.abspath(os.sep)
while directory != root:
server_file = os.path.join(directory, ".vizzly", "server.json")
if os.path.exists(server_file):
with open(server_file) as f:
data = json.load(f)
return f"http://localhost:{data['port']}"
directory = os.path.dirname(directory)
return None

This is how the built-in client auto-discovers TDD mode.

Send a screenshot

Send a JSON POST request to {server_url}/screenshot.

{
"name": "login-page",
"image": "iVBORw0KGgoAAAANSUhEUg...",
"type": "base64",
"properties": {
"browser": "chrome",
"viewport": { "width": 1920, "height": 1080 }
}
}

You can also send a file path instead of base64:

{
"name": "login-page",
"image": "/path/to/screenshot.png",
"type": "file-path",
"properties": {
"browser": "chrome",
"viewport": { "width": 1920, "height": 1080 }
}
}

Send user metadata directly in properties. Nested objects, including a key named properties, stay intact; Vizzly options belong beside that metadata bag.

Required fields

  • name
  • image

Useful optional fields

  • type
  • buildId
  • properties

Keep properties focused on metadata that helps identify variants, like browser, viewport, device, theme, or locale.

What to expect back

The server returns JSON. In cloud mode, HTTP 200 with success: true and queued: true means the local server accepted the capture for upload. It doesn’t confirm that Vizzly Cloud stored the image.

The CLI tracks upload results and reports failed screenshot names and errors. It accepts later captures even after an upload fails. vizzly run waits for pending uploads before finishing and marks an incomplete visual build as failed, while preserving the test command’s exit code.

Your SDK should await the local response. Let vizzly run handle the final upload summary and build status. For custom tooling that needs upload results earlier, POST /flush waits for pending uploads and returns uploaded, reused, failed, total, and failures (each with name and error). Its success field is false when any upload failed. These counts cover the whole run, including results from earlier flushes.

Cloud captures follow the image and name requirements.

In TDD mode, the response includes tddMode: true and comparison details.

The built-in JS client treats visual diffs as part of the normal flow so the rest of the test run can continue and report a full summary at the end.

Reference implementation

If you want your custom SDK to behave like the official one, start from the public vizzly-cli source:

  • https://github.com/vizzly-testing/cli/blob/main/src/client/index.js
  • https://github.com/vizzly-testing/cli/blob/main/src/server/routers/screenshot.js
  • https://github.com/vizzly-testing/cli/blob/main/src/server/handlers/tdd-handler.js

Mirror that contract first and keep the surface area small.