Skip to content
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.

$npm i @medalsocial/sdk View on GitHub npm
Quickstart

From install to first call in five minutes

bashInstall
npm 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 calls
import { 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.
Get started guide Authentication & API keys Webhooks REST API reference MCP server for AI agents