SDKApache-2.0 · TypeScript-first
The Medal platform, in your codebase.
A typed TypeScript client for the Medal REST API: posts, emails, contacts and deals, bookings, helpdesk, webhooks and GDPR. It uses native fetch, so it works in Node.js, Bun, Deno, Cloudflare Workers and the browser.
From install to first call in five minutes
bashInstallnpm i @medalsocial/sdk # or pnpm add @medalsocial/sdk
Authenticate
Create an API key in your workspace settings. Keys start with medal_ and are scoped to a single workspace, so an integration can never reach the wrong data. Pass one to new Medal(apiKey). OAuth access tokens work too — add { workspaceId } to the options, alongside baseUrl and timeout.
tsYour first callsimport { Medal } from '@medalsocial/sdk'; const apiKey = process.env.MEDAL_API_KEY; if (!apiKey) throw new Error('Set MEDAL_API_KEY to a workspace API key (medal_…)'); const medal = new Medal(apiKey); // Which channels can this workspace post to? const { data: channels } = await medal.posts.channels(); const [channel] = channels; if (!channel) throw new Error('Connect a channel in the Medal app first'); const { data: post } = await medal.posts.create({ content: 'Hello from the Medal SDK!', channel_ids: [channel.id], }); const tomorrow = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); await medal.posts.schedule(post.id, { scheduled_at: tomorrow }); await medal.emails.send({ template_slug: 'welcome', to: 'user@example.com', variables: { name: 'Ida' }, }); const { data: contact } = await medal.contacts.create({ email: 'ida@example.com', first_name: 'Ida', status: 'lead', });
Ship your first integration
Sync signups from your app into contacts, schedule posts straight from your own pipeline, send transactional email from a template, and bridge Helpdesk conversations into your stack with signed webhooks.
Built for production
Failures arrive as a typed MedalApiError carrying status, code, message and details. Requests retry automatically on 429 and 5xx, up to three attempts, honouring Retry-After. List endpoints use cursor pagination. The package ships an OpenAPI 3.1 contract, so you can generate clients for other languages from the same source of truth.