DeltaBase with Alchemy
Manage DeltaBase event stores and webhook subscriptions from alchemy.run.ts
If your project already uses Alchemy.run, keep DeltaBase there too.
This guide shows how to create event stores and webhook subscriptions with @delta-base/alchemy so your DeltaBase control plane lives beside the rest of your infrastructure.
When to use this
Section titled “When to use this”Use this guide when:
- you already deploy infra with
alchemy.run.ts - you want DeltaBase resources reconciled with the same deploy
- you prefer reusable TypeScript resources over a separate CLI config file
If you want DeltaBase-only infrastructure and nothing else, the CLI IaC guide is simpler.
1. Install the packages
Section titled “1. Install the packages”pnpm add @delta-base/alchemy alchemy @delta-base/serverWhy @delta-base/server too?
Because @delta-base/alchemy builds on the same public SDK you use elsewhere. Less drift. Fewer surprises.
2. Create an alchemy.run.ts
Section titled “2. Create an alchemy.run.ts”import alchemy from 'alchemy';import { DeltaBaseEventStore, DeltaBaseSubscription,} from '@delta-base/alchemy';
const app = await alchemy('billing');
const baseUrl = process.env.DELTABASE_URL ?? 'https://api.delta-base.com';const apiKey = process.env.DELTABASE_API_KEY ?? '';const projectionToken = process.env.PROJECTION_AUTH_TOKEN ?? '';
const billingStore = await DeltaBaseEventStore('billing-events', { baseUrl, apiKey, description: 'Billing service event store', settings: { retentionPeriodDays: 365, },});
await DeltaBaseSubscription('invoice-projection', { baseUrl, apiKey, eventStoreName: billingStore.eventStoreName, eventFilter: ['invoice.created', 'invoice.paid'], webhook: { url: 'https://billing.example.com/api/projections/invoices/events', headers: { Authorization: `Bearer ${projectionToken}`, }, retryPolicy: { strategy: 'fixed', maxAttempts: 5, initialDelayMs: 60_000, maxDelayMs: 60_000, }, },});
await app.finalize();That’s the core flow.
DeltaBaseEventStorereconciles the event storeDeltaBaseSubscriptionreconciles a webhook subscriber for that storeapp.finalize()tells Alchemy to finish the deployment and clean up anything orphaned
3. Deploy it
Section titled “3. Deploy it”pnpm alchemy deploy ./alchemy.run.tsOr for local Alchemy development:
pnpm alchemy dev ./alchemy.run.tsWhat gets reconciled
Section titled “What gets reconciled”Event stores
Section titled “Event stores”DeltaBaseEventStore will:
- create the store if it does not exist
- update description and settings if they drift
- delete the store when the resource is removed
Subscriptions
Section titled “Subscriptions”DeltaBaseSubscription will:
- create a webhook subscription if it does not exist
- update the event filter and webhook config when they change
- delete the subscription when the resource is removed
Webhook only for now. That’s intentional.
Things to know before you use it
Section titled “Things to know before you use it”subscriberId is stable
Section titled “subscriberId is stable”If you set subscriberId, treat it like infrastructure identity. Changing it later means making a new resource.
eventStoreName is not mutable
Section titled “eventStoreName is not mutable”Move a subscription to a different store by creating a new resource. Don’t try to repoint the old one.
Keep secrets out of git
Section titled “Keep secrets out of git”Use environment variables or Alchemy secrets for tokens and API keys.
const apiKey = process.env.DELTABASE_API_KEY ?? '';Normalize webhook URLs
Section titled “Normalize webhook URLs”The resource normalizes extra trailing slashes for you. Still, give it the real endpoint you expect to run in prod.
Alchemy docs worth reading
Section titled “Alchemy docs worth reading”Those explain how custom resources work and why app.finalize() matters.