Node talks to POST https://api.trendsapi.ai/api with fetch or any HTTP library. Auth is Authorization: Bearer plus process.env. The envelope field body is a JSON string and must be parsed a second time. ESM and CommonJS differ only in import syntax. A worker should abort a hung call instead of waiting for the host to SIGKILL it. source npm needs the exact registry name. Docs: the API reference. Caps: pricing. npm name rules: the npm guide.

node:fetch on 18+ versus CJS require

ESM (package.json "type": "module" or .mjs):

const key = process.env.TRENDSAPI_API_KEY;
if (!key) throw new Error("TRENDSAPI_API_KEY missing");

const resp = await fetch("https://api.trendsapi.ai/api", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${key}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    mode: "get_growth",
    source: "npm",
    keyword: "react",
    percent_growth: ["3M", "12M"],
  }),
});
if (!resp.ok) throw new Error(`http ${resp.status}`);
const outer = await resp.json();
const inner = JSON.parse(outer.body);

CommonJS:

const { fetch } = require("undici"); // Node < 18

react is a labeled sample. The name is case-sensitive.

process.env and dotenv

npm i dotenv

require("dotenv").config() at the top of a CJS worker. ESM can import "dotenv/config". Do not log the key. Do not put .env in the image layer of a public container.

AbortController in a worker

const ac = new AbortController();
const t = setTimeout(() => ac.abort(), 60_000);
try {
  await fetch("https://api.trendsapi.ai/api", { signal: ac.signal, /* ... */ });
} finally {
  clearTimeout(t);
}

_ in 60_000 is a numeric separator, not a double hyphen. A 429 should abort the batch, not spawn more fetches.

ESM package.json type module

"type": "module" changes every .js file in that package. A mixed repo can keep this client in trends.mjs and leave the rest CJS. The product MCP server at https://api.trendsapi.ai/mcp is for agents sitting next to Node, not a replacement for fetch in a cron.