# Vercel AI SDK (/docs/vercel-ai-sdk)



Vercel AI SDK [#vercel-ai-sdk]

SocialCrawl has no dedicated AI SDK provider, and it does not need one: the API is a single authenticated GET request, so you wrap it in a `tool()` and hand it to `generateText`. One tool gives your agent access to current public data from 48 platforms; documented endpoint caches apply.

How do I give a Vercel AI SDK agent social media data? [#how-do-i-give-a-vercel-ai-sdk-agent-social-media-data]

Define a tool with a zod `inputSchema` that takes a `platform`, a `resource`, and the endpoint's `params`, then call the SocialCrawl REST API inside `execute` with your key in the `x-api-key` header. Pass the tool to `generateText` (or `streamText`) and set `stopWhen` so the model can call the tool and then answer.

```typescript
// socialcrawl-ai-sdk.ts
// Run with: SOCIALCRAWL_API_KEY=sc_... ANTHROPIC_API_KEY=... npx tsx socialcrawl-ai-sdk.ts
import { generateText, tool, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";

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

const socialcrawl = tool({
  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' }).",
  inputSchema: 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"),
  }),
  execute: 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 json.data;
  },
});

const { text } = await generateText({
  model: anthropic("claude-sonnet-5"),
  tools: { socialcrawl },
  // Let the model call the tool, then answer with the result.
  stopWhen: stepCountIs(5),
  maxOutputTokens: 1024,
  prompt: "How many followers does @charlidamelio have on TikTok?",
});

console.log(text);
```

Install the packages first (check the [AI SDK docs](https://ai-sdk.dev/docs) for the current versions):

```bash
npm install ai @ai-sdk/anthropic zod
```

The tool uses `inputSchema` (the AI SDK v6 field, not `parameters`) and the call uses `maxOutputTokens` (not `maxTokens`). `stopWhen: stepCountIs(5)` lets the model call the tool and keep going for up to five steps, so a question needing two lookups still resolves. Swap `anthropic("claude-sonnet-5")` for any provider model the AI SDK supports; the tool definition does not change.

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 a new tool per call. Point the model at the [platform directory](/platforms) or the machine-readable [`llms.txt`](/docs/ai-agents) so it knows which values to pass, and it will pick the right endpoint on its own.

How do I control credit spend? [#how-do-i-control-credit-spend]

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, and the response envelope includes `credits_remaining` so you can surface spend to the user. See [Credits](/docs/credits) for how the ledger works.

Can I stream results into the UI? [#can-i-stream-results-into-the-ui]

Yes, for the endpoints that support it. `search/everywhere`, `search/news`, and several Prism composites answer with Server-Sent Events when you send `Accept: text/event-stream`, so you can render partial results while slow sources are still running instead of blocking on a single 20-second envelope. That is a plain SSE stream you consume yourself inside the tool or alongside it — it is not the AI SDK's own `streamText` transport. See [Streaming (SSE)](/docs/streaming) for which endpoints stream and what the frames look like.

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 LangChain? The same pattern in that framework is on the [LangChain](/docs/langchain) 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).
