Skip to main content

SDK quickstart

Install the SDK, give it a key, and make your first call. The whole thing is three steps.

:::warning Pre-release This page documents @slothbox/sdk 0.1.0 and slothbox 0.1.0, which are not yet on npm / PyPI at the time of writing — the install commands below will work once those releases ship. See the SDKs overview. :::

1. Install

npm install @slothbox/sdk

The package ships dual ESM + CJS builds with bundled types and has zero runtime dependencies. It runs anywhere a WHATWG fetch global exists — Node.js 18+, Cloudflare Workers, Deno, Bun, and modern browsers.

2. Authenticate

The SDKs authenticate with an org service-account sk_ key — the org-level credential for headless, unattended use that comes with the API plan. Personal seat keys and browser sessions are not supported. An organization owner creates the key in the web app under the org's Service accounts settings — the headless guide walks through it.

The key is shown once — store it in your secret manager, never in code. Export it as SLOTHBOX_API_KEY (that's the service-account key, not a personal one) and the client picks it up automatically:

export SLOTHBOX_API_KEY="sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
import { Slothbox } from "@slothbox/sdk";

// Reads SLOTHBOX_API_KEY from the environment.
const slothbox = new Slothbox();

// Or pass the key explicitly (e.g. in runtimes without process.env):
// const slothbox = new Slothbox({ apiKey: "sk_…" });

The constructor throws immediately if no key is available, so a missing secret fails fast rather than on the first request. The key is sent the way the API expects it — verbatim in the Authorization header, no Bearer prefix (see Authentication) — so there's nothing to format yourself.

You can also pass baseUrl to target a different stack, or fetch to supply your own implementation (middleware, proxying, testing) — see Configuration for every option.

3. Make your first call

GET /me is the API's "who am I" — it returns your identity and the organizations the key can see, and it's the same first call the curl quickstart makes:

const { user, organizations } = await slothbox.me.get();
console.log(`Hello ${user.email}`);

// Most operations are org-scoped — grab an orgId and look around:
const orgId = organizations[0].orgId;
const { environments } = await slothbox.environments.list({ orgId });

If the call throws an AuthenticationError, the key is missing, mistyped, or revoked — see Errors, retries & rate limits for the full error hierarchy.

How methods are named

Every published operation is exposed, grouped by resource family and named after the operation ids you see in the API reference: slothbox.environments.launch(…), slothbox.templates.rebake(…), slothbox.webhooks.rollSecret(…), and so on. In TypeScript, path parameters sit at the top of the args object, with query and body keys where the operation defines them — all typed from the API's OpenAPI document.

Python uses the same families and names in snake_case (client.webhooks.roll_secret(…)), with path parameters as positional arguments, query parameters as keyword arguments, and the request body as a typed model from slothbox.models or a plain dict keyed by the wire (JSON) names:

client.environments.launch(org_id, {"templateId": template_id})

Every method also takes per-request options (signal/headers in TypeScript; options=RequestOptions(…) in Python — see Configuration). Cursor-paginated lists (audit events, webhook deliveries) resolve to a page you can iterate to walk every page transparently — see Pagination.

Async Python

AsyncSlothbox is the same surface with await — full resource coverage, async for pagination, async waiters. Use it as an async context manager so the underlying httpx client is closed:

from slothbox import AsyncSlothbox

async def main() -> None:
async with AsyncSlothbox() as client:
me = await client.me.get()
box = await client.environments.launch_and_wait(
me.organizations[0].org_id, {"templateId": template_id}
)

(The sync Slothbox is a context manager too — with Slothbox() as client: — or call client.close() when you're done.)

Next steps