# Utility (/docs/utility) Free endpoints that describe the API itself: the catalog, a per-endpoint guide, a quickstart, the agent context payload, and a call planner The utility platform is the API describing itself. Five endpoints answer "what can I call", "how do I call this one", "how do I make my first request", "give my agent everything it needs to know", and "which calls does this job need". All five are free, cost 0 credits, and never consume credits. Base URL: `/v1/utility/...` Every response here is generated from the running registry at request time, so it cannot drift from what is actually callable. That is the reason to prefer these over a cached copy of the documentation. ## What is in here, and when you need it | You need | Call this | | ------------------------------------------------ | ---------------------------- | | Everything needed for a first successful request | `GET /v1/utility/quickstart` | | The list of what you can call, filtered | `GET /v1/utility/endpoints` | | Which endpoints support a parameter, and its cost | `GET /v1/utility/capabilities` | | Exactly how to call one endpoint | `GET /v1/utility/endpoint` | | A context payload to bootstrap an AI agent | `GET /v1/utility/llms` | | The calls a job needs, in order, with prices | `GET /v1/utility/plan` | ## Quickstart ### 1. Onboard in one call `quickstart` returns authentication, the base URL, the response envelope, the credit billing model, the error taxonomy, rate limits, pagination rules, and a copy-paste first request. ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/utility/quickstart?platform=tiktok" \ -H "x-api-key: YOUR_API_KEY" ``` Pass `platform` to tailor the first-call example and links to one platform. ### 2. Find and read the endpoint you want ```bash title="cURL" # Everything callable, filterable by platform, keyword, or method curl "https://www.socialcrawl.dev/v1/utility/endpoints?platform=tiktok&search=comment" \ -H "x-api-key: YOUR_API_KEY" # How to call one of them, by id or by path curl "https://www.socialcrawl.dev/v1/utility/endpoint?url=/v1/tiktok/profile" \ -H "x-api-key: YOUR_API_KEY" ``` ## Discover the surface | Endpoint | Credits | What it returns | Key parameters | | ---------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | | `GET /v1/utility/quickstart` | 0 | Everything needed for a first successful call: auth, base URL, envelope, billing, errors, rate limits, pagination, a first request | `platform` | | `GET /v1/utility/endpoints` | 0 | A machine-readable catalog of every active endpoint: path, method, credit cost, parameters, and a link to its usage guide | `platform`, `search`, `method` | | `GET /v1/utility/endpoint` | 0 | One endpoint end to end: every parameter with type and example, the exact credit cost, cache behaviour, the pagination recipe, a copy-paste request, and related endpoints | `id` or `url`, plus `method` | `endpoint` takes either `id` (`tiktok/profile`) or `url` (`/v1/tiktok/profile`), and one of them is required. Pass `method` to disambiguate a resource registered under more than one HTTP method: `/v1/web/monitors/{monitor_id}` is `GET`, `PATCH` and `DELETE`. Omit it and the first registered method wins. On `endpoints`, `search` is a keyword search over endpoint paths, summaries, parameter names and descriptions, and tags, so `search=sentiment` finds the comment endpoints that take `label=sentiment`. Every word has to match somewhere, and results whose path or summary contains the whole search come first. Results come back in keyword order, and `data.ranking` says `keyword`. The guide from `endpoint` also lists `params.featured`: up to three parameters worth sending, each with a one-line reason, and the example request already sends them (they never raise the price). Its `related` list names the endpoints that do more of the same job, each with `why`: the Prism composite that does it in one call, the batch variant, or the same data on another platform. ## Which endpoints support a parameter | Endpoint | Credits | What it returns | Key parameters | | -------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- | -------------- | | `GET /v1/utility/capabilities` | 0 | Every parameter that works across endpoints, with what it does, what it costs, and every endpoint that supports it | `param` | The index lists the `label=` presets separately for comments, posts and reviews (`free_values` run on every page at no extra credits, `metered_values` cost a credit per started 25 rows judged), `relevance=`, `judgments=`, `include=`, `since=` and `stop_at_id=`, `recent_days=`, the row filters, `seen=`, `trim=`, `download_media=`, `market=` and `fit=`. Pass `param=relevance` for one entry; an unknown name is a `404` that lists the valid ones. ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/utility/capabilities?param=label" \ -H "x-api-key: YOUR_API_KEY" ``` ## How often is each field filled? `endpoint` also returns a `quality` block: the share of rows that carried a value for each response field over the last 7 days, measured with production calls that bypass the cache. Use it to see which fields you can rely on before you build on one. ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/utility/endpoint?id=instagram/search/hashtag" \ -H "x-api-key: YOUR_API_KEY" ``` This `quality` block is shortened to a few fields: ```json title="Response" { "quality": { "measured": true, "window_days": 7, "measured_from": "2026-09-23", "measured_to": "2026-09-23", "sampled_calls": 1, "fill_rate": { "post.engagement.comments": 1, "post.engagement.likes": 0.79, "post.content.duration_seconds": 0.71 }, "null_by_design": [ { "leaf": "post.engagement.views", "reason": "A hashtag feed mixes photos and reels, and a photo has no play count", "when": "photo rows" } ], "by_rung": [], "freshness_hours": 3.4, "method": "Production calls made with the endpoint's example inputs, bypassing the cache; ..." } } ``` | Field | What it tells you | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `fill_rate` | For each field, the share of returned rows (0 to 1) that carried a value. `0.79` means 79 of every 100 rows had it. | | `null_by_design` | Fields that are empty on purpose, with the reason and, when it applies to some rows only, which rows. They are left out of `fill_rate`, so a correct empty value never reads as a gap. | | `by_rung` | Which data source position answered the sampled calls: `primary`, then `fallback_1`, `fallback_2` in order, each with its share of calls and its own fill rate. Empty when that was not recorded. | | `freshness_hours` | The median age, in hours, of the newest dated row per sampled call. `null` when the rows carry no date. | | `measured_from`, `measured_to` | The first and last day (UTC, `YYYY-MM-DD`) with a sample in the window. | | `sampled_calls` | How many sampled calls the numbers are computed from. | An endpoint with no sample in the last 7 days returns `"measured": false` with a `reason` and its `null_by_design` list, never a stale rate. ## Bootstrap an agent | Endpoint | Credits | What it returns | Key parameters | | ---------------------- | ------- | --------------------------------------------------------------------- | ------------------------------------------- | | `GET /v1/utility/llms` | 0 | The SocialCrawl context corpus, as markdown or as a structured object | `platform`, `format` (`markdown` or `json`) | An agent holding nothing but a key can learn the surface in one call rather than scraping documentation pages. `format` defaults to `markdown`. `platform` narrows the corpus to one platform when the full context is more than the agent needs. ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/utility/llms?platform=youtube&format=json" \ -H "x-api-key: YOUR_API_KEY" ``` ## Plan the calls for a job | Endpoint | Credits | What it returns | Key parameters | | ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------- | | `GET /v1/utility/plan` | 0 | The calls a job needs, in order: each call's path, the values your question filled, the ones still missing, its price, a cURL | `query` | Write the job in plain words in `query`, in any language. The planner covers four jobs today: monitoring a brand, one creator's profile and posts, a topic search, and a saved search on a monitor. A question that one endpoint answers returns that one call. Nothing is run, and the plan itself costs 0 credits. ```bash title="cURL" curl -G "https://www.socialcrawl.dev/v1/utility/plan" \ --data-urlencode "query=Combine @nike's TikTok profile with their recent videos and the comments on them" \ -H "x-api-key: YOUR_API_KEY" ``` The response carries `kind: "call_plan"` and a `steps` list. This one is shortened to the fields you act on: ```json title="Response" { "success": true, "data": { "kind": "call_plan", "recipe": "creator_profile", "uncertain": false, "steps": [ { "id": "tiktok_profile", "method": "GET", "path": "/v1/tiktok/profile", "params": { "handle": "nike" }, "missing": [], "credits": 1, "run": "ready" }, { "id": "tiktok_posts", "method": "GET", "path": "/v1/tiktok/profile/videos", "params": { "handle": "nike" }, "missing": [], "credits": 1, "run": "after_approval" }, { "id": "tiktok_comments", "method": "GET", "path": "/v1/tiktok/post/comments", "params": {}, "missing": ["url"], "binds": { "url": "tiktok_posts.items[].post.url" }, "credits": 1, "run": "blocked" } ], "ask": [], "cannot": [] }, "credits_used": 0 } ``` | Field | What it tells you | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `steps[].path` | The endpoint to call, checked against the current catalog, so a withdrawn endpoint never appears. | | `steps[].params` | Values your question supplied, under the parameter names the endpoint declares. | | `steps[].missing` | Parameters that still need a value before the call can run. | | `steps[].binds` | Where a missing value comes from: a field in an earlier step's rows. Above, each comment call takes a `url` from the videos step. | | `steps[].run` | `ready` is the first call you can make now. `after_approval` is complete but runs after an earlier step. `blocked` still waits for a value. | | `steps[].credits` | The price of that one call. A monitor row has `null`. | | `steps[].curl` | A copy-paste request for that step. A value the plan does not have stays a `{param}` placeholder. | | `ask` | The values only you can supply, as `step` and `param` pairs. A bound parameter is not listed here. | | `cannot` | One sentence for each part of the job the API cannot do, such as a follower history (past values are not stored) or a new-post alert. | | `uncertain` | `true` when the question is outside the four jobs or the planner is not confident. `steps` is then empty and `reason` says why, so you never get a guessed chain. | A job that should repeat (for example "every day") adds a `POST /v1/monitors` row, described in [Webhooks](/docs/webhooks.md). A question with a date window adds a note to each step: the parameter that sets the window, or where to stop paging when the endpoint has no such parameter. Sending `query` empty or leaving it out is a `400`. ## All endpoints ## Platform notes - **All five endpoints are free.** They cost 0 credits and never consume credits, so polling them is safe. - **`endpoint` requires `id` or `url`.** Sending neither is a `400`. - **`plan` requires `query`.** A plan lists calls and runs none of them; each call it lists is billed at its own price when you make it. - All endpoints use `GET` with query parameters, authenticate with the `x-api-key` header, and return the unified SocialCrawl envelope. ## Next steps - [Quickstart](/docs/quickstart.md): The same first-call walkthrough, written for a human. - [AI agents](/docs/ai-agents.md): Wiring SocialCrawl into an agent loop. - [Choosing endpoints](/docs/choosing-endpoints.md): Which endpoint answers which question, across the catalogue.