# LangChain (/docs/langchain)



LangChain [#langchain]

SocialCrawl does not ship a LangChain package, and it does not need one: the API is one authenticated GET request, so you wrap it in a `tool()` in about 30 lines. Once bound to your model, your agent can pull current public data from 48 platforms through a single tool; documented endpoint caches apply.

How do I add social media data to a LangChain agent? [#how-do-i-add-social-media-data-to-a-langchain-agent]

Define a tool with a zod schema that takes a `platform`, a `resource`, and the endpoint's query `params`, then call the SocialCrawl REST API inside the tool function with your key in the `x-api-key` header. Hand the tool to `createAgent` and it runs the tool loop for you.

```typescript
// socialcrawl-langchain.ts
// Run with: SOCIALCRAWL_API_KEY=sc_... ANTHROPIC_API_KEY=... npx tsx socialcrawl-langchain.ts
import { createAgent, tool } from "langchain";
import * as z from "zod";

const API_KEY = process.env.SOCIALCRAWL_API_KEY;
if (!API_KEY) throw new Error("Set SOCIALCRAWL_API_KEY");

const socialcrawl = tool(
  async ({ platform, resource, params }) => {
    const url = new URL(
      `https://www.socialcrawl.dev/v1/${platform}/${resource}`,
    );
    for (const [key, value] of Object.entries(params ?? {})) {
      url.searchParams.set(key, String(value));
    }
    const res = await fetch(url, { headers: { "x-api-key": API_KEY } });
    const json = await res.json();
    if (!json.success) {
      // Hand the model a directive it can act on, not a raw error envelope.
      return `SocialCrawl error ${json.error.type}: ${json.error.message}. See ${json.error.doc_url}`;
    }
    // Return a string so the model can read it back as a tool message.
    return JSON.stringify(json.data);
  },
  {
    name: "socialcrawl",
    description:
      "Fetch current public social media, commerce, and review data from SocialCrawl; documented endpoint caches apply. " +
      "Covers TikTok, Instagram, YouTube, LinkedIn, Reddit, Amazon and more. " +
      "Set `platform` (e.g. 'tiktok'), `resource` (e.g. 'profile'), and `params` " +
      "(the endpoint's query fields, e.g. { handle: 'charlidamelio' }).",
    schema: z.object({
      platform: z
        .string()
        .describe("Platform slug, e.g. 'tiktok' or 'youtube'"),
      resource: z
        .string()
        .describe("Endpoint resource, e.g. 'profile' or 'search'"),
      params: z
        .record(z.string(), z.union([z.string(), z.number()]))
        .describe("Query parameters for the endpoint"),
    }),
  },
);

const agent = createAgent({
  model: "claude-sonnet-5",
  tools: [socialcrawl],
});

const result = await agent.invoke({
  messages: [
    {
      role: "user",
      content: "How many followers does @charlidamelio have on TikTok?",
    },
  ],
});

console.log(result.messages.at(-1)?.content);
```

Install the packages first (check the [LangChain docs](https://docs.langchain.com/oss/javascript) for the current versions):

```bash
npm install langchain @langchain/anthropic zod
```

`createAgent` from the `langchain` package is the LangChain v1 standard — it replaced `createReactAgent` and runs the model-calls-tool-calls-model loop itself, so a query needing two rounds of tool calls still works. Swap `"claude-sonnet-5"` for any model string LangChain resolves. If you need to drive the loop by hand, `new ChatAnthropic({ model }).bindTools([socialcrawl])` still works: invoke the model, iterate `response.tool_calls`, push a `ToolMessage` per call, and invoke again until the model stops asking for tools.

Why one tool instead of one per endpoint? [#why-one-tool-instead-of-one-per-endpoint]

Every SocialCrawl endpoint shares the same shape: a GET at `/v1/{platform}/{resource}` with query parameters and one `x-api-key` header, returning the same JSON envelope. A single tool that takes `platform`, `resource`, and `params` therefore reaches all 381 endpoints without you writing a new tool each time. Point the model at the [platform directory](/platforms) or the machine-readable [`llms.txt`](/docs/ai-agents) so it knows which platform and resource to pass.

How do I keep the agent from spending too many credits? [#how-do-i-keep-the-agent-from-spending-too-many-credits]

Credits are billed exactly as the REST API bills them — most endpoints are 1 credit, heavier ones 5 or 10, and composite or bundle endpoints carry their own price (for example `search/everywhere` is a flat 20). Cache hits cost 0 credits. See [Endpoint pricing](/docs/endpoint-pricing) for the exact figure per endpoint. Empty results and upstream errors are auto-refunded. Read `credits_remaining` from the envelope after each call to track spend, and see [Credits](/docs/credits) for how the ledger works.

Where to go next [#where-to-go-next]

* Get a key at [socialcrawl.dev](https://www.socialcrawl.dev) (100 free credits) and read [Authentication](/docs/authentication).
* Prefer the Vercel AI SDK? The same pattern in that framework is on the [Vercel AI SDK](/docs/vercel-ai-sdk) page.
* Using an MCP client instead? [Claude Code](/docs/claude-code) and [Skills & MCP](/docs/skills-and-mcp) skip the DIY tool entirely.
* Fetching many items at once? [Batch endpoints](/docs/batch) replace a loop of tool calls with one request.
* Explore the [platform directory](/platforms) or start with the [Quickstart](/docs/quickstart).
