> **For coding agents and LLMs:** This is one published Social Fetch blog post (markdown export). Product docs and API orientation live in [`/llms.txt`](https://www.socialfetch.dev/llms.txt). The HTML article is at the on-site URL below.

## This page

- **On-site (HTML):** [https://www.socialfetch.dev/blog/typescript-sdk](https://www.socialfetch.dev/blog/typescript-sdk)
- **Markdown (.mdx) URL:** [https://www.socialfetch.dev/blog/typescript-sdk.mdx](https://www.socialfetch.dev/blog/typescript-sdk.mdx)
- **Blog:** [https://www.socialfetch.dev/blog](https://www.socialfetch.dev/blog)

---

# The official TypeScript SDK for Social Fetch

If you are calling the Social Fetch API from Node.js or an edge worker, you can keep writing `fetch` wrappers. The SDK is for when you want method names that match the REST routes, typed response bodies, and one failure model you can branch on without re-reading the OpenAPI spec every week.

The package is [`@socialfetch/sdk`](https://www.npmjs.com/package/@socialfetch/sdk) on npm. Install it, pass your API key, and call the same routes you would hit over HTTP:

```ts
import { SocialFetchClient } from "@socialfetch/sdk";

const client = new SocialFetchClient({
  apiKey: process.env.SOCIALFETCH_API_KEY!,
});

const result = await client.tiktok.getProfile({ handle: "charlidamelio" });

if (!result.ok) {
  console.error(result.error.code, result.error.requestId);
  return;
}

console.log(result.value.data.profile);
console.log(result.value.meta.creditsCharged);
```

## What the SDK gives you

`SocialFetchClient` exposes a namespace per platform (`tiktok`, `instagram`, `twitter`, `reddit`, `linkedin`, and the rest), plus `web` for URL extraction, `auth.whoami()` and `billing.getBalance()` for free connectivity checks, and top-level `health()` and `ask()`. Method names map to HTTP routes: `client.tiktok.getProfile({ handle })` is `GET /v1/tiktok/profiles/{handle}`, `client.instagram.getPost({ url })` is `GET /v1/instagram/posts`, and so on.

Expected API and runtime failures come back as `{ ok: false, error }` instead of thrown exceptions. Successful calls return `{ ok: true, value }` where `value` is the same `{ data, meta }` envelope the REST API returns, including `meta.requestId`, `meta.creditsCharged`, and `meta.version`.

The SDK is not a separate product with different rules. It is the documented API with TypeScript types on top. Run it from your backend, Cloudflare Worker, or cron job. API keys belong server-side, not in browser bundles.

## Result-based error handling

SDK methods return a `Result` type. That keeps the failure path next to the call:

```ts
const tweets = await client.twitter.getProfileTweets({
  handle: "elonmusk",
});

if (!tweets.ok) {
  console.error("Twitter fetch failed:", tweets.error.code, tweets.error.requestId);
  return;
}

console.log(tweets.value.data.tweets);
console.log(tweets.value.meta.creditsCharged);
```

Log `error.requestId` on failures. Branch on `error.code` to decide whether to retry, skip a record, or show a message upstream. The SDK normalizes API errors (`unauthorized`, `insufficient_credits`, `lookup_failed`) and client-side failures (`network_error`, `parse_error`) into the same shape.

## Prefer exceptions? Use unwrap

Some codebases prefer `try/catch`. Import `unwrap()` and it throws `SocialFetchUnwrapError` when `result.ok` is false:

```ts
import { SocialFetchClient, SocialFetchUnwrapError, unwrap } from "@socialfetch/sdk";

const client = new SocialFetchClient({
  apiKey: process.env.SOCIALFETCH_API_KEY!,
});

try {
  const profile = unwrap(
    await client.instagram.getProfile({ handle: "instagram" })
  );

  console.log(profile.data.profile);
  console.log(profile.meta.creditsCharged);
} catch (error) {
  if (error instanceof SocialFetchUnwrapError) {
    console.error("API Error:", error.error.code, error.error.requestId);
    return;
  }

  throw error;
}
```

Either pattern keeps the same normalized error details. Pick the one that matches how the rest of your app handles failures.

## Domain outcomes vs SDK failures

The SDK preserves the API's outcome semantics. A route can return HTTP `200` with `data.lookupStatus: "not_found"`, `"private"`, or `"restricted"`. That is a completed lookup with domain data, not an SDK failure.

After `result.ok` is true, read `result.value.data.lookupStatus` (when the route provides it) before you touch profile or post fields. Log `result.value.meta.requestId` whenever you need to trace a call in support.

```ts
const profile = await client.instagram.getProfile({ handle: "instagram" });

if (!profile.ok) {
  // 401, 402, 503, parse errors, etc.
  console.error(profile.error.code, profile.error.requestId);
  return;
}

switch (profile.value.data.lookupStatus) {
  case "found":
    // use profile.value.data.profile / metrics
    break;
  case "private":
  case "not_found":
    // HTTP 200 from the API — handle without treating as SDK failure
    break;
}
```

Some list routes omit `lookupStatus` and can return empty arrays for more than one reason. See [Errors](/docs/errors) for disambiguation patterns.

## Billing on completed lookups

Metered routes charge credits when we complete a lookup attempt, same as raw HTTP. That includes `not_found`, `private`, and `restricted` outcomes that come back as HTTP `200` with a `lookupStatus` in the body. Pre-send validation errors, `lookup_failed`, and `503 temporarily_unavailable` do not bill the same way.

Reconcile your ledger against `meta.creditsCharged` on every response, not your request count. Per-route costs are in the [API reference](/docs/api). Full rules: [Credits](/docs/credits).

Before you hit metered routes in a new environment, call `client.auth.whoami()`. It checks your API key and costs nothing.

## Get started

Start with the [TypeScript SDK guide](/docs/sdk) for install steps, `Result` handling, and `unwrap()` details. Keep the [capability matrix](/docs/capability-matrix) open for the method inventory and route mapping. Use the [API reference](/docs/api) when you need exact params and schemas.

If this is your first integration, read [Quickstart](/docs/quickstart) for auth headers, [Errors](/docs/errors) for retry rules, and [Pricing](/pricing) to model volume.

TypeScript SDK guide Install, configure, and handle Results. /docs/sdk
Capability matrix Method names, route mappings, and typed coverage. /docs/capability-matrix
Quickstart Auth, first request, and the whoami smoke test. /docs/quickstart
API reference Paths, query parameters, and response schemas. /docs/api

[/docs/sdk](/docs/sdk)
[/docs/capability-matrix](/docs/capability-matrix)
[/docs/quickstart](/docs/quickstart)
[/docs/api](/docs/api)

Same envelope as curl. Fewer hand-written wrappers.
