SocialCrawl

LangChain

Wrap the SocialCrawl API in a LangChain tool so your agent can fetch current public social media data. Documented endpoint caches apply.

SocialCrawl does not ship a LangChain package and does not need one. The API is a single authenticated GET request, so you wrap it in a tool() in about 30 lines and your agent reaches 67 platforms through that one tool. Documented endpoint caches apply.

Prefer not to write the tool yourself? An MCP client gets the same access with one command, plus local validation that refuses a bad call before it costs a credit. See Skills & MCP.

Prerequisites

  • Node.js and a TypeScript runner such as tsx.
  • A SocialCrawl API key from socialcrawl.dev, under Dashboard → API Keys. New accounts start with 100 free credits.
  • A model provider key for whichever model you bind the tool to.

How do I add social media data to a LangChain agent?

Install the packages

Check the LangChain docs for current versions.

Terminal
npm install langchain @langchain/anthropic zod

Define one tool for the whole API

Give it a zod schema that takes a platform, a resource, and the endpoint's query params, then call the 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"),
    }),
  },
);

Bind it to a model and run

TypeScript
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);

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.

What can the tool call?

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 631 endpoints without you writing a new tool each time.

To let the agent do thisPass
Read one profile, post, or listingplatform: "tiktok", resource: "profile", params: { handle: ... }
Search one platformplatform: "youtube", resource: "search", params: { query: ... }
Search many sources at onceplatform: "search", resource: "everywhere"
Check the balance before it spendsplatform: "credits", resource: "balance"

Point the model at the platform directory or the machine-readable llms.txt so it knows which platform and resource to pass.

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 (search/everywhere is a flat 20). Cache hits cost 0 credits, and empty results and upstream errors are auto-refunded. Read credits_remaining from the envelope after each call to track spend, and see Credits for how the ledger works.

Troubleshooting

Next steps