Home/Node.js SDK
SDK

Node.js SDK

Node.js 22+npmGitHub

Typed TypeScript client for the ScrapingIsNotACrime API, with ESM and CommonJS builds and zero runtime dependencies.

npmRepository

01Install

bash
npm install @scrapingisnotacrime/sdk

02Quick start

typescript
import { ScrapingIsNotACrime } from "@scrapingisnotacrime/sdk";

const client = new ScrapingIsNotACrime({ apiKey: process.env.SCRAPINGISNOTACRIME_API_KEY });

const profile = await client.instagram.profile("nasa");
console.log(profile.username, profile.followers);
commonjs
const { ScrapingIsNotACrime } = require("@scrapingisnotacrime/sdk");

Get a key at your dashboard. Keys start with sinac_, and new accounts get 100 free credits.

If you omit apiKey, the client reads SCRAPINGISNOTACRIME_API_KEY from the environment.

03Configuration

typescript
new ScrapingIsNotACrime({
  apiKey: "sinac_...",
  baseUrl: "https://api.scrapingisnotacrime.com/v1",
  timeoutMs: 30_000,
  maxRetries: 2,
  fetch: customFetch,
});
OptionDefaultDescription
apiKeySCRAPINGISNOTACRIME_API_KEYYour API key. The constructor throws if none is set. Defaults to the SCRAPINGISNOTACRIME_API_KEY environment variable.
baseUrlhttps://api.scrapingisnotacrime.com/v1API base URL.
timeoutMs30000Per-attempt timeout, in milliseconds.
maxRetries2Extra attempts for 429, 502 and network errors. 0 disables retries.
fetchfetchCustom fetch implementation, for tests or proxies. Defaults to the global fetch.

A custom fetch receives an init.signal that the SDK aborts when timeoutMs elapses. Honor it so the underlying request stops too.

04Methods

05Pagination

A Page exposes items, hasMore, nextCursor or nextPage, and data with the full response. Iterating it fetches further pages lazily.

Each page fetched is one billed request, so bound your loops. Breaking out early stops fetching.

typescript
const page = await client.github.followers("torvalds", { limit: 100 });
for await (const user of page) {
  console.log(user.username);
}

06Errors

Every failure throws a subclass of ScrapingIsNotACrimeError with status, message and requestId.

TypeStatusRetried
BadRequestError400no
AuthenticationError401no
QuotaExceededError402no
NotFoundError404no
RateLimitError429yes
UpstreamError502yes
ConnectionErrornetwork failure or timeoutyes
APIErrorany other non-2xx responseno
typescript
import { NotFoundError, QuotaExceededError, RateLimitError, ScrapingIsNotACrime } from "@scrapingisnotacrime/sdk";

const client = new ScrapingIsNotACrime({ maxRetries: 3 });

try {
  await client.tiktok.profile("this-user-does-not-exist-123");
} catch (error) {
  if (error instanceof NotFoundError) console.log("No such profile.");
  else if (error instanceof QuotaExceededError) console.log("Out of credits:", error.message);
  else if (error instanceof RateLimitError) console.log("TikTok is rate limiting; try again later.");
  else throw error;
}

07Retries

Rate limits (429), upstream failures (502) and network failures or timeouts are retried automatically, up to 2 extra attempts by default. These failures don't consume credits. The wait honors the Retry-After header; otherwise it is exponential backoff with jitter, starting at 500 ms and capped at 10 seconds.

Set maxRetries: 0 to disable retries.

08Do not use in the browser

Calling the SDK from a browser exposes your API key to anyone who opens the network tab. Call it from your server and proxy client requests through your backend.

09ESM and CommonJS

The package ships both builds. If one application loads both, there are two copies of every error class and instanceof fails across them. Stick to one module system, or check error.name or error.status.

With your consent, we use Google Analytics and non-personalized Google Ads measurement to understand how the site and the dashboard are used and whether our ads work β€” pages visited and actions like creating an API key or testing a request. We never send Google your email, name, account ID, API keys or request content. You can change your mind anytime in Cookie preferences, in the footer.