TypeScript SDK

A client for the delivery API.

npm install @coppercms/sdk

The SDK uses fetch and nothing else. It runs in Node and browsers and Cloudflare Workers and Deno. It has no dependencies and no build step.

Keep the key on a server. A key in a browser bundle is public.

Create a client

import { createClient } from '@coppercms/sdk'

const copper = createClient({ apiKey: process.env.COPPER_KEY })
OptionWhat it is
apiKeyThe delivery key. Required.
baseUrlDefaults to https://api.coppercms.com.
fetchA different fetch. For tests or a custom agent.

listPosts

const { data, nextCursor } = await copper.listPosts({
  tag: 'news',
  since: new Date('2026-08-01'),
  limit: 20,
})

Takes tag and since and limit and cursor and q. It also takes an AbortSignal.

since takes a Date or a string.

getPost

const post = await copper.getPost('a-new-office-in-lisbon')

Returns null when the article is not found. Every other failure throws.

allPosts

for await (const post of copper.allPosts({ since })) {
  await upsert(post)
}

Walks every page.

verifyWebhook

import { verifyWebhook } from '@coppercms/sdk'

const ok = await verifyWebhook({ secret, rawBody, signature, timestamp })

Returns a promise. It uses the crypto built into the platform.

It never throws. A bad signature returns false. An unreadable timestamp returns false. The wrong secret returns false.

The timestamp is checked before the signature.

Default tolerance5 minutes either way

Change it with toleranceSeconds.

Errors

import { CopperError } from '@coppercms/sdk'

try {
  await copper.listPosts()
} catch (error) {
  if (error instanceof CopperError) handle(error.status)
}

CopperError carries the HTTP status and the message from the API. See Errors.