Skip to content

Integrations

SDKs & CLI

Official Node.js/TypeScript and Python clients and a command-line tool.

The official clients wrap every endpoint with typed parameters, automatic retries and helpful errors.

Node.js / TypeScript

npm install @snaplens/sdk
import { SnaplensClient, SnaplensApiError } from "@snaplens/sdk";

const client = new SnaplensClient({ apiKey: process.env.SNAPLENS_API_KEY });

// Screenshot → bytes (Buffer on Node)
const shot = await client.capture({ url: "https://example.com", full_page: true, format: "png" });
// or write straight to disk
await client.captureToFile({ url: "https://example.com" }, "example.png");

// Content
const page = await client.content({ url: "https://example.com", include_markdown: true });

// AI analysis
const insights = await client.analyze({ url: "https://example.com", custom_prompt: "Focus on pricing" });

// Raw HTTP crawl
const crawl = await client.crawler({ query: "https://example.com" });

// Free endpoints
const usage = await client.usage();
const health = await client.stats({ engine: "capture" });

Options

Option Default Description
apiKey SNAPLENS_API_KEY env Your API key.
baseUrl SNAPLENS_BASE_URL env or the public API Override for testing.
timeoutMs 65000 Per-request timeout.
maxRetries 3 Retries for transient failures.
retryDelay 1000 Initial backoff in ms (multiplied by 1.5 each attempt).

Retries

Requests are retried up to 3 times with a backoff of 1 s × 1.5ⁿ on:

  • 5xx responses and 408;
  • network errors and timeouts;
  • plan rate limits (401 Rate limit exceeded: …). Per-key quota errors are not retried.

A Retry-After header, when present, takes precedence.

Async jobs

const accepted = await client.capture({ url: "https://example.com", is_async: true });
const job = await client.waitForJob(accepted.data.job_id, {
  onProgress: (j) => console.log(j.status, j.progress),
});

waitForJob(id, { onProgress, intervalMs, timeoutMs }) polls with backoff (×1.5 up to 60 s) and throws SnaplensJobError if the job fails.

Batches

const results = await client.batch(urls, (url) => client.content({ url, include_markdown: true }), { concurrency: 5 });
for (const r of results) {
  if (r.status === "fulfilled") console.log(r.value);
  else console.error(r.reason);
}

batch(inputs, fn, { concurrency }) runs with bounded concurrency (default 10); one failure doesn't stop the rest and results keep input order.

Errors

try {
  await client.capture({ url: "https://example.com" });
} catch (err) {
  if (err instanceof SnaplensApiError) {
    console.error(err.status, err.message); // e.g. 402 "Insufficient credits: 1 required, 0 available"
  }
}
const ok = SnaplensClient.verifyWebhook(process.env.SNAPLENS_WEBHOOK_SECRET!, rawBody, req.headers["x-snaplens-signature"]);
pip install snaplens
from snaplens import Snaplens, SnaplensApiError

client = Snaplens(api_key="YOUR_API_KEY")  # or set SNAPLENS_API_KEY

png = client.capture(url="https://example.com", full_page=True)
open("example.png", "wb").write(png)

page = client.content(url="https://example.com", include_markdown=True)
insights = client.analyze(url="https://example.com")
crawl = client.crawler(query="https://example.com")
print(client.usage()["remaining"])

job = client.content(url="https://example.com", is_async=True)
done = client.wait_for_job(job["job_id"], on_progress=lambda j: print(j["progress"]))

The Python client has the same methods, retry rules and error semantics as the Node SDK (SnaplensApiError with status and message).

CLI

npx @snaplens/cli capture https://example.com -o shot.png

Set your key once:

export SNAPLENS_API_KEY="your_api_key"

Common commands:

snaplens capture https://example.com -o shot.png --full-page --format webp
snaplens content https://example.com --markdown > page.md
snaplens analyze https://example.com
snaplens usage

Any API parameter can be passed as a flag. Run snaplens --help for the full list.

Exit codes

Code Meaning
0 Success
1 API error (non-2xx response) — the message is printed to stderr
2 Usage error (invalid arguments, missing API key)

Other languages

The API is plain HTTP — see the multi-language examples on the home page and in each API reference page.