npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sendclover/sdk

v0.1.0

Published

Official TypeScript client for the Clover email API

Readme

@sendclover/sdk

Official TypeScript client for Clover's account/environment-scoped platform API. Read the Clover API reference for the public request and response contract.

Install

npm install @sendclover/sdk

Native client

Bind the client to a Clover account and environment. All resource calls then use the current /api/v1/platform/... route family and camelCase DTOs.

import { CloverClient } from "@sendclover/sdk";

const clover = new CloverClient({
  baseUrl: process.env.CLOVER_API_URL!,
  apiKey: process.env.CLOVER_API_KEY!,
  accountId: process.env.CLOVER_ACCOUNT_ID!,
  environmentId: process.env.CLOVER_ENVIRONMENT_ID!,
});

const accepted = await clover.emails.send(
  {
    from: { address: "[email protected]" },
    to: [{ address: "[email protected]" }],
    subject: "Hello",
    text: "Sent asynchronously",
  },
  { idempotencyKey: "order-1234" },
);

await clover.domains.list();
await clover.webhooks.list();

For applications that select several environments dynamically, use the explicit platform message resource:

const message = await clover.platformMessages.send(
  { accountId: "account_01", environmentId: "environment_01" },
  {
    from: { address: "[email protected]" },
    to: [{ address: "[email protected]" }],
    subject: "Hello",
    text: "Sent through the scoped platform API",
  },
  { idempotencyKey: "order-1234" },
);

The client exposes scoped emails, domains, and webhooks resources plus top-level email convenience methods. Platform API-key management stays in the dashboard-only control plane and is intentionally not exposed here.

Resend-compatible façade

For applications using Resend-style method names, pass the same account and environment scope:

import { Resend } from "@sendclover/sdk/resend";

const resend = new Resend(process.env.CLOVER_API_KEY, {
  baseUrl: process.env.CLOVER_API_URL,
  accountId: process.env.CLOVER_ACCOUNT_ID,
  environmentId: process.env.CLOVER_ENVIRONMENT_ID,
});

const { data, error } = await resend.emails.send({
  from: "Acme <[email protected]>",
  to: "[email protected]",
  subject: "Hello",
  html: "<p>Hi</p>",
  tags: [{ name: "campaign", value: "welcome" }],
});

The façade maps email and batch sends, scheduling, cancellation, domains, and webhooks to the scoped platform routes. Domain onboarding requires providerBindingId. Results use { data, error }, and mutations automatically send a valid Idempotency-Key when one is not supplied.

Transport contract

  • baseUrl is the API origin only; paths are scoped under /api/v1/platform.
  • Authentication uses Authorization: Bearer <api-key>.
  • Success bodies unwrap CommonResponse.data.
  • Errors use the V2 nested ErrorResponse envelope.
  • Mutations require an idempotency key matching ^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$.
  • Clients send X-Request-ID values matching ^req_[A-Za-z0-9_-]{8,128}$.

Quality gates

npm run quality       # lint, format, typecheck, tests, coverage thresholds
npm pack --dry-run    # inspect the publish file list

The package also runs quality from prepublishOnly. Provider and DNS qualification stays in Clover's backend-owned E2E harness because it requires real provider bindings and public DNS; the SDK publication gate remains fully offline and deterministic.