Integration

SDK Integration

Use official API client libraries with Ghostbox. Most SDKs let you override the base URL -- change one line and your existing code works.

Stripe

TypeScript / Node.jstypescript
import Stripe from 'stripe';

const stripe = new Stripe(process.env.GHOSTBOX_API_KEY!, {
  apiVersion: '2024-12-18.acacia',
  host: 'ghostbox.dev/sandbox/stripe',
  protocol: 'https',
});

// All SDK methods work as normal
const customer = await stripe.customers.create({
  email: 'jane@example.com',
  name: 'Jane Doe',
});

const paymentIntent = await stripe.paymentIntents.create({
  amount: 2000,
  currency: 'usd',
  customer: customer.id,
});
Pythonpython
import stripe

stripe.api_key = "sandbox_test_abc123..."
stripe.api_base = "https://ghostbox.dev/sandbox/stripe"

customer = stripe.Customer.create(
    email="jane@example.com",
    name="Jane Doe",
)

payment_intent = stripe.PaymentIntent.create(
    amount=2000,
    currency="usd",
    customer=customer.id,
)

Resend

TypeScript / Node.jstypescript
import { Resend } from 'resend';

const resend = new Resend('sandbox_test_abc123...', {
  baseUrl: 'https://ghostbox.dev/sandbox/resend',
});

const { data, error } = await resend.emails.send({
  from: 'hello@example.com',
  to: 'user@example.com',
  subject: 'Hello from Ghostbox',
  html: '<p>Welcome!</p>',
});
Pythonpython
import resend

resend.api_key = "sandbox_test_abc123..."
resend.base_url = "https://ghostbox.dev/sandbox/resend"

email = resend.Emails.send({
    "from": "hello@example.com",
    "to": "user@example.com",
    "subject": "Hello from Ghostbox",
    "html": "<p>Welcome!</p>",
})

PostHog

TypeScript / Node.jstypescript
import PostHog from 'posthog-node';

const posthog = new PostHog('sandbox_test_abc123...', {
  host: 'https://ghostbox.dev/sandbox/posthog',
});

// Capture events
posthog.capture({
  distinctId: 'user-123',
  event: 'page_view',
  properties: { page: '/pricing' },
});

// Evaluate feature flags
const isEnabled = await posthog.isFeatureEnabled(
  'new-checkout',
  'user-123',
);
Pythonpython
from posthog import Posthog

posthog = Posthog(
    "sandbox_test_abc123...",
    host="https://ghostbox.dev/sandbox/posthog",
)

posthog.capture(
    "user-123",
    "page_view",
    properties={"page": "/pricing"},
)

is_enabled = posthog.feature_enabled(
    "new-checkout",
    "user-123",
)

Mailchimp

TypeScript / Node.jstypescript
import mailchimp from '@mailchimp/mailchimp_marketing';

mailchimp.setConfig({
  apiKey: 'sandbox_test_abc123...',
  server: 'ghostbox', // normally 'us1', 'us2', etc.
});

// Override the base URL for sandbox
// Mailchimp SDK constructs URLs as https://{server}.api.mailchimp.com
// so we need to use a direct fetch approach:

const response = await fetch(
  'https://ghostbox.dev/sandbox/mailchimp/3.0/lists',
  {
    headers: {
      Authorization: `Basic ${btoa('anyuser:sandbox_test_abc123...')}`,
    },
  },
);

const lists = await response.json();
Pythonpython
import requests
from base64 import b64encode

API_KEY = "sandbox_test_abc123..."
BASE_URL = "https://ghostbox.dev/sandbox/mailchimp/3.0"

auth = b64encode(f"anyuser:{API_KEY}".encode()).decode()
headers = {
    "Authorization": f"Basic {auth}",
    "Content-Type": "application/json",
}

# Create a list
response = requests.post(
    f"{BASE_URL}/lists",
    json={"name": "Newsletter"},
    headers=headers,
)
list_data = response.json()

The Mailchimp SDK constructs its own base URL from the server config parameter, making direct SDK override difficult. We recommend using HTTP clients directly for Mailchimp sandbox testing.

Environment variable pattern

The cleanest integration pattern: use environment variables to switch between real and sandbox APIs. Your application code stays the same -- only the config changes.

.env.testbash
GHOSTBOX_API_KEY=sandbox_test_abc123...
STRIPE_BASE_URL=https://ghostbox.dev/sandbox/stripe
RESEND_BASE_URL=https://ghostbox.dev/sandbox/resend
POSTHOG_HOST=https://ghostbox.dev/sandbox/posthog
MAILCHIMP_BASE_URL=https://ghostbox.dev/sandbox/mailchimp/3.0
config.tstypescript
export const config = {
  stripe: {
    key: process.env.STRIPE_API_KEY ?? process.env.GHOSTBOX_API_KEY!,
    host: process.env.STRIPE_BASE_URL
      ? new URL(process.env.STRIPE_BASE_URL).host
      : 'api.stripe.com',
  },
  resend: {
    key: process.env.RESEND_API_KEY ?? process.env.GHOSTBOX_API_KEY!,
    baseUrl: process.env.RESEND_BASE_URL ?? 'https://api.resend.com',
  },
};

Common gotchas

Stripe API version header

Ghostbox ignores the Stripe-Version header. The sandbox always returns the same response shape regardless of the API version specified.

Webhook endpoints

Ghostbox does not send webhook events. If your code depends on webhooks, you will need to simulate those separately or trigger the webhook handler directly in tests.

HTTPS required

All sandbox endpoints use HTTPS. Plain HTTP requests will be rejected. Make sure your SDK config uses protocol: 'https' where applicable.