Skip to content

cycletask/node-sdk

Repository files navigation

@cycletask/node

The official Node.js / TypeScript SDK for the CycleTask Mail Forwarding API.

npm version License: MIT

  • Zero runtime dependencies (native fetch, Node 18+)
  • Full TypeScript type coverage
  • Automatic retries with exponential back-off (429 & 5xx)
  • ESM and CommonJS dual-module support

Installation

npm install @cycletask/node
yarn add @cycletask/node
pnpm add @cycletask/node

Quick Start

import CycleTask from '@cycletask/node';

const cycletask = new CycleTask('ct_live_your_api_key');

// List your domains
const domains = await cycletask.domains.list();
console.log(domains);

// Create an alias
const alias = await cycletask.aliases.create({
  alias: 'hello',
  domainId: domains[0]._id,
  destinations: ['me@gmail.com'],
});
console.log(alias.fullAddress); // hello@yourdomain.com

Configuration

const cycletask = new CycleTask('ct_live_your_api_key', {
  baseUrl: 'https://api.task-cycle.com/api', // default
  timeout: 30_000,                            // 30 seconds (default)
  maxRetries: 3,                              // retry on 429 / 5xx (default)
});
Option Type Default Description
baseUrl string https://api.task-cycle.com/api API base URL
timeout number 30000 Request timeout in milliseconds
maxRetries number 3 Max retries on 429 / 5xx responses

API Reference

Domains

// List all domains
const domains = await cycletask.domains.list();

// Create a domain
const domain = await cycletask.domains.create({ domain: 'example.com' });

// Get a domain by ID
const domain = await cycletask.domains.get('domain_id');

// Delete a domain
await cycletask.domains.delete('domain_id');

// Trigger DNS verification
const result = await cycletask.domains.verify('domain_id');
// result.allVerified → boolean
// result.results    → { mx, spf, dkim, dmarc }

// Get required DNS records
const dns = await cycletask.domains.getDnsRecords('domain_id');
// dns.records → Array<{ type, host, value, priority?, verified }>

Aliases

// List aliases (with pagination & filtering)
const { data, pagination } = await cycletask.aliases.list({
  page: 1,
  limit: 20,
  search: 'hello',
  domain: 'domain_id',
  status: 'active',
  sort: '-createdAt',
});

// Create an alias
const alias = await cycletask.aliases.create({
  alias: 'hello',
  domainId: 'domain_id',
  destinations: ['me@gmail.com', 'backup@gmail.com'],
  description: 'Main contact alias',
  privacyMode: false,
});

// Update an alias
const updated = await cycletask.aliases.update('alias_id', {
  destinations: ['new@gmail.com'],
  isActive: false,
  description: 'Updated description',
});

// Delete an alias
await cycletask.aliases.delete('alias_id');

// Get forwarding logs for an alias
const logs = await cycletask.aliases.getLogs('alias_id');

Stats

// Dashboard overview
const overview = await cycletask.stats.overview();
// overview.domains  → { total, verified }
// overview.aliases  → { total, active }
// overview.emails   → { totalForwarded, delivered, bounced, deferred, rejected }

// Daily chart data
const chart = await cycletask.stats.chart({ days: 30 });
// chart → Array<{ date, forwarded, bounced, deferred, rejected }>

// Global email logs (paginated)
const { data, pagination } = await cycletask.stats.logs({
  page: 1,
  limit: 50,
  status: 'delivered',
  search: 'sender@example.com',
});

Status (Public — no auth required)

// Service health
const status = await cycletask.status.get();

// 90-day uptime data
const uptime = await cycletask.status.uptime();

// Recent incidents
const incidents = await cycletask.status.incidents();

Error Handling

The SDK throws typed errors that you can catch and handle:

import CycleTask, {
  CycleTaskError,
  AuthenticationError,
  NotFoundError,
  ValidationError,
  RateLimitError,
} from '@cycletask/node';

const cycletask = new CycleTask('ct_live_your_api_key');

try {
  await cycletask.domains.create({ domain: 'example.com' });
} catch (err) {
  if (err instanceof AuthenticationError) {
    // 401 — invalid API key
    console.error('Bad API key:', err.message);
  } else if (err instanceof ValidationError) {
    // 422 — invalid request body
    console.error('Validation failed:', err.message);
    console.error('Field errors:', err.errors);
  } else if (err instanceof NotFoundError) {
    // 404
    console.error('Not found:', err.message);
  } else if (err instanceof RateLimitError) {
    // 429 — all retries exhausted
    console.error('Rate limited. Retry after:', err.retryAfter, 'seconds');
  } else if (err instanceof CycleTaskError) {
    // Any other API error
    console.error(`API error ${err.statusCode}:`, err.message);
  } else {
    throw err;
  }
}

Error Classes

Class HTTP Status Description
CycleTaskError any Base class for all API errors
AuthenticationError 401 Invalid or missing API key
ForbiddenError 403 Insufficient permissions
NotFoundError 404 Resource not found
ValidationError 422 Request body failed validation
RateLimitError 429 Rate limit exceeded after retries

All error classes expose:

  • message — human-readable description
  • statusCode — HTTP status code (or 0 for network / timeout errors)
  • code — machine-readable error code

ValidationError additionally exposes errors: Record<string, string[]> with per-field messages.

RateLimitError additionally exposes retryAfter: number (seconds until reset).


Automatic Retries

Requests that receive a 429 Too Many Requests or 5xx response are automatically retried with exponential back-off:

Attempt Delay
1st ~500 ms
2nd ~1 000 ms
3rd ~2 000 ms

Each delay includes up to 25 % random jitter. After maxRetries attempts the SDK throws the underlying error.

Network errors and timeouts are also retried.


TypeScript

Every request parameter and API response is fully typed. Import types directly:

import type {
  Domain,
  Alias,
  EmailLog,
  StatsOverview,
  PaginatedResponse,
  CreateAliasParams,
} from '@cycletask/node';

Requirements

  • Node.js 18+ (uses native fetch)
  • No runtime dependencies

License

MIT

About

Official Node.js/TypeScript SDK for CycleTask Mail Forwarding API

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors