SDKs

Node.js SDK

Type-safe wrapper around the Outfame API. Ships with TypeScript definitions, automatic retries on 5xx/429, and cursor-based pagination helpers.

FeatureDetails
Package@outfame/sdk
Version2.4.1
Node.js≥ 18.0
TypeScript≥ 5.0
LicenseMIT
Sourcegithub.com/outfame/outfame-node

Installation

npm install @outfame/sdk
# or
yarn add @outfame/sdk
# or
pnpm add @outfame/sdk
# or
bun add @outfame/sdk

Initialization

import Outfame from "@outfame/sdk";

const outfame = new Outfame({
  apiKey: process.env.OUTFAME_API_KEY,    // Required
  baseUrl: "https://api.outfame.com/v1",  // Optional, default shown
  timeout: 30000,                          // Optional, ms (default: 30s)
  maxRetries: 3,                           // Optional (default: 3)
});

OAuth token authentication

const outfame = new Outfame({
  accessToken: "oa_live_xYz789AbC...",
});

Accounts

// List all accounts
const accounts = await outfame.accounts.list({
  platform: "instagram",
  status: "active",
  limit: 20,
});
// accounts.data: Account[]
// accounts.hasMore: boolean
// accounts.nextCursor: string | null

// Auto-paginate through all accounts
for await (const account of outfame.accounts.list({ platform: "instagram" })) {
  console.log(account.id, account.instagram_username);
}

// Retrieve a single account
const account = await outfame.accounts.retrieve("acc_7Gx2kLm9Qr");

// Create an account
const newAccount = await outfame.accounts.create({
  instagram_username: "new_handle",
  platform: "instagram",
  targeting_config: {
    competitor_accounts: ["competitor1"],
    hashtags: ["fitness"],
  },
});

// Update an account
const updated = await outfame.accounts.update("acc_7Gx2kLm9Qr", {
  targeting_config: {
    hashtags: ["fitness", "wellness", "health"],
  },
});

// Delete an account
await outfame.accounts.delete("acc_7Gx2kLm9Qr");

Analytics

// Overview
const overview = await outfame.analytics.overview("acc_7Gx2kLm9Qr", {
  period: "30d",
});
console.log(`Net growth: +${overview.net_growth}`);
console.log(`Engagement rate: ${overview.engagement_rate}%`);

// Growth time series
const growth = await outfame.analytics.growth("acc_7Gx2kLm9Qr", {
  period: "7d",
  granularity: "daily",
});
growth.data_points.forEach(point => {
  console.log(`${point.date}: ${point.followers} (+${point.net})`);
});

// Engagement breakdown
const engagement = await outfame.analytics.engagement("acc_7Gx2kLm9Qr", {
  period: "30d",
});
console.log("Top content type:", engagement.by_content_type);

// Audience demographics
const audience = await outfame.analytics.audience("acc_7Gx2kLm9Qr");
console.log("Top countries:", audience.demographics.top_countries);

// Custom date range
const custom = await outfame.analytics.overview("acc_7Gx2kLm9Qr", {
  period: "custom",
  startDate: "2026-01-01",
  endDate: "2026-01-31",
});

Targeting

// Get current config
const config = await outfame.targeting.config("acc_7Gx2kLm9Qr");

// Update targeting
await outfame.targeting.update("acc_7Gx2kLm9Qr", {
  competitor_accounts: ["rival1", "rival2"],
  hashtags: ["travel", "adventure"],
  locations: [{ name: "Barcelona, Spain", radius_km: 40 }],
  filters: {
    age_range: { min: 22, max: 38 },
    activity_level: "high",
  },
  ai_optimization: {
    enabled: true,
    mode: "balanced",
    quality_threshold: 0.75,
  },
});

// Get AI suggestions
const suggestions = await outfame.targeting.suggestions("acc_7Gx2kLm9Qr", {
  goal: "growth",
  includeReasoning: true,
});
console.log("Confidence:", suggestions.confidence);
console.log("Estimated impact:", suggestions.estimated_impact);

Engagement

// Get activity log
const activity = await outfame.engagement.activity("acc_7Gx2kLm9Qr", {
  type: "like",
  limit: 50,
});

// Get today's stats
const stats = await outfame.engagement.stats("acc_7Gx2kLm9Qr");
console.log("Likes:", stats.actions.likes.performed, "/", stats.actions.likes.limit);

// Pause
await outfame.engagement.pause("acc_7Gx2kLm9Qr", {
  reason: "Content refresh",
});

// Resume
await outfame.engagement.resume("acc_7Gx2kLm9Qr");

Webhooks

// Create webhook
const webhook = await outfame.webhooks.create({
  url: "https://yourapp.com/webhooks/outfame",
  events: ["account.growth_milestone", "engagement.daily_summary"],
});
// Save webhook.signingSecret securely

// List webhooks
const webhooks = await outfame.webhooks.list();

// Delete webhook
await outfame.webhooks.delete("wh_4nRtYuIo");

// Verify webhook signature (helper)
import { verifyWebhookSignature } from "@outfame/sdk/webhooks";

app.post("/webhooks/outfame", (req, res) => {
  const isValid = verifyWebhookSignature({
    payload: req.rawBody,
    signature: req.headers["x-outfame-signature"],
    timestamp: req.headers["x-outfame-timestamp"],
    secret: process.env.OUTFAME_WEBHOOK_SECRET,
  });

  if (!isValid) return res.status(401).send("Invalid signature");

  const event = req.body;
  switch (event.type) {
    case "account.growth_milestone":
      console.log(`Milestone reached: ${event.data.milestone}`);
      break;
    case "engagement.daily_summary":
      console.log(`Daily growth: +${event.data.net_growth}`);
      break;
  }

  res.status(200).json({ received: true });
});

TypeScript types

All types are exported from the package root.

import Outfame from "@outfame/sdk";
import type {
  Account,
  AnalyticsOverview,
  GrowthDataPoint,
  TargetingConfig,
  TargetingSuggestions,
  EngagementActivity,
  EngagementStats,
  Webhook,
  WebhookEvent,
} from "@outfame/sdk";

// All response types are fully typed
const account: Account = await outfame.accounts.retrieve("acc_7Gx2kLm9Qr");
const overview: AnalyticsOverview = await outfame.analytics.overview(account.id);

Error handling

import Outfame, {
  OutfameError,
  RateLimitError,
  AuthenticationError,
  NotFoundError,
  ValidationError,
} from "@outfame/sdk";

try {
  const account = await outfame.accounts.retrieve("acc_invalid");
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log("Account not found:", error.message);
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter}s`);
  } else if (error instanceof AuthenticationError) {
    console.log("Invalid API key");
  } else if (error instanceof ValidationError) {
    console.log("Validation errors:", error.errors);
  } else if (error instanceof OutfameError) {
    console.log("API error:", error.code, error.message);
  }
}

Configuration options

OptionTypeDefaultDescription
apiKeystringYour API key. Required unless accessToken is provided.
accessTokenstringOAuth access token for user-scoped requests.
baseUrlstringhttps://api.outfame.com/v1API base URL.
timeoutnumber30000Request timeout in milliseconds.
maxRetriesnumber3Automatic retry count for transient errors and 429s.
loggerLoggernullCustom logger for debug output.