> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deploybaseline.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Programmatic API

> Start any emulator from your tests with createEmulator, or import a provider package directly.

Use emulators as libraries in your tests and scripts. There are two approaches: the `@deploybaseline/cli` package (which wraps all services) and the individual `@deploybaseline/*` scoped packages.

## CLI package

The `@deploybaseline/cli` package provides a `createEmulator` helper that starts any service by name.

```bash theme={null}
npm install @deploybaseline/cli
```

```typescript theme={null}
import { createEmulator } from "@deploybaseline/cli";

const github = await createEmulator({ service: "github", port: 4001 });
const stripe = await createEmulator({ service: "stripe", port: 4002 });

github.url; // 'http://localhost:4001'
stripe.url; // 'http://localhost:4002'

await github.close();
await stripe.close();
```

Each built-in emulator runs in its own Node process, as it does under the CLI, so starting one takes around 100 ms. Start one per test suite and call `reset()` between tests, as below, rather than one per test. `close()` stops the process. [Custom emulators](/custom-emulators.md) run in your test process.

### Generated secrets

When a GitHub App omits `private_key`, `createEmulator` generates an RSA-2048 PKCS#1 key for that emulator instance:

```typescript theme={null}
const github = await createEmulator({
  service: "github",
  seed: {
    github: {
      users: [{ login: "octocat" }],
      apps: [
        {
          app_id: 12345,
          slug: "my-github-app",
          name: "My GitHub App",
          installations: [{ installation_id: 100, account: "octocat" }],
        },
      ],
    },
  },
});

const privateKey = github.generatedSecrets.find(
  (secret) => secret.kind === "github.app_private_key" && secret.id === "12345",
)?.value;
```

Generated keys remain stable across `reset()` calls and appear only in `generatedSecrets`. Explicitly configured keys are never returned there. A new `createEmulator` call generates a new key.

### Vitest / Jest setup

```typescript theme={null}
// vitest.setup.ts
import { createEmulator, type Emulator } from "@deploybaseline/cli";

let github: Emulator;
let stripe: Emulator;

beforeAll(async () => {
  [github, stripe] = await Promise.all([
    createEmulator({ service: "github", port: 4001 }),
    createEmulator({ service: "stripe", port: 4002 }),
  ]);
  process.env.GITHUB_EMULATOR_URL = github.url;
  process.env.STRIPE_EMULATOR_URL = stripe.url;
});

afterEach(() => Promise.all([github.reset(), stripe.reset()]));
afterAll(() => Promise.all([github.close(), stripe.close()]));
```

### createEmulator options

<table>
  <thead>
    <tr>
      <th>Option</th>
      <th>Default</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `service`
      </td>

      <td>
        *(required)*
      </td>

      <td>
        Service name: `'github'`, `'google'`, `'slack'`,&#x20;
        `'apple'`, `'microsoft'`, `'okta'`, `'resend'`,&#x20;
        `'stripe'`, `'clerk'`, `'linear'`, or `'twilio'`
      </td>
    </tr>

    <tr>
      <td>
        `port`
      </td>

      <td>
        `4000`
      </td>

      <td>Port for the HTTP server</td>
    </tr>

    <tr>
      <td>
        `hostname`
      </td>

      <td>
        `127.0.0.1`
      </td>

      <td>Listening address for built-in and custom emulators</td>
    </tr>

    <tr>
      <td>
        `seed`
      </td>

      <td>none</td>
      <td>Inline seed data (same shape as a provider's section in the config file)</td>
    </tr>

    <tr>
      <td>
        `baseUrl`
      </td>

      <td>none</td>

      <td>
        Override the advertised base URL (used in OAuth redirects, webhook URLs, etc.). Per-service `baseUrl`&#x20;
        in seed config takes highest priority, then this option, then the `BASELINE_BASE_URL` env var
        (supports `{service}` template), then `http://localhost:<port>`.
      </td>
    </tr>

    <tr>
      <td>
        `state`
      </td>

      <td>none</td>

      <td>
        Keep state across restarts: a JSON file path, `sqlite:<path>`, or `libsql://` URL
        (locked to one emulator at a time), or a `PersistenceAdapter` such as `sqliteState()`.
        Saved state wins over `seed`. See [Saved state](/state.md).
      </td>
    </tr>

    <tr>
      <td>
        `resetState`
      </td>

      <td>
        `false`
      </td>

      <td>Ignore saved state, reseed, and overwrite it</td>
    </tr>

    <tr>
      <td>
        `saveDebounceMs`
      </td>

      <td>
        `250`
      </td>

      <td>
        Wait after a change before saving; `close()` always saves
      </td>
    </tr>

    <tr>
      <td>
        `version`
      </td>

      <td>this CLI's range</td>

      <td>
        Provider version range for a built-in service, such as `'^0.14'`. The provider comes from the
        project's `node_modules`, the provider cache, or a pull from npm. See&#x20;
        [Provider versions](/provider-versions.md)
      </td>
    </tr>

    <tr>
      <td>
        `offline`
      </td>

      <td>
        `false` (or `BASELINE_OFFLINE=1`)
      </td>

      <td>Never touch the network when finding the provider</td>
    </tr>

    <tr>
      <td>
        `faults`
      </td>

      <td>none</td>

      <td>
        Injected latency and errors, in the same shape as a service's `faults` config. Also read from the
        service's seed section. Off unless set. See [Fault injection](/configuration.md#fault-injection)
      </td>
    </tr>
  </tbody>
</table>

Use `hostname: '0.0.0.0'` to allow connections from containers or other machines, and `baseUrl` to advertise a URL reachable by those clients. This option also applies to custom definitions passed to `createEmulator`.

### Instance methods

<table>
  <thead>
    <tr>
      <th>Method</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`url`</td>
      <td>Base URL of the running server</td>
    </tr>

    <tr>
      <td>`generatedSecrets`</td>
      <td>Readonly secrets generated while preparing seed data (reused from saved state when restored)</td>
    </tr>

    <tr>
      <td>`restored`</td>
      <td>`true` when the emulator started from saved state instead of seeding</td>
    </tr>

    <tr>
      <td>`reset()`</td>
      <td>Wipe the store and replay seed data (saved too, with `state`). Returns a Promise: await it before the next request</td>
    </tr>

    <tr>
      <td>`flush()`</td>
      <td>Write pending state now (with `state`)</td>
    </tr>

    <tr>
      <td>`snapshot()`</td>
      <td>Resolves to the current state as a state file object</td>
    </tr>

    <tr>
      <td>`restore(state)`</td>
      <td>Replace the current state with a `snapshot()` result, or a state file's contents (object or JSON text). Resolves to </td>
    </tr>

    <tr>
      <td>`saveSnapshot(name)`</td>
      <td>Save the current state under a name: a file next to `state`, otherwise in memory</td>
    </tr>

    <tr>
      <td>`restoreSnapshot(name)`</td>
      <td>Replace the current state with a named snapshot</td>
    </tr>

    <tr>
      <td>`listSnapshots()`, `deleteSnapshot(name)`</td>
      <td>List or delete named snapshots</td>
    </tr>

    <tr>
      <td>`close()`</td>
      <td>Shut down the HTTP server, close WebSocket connections (code 1001), and save state; returns a Promise</td>
    </tr>
  </tbody>
</table>

## Scoped packages

Each emulator is published as its own `@deploybaseline/*` package. Install only the ones you need:

```bash theme={null}
npm install @deploybaseline/github @deploybaseline/google @deploybaseline/linear @deploybaseline/twilio
```

### Available packages

One package per provider, in the same categories as the [Providers](/providers.md) page, plus the kits they share:

<table>
  <thead>
    <tr>
      <th>Package</th>
      <th>Provider</th>
      <th>What is emulated</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th colSpan="3">Identity and auth</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/auth0`
      </td>

      <td>Auth0</td>
      <td>Universal Login, OAuth and OIDC, Management API, role-based access control</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/clerk`
      </td>

      <td>Clerk</td>
      <td>Frontend API, Backend API, OAuth and OIDC, organizations, sessions, JWT templates</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/okta`
      </td>

      <td>Okta</td>
      <td>OAuth 2.0 and OIDC, authorization servers, users, groups, apps</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/apple`
      </td>

      <td>Apple</td>
      <td>Sign in with Apple: authorization, client secrets, ID tokens, server-to-server notifications</td>
    </tr>

    <tr>
      <th colSpan="3">Workspace and productivity</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/google`
      </td>

      <td>Google</td>
      <td>OAuth 2.0 and OIDC, Gmail, Calendar, Drive, Sheets, Docs</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/microsoft`
      </td>

      <td>Microsoft</td>
      <td>Entra ID OAuth 2.0 and OIDC, Microsoft Graph: Outlook mail, calendar, contacts, To Do, users and groups; SharePoint Online and OneDrive over Graph and the SharePoint REST API</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/notion`
      </td>

      <td>Notion</td>
      <td>Pages, databases and data sources, queries, search, blocks, comments, OAuth, webhooks</td>
    </tr>

    <tr>
      <th colSpan="3">Messaging and email</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/slack`
      </td>

      <td>Slack</td>
      <td>Web API, OAuth v2, incoming webhooks, interactivity, events, Socket Mode</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/discord`
      </td>

      <td>Discord</td>
      <td>Bot REST API, Gateway over WebSocket, interactions, OAuth2, rate limits</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/twilio`
      </td>

      <td>Twilio</td>
      <td>Programmable Messaging, Messaging Services, Verify, Voice, Conversations</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/whatsapp`
      </td>

      <td>WhatsApp</td>
      <td>Cloud API messages, templates, media, phone numbers and accounts, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/resend`
      </td>

      <td>Resend</td>
      <td>Emails, idempotency, domains, API keys, audiences and contacts, a local inbox</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/sendgrid`
      </td>

      <td>SendGrid</td>
      <td>Mail Send, scheduling, templates, API keys, Marketing, Event Webhook, a local inbox</td>
    </tr>

    <tr>
      <th colSpan="3">Payments and commerce</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/stripe`
      </td>

      <td>Stripe</td>

      <td>
        Customers, Payment and Setup Intents, charges, refunds, subscriptions, invoices, Checkout, Connect, webhooks
      </td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/paypal`
      </td>

      <td>PayPal</td>
      <td>Orders v2, a hosted approval page, Payments v2, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/square`
      </td>

      <td>Square</td>
      <td>Payments, refunds, orders, customers, catalog, locations, OAuth, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/plaid`
      </td>

      <td>Plaid</td>
      <td>Link, items and accounts, transactions, institutions, sandbox helpers, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/shopify`
      </td>

      <td>Shopify</td>
      <td>Admin GraphQL API, OAuth, webhooks</td>
    </tr>

    <tr>
      <th colSpan="3">Developer platforms</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/github`
      </td>

      <td>GitHub</td>

      <td>
        REST and GraphQL: repositories, issues, pull requests, organizations, webhooks, Actions, Checks, OAuth Apps and
        GitHub Apps
      </td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/linear`
      </td>

      <td>Linear</td>
      <td>GraphQL API, OAuth, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/jira`
      </td>

      <td>Jira</td>
      <td>REST API, JQL search, Agile boards and sprints, OAuth 2.0 (3LO), webhooks</td>
    </tr>

    <tr>
      <th colSpan="3">CRM and support</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/salesforce`
      </td>

      <td>Salesforce</td>
      <td>Records, SOQL, describe, sObject collections, composite requests, OAuth</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/hubspot`
      </td>

      <td>HubSpot</td>
      <td>CRM objects, search, associations, properties, pipelines, owners, OAuth, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/zendesk`
      </td>

      <td>Zendesk</td>
      <td>Tickets, comments, users, organizations and groups, search, views, triggers, OAuth, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/servicenow`
      </td>

      <td>ServiceNow</td>
      <td>Table API, Attachment API, Aggregate API</td>
    </tr>

    <tr>
      <th colSpan="3">Finance and ERP</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/netsuite`
      </td>

      <td>NetSuite</td>
      <td>Records, transforms, SuiteQL, custom fields and records, metadata, OAuth 2.0</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/quickbooks`
      </td>

      <td>QuickBooks</td>
      <td>Accounting entities, queries, batch, change data capture, OAuth 2.0, webhooks</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/xero`
      </td>

      <td>Xero</td>
      <td>Accounting API, OAuth 2.0 and OpenID Connect, webhooks</td>
    </tr>

    <tr>
      <th colSpan="3">Shared</th>
    </tr>

    <tr>
      <td>
        `@deploybaseline/core`
      </td>

      <td colSpan="2">Shared store, middleware, and utilities</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/graphql`
      </td>

      <td colSpan="2">GraphQL kit (Linear, GitHub, and Shopify run on it)</td>
    </tr>

    <tr>
      <td>
        `@deploybaseline/ws`
      </td>

      <td colSpan="2">WebSocket kit (Slack Socket Mode and the Discord Gateway run on it, and bundle it)</td>
    </tr>
  </tbody>
</table>

### Direct usage

Each scoped package exports its service plugin and seed helpers:

```typescript theme={null}
import * as github from "@deploybaseline/github";
import * as stripe from "@deploybaseline/stripe";
```

These are the same modules the CLI loads internally.

## Custom emulators

Custom definitions created with `defineEmulator` from `@deploybaseline/cli` work in the CLI and in in-process tests. The same definition provides typed state, HTTP handlers, reset, versioned snapshots, and optional inspection/persistence. See [Custom emulators](/custom-emulators.md) for the quickstart, API reference, and complete lifecycle semantics.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.