Agent skill

Customerio SDK Patterns

by jeremylongshore in jeremylongshore/tons-of-skills-marketplace

Apply production-ready Customer.io SDK patterns. An agent skill from jeremylongshore/tons-of-skills-marketplace.

MITAuto-check: notesDevelopment

Install Customerio SDK Patterns

skills CLI
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-sdk-patterns -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jeremylongshore/tons-of-skills-marketplace customerio-sdk-patterns --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/.curated/customerio-sdk-patterns .claude/skills/customerio-sdk-patterns && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
customerio-sdk-patterns
GitHub stars
2.8k
Token cost
~2.5k tokens
SKILL.md length
274 words
Files
2 (incl. references)
Skills in repo
3,342
Repo updated
First seen
Licence
MIT

At a glance

Apply production-ready Customer.io SDK patterns. An agent skill from jeremylongshore/tons-of-skills-marketplace.

  • Implementing typed clients
  • SKILL.md covers Output, Examples, Overview and Prerequisites, plus 5 more sections
  • Needs CUSTOMERIO_TRACK_API_KEY and CUSTOMERIO_APP_API_KEY
  • Singleton management for customerio-node

What it does

Customerio SDK Patterns is an agent skill from jeremylongshore/tons-of-skills-marketplace. Apply production-ready Customer.io SDK patterns. Use when implementing typed clients, retry logic, event batching, or singleton management for customerio-node. Trigger: "customer.io best practices", "customer.io patterns", "production customer.io", "customer.io architecture", "customer.io singleton".

Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/implementation-guide.md`). Compatibility notes: Designed for Claude Code

It sits in Development, covering Error handling. The repository describes itself as: Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com. The licence is MIT.

When your agent uses it

  • Implementing typed clients
  • Singleton management for customerio-node

Example prompts

  • “customer.io best practices”
  • “customer.io patterns”
  • “production customer.io”
  • “/customerio-sdk-patterns”

Requirements

  • Node.js
  • A credential in CUSTOMERIO_TRACK_API_KEY
  • A credential in CUSTOMERIO_APP_API_KEY
  • Compatibility (from SKILL.md): Designed for Claude Code
  • Pre-approved tools (allowed-tools): Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep

What it can do on your machine

Read from SKILL.md and the folder at commit cfae287. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit
    • Bash(npm:*)
    • Bash(npx:*)
    • Glob
    • Grep

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • docs.customer.io
    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • CUSTOMERIO_TRACK_API_KEY
    • CUSTOMERIO_APP_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Designed for Claude Code

    From compatibility in the SKILL.md frontmatter.

Context cost

Customerio SDK Patterns loads about 2.5k tokens when it runs, and up to ~3.7k if it reads all its reference files. Until then it costs about 81 tokens; SKILL.md has 274 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~81
When it runs · the whole SKILL.md, loaded when a task matches
~2.5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~3.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:272
    "Set these in your environment or .env file."
  • NoteMentions a .env fileSKILL.md:287
    "Set this in your environment or .env file."

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jeremylongshore/tons-of-skills-marketplace at commit cfae287, republished under its MIT licence (© jeremylongshore). 274 words, ~2,496 tokens.

Download SKILL.mdSave it as .claude/skills/customerio-sdk-patterns/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
customerio-sdk-patterns
description
Apply production-ready Customer.io SDK patterns. Use when implementing typed clients, retry logic, event batching, or singleton management for customerio-node. Trigger: "customer.io best practices", "customer.io patterns", "production customer.io", "customer.io architecture", "customer.io singleton".
allowed-tools
Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep
compatibility
Designed for Claude Code
version
1.14.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
saas, customer-io, sdk, patterns, typescript

Customer.io SDK Patterns

Output

  • A reusable SDK integration pattern with scoped configuration, schema validation, idempotency, observability, and error classification.
  • A test-backed client boundary that keeps credentials and recipient data out of logs and source control.

Examples

Instantiate the client from an environment-specific secret reference, validate a synthetic event against the contract, attach a stable idempotency key, and assert the SDK call in a mocked unit test. For a development integration test, use a synthetic profile and record only result status/correlation ID; never log the client token or full event payload.

Overview

Production-ready patterns for customerio-node: type-safe wrappers with enum-constrained events, retry with exponential backoff, event batching for high-volume scenarios, and singleton lifecycle management.

Prerequisites

  • customerio-node installed
  • TypeScript project (recommended for type-safe patterns)
  • Understanding of your event taxonomy

Instructions

Pattern 1: Type-Safe Client Wrapper
typescript
// lib/customerio-typed.ts
import { TrackClient, RegionUS, RegionEU } from "customerio-node";

// Define your event taxonomy as a union type
type CioEvent =
  | { name: "signed_up"; data: { method: string; source?: string } }
  | { name: "plan_changed"; data: { from: string; to: string; mrr: number } }
  | { name: "feature_used"; data: { feature: string; duration_ms?: number } }
  | { name: "checkout_completed"; data: { order_id: string; total: number; items: number } }
  | { name: "subscription_cancelled"; data: { reason: string; feedback?: string } };

// Define user attributes with strict types
interface CioUserAttributes {
  email: string;
  first_name?: string;
  last_name?: string;
  plan?: "free" | "starter" | "pro" | "enterprise";
  company?: string;
  created_at?: number;       // Unix seconds
  last_seen_at?: number;     // Unix seconds
  [key: string]: unknown;    // Allow additional attributes
}

export class TypedCioClient {
  private client: TrackClient;

  constructor(siteId: string, apiKey: string, region: "us" | "eu" = "us") {
    this.client = new TrackClient(siteId, apiKey, {
      region: region === "eu" ? RegionEU : RegionUS,
    });
  }

  async identify(userId: string, attributes: CioUserAttributes): Promise<void> {
    await this.client.identify(userId, {
      ...attributes,
      last_seen_at: Math.floor(Date.now() / 1000),
    });
  }

  async track(userId: string, event: CioEvent): Promise<void> {
    await this.client.track(userId, {
      name: event.name,
      data: { ...event.data, tracked_at: Math.floor(Date.now() / 1000) },
    });
  }

  async suppress(userId: string): Promise<void> {
    await this.client.suppress(userId);
  }

  async destroy(userId: string): Promise<void> {
    await this.client.destroy(userId);
  }
}
Pattern 2: Retry with Exponential Backoff
typescript
// lib/customerio-retry.ts
interface RetryOptions {
  maxRetries: number;
  baseDelayMs: number;
  maxDelayMs: number;
  jitterFactor: number;  // 0 to 1
}

const DEFAULT_RETRY: RetryOptions = {
  maxRetries: 3,
  baseDelayMs: 1000,
  maxDelayMs: 30000,
  jitterFactor: 0.3,
};

async function withRetry<T>(
  fn: () => Promise<T>,
  opts: RetryOptions = DEFAULT_RETRY
): Promise<T> {
  let lastError: Error | undefined;

  for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err: any) {
      lastError = err;
      const statusCode = err.statusCode ?? err.status;

      // Don't retry client errors (except 429 rate limit)
      if (statusCode >= 400 && statusCode < 500 && statusCode !== 429) {
        throw err;
      }

      if (attempt === opts.maxRetries) break;

      // Exponential backoff with jitter
      const delay = Math.min(
        opts.baseDelayMs * Math.pow(2, attempt),
        opts.maxDelayMs
      );
      const jitter = delay * opts.jitterFactor * Math.random();
      await new Promise((r) => setTimeout(r, delay + jitter));
    }
  }
  throw lastError;
}

// Usage with Customer.io client
import { TrackClient, RegionUS } from "customerio-node";

const cio = new TrackClient(
  process.env.CUSTOMERIO_SITE_ID!,
  process.env.CUSTOMERIO_TRACK_API_KEY!,
  { region: RegionUS }
);

// Wrap any operation with retry
await withRetry(() =>
  cio.identify("user-123", { email: "user@example.com" })
);

await withRetry(() =>
  cio.track("user-123", { name: "page_viewed", data: { url: "/pricing" } })
);
Pattern 3: Event Queue with Batching
typescript
// lib/customerio-batch.ts
import { TrackClient, RegionUS } from "customerio-node";

interface QueuedEvent {
  userId: string;
  name: string;
  data?: Record<string, any>;
}

export class CioBatchTracker {
  private queue: QueuedEvent[] = [];
  private timer: NodeJS.Timeout | null = null;
  private client: TrackClient;

  constructor(
    private readonly batchSize: number = 50,
    private readonly flushIntervalMs: number = 5000
  ) {
    this.client = new TrackClient(
      process.env.CUSTOMERIO_SITE_ID!,
      process.env.CUSTOMERIO_TRACK_API_KEY!,
      { region: RegionUS }
    );
    this.startTimer();
  }

  enqueue(userId: string, name: string, data?: Record<string, any>): void {
    this.queue.push({ userId, name, data });
    if (this.queue.length >= this.batchSize) {
      this.flush();
    }
  }

  async flush(): Promise<void> {
    if (this.queue.length === 0) return;
    const batch = this.queue.splice(0, this.batchSize);
    const concurrency = 10;

    for (let i = 0; i < batch.length; i += concurrency) {
      const chunk = batch.slice(i, i + concurrency);
      await Promise.allSettled(
        chunk.map((event) =>
          this.client.track(event.userId, {
            name: event.name,
            data: event.data,
          })
        )
      );
    }
  }

  private startTimer(): void {
    this.timer = setInterval(() => this.flush(), this.flushIntervalMs);
  }

  async shutdown(): Promise<void> {
    if (this.timer) clearInterval(this.timer);
    await this.flush();
  }
}

// Usage
const tracker = new CioBatchTracker(50, 5000);

// Non-blocking — events are queued and flushed automatically
tracker.enqueue("user-1", "page_viewed", { url: "/home" });
tracker.enqueue("user-2", "button_clicked", { button: "cta" });

// On process exit
process.on("SIGTERM", async () => {
  await tracker.shutdown();
  process.exit(0);
});
Pattern 4: Singleton with Validation
typescript
// lib/customerio-singleton.ts
import { TrackClient, APIClient, RegionUS, RegionEU } from "customerio-node";

class CioClientFactory {
  private static trackInstance: TrackClient | null = null;
  private static appInstance: APIClient | null = null;

  static getTrackClient(): TrackClient {
    if (!this.trackInstance) {
      const siteId = process.env.CUSTOMERIO_SITE_ID;
      const apiKey = process.env.CUSTOMERIO_TRACK_API_KEY;
      if (!siteId || !apiKey) {
        throw new Error(
          "Missing CUSTOMERIO_SITE_ID or CUSTOMERIO_TRACK_API_KEY. " +
          "Set these in your environment or .env file."
        );
      }
      const region = process.env.CUSTOMERIO_REGION === "eu" ? RegionEU : RegionUS;
      this.trackInstance = new TrackClient(siteId, apiKey, { region });
    }
    return this.trackInstance;
  }

  static getAppClient(): APIClient {
    if (!this.appInstance) {
      const appKey = process.env.CUSTOMERIO_APP_API_KEY;
      if (!appKey) {
        throw new Error(
          "Missing CUSTOMERIO_APP_API_KEY. " +
          "Set this in your environment or .env file."
        );
      }
      const region = process.env.CUSTOMERIO_REGION === "eu" ? RegionEU : RegionUS;
      this.appInstance = new APIClient(appKey, { region });
    }
    return this.appInstance;
  }

  /** Reset for testing */
  static reset(): void {
    this.trackInstance = null;
    this.appInstance = null;
  }
}

// Usage — same instance everywhere
const cio = CioClientFactory.getTrackClient();
const api = CioClientFactory.getAppClient();

Pattern Summary

PatternWhen to UseKey Benefit
Typed ClientAlwaysCompile-time safety on events + attributes
Retry + BackoffProduction API callsHandles transient 5xx and 429 errors
Batch QueueHigh-volume tracking (>100 events/sec)Reduces connection overhead, respects rate limits
Singleton FactoryMulti-module appsPrevents connection leaks, validates config once

Error Handling

ErrorCauseSolution
Type mismatchWrong event data shapeUse TypeScript union types for events
Queue memory growthEvents produced faster than flushedLower batchSize, increase flush frequency
Retry exhausted (3x)Persistent API failureCheck credentials, Customer.io status page
Singleton null credentialsEnv vars not loadedEnsure dotenv loads before client creation

Resources

Next Steps

After implementing patterns, proceed to customerio-primary-workflow for messaging workflows.

© jeremylongshore, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (references) in skills/.curated/customerio-sdk-patterns of jeremylongshore/tons-of-skills-marketplace.

  • SKILL.md
  • references/implementation-guide.md

Open the folder on GitHubat commit cfae287

Compare with similar skills

Customerio SDK Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Customerio SDK Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Customerio SDK Patterns this skilljeremylongshore/tons-of-skills-marketplace2.8k—~2.5kAutomated safety check: NotesMIT
Mole Bug Patternstw93/Mole70k—~2kAutomated safety check: PassGPL-3.0
Native Data FetchingCherryHQ/cherry-studio-app4k6 repos~2.9kAutomated safety check: NotesMIT
Rust Best Practicesfarm-fe/farm5.6k3 repos~1.1kAutomated safety check: PassMIT
R Function Input Validationtidyverse/dplyr5.1k1 repos~2.3kAutomated safety check: PassCustom licence
Next Best Practicesvercel-labs/openreview1.7k18 repos~1kAutomated safety check: PassNone

Similar skills

  • A catalog of recurring bug shapes in the Mole Mac cleaner, used to review safety-sensitive diffs for deletion safety, unbounded commands, shell traps and weak tests.

    70k GitHub stars~2k tokensUpdated today
    DevelopmentAuto-check passed
  • Native Data Fetching

    CherryHQ/cherry-studio-app

    A skill your agent uses when implementing or debugging ANY network request, API call, or data fetching.

    4k GitHub starsUsed in 6 repos~2.9k tokens
    DevelopmentAuto-check: notes
  • Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook.

    5.6k GitHub starsUsed in 3 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Validates arguments of exported R functions with the standalone check_* type checkers from rlang, in tidyverse style with clear error messages.

    5.1k GitHub starsUsed in 1 repo~2.3k tokens
    DevelopmentAuto-check passed
  • Next Best Practices

    vercel-labs/openreview

    Official

    Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling

    1.7k GitHub starsUsed in 18 repos~1k tokens
    DevelopmentAuto-check passed
  • Error Handling

    microsoft/data-formulator

    Official

    统一错误处理系统。在添加 API 端点、修改错误处理、添加前端 API 调用、编写错误相关测试时使用. An agent skill from microsoft/data-formulator.

    18k GitHub stars~3.8k tokensUpdated 2 days ago
    DevelopmentAuto-check passed

More from jeremylongshore/tons-of-skills-marketplace

All 3,342 skills in this repo
  • Performing Security Code Review

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to conduct a security-focused code review using the security-agent plugin.

    2.8k GitHub starsUsed in 2 repos~1.3k tokens
    Auto-check: notes
  • Adapting Transfer Learning Models

    jeremylongshore/tons-of-skills-marketplace

    Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques.

    2.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Agent Context Loader

    jeremylongshore/tons-of-skills-marketplace

    Execute proactive auto-loading: automatically detects and loads agents.md files.

    2.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Aggregating Performance Metrics

    jeremylongshore/tons-of-skills-marketplace

    Aggregate and centralize performance metrics from applications, systems, databases, caches, and services.

    2.8k GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Analyzing Capacity Planning

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to analyze capacity requirements and plan for future growth.

    2.8k GitHub stars~947 tokensUpdated today
    Auto-check passed
  • Analyzing Database Indexes

    jeremylongshore/tons-of-skills-marketplace

    Process use when you need to work with database indexing. An agent skill from jeremylongshore/tons-of-skills-marketplace.

    2.8k GitHub stars~2k tokensUpdated today
    Auto-check passed

Categories

Questions about Customerio SDK Patterns

What does Customerio SDK Patterns do?

Apply production-ready Customer.io SDK patterns. An agent skill from jeremylongshore/tons-of-skills-marketplace. Customerio SDK Patterns is an agent skill from jeremylongshore/tons-of-skills-marketplace.io SDK patterns.

When should I use Customerio SDK Patterns?

Customerio SDK Patterns fits situations like: implementing typed clients; singleton management for customerio-node.

How do I install Customerio SDK Patterns in Claude Code?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-sdk-patterns -a claude-code`. Or copy the skill folder (skills/.curated/customerio-sdk-patterns in jeremylongshore/tons-of-skills-marketplace) into .claude/skills/customerio-sdk-patterns in your project. Claude Code loads it when a task matches its description.

How do I install Customerio SDK Patterns in Codex?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-sdk-patterns -a codex`. Or copy the skill folder (skills/.curated/customerio-sdk-patterns in jeremylongshore/tons-of-skills-marketplace) into .agents/skills/customerio-sdk-patterns in your project. Codex loads it when a task matches its description.

Can I use Customerio SDK Patterns in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill customerio-sdk-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/customerio-sdk-patterns, .gemini/skills/customerio-sdk-patterns, .github/skills/customerio-sdk-patterns and .opencode/skills/customerio-sdk-patterns in your project.

What does Customerio SDK Patterns need to run?

Going by SKILL.md and its folder, Customerio SDK Patterns needs credentials named CUSTOMERIO_TRACK_API_KEY and CUSTOMERIO_APP_API_KEY. Our summary lists: Node.js; A credential in CUSTOMERIO_TRACK_API_KEY; A credential in CUSTOMERIO_APP_API_KEY. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep. Compatibility (from SKILL.md): Designed for Claude Code.

Does Customerio SDK Patterns access the network?

SKILL.md names 2 domains. As links in the text: docs.customer.io and github.com. This is read from the text; nothing was executed.

Is Customerio SDK Patterns safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Customerio SDK Patterns use?

Customerio SDK Patterns is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Customerio SDK Patterns use?

About 2.5k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.2k tokens, read only when the agent opens those files.

What are the alternatives to Customerio SDK Patterns?

Skills that share tags, products or a category with Customerio SDK Patterns: Mole Bug Patterns (tw93/Mole, 70k stars), Native Data Fetching (CherryHQ/cherry-studio-app, 4k stars), Rust Best Practices (farm-fe/farm, 5.6k stars) and R Function Input Validation (tidyverse/dplyr, 5.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Customerio SDK Patterns?

jeremylongshore (a GitHub user) maintains it in jeremylongshore/tons-of-skills-marketplace, which has 2,827 GitHub stars. The repository holds 3,342 skills in this directory. The repository was last updated on October 10, 2026.

Source: jeremylongshore/tons-of-skills-marketplace on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.