@craftatom/sdk
v0.3.2
Published
Type-safe CraftAtom integration SDK
Downloads
34
Maintainers
Readme
@craftatom/sdk
Type-safe Node.js and browser SDK for the CraftAtom email platform.
Install
npm install @craftatom/sdk
# or
pnpm add @craftatom/sdk
# or
yarn add @craftatom/sdkQuick Start
import { CraftAtomClient } from "@craftatom/sdk";
const craftatom = new CraftAtomClient({
apiKey: "your-api-key",
});
// Send an email
await craftatom.send({
template: "welcome",
to: ["[email protected]"],
data: { name: "Jane" },
});Configuration
const craftatom = new CraftAtomClient({
apiKey: "your-api-key", // Required
baseUrl: "https://...", // Optional — defaults to https://app.craftatom.com/api
fetch: customFetch, // Optional — custom fetch implementation
headers: { "X-Custom": "v" }, // Optional — extra headers on every request
});You can also use the factory function:
import { createCraftAtomClient } from "@craftatom/sdk";
const craftatom = createCraftAtomClient({ apiKey: "your-api-key" });API Reference
Send
// Send to individual recipients
await craftatom.send({
template: "welcome",
to: ["[email protected]"],
data: { name: "Jane" },
});
// With idempotency key (prevents duplicate sends)
await craftatom.send(
{ template: "receipt", to: ["[email protected]"], data: { orderId: "123" } },
"unique-idempotency-key"
);
// Send to an entire segment
await craftatom.sendToSegment({
template: "newsletter",
segmentId: "seg_abc123",
data: { subject: "March Update" },
});Subscribers
// Create
await craftatom.subscribers.create({
email: "[email protected]",
name: "Jane Doe",
attributes: { plan: "pro" },
});
// List (with optional filters)
await craftatom.subscribers.list({ page: 1, limit: 25, status: "active" });
// Get by ID
await craftatom.subscribers.get("sub_abc123");
// Update
await craftatom.subscribers.update("sub_abc123", { name: "Jane Smith" });
// Soft delete
await craftatom.subscribers.delete("sub_abc123");
// Hard delete (permanently removes all data)
await craftatom.subscribers.delete("sub_abc123", { hard: true });Segments
// Create
await craftatom.segments.create({ name: "VIP Customers" });
// List
await craftatom.segments.list({ page: 1, limit: 25 });
// Get / Update / Delete
await craftatom.segments.get("seg_abc123");
await craftatom.segments.update("seg_abc123", { name: "Premium Customers" });
await craftatom.segments.delete("seg_abc123");
// Manage subscribers in a segment
await craftatom.segments.addSubscribers("seg_abc123", {
subscriberIds: ["sub_1", "sub_2"],
});
await craftatom.segments.removeSubscribers("seg_abc123", {
subscriberIds: ["sub_1"],
});
await craftatom.segments.listSubscribers("seg_abc123", { page: 1, limit: 25 });Jobs
// List jobs (with optional filters)
await craftatom.jobs.list({ status: "failed", limit: 50 });
// Get job details
await craftatom.jobs.get("job_abc123");
// Retry a single job
await craftatom.jobs.retry("job_abc123");
// Bulk retry failed jobs
await craftatom.jobs.bulkRetry({ jobIds: ["job_1", "job_2"] });Email Logs
// List logs (with optional filters)
await craftatom.logs.list({
status: "bounced",
since: "2025-01-01T00:00:00Z",
limit: 100,
});
// Get a single log entry
await craftatom.logs.get("log_abc123");Analytics
// Get bounce analytics
await craftatom.analytics.bounces();Email Verification
await craftatom.verifyEmail({ email: "[email protected]" });CSV Import
// Upload a CSV file
await craftatom.imports.upload(file);
// Check import status
await craftatom.imports.status("job_abc123");Error Handling
All methods throw a DetailedError on failure, which includes the HTTP status and the error response body:
import { CraftAtomClient, type CraftAtomDetailedError } from "@craftatom/sdk";
try {
await craftatom.send({ template: "welcome", to: ["bad"] });
} catch (err) {
const error = err as CraftAtomDetailedError;
console.error(error.message); // HTTP status code
console.error(error.detail); // Response body with error details
}Runtime Support
Works in Node.js 18+, Bun, Deno, Cloudflare Workers, and modern browsers. ESM and CJS builds are both included.
License
MIT
