{
  "openapi": "3.1.0",
  "info": {
    "title": "SocialCrawl API: Universal Search",
    "version": "1.0.0",
    "description": "Unified social media data API - one API key, one consistent response format, 69 platforms, 679 endpoints. Power AI agents with clean social data.\n\nThis document covers the Universal Search endpoints only (5 operations). The full contract for every platform is at https://www.socialcrawl.dev/v1/openapi.json, and every per-platform document is listed at https://www.socialcrawl.dev/openapi/index.json.",
    "contact": {
      "name": "SocialCrawl",
      "url": "https://www.socialcrawl.dev",
      "email": "socialcrawl@ridio.io"
    }
  },
  "servers": [
    {
      "url": "https://www.socialcrawl.dev/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key authentication. Send your key in the `x-api-key` request header on every call. Create and manage keys in the dashboard."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "The same API key sent as `Authorization: Bearer <key>`, the default in most agents and HTTP tools. Same key, same rules; when both headers are sent, `x-api-key` wins."
      }
    },
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "description": "Unified error response envelope. Every 4xx/5xx response returns this shape; `error.type` is a machine-readable code from the API's error catalog.",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ],
            "example": false,
            "description": "Always false on an error response."
          },
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "MISSING_API_KEY",
                  "INVALID_API_KEY",
                  "INSUFFICIENT_CREDITS",
                  "INVALID_REQUEST",
                  "ENDPOINT_NOT_FOUND",
                  "RESOURCE_NOT_FOUND",
                  "CONCURRENCY_LIMIT",
                  "UPSTREAM_ERROR",
                  "SERVICE_UNAVAILABLE",
                  "INTERNAL_ERROR",
                  "METHOD_NOT_ALLOWED",
                  "IDEMPOTENCY_KEY_CONFLICT",
                  "IDEMPOTENCY_IN_PROGRESS",
                  "IDEMPOTENCY_REPLAY_UNAVAILABLE",
                  "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
                  "COHORT_MEMBER_LIMIT_EXCEEDED",
                  "COHORT_LIMIT_EXCEEDED",
                  "COHORT_IDENTITY_PLATFORM_UNSUPPORTED",
                  "COHORT_IDENTITY_CONFLICT",
                  "COHORT_QUERY_NOT_CANCELLABLE",
                  "COHORT_QUERY_NOT_READY",
                  "COHORT_RESULT_TOO_LARGE",
                  "PAYLOAD_TOO_LARGE",
                  "RATE_LIMITED",
                  "KEY_BUDGET_EXCEEDED",
                  "RUN_NOT_FOUND",
                  "RUN_STATE_CONFLICT",
                  "RUN_EXPIRED",
                  "NEEDS_ASYNC",
                  "CURSOR_EXPIRED",
                  "SCHEDULE_NOT_FOUND",
                  "STREAM_NOT_FOUND",
                  "STREAM_STATE_CONFLICT"
                ],
                "example": "INVALID_REQUEST",
                "description": "Machine-readable error code. The per-status `x-error-codes` list on each response narrows which codes that status can carry."
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation of the error."
              },
              "status": {
                "type": "integer",
                "description": "HTTP status code, echoed in the body."
              },
              "doc_url": {
                "type": "string",
                "description": "Link to the docs page for this error code."
              },
              "retryable": {
                "type": "boolean",
                "description": "Whether retrying the identical request can succeed. True for rate limits, concurrency limits, idempotency contention and transient upstream or server failures; false for every other code, including both 402s."
              },
              "details": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "Optional structured context. Omitted on ordinary errors. Both 402s carry `reason` (`balance_too_low` or `key_budget_reached`), `retry_will_succeed: false`, a one-sentence `next_step`, and `top_up_url` or `key_settings_url`; the GET endpoints add `credits_required`; a metered endpoint adds `pricing` (`\"ceiling\"` when the hold is the most the call can cost and the unused part is refunded, `\"exact\"` when the call is charged what it holds; measured on recent production calls), `credits_typical` (on a ceiling, what a call like this is usually charged), and, when a cheaper shape of the same request exists, `lower_cost_with`, `lower_cost_options` (`param`, `value` or null to leave it out, and `credits_required` with that change) and `credits_required_cheapest`. A `max_credits` page that switched to a cheaper form to fit (`threads/search` with `expand=false`) and still found the balance short adds `balance_fallback`: the `param` and `value` it switched to, and `credits_required` for the call as sent. A page-cap rejection carries `reason: \"page_limit\"` with `max_page`, `requested_page` and `narrow_with`. An `INVALID_REQUEST` that sends no member of a required one-of group carries `fields` (the parameters of that group) and a one-sentence `next_step`. Other endpoints use it for their own taxonomies, such as the comment-lookup not-found reasons."
              },
              "status_url": {
                "type": "string",
                "format": "uri",
                "description": "Present on 5xx responses: the public status page, filtered to the platform when one is known."
              },
              "incident": {
                "type": "object",
                "description": "Present on a 5xx response when an open public incident explains the failure.",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "k3v9w2m8q1zt"
                  },
                  "title": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "example": "investigating"
                  },
                  "impact": {
                    "type": "string",
                    "example": "major"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "id",
                  "title",
                  "status",
                  "impact",
                  "url"
                ]
              }
            },
            "required": [
              "type",
              "message",
              "status",
              "doc_url"
            ]
          },
          "credits_used": {
            "type": "integer",
            "description": "Net credits charged for this request. Error paths deduct-then-refund, so this is 0 in almost every case; a partial-coverage composite may keep the succeeded-leg cost."
          },
          "credits_remaining": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Credits left after this request when established. Some unauthenticated errors use null; on a prebilling route whose attempted balance lookup fails, this field is omitted instead of fabricated."
          },
          "request_id": {
            "type": "string",
            "description": "Unique request identifier - matches the X-Request-Id header. Quote it in support requests."
          }
        },
        "required": [
          "success",
          "error",
          "credits_used",
          "request_id"
        ]
      },
      "MonitorAlertRule": {
        "description": "A numeric condition evaluated against a monitor run and, for change operators, a previous comparable run.",
        "properties": {
          "metric": {
            "description": "Dot path to a numeric key in the recipe's own result, for example `coverage` or `summary.total`. On a numbers-only monitor (created with `track`) the metric must be one of `track.metrics`, and an `items[].<path>` metric is evaluated once per row: a fired alert then carries `row_id`. The special metric `rows_new` (numbers-only monitors only; it needs an `items[].` metric in `track.metrics` and is not itself tracked) counts the list rows this run has that the previous run did not: `{\"metric\":\"rows_new\",\"op\":\"gt\",\"value\":0}` alerts on any new post or video. It accepts only `gt` and `gte`, and is skipped on the first run. \"New\" means absent from the previous successful run's stored rows (capped at `max_rows`, default 100), so a row that drops off and returns later counts as new again. An empty-page run is refunded and is not a baseline, so on a sparse feed the first run that holds rows has no baseline and stays silent: the first new post after a quiet period may not alert. Use a daily cadence or leave `max_rows` headroom.",
            "type": "string"
          },
          "op": {
            "enum": [
              "gt",
              "lt",
              "gte",
              "lte",
              "abs_change_gt",
              "pct_change_gt",
              "pct_change_lt"
            ],
            "type": "string"
          },
          "value": {
            "type": "number"
          },
          "window": {
            "description": "Accepted and stored, but ignored: a change op always compares against the immediately preceding comparable run, whatever the value.",
            "enum": [
              "1d",
              "1w"
            ],
            "type": "string"
          }
        },
        "required": [
          "metric",
          "op",
          "value"
        ],
        "type": "object"
      },
      "EventEnvelope": {
        "description": "One event, identical in the feed and in every webhook batch. `id` is stable for one fact, so deduplicate on it.",
        "properties": {
          "id": {
            "description": "Deterministic event id: the same fact never mints a second event.",
            "example": "evt_k3m7q2xwcbvd4nph6trz5ycgda",
            "type": "string"
          },
          "type": {
            "description": "Dot-delimited lower-case type. Types written today: `discover.progress`, `discover.accounts_ready`, `discover.completed`, `discover.partial`, `discover.paused`, `discover.failed`, `discover.new_rows`, `discover.new_accounts`, `discover.new_items`, `discover.run_skipped`, `discover.run_failed`, `endpoint.disabled`, `mention.created`, `mention.deleted`, `stream.baseline.established`, `stream.coverage_gap`, `stream.paused`, `stream.resumed`, `stream.deleted`, `stream.budget.warning`, `stream.health`.",
            "example": "discover.completed",
            "type": "string"
          },
          "api_version": {
            "example": "2026-10-01",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "cursor": {
            "description": "The feed position right after this event. Send it as `cursor` to read what came after; an event id works too.",
            "example": "c_MS4xMi4xNzkyNDA0OTA0",
            "type": "string"
          },
          "subject": {
            "description": "The object the event is about, for example `{ kind: \"discover_run\", id: \"run_…\" }`.",
            "properties": {
              "id": {
                "type": "string"
              },
              "kind": {
                "type": "string"
              },
              "metadata": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "kind",
              "id"
            ],
            "type": [
              "object",
              "null"
            ]
          },
          "data": {
            "description": "The event's facts. Discover events carry counts and ids, never keywords or row text.",
            "type": "object"
          },
          "links": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Absolute URLs to the subject, such as `run` and `results` (for example `https://www.socialcrawl.dev/v1/prism/discover/runs/run_...`), the same in the feed and in webhook batches. Events served before 26/10/2026 carried relative paths.",
            "type": "object"
          }
        },
        "required": [
          "id",
          "type",
          "api_version",
          "created_at",
          "cursor",
          "subject",
          "data",
          "links"
        ],
        "type": "object"
      },
      "WebhookEndpoint": {
        "description": "A registered receiver. The signing secret is never part of it: it is returned once, by create and by rotate-secret.",
        "properties": {
          "id": {
            "example": "we_V1StGXR8Z5jdHi6BmyT",
            "type": "string"
          },
          "url": {
            "example": "https://example.com/hooks/socialcrawl",
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "types": {
            "description": "Subscribed event types: exact types, `ns.*` wildcards, or `*` for every type.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "subject_ids": {
            "description": "Only events about these subjects (a run or schedule id); null for every subject.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "status": {
            "enum": [
              "enabled",
              "disabled"
            ],
            "type": "string"
          },
          "disabled_reason": {
            "description": "`gone` (the receiver answered 410), `failing` (5 consecutive days of failed deliveries), `key_revoked` (the creating key was revoked or deleted) or `user` (set with PATCH). Null while enabled.",
            "enum": [
              "gone",
              "failing",
              "key_revoked",
              "user",
              null
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "failing_since": {
            "description": "Start of the current run of failed deliveries; null while healthy.",
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "api_version": {
            "example": "2026-10-01",
            "type": "string"
          },
          "secret_rotation": {
            "description": "Set during a rotation: until `previous_secret_expires_at` every delivery is signed with both secrets.",
            "properties": {
              "previous_secret_expires_at": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "next": {
            "description": "Ready relative URLs for the next calls.",
            "properties": {
              "attempts_url": {
                "type": "string"
              },
              "events_url": {
                "type": "string"
              },
              "rotate_secret_url": {
                "type": "string"
              },
              "self_url": {
                "type": "string"
              },
              "test_url": {
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "required": [
          "id",
          "url",
          "types",
          "status",
          "api_version",
          "created_at"
        ],
        "type": "object"
      },
      "WebhookAttempt": {
        "description": "One delivery attempt. `response_excerpt` is at most 1 KB of your receiver's answer.",
        "properties": {
          "id": {
            "type": "string"
          },
          "delivery_id": {
            "description": "The batch's `webhook-id`, the same on every retry.",
            "type": "string"
          },
          "test": {
            "type": "boolean"
          },
          "status": {
            "description": "Your receiver's HTTP status; null for a timeout, a refused host, a network error or a secret that could not be opened.",
            "type": [
              "integer",
              "null"
            ]
          },
          "outcome": {
            "enum": [
              "delivered",
              "failed",
              "gone",
              "retry_after",
              "timeout",
              "redirect",
              "refused_host",
              "secret_unavailable",
              "network_error"
            ],
            "type": "string"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ]
          },
          "response_excerpt": {
            "type": [
              "string",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "delivery_id",
          "test",
          "status",
          "outcome",
          "created_at"
        ],
        "type": "object"
      },
      "EventBatch": {
        "description": "What every delivery carries, also for one event: at most 100 events or 256 KB. Each inner event keeps its own `id` and `cursor`; deduplicate on the inner ids. A test send marks its event `\"test\": true` with `\"cursor\": null`.",
        "properties": {
          "id": {
            "example": "bat_V1StGXR8Z5jdHi6BmyT",
            "type": "string"
          },
          "type": {
            "const": "event.batch",
            "type": "string"
          },
          "data": {
            "properties": {
              "events": {
                "items": {
                  "$ref": "#/components/schemas/EventEnvelope"
                },
                "maxItems": 100,
                "type": "array"
              }
            },
            "required": [
              "events"
            ],
            "type": "object"
          }
        },
        "required": [
          "id",
          "type",
          "data"
        ],
        "type": "object"
      },
      "ListeningRuleAst": {
        "description": "A rule as a tree of `and`, `or`, `not`, `term`, `phrase` and `field` nodes, as the dry run returns it in `data.stream.groups[].ast`.",
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "and": {
                "minItems": 1,
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ListeningRuleAst"
                }
              }
            },
            "required": [
              "and"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "or": {
                "minItems": 1,
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ListeningRuleAst"
                }
              }
            },
            "required": [
              "or"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "not": {
                "$ref": "#/components/schemas/ListeningRuleAst"
              }
            },
            "required": [
              "not"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "term": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "term"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "phrase": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "phrase"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "field": {
                "type": "string",
                "enum": [
                  "lang",
                  "country",
                  "platform",
                  "site",
                  "community"
                ]
              },
              "value": {
                "type": "string",
                "minLength": 1
              }
            },
            "required": [
              "field",
              "value"
            ],
            "additionalProperties": false
          }
        ]
      }
    }
  },
  "tags": [
    {
      "name": "search",
      "description": "Search endpoints"
    }
  ],
  "paths": {
    "/search/everywhere": {
      "get": {
        "summary": "Universal social search across 15 platforms",
        "description": "One query, searched on every platform at once, returns one ranked list with clusters and top comments. It searches up to 20 sources across 15 platforms: Reddit (`reddit`), X posts (`twitter`), a written summary of X posts (`twitter-ai-search`), YouTube (`youtube`), TikTok (`tiktok`), Instagram (`instagram`), Hacker News (`hackernews`), Polymarket (`polymarket`), GitHub (`github`), Threads (`threads`), Pinterest (`pinterest`), a cited web answer (`perplexity`), web search results (`web`), LinkedIn (`linkedin`), Rumble (`rumble`), Naver (`naver`) and Facebook (`facebook`), plus TikTok hashtags (`tiktok-hashtag`), Instagram hashtags (`instagram-hashtag`) and YouTube hashtags (`youtube-hashtag`) in hashtag mode. `naver` (Naver blog, cafe and KnowledgeiN) joins when the query contains Hangul, and on any query when you name it in `sources`; Naver rows carry the corpus in `metadata.corpus`. `facebook` runs only when you ask for it: `include=facebook` adds it to the default sources, and `sources=facebook` runs only the sources you name; it returns about 5 public posts, newest first inside your date window. The hashtag lanes run only in hashtag mode: an explicit `#tag`, a single word, or a topic term the planner names. A source you name in `sources` is always searched. What ranks and what filters: `lookback_days` is a ranking signal that sets the freshness curve, so an older row can still rank when nothing recent matches; `since`, `until`, `from_date` and `to_date` are hard bounds that drop rows outside the window (rows with no date are kept and counted in `data.since`); `relevance=filter` drops the rows judged off topic; `limit` (1 to 40) trims the answer. Every result carries `computed.relevance` and `computed.stance`, and `data.judgments` says whether each judgment ran. Top comments ride the results on the six lanes that have them (Reddit, Hacker News, YouTube, TikTok, Instagram and GitHub) at `items[i].source_items[0].metadata.top_comments[]`: up to 15 on each of the top 10 results and 5 after, each `{ score, excerpt, truncated, author, url, date }`. X posts (`twitter`, also `x`) are ranked rows. The X summary (`twitter-ai-search`, which takes 15 to 45 seconds) runs only with `include=synthesis` and arrives in `data.synthesis.x` beside the cited web answer (`data.synthesis.web`), never as ranked rows. On the JSON path the X summary is included only when it is ready with the rest of the answer, and otherwise `sources_failed` says so; the stream waits for it. Every source is a call to its own public endpoint, with that endpoint's fallbacks, inside the flat price: a source whose endpoint keeps failing is skipped (`sources_failed` says `skipped: breaker_open`), and `data.platforms` reports each platform's status, rows, latency and outcome code. Each source has 12 seconds (25 seconds when you search one platform, 20 seconds for `facebook`, 6 seconds for `twitter` beside other sources), and a full search usually takes 20 to 30 seconds: allow a 120-second client timeout. Answers are cached for 120 seconds, and a cache hit is free. Each row's `date_confidence` and `date_source` say how far to trust `published_at`. Streams over SSE with `Accept: text/event-stream` (the terminal `done` chunk carries the page blocks of the JSON answer except `platforms` and `synthesis`; on the stream the web answer and the X summary arrive as `items` chunks), or answers JSON with `Accept: application/json`. Flat 20 credits per call: an answer with no row anywhere costs 0 credits, and when fewer than half the planned sources answer, half is refunded. A parameter this endpoint does not take is ignored with a `data._warnings` line, never refused.",
        "tags": [
          "search"
        ],
        "operationId": "get_search_everywhere",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-credit-tier": "standard",
        "x-credit-cost": 20,
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "Search query (1-512 chars)",
            "schema": {
              "type": "string"
            },
            "example": "kanye west"
          },
          {
            "name": "lookback_days",
            "in": "query",
            "required": false,
            "description": "Recency window in days (minimum 1, default 30). This is a ranking signal, not a hard filter: it sets the freshness curve, so a much older item can still rank when nothing recent matches, and it sets the date window sent to `facebook`. When `from_date` is sent too, `from_date` applies. On the stream, windows over 90 days add a `warning` chunk. For hard bounds use `since`, `until`, `from_date` and `to_date`. Check each row's `date_confidence` and `date_source` before filtering on its date: `low` means the date is an estimate (a rounded YouTube label, a KnowledgeiN estimate).",
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "example": 30
          },
          {
            "name": "from_date",
            "in": "query",
            "required": false,
            "description": "Lower date bound, YYYY-MM-DD (from the start of that UTC day) or an ISO 8601 timestamp; when `lookback_days` is sent too, `from_date` applies. A hard bound on `items`: rows dated before it are dropped, rows with no date are kept, and `data.since` reports `{ since, until, dropped, kept_undated }`. Sent with `since`, the later of the two applies and `data._warnings` says so. An invalid date is a free 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "required": false,
            "description": "Upper date bound, YYYY-MM-DD (to the end of that UTC day, inclusive) or an ISO 8601 timestamp; defaults to today when from_date is set alone. A hard bound on `items`: rows dated after it are dropped, rows with no date are kept. Sent with `until`, the earlier of the two applies and `data._warnings` says so. An invalid date is a free 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Only rows published at or after this time (ISO 8601 timestamp or date), for polling: pass the previous run's time. A hard filter on `items`, unlike lookback_days; rows with no date are kept and `data.since` reports `{ since, until, dropped, kept_undated }`. Billed as usual.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "Only rows published at or before this time: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. A hard filter on `items`, like since; rows with no date are kept and counted in `data.since`. Billed as usual. An invalid date is a free 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "A window that holds, by name: `Nd` (1 to 3650 days, ending now), `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `last_quarter`, `this_year` or `ytd`, with calendar periods read in `tz`. Each platform is sent its own date filter, and every row is checked against the window again, so rows outside it are dropped whatever the platform did; `data.request.window` echoes the resolved window and `data.platforms.<p>.window` counts the rows dropped. `since`, `until`, `from_date`, `to_date` and `lookback_days` win over `period` when sent with it, and `data._warnings` says so. Billed as usual.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "IANA time zone name (default UTC, for example Asia/Seoul) that `period` and bare `since`, `until`, `from_date` and `to_date` dates are read in. An unknown zone is a free 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "undated",
            "in": "query",
            "required": false,
            "description": "What a row with no date does inside a window: `keep` (default) keeps it and counts it in `data.request.window.undated_kept`, `drop` removes it and counts it in `undated_dropped`. Applies only when a window is set.",
            "schema": {
              "type": "string",
              "enum": [
                "keep",
                "drop"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many ranked results `items` returns, 1 to 40 (default 40). Above 40 is clamped to 40 with a `data._warnings` line. It trims the answer only: the search, its price and its cache entry are the same whatever the limit, so `limit=10` then `limit=20` on the same query is one billed search.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "sources",
            "in": "query",
            "required": false,
            "description": "Optional CSV allowlist of sources (mutually exclusive with exclude). Valid names: reddit, twitter, twitter-ai-search, youtube, tiktok, instagram, hackernews, polymarket, github, threads, pinterest, perplexity, web, linkedin, rumble, tiktok-hashtag, instagram-hashtag, youtube-hashtag, naver, facebook. `naver` (Naver blog, cafe and KnowledgeiN) is in the default set only when the query contains Hangul. `facebook` (public post search) runs only when you name it here. `x` is another name for `twitter` (X posts) and `tavily` for `web`; `twitter-ai-search` here means `twitter` plus include=synthesis. Platform shorthands expand to their full group: youtube, instagram, tiktok also include their -hashtag lane. Unknown names return a 400.",
            "schema": {
              "type": "string"
            },
            "example": "reddit,youtube,github"
          },
          {
            "name": "platforms",
            "in": "query",
            "required": false,
            "description": "Another name for sources, with the same values. When both are sent and differ, sources applies and `data._warnings` says so.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exclude",
            "in": "query",
            "required": false,
            "description": "Optional CSV blocklist of sources (mutually exclusive with sources). Same valid names and platform shorthands as sources: excluding youtube/instagram/tiktok also excludes the platform's -hashtag lane. Unknown names return a 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_transcripts",
            "in": "query",
            "required": false,
            "description": "Fetch spoken-word transcripts for the top 3 video results (default false), so a video whose title never mentions your query but whose narration does can still be found and quoted. Applies to the YouTube, Rumble, TikTok and Instagram lanes; YouTube and Rumble transcripts carry timestamped segments, TikTok and Instagram are plain text. Transcripts land on `data.items[i].source_items[0].metadata.transcript` and stream as `transcript_enriched` chunks. Included in the flat 20 credits.",
            "schema": {
              "type": "boolean"
            },
            "example": false
          },
          {
            "name": "relevance",
            "in": "query",
            "required": false,
            "description": "Optional. filter drops the ranked results our relevance judgment already scored as off-topic for your query (unrelated, or clearly about a different thing that shares its words) and lists their ids in data.relevance.dropped_ids, with counts. A result that could not be judged is never dropped; when none could be judged nothing is dropped and data._warnings says relevance_unavailable. items_by_source is not filtered. Omit it to keep every ranked result, ordered as before; each result still carries computed.relevance by default (see judgments). Included in the flat 20 credits.",
            "schema": {
              "type": "string",
              "enum": [
                "filter"
              ]
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "Optional CSV of extra blocks and opt-in sources. synthesis adds the X summary (twitter-ai-search) and returns it in data.synthesis.x with its citations. facebook adds Facebook public post search to the default sources (it is not in the default fan-out, and `sources=` would replace the defaults instead). stance is now on by default and accepted for compatibility: data.items[i].computed.stance ({ label: positive, negative, neutral, no_opinion or null when unsure, probabilities, confidence }) says what each post, with any replies shown, says about your query, and data.stance_split counts it per platform and overall with the ids behind every count. Posts judged under the confidence floor count as uncertain, never as a stance. If the judgment is unavailable the search still returns, stance is null and data._warnings says stance_unavailable (or stance_skipped when judging was skipped). Included in the flat 20 credits.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "judgments",
            "in": "query",
            "required": false,
            "description": "Optional. on (default) or off. On, every result also carries data.items[i].computed.stance (see include) and data.items[i].computed.relevance ({ score 0 to 1, on_topic, entity }), with data.relevance counting the off-topic results and listing their ids. Nothing is dropped or reordered and the price does not change. off returns the response without these blocks.",
            "schema": {
              "type": "string",
              "enum": [
                "on",
                "off"
              ]
            }
          },
          {
            "name": "switch_from",
            "in": "query",
            "required": false,
            "description": "Optional brand. data.switch_receipts lists results where the author says they personally left that brand, with the verbatim text, the reason, where they went, and the link. There is no percentage. Rows that are not a switch stay in items. Included in the flat 20 credits.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "max_age_s",
            "in": "query",
            "required": false,
            "description": "The oldest cached copy you accept, in seconds. A copy that old or younger is served for 0 credits, with its age in `age_s` and the `X-Cache-Age` header. Without it a copy up to 120 seconds old is served. A lower value fetches fresh (billed) when the copy is older, and 0 always fetches live, like `Cache-Control: no-cache`.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 120
            }
          },
          {
            "name": "Cache-Control",
            "in": "header",
            "required": false,
            "description": "Send `no-cache` to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the `no-cache` directive triggers this. To accept an older cached copy, or to require a younger one, send the `max_age_s` query parameter instead. See the Response Schema guide for details.",
            "schema": {
              "type": "string"
            },
            "example": "no-cache"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives `409 IDEMPOTENCY_IN_PROGRESS` with a `Retry-After` of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: `credits_used` becomes 0, `idempotent_replay` becomes true, and `credits_remaining` is refreshed to the current balance. A known current balance appears in both the body and `X-Credits-Remaining` header; no balance row resolves to 0. On a transient lookup failure, body `credits_remaining` is null and `X-Credits-Remaining` is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use `Accept: application/json` when sending this header. The unsupported key-plus-SSE combination is rejected before billing.",
            "schema": {
              "type": "string"
            },
            "example": "7a5e1b4c-2d8f-4a3b-9c1e-6e8b4d2a1f3c"
          },
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "Send `respond-async` to run this GET in the background instead of waiting on the socket (or add `?async=true` to the query). The answer is 202 with `data.job_id`, a `Location` header and `Retry-After`; read the result free at `GET /v1/prism/jobs/{job_id}`, where `results[0].response` is exactly what this call returns. Nothing is held at submit: the call is validated now and billed as this call when it runs. Use it for calls that can outlast your client's timeout (MCP and many HTTP clients stop at 30 s). `Idempotency-Key` returns the same job on a retry.",
            "schema": {
              "type": "string"
            },
            "example": "respond-async"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-Credits-Used": {
                "description": "Net credits charged for this response. Idempotency replays report 0.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Credits-Remaining": {
                "description": "Current authoritative balance. Free cache hits and idempotency replays omit this header when the balance cannot be determined; body `credits_remaining` is null instead.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Key-Credits-Remaining": {
                "description": "Only when the API key has a credit limit: the credits this key may still spend under that limit, after this call (never below 0). Absent for a key with no limit. `GET /v1/keys/current` has the limit and what is used.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Idempotent-Replay": {
                "description": "Present with value `true` only when this response replays a settled idempotency record.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "Idempotent-Replayed": {
                "description": "Present with value `true` only when this response replays a settled idempotency record. Same meaning as `X-Idempotent-Replay`.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Whether the request succeeded",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "description": "Platform name",
                      "example": "search"
                    },
                    "endpoint": {
                      "type": "string",
                      "description": "API endpoint path",
                      "example": "/v1/search/everywhere"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string",
                          "description": "The same id as the envelope's request_id."
                        },
                        "trace_id": {
                          "description": "The search pipeline's own id, for support.",
                          "type": "string"
                        },
                        "query": {
                          "type": "string",
                          "description": "The query as the planner saw it."
                        },
                        "plan": {
                          "type": "object",
                          "properties": {
                            "intent": {
                              "type": "string",
                              "enum": [
                                "factual",
                                "product",
                                "concept",
                                "opinion",
                                "how_to",
                                "comparison",
                                "breaking_news",
                                "prediction"
                              ]
                            },
                            "freshness_mode": {
                              "type": "string",
                              "enum": [
                                "strict_recent",
                                "balanced_recent",
                                "evergreen_ok"
                              ]
                            },
                            "cluster_mode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "story",
                                "workflow",
                                "market",
                                "debate"
                              ]
                            },
                            "subqueries": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "label": {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  "search_query": {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  "ranking_query": {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  "sources": {
                                    "minItems": 1,
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "weight": {
                                    "type": "number",
                                    "exclusiveMinimum": 0
                                  }
                                },
                                "required": [
                                  "label",
                                  "search_query",
                                  "ranking_query",
                                  "sources",
                                  "weight"
                                ]
                              }
                            },
                            "source_weights": {
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "number",
                                "minimum": 0
                              }
                            },
                            "notes": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          },
                          "required": [
                            "intent",
                            "freshness_mode",
                            "cluster_mode",
                            "subqueries",
                            "source_weights",
                            "notes"
                          ]
                        },
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "candidate_id": {
                                "type": "string"
                              },
                              "id": {
                                "type": "string"
                              },
                              "native_id": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "also_on": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "platform": {
                                      "type": "string"
                                    },
                                    "id": {
                                      "type": "string"
                                    },
                                    "url": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    }
                                  },
                                  "required": [
                                    "platform",
                                    "id",
                                    "url"
                                  ]
                                }
                              },
                              "item_id": {
                                "type": "string"
                              },
                              "source": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string"
                              },
                              "snippet": {
                                "type": "string"
                              },
                              "subquery_labels": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "native_ranks": {
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {
                                  "type": "number"
                                }
                              },
                              "local_relevance": {
                                "type": "number"
                              },
                              "freshness": {
                                "type": "number"
                              },
                              "engagement": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "source_quality": {
                                "type": "number"
                              },
                              "rrf_score": {
                                "type": "number"
                              },
                              "sources": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "source_items": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "item_id": {
                                      "type": "string"
                                    },
                                    "id": {
                                      "type": "string"
                                    },
                                    "native_id": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "candidate_id": {
                                      "type": "string"
                                    },
                                    "source": {
                                      "type": "string"
                                    },
                                    "title": {
                                      "type": "string"
                                    },
                                    "body": {
                                      "default": "",
                                      "type": "string"
                                    },
                                    "url": {
                                      "default": "",
                                      "type": "string"
                                    },
                                    "author": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "container": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "published_at": {
                                      "anyOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "date_confidence": {
                                      "default": "low",
                                      "type": "string",
                                      "enum": [
                                        "high",
                                        "med",
                                        "low"
                                      ]
                                    },
                                    "date_source": {
                                      "type": "string",
                                      "enum": [
                                        "platform",
                                        "serp",
                                        "page_meta",
                                        "estimate"
                                      ]
                                    },
                                    "engagement": {
                                      "default": {},
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {
                                        "anyOf": [
                                          {
                                            "type": "number"
                                          },
                                          {
                                            "type": "null"
                                          }
                                        ]
                                      }
                                    },
                                    "relevance_hint": {
                                      "type": "number"
                                    },
                                    "why_relevant": {
                                      "default": "",
                                      "type": "string"
                                    },
                                    "snippet": {
                                      "default": "",
                                      "type": "string"
                                    },
                                    "metadata": {
                                      "default": {},
                                      "type": "object",
                                      "propertyNames": {
                                        "type": "string"
                                      },
                                      "additionalProperties": {}
                                    },
                                    "media": {
                                      "default": {
                                        "thumbnail_url": null,
                                        "video_url": null,
                                        "duration_s": null,
                                        "image_urls": [],
                                        "aspect_ratio": null,
                                        "author_avatar_url": null,
                                        "favicon_url": null
                                      },
                                      "type": "object",
                                      "properties": {
                                        "thumbnail_url": {
                                          "default": null,
                                          "anyOf": [
                                            {
                                              "type": "string",
                                              "format": "uri"
                                            },
                                            {
                                              "type": "null"
                                            }
                                          ]
                                        },
                                        "video_url": {
                                          "default": null,
                                          "anyOf": [
                                            {
                                              "type": "string",
                                              "format": "uri"
                                            },
                                            {
                                              "type": "null"
                                            }
                                          ]
                                        },
                                        "duration_s": {
                                          "default": null,
                                          "anyOf": [
                                            {
                                              "type": "number",
                                              "minimum": 0
                                            },
                                            {
                                              "type": "null"
                                            }
                                          ]
                                        },
                                        "image_urls": {
                                          "default": [],
                                          "type": "array",
                                          "items": {
                                            "type": "string",
                                            "format": "uri"
                                          }
                                        },
                                        "aspect_ratio": {
                                          "default": null,
                                          "anyOf": [
                                            {
                                              "type": "number",
                                              "exclusiveMinimum": 0
                                            },
                                            {
                                              "type": "null"
                                            }
                                          ]
                                        },
                                        "author_avatar_url": {
                                          "default": null,
                                          "anyOf": [
                                            {
                                              "type": "string",
                                              "format": "uri"
                                            },
                                            {
                                              "type": "null"
                                            }
                                          ]
                                        },
                                        "favicon_url": {
                                          "default": null,
                                          "anyOf": [
                                            {
                                              "type": "string",
                                              "format": "uri"
                                            },
                                            {
                                              "type": "null"
                                            }
                                          ]
                                        }
                                      }
                                    },
                                    "local_relevance": {
                                      "anyOf": [
                                        {
                                          "type": "number"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "freshness": {
                                      "anyOf": [
                                        {
                                          "type": "number"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "engagement_score": {
                                      "anyOf": [
                                        {
                                          "type": "number"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "source_quality": {
                                      "anyOf": [
                                        {
                                          "type": "number"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "local_rank_score": {
                                      "anyOf": [
                                        {
                                          "type": "number"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    }
                                  },
                                  "required": [
                                    "item_id",
                                    "source",
                                    "title"
                                  ]
                                }
                              },
                              "rerank_score": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "final_score": {
                                "default": 0,
                                "type": "number"
                              },
                              "explanation": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "cluster_id": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "metadata": {
                                "default": {},
                                "type": "object",
                                "propertyNames": {
                                  "type": "string"
                                },
                                "additionalProperties": {}
                              },
                              "computed": {
                                "type": "object",
                                "properties": {
                                  "stance": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "label": {
                                            "anyOf": [
                                              {
                                                "type": "string",
                                                "enum": [
                                                  "positive",
                                                  "negative",
                                                  "neutral",
                                                  "no_opinion"
                                                ]
                                              },
                                              {
                                                "type": "null"
                                              }
                                            ]
                                          },
                                          "probabilities": {
                                            "type": "object",
                                            "propertyNames": {
                                              "type": "string"
                                            },
                                            "additionalProperties": {
                                              "type": "number"
                                            }
                                          },
                                          "confidence": {
                                            "anyOf": [
                                              {
                                                "type": "number",
                                                "minimum": 0,
                                                "maximum": 1
                                              },
                                              {
                                                "type": "null"
                                              }
                                            ]
                                          }
                                        },
                                        "required": [
                                          "label",
                                          "probabilities",
                                          "confidence"
                                        ]
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  },
                                  "relevance": {
                                    "anyOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "p": {
                                            "anyOf": [
                                              {
                                                "type": "number",
                                                "minimum": 0,
                                                "maximum": 1
                                              },
                                              {
                                                "type": "null"
                                              }
                                            ]
                                          },
                                          "score": {
                                            "type": "number",
                                            "minimum": 0,
                                            "maximum": 1
                                          },
                                          "on_topic": {
                                            "type": "boolean"
                                          },
                                          "entity": {
                                            "anyOf": [
                                              {
                                                "type": "number",
                                                "minimum": 0,
                                                "maximum": 1
                                              },
                                              {
                                                "type": "null"
                                              }
                                            ]
                                          }
                                        },
                                        "required": [
                                          "score",
                                          "on_topic",
                                          "entity"
                                        ]
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "required": [
                              "candidate_id",
                              "item_id",
                              "source",
                              "title",
                              "url",
                              "snippet",
                              "subquery_labels",
                              "native_ranks",
                              "local_relevance",
                              "freshness",
                              "engagement",
                              "source_quality",
                              "rrf_score",
                              "sources",
                              "source_items"
                            ]
                          },
                          "description": "The ranked, deduplicated results (up to 40, or `limit`)."
                        },
                        "items_by_source": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "item_id": {
                                  "type": "string"
                                },
                                "id": {
                                  "type": "string"
                                },
                                "native_id": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "candidate_id": {
                                  "type": "string"
                                },
                                "source": {
                                  "type": "string"
                                },
                                "title": {
                                  "type": "string"
                                },
                                "body": {
                                  "default": "",
                                  "type": "string"
                                },
                                "url": {
                                  "default": "",
                                  "type": "string"
                                },
                                "author": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "container": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "published_at": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "date_confidence": {
                                  "default": "low",
                                  "type": "string",
                                  "enum": [
                                    "high",
                                    "med",
                                    "low"
                                  ]
                                },
                                "date_source": {
                                  "type": "string",
                                  "enum": [
                                    "platform",
                                    "serp",
                                    "page_meta",
                                    "estimate"
                                  ]
                                },
                                "engagement": {
                                  "default": {},
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {
                                    "anyOf": [
                                      {
                                        "type": "number"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  }
                                },
                                "relevance_hint": {
                                  "type": "number"
                                },
                                "why_relevant": {
                                  "default": "",
                                  "type": "string"
                                },
                                "snippet": {
                                  "default": "",
                                  "type": "string"
                                },
                                "metadata": {
                                  "default": {},
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                "media": {
                                  "default": {
                                    "thumbnail_url": null,
                                    "video_url": null,
                                    "duration_s": null,
                                    "image_urls": [],
                                    "aspect_ratio": null,
                                    "author_avatar_url": null,
                                    "favicon_url": null
                                  },
                                  "type": "object",
                                  "properties": {
                                    "thumbnail_url": {
                                      "default": null,
                                      "anyOf": [
                                        {
                                          "type": "string",
                                          "format": "uri"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "video_url": {
                                      "default": null,
                                      "anyOf": [
                                        {
                                          "type": "string",
                                          "format": "uri"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "duration_s": {
                                      "default": null,
                                      "anyOf": [
                                        {
                                          "type": "number",
                                          "minimum": 0
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "image_urls": {
                                      "default": [],
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "format": "uri"
                                      }
                                    },
                                    "aspect_ratio": {
                                      "default": null,
                                      "anyOf": [
                                        {
                                          "type": "number",
                                          "exclusiveMinimum": 0
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "author_avatar_url": {
                                      "default": null,
                                      "anyOf": [
                                        {
                                          "type": "string",
                                          "format": "uri"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    },
                                    "favicon_url": {
                                      "default": null,
                                      "anyOf": [
                                        {
                                          "type": "string",
                                          "format": "uri"
                                        },
                                        {
                                          "type": "null"
                                        }
                                      ]
                                    }
                                  }
                                },
                                "local_relevance": {
                                  "anyOf": [
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "freshness": {
                                  "anyOf": [
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "engagement_score": {
                                  "anyOf": [
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "source_quality": {
                                  "anyOf": [
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "local_rank_score": {
                                  "anyOf": [
                                    {
                                      "type": "number"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                }
                              },
                              "required": [
                                "item_id",
                                "source",
                                "title"
                              ]
                            }
                          },
                          "description": "Every row each source returned, grouped by source."
                        },
                        "clusters": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "cluster_id": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              },
                              "candidate_ids": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "representative_ids": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "sources": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "score": {
                                "type": "number"
                              },
                              "uncertainty": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "enum": [
                                      "single-source",
                                      "thin-evidence"
                                    ]
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "cluster_id",
                              "title",
                              "candidate_ids",
                              "representative_ids",
                              "sources",
                              "score"
                            ]
                          }
                        },
                        "sources_called": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "sources_failed": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Searched sources that failed, and the X lane when not run on the JSON path, with a reason."
                        },
                        "sources_succeeded": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "sources_pruned": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "number"
                          },
                          "description": "Sources the planner pruned for low affinity, with the score."
                        },
                        "coverage": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "partial_failure": {
                          "type": "boolean"
                        },
                        "topic_coverage": {
                          "type": "object",
                          "properties": {
                            "verdict": {
                              "type": "string",
                              "enum": [
                                "ok",
                                "thin",
                                "none_relevant"
                              ]
                            },
                            "best_p": {
                              "type": "number"
                            }
                          },
                          "required": [
                            "verdict",
                            "best_p"
                          ]
                        },
                        "relevance": {
                          "description": "The relevance report: judged and off-topic counts, or what relevance=filter dropped.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {}
                        },
                        "stance_split": {
                          "description": "Stance counts and shares, overall and per platform; null when no post could be judged.",
                          "anyOf": [
                            {
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {}
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "judgments": {
                          "type": "object",
                          "properties": {
                            "relevance": {
                              "type": "string",
                              "enum": [
                                "judged",
                                "skipped",
                                "unavailable"
                              ]
                            },
                            "stance": {
                              "type": "string",
                              "enum": [
                                "judged",
                                "skipped",
                                "unavailable"
                              ]
                            }
                          },
                          "required": [
                            "relevance",
                            "stance"
                          ]
                        },
                        "since": {
                          "description": "The date window applied to the ranked rows, and what it dropped.",
                          "type": "object",
                          "properties": {
                            "since": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "until": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "dropped": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            },
                            "kept_undated": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            }
                          },
                          "required": [
                            "since",
                            "until",
                            "dropped",
                            "kept_undated"
                          ]
                        },
                        "switch_receipts": {},
                        "platforms": {
                          "description": "What each searched platform's source calls did: status, rows, latency and an outcome code when it failed or was skipped.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "status": {
                                "type": "string",
                                "enum": [
                                  "ok",
                                  "empty",
                                  "failed",
                                  "skipped",
                                  "pruned"
                                ]
                              },
                              "rows": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991
                              },
                              "latency_ms": {
                                "type": "number",
                                "minimum": 0
                              },
                              "error": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "code": {
                                        "type": "string"
                                      },
                                      "retryable": {
                                        "type": "boolean"
                                      }
                                    },
                                    "required": [
                                      "code",
                                      "retryable"
                                    ]
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "status",
                              "rows",
                              "latency_ms",
                              "error"
                            ]
                          }
                        },
                        "synthesis": {
                          "description": "The written web answer and, with include=synthesis, the X summary, each with its citations. Never ranked rows.",
                          "type": "object",
                          "properties": {
                            "web": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "text": {
                                      "type": "string"
                                    },
                                    "citations": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "url": {
                                            "type": "string"
                                          },
                                          "also_on": {
                                            "type": "string"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "text",
                                    "citations"
                                  ]
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "x": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "text": {
                                      "type": "string"
                                    },
                                    "citations": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "url": {
                                            "type": "string"
                                          },
                                          "also_on": {
                                            "type": "string"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "text",
                                    "citations"
                                  ]
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "web",
                            "x"
                          ]
                        },
                        "next_step": {
                          "description": "One sentence on what to send next, when there is something better to send.",
                          "type": "string"
                        },
                        "_warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "dropped": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "empty_reason": {
                          "type": "string"
                        },
                        "empty_reason_note": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "request_id",
                        "query",
                        "plan",
                        "items",
                        "items_by_source",
                        "clusters",
                        "sources_called",
                        "sources_failed",
                        "sources_succeeded",
                        "sources_pruned",
                        "coverage",
                        "partial_failure"
                      ],
                      "description": "The search answer, generated from the lane's own schema"
                    },
                    "credits_used": {
                      "type": "integer",
                      "description": "Number of credits consumed",
                      "example": 1
                    },
                    "credits_remaining": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.",
                      "example": 4999
                    },
                    "credits_remaining_note": {
                      "type": "string",
                      "description": "Present only when `credits_remaining` is null by design, as on a free cache hit: says why the balance was not read and where to read it.",
                      "example": "not read on cache hits (credits_used is 0); call GET /v1/credits/balance for the current balance"
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Unique request identifier for support",
                      "example": "req-abc123"
                    },
                    "cached": {
                      "type": "boolean",
                      "description": "Whether the response was served from cache",
                      "example": false
                    },
                    "age_s": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Present only on a cache hit (`cached: true`): whole seconds since this copy was fetched, also sent as the `X-Cache-Age` header. Null for a copy stored before ages were recorded. Send `max_age_s` to set how old a copy you accept: a profile or post copy up to an hour old is served for 0 credits, and a lower value fetches fresh.",
                      "example": 340
                    },
                    "idempotent_replay": {
                      "type": "boolean",
                      "description": "True only when this response is an idempotency replay",
                      "example": true
                    },
                    "meta": {
                      "type": "object",
                      "description": "Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.",
                      "properties": {
                        "hint": {
                          "type": "object",
                          "description": "One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat | batch_comments | batch_jobs",
                              "example": "search_multi"
                            },
                            "message": {
                              "type": "string",
                              "description": "One sentence for a person or an agent to read.",
                              "example": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged."
                            },
                            "method": {
                              "type": "string",
                              "description": "GET or POST.",
                              "example": "GET"
                            },
                            "path": {
                              "type": "string",
                              "description": "The call the hint points to.",
                              "example": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "platform",
                    "endpoint",
                    "data",
                    "credits_used",
                    "credits_remaining",
                    "request_id",
                    "cached"
                  ]
                },
                "example": {
                  "success": true,
                  "platform": "search",
                  "endpoint": "/v1/search/everywhere",
                  "data": {
                    "request_id": "meta-1790945284064-0bmfbq",
                    "query": "kanye west",
                    "plan": {
                      "intent": "factual",
                      "freshness_mode": "balanced_recent",
                      "cluster_mode": "story",
                      "subqueries": [
                        {
                          "label": "primary",
                          "search_query": "kanye west",
                          "ranking_query": "What recent evidence from the last 30 days is most relevant to kanye west?",
                          "sources": [
                            "reddit",
                            "youtube"
                          ],
                          "weight": 0.19801980198019803
                        },
                        {
                          "label": "reddit discourse and updates",
                          "search_query": "Kanye West controversy album tour merch",
                          "ranking_query": "What are the most cited current talking points about Kanye West on Reddit, and what context do users give for each claim?",
                          "sources": [
                            "reddit"
                          ],
                          "weight": 0.19801980198019803,
                          "topic_term": null
                        }
                      ],
                      "source_weights": {
                        "reddit": 0.25,
                        "youtube": 0.25,
                        "youtube-hashtag": 0.25,
                        "github": 0.25
                      },
                      "notes": [
                        "deterministic-plan",
                        "llm-plan"
                      ]
                    },
                    "items": [
                      {
                        "candidate_id": "https://reddit.com/r/music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled",
                        "item_id": "1wv1ox9",
                        "source": "reddit",
                        "title": "Kanye West's sold-out Russia concerts canceled",
                        "url": "https://www.reddit.com/r/Music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled/",
                        "snippet": "",
                        "subquery_labels": [
                          "primary"
                        ],
                        "native_ranks": {
                          "primary:reddit": 1
                        },
                        "local_relevance": 0.2222222222222222,
                        "freshness": 89,
                        "engagement": 77,
                        "source_quality": 0.6,
                        "rrf_score": 0.0008115565654926149,
                        "sources": [
                          "reddit"
                        ],
                        "source_items": [
                          {
                            "item_id": "1wv1ox9",
                            "source": "reddit",
                            "title": "Sample comment text (redacted).",
                            "body": "Sample comment text (redacted).",
                            "url": "https://www.reddit.com/r/Music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled/",
                            "author": "user_d83d82",
                            "published_at": "2026-10-01T14:59:27.000Z",
                            "date_confidence": "low",
                            "engagement": {
                              "score": 782,
                              "num_comments": 68
                            },
                            "relevance_hint": 0.5,
                            "why_relevant": "",
                            "snippet": "Sample comment text (redacted).",
                            "metadata": {
                              "top_comments": [
                                {
                                  "score": 544,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_8164a5",
                                  "url": "https://example.com/redacted",
                                  "date": "2026-10-01T15:42:25.433Z"
                                },
                                {
                                  "score": 216,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_f3bf8b",
                                  "url": "https://example.com/redacted",
                                  "date": "2026-10-01T15:52:14.228Z"
                                }
                              ]
                            },
                            "media": {
                              "thumbnail_url": null,
                              "video_url": null,
                              "duration_s": null,
                              "image_urls": [],
                              "aspect_ratio": null,
                              "author_avatar_url": null,
                              "favicon_url": null
                            },
                            "local_relevance": 0.2222222222222222,
                            "freshness": 89,
                            "engagement_score": 77,
                            "source_quality": 0.6,
                            "local_rank_score": 0.4439444444444444
                          }
                        ],
                        "final_score": 66.20088914137315,
                        "metadata": {
                          "provenance": [
                            {
                              "source": "reddit",
                              "subquery_label": "primary",
                              "native_rank": 1,
                              "item_id": "1wv1ox9"
                            }
                          ]
                        },
                        "rerank_score": 81.83,
                        "explanation": "Directly discusses the query's entity or question",
                        "computed": {
                          "relevance": {
                            "score": 0.74,
                            "on_topic": true,
                            "entity": 0.97
                          },
                          "stance": {
                            "label": "negative",
                            "probabilities": {
                              "positive": 0,
                              "negative": 0.96,
                              "neutral": 0.03,
                              "no_opinion": 0.01
                            },
                            "confidence": 0.94
                          }
                        },
                        "cluster_id": "cluster-1"
                      },
                      {
                        "candidate_id": "https://youtube.com/watch?v=qxoewuahoiw",
                        "item_id": "qxOeWuAHOiw",
                        "source": "youtube",
                        "title": "Joe Rogan Experience #1554 - Kanye West",
                        "url": "https://www.youtube.com/watch?v=qxOeWuAHOiw",
                        "snippet": "",
                        "subquery_labels": [
                          "primary"
                        ],
                        "native_ranks": {
                          "primary:youtube": 13
                        },
                        "local_relevance": 0.2222222222222222,
                        "freshness": 0,
                        "engagement": 43,
                        "source_quality": 0.85,
                        "rrf_score": 0.0006781500067815001,
                        "sources": [
                          "youtube"
                        ],
                        "source_items": [
                          {
                            "item_id": "qxOeWuAHOiw",
                            "source": "youtube",
                            "title": "Sample comment text (redacted).",
                            "body": "Sample comment text (redacted).",
                            "url": "https://www.youtube.com/watch?v=qxOeWuAHOiw",
                            "author": "user_e3b0c4",
                            "published_at": "2021-10-02T12:48:09.738Z",
                            "date_confidence": "med",
                            "engagement": {
                              "views": 21128467
                            },
                            "relevance_hint": 0.5,
                            "why_relevant": "",
                            "snippet": "Sample comment text (redacted).",
                            "metadata": {
                              "top_comments": [
                                {
                                  "score": 7,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_446c78",
                                  "url": null,
                                  "date": "2026-07-18T06:28:44.000Z"
                                },
                                {
                                  "score": 6,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_bd900e",
                                  "url": null,
                                  "date": "2026-07-17T05:47:30.000Z"
                                }
                              ]
                            },
                            "media": {
                              "thumbnail_url": "https://i.ytimg.com/vi/qxOeWuAHOiw/hqdefault.jpg?sqp=-oaymwEnCOADEI4CSFryq4qpAxkIARUAAIhCGAHYAQHiAQoIGBACGAY4AUAB&rs=AOn4CLBTYB39onRUPWxvKQWCPtVgaBR9LA",
                              "video_url": null,
                              "duration_s": null,
                              "image_urls": [],
                              "aspect_ratio": null,
                              "author_avatar_url": "https://example.com/avatars/user_7c6736.png",
                              "favicon_url": null
                            },
                            "local_relevance": 0.2222222222222222,
                            "freshness": 0,
                            "engagement_score": 43,
                            "source_quality": 0.85,
                            "local_rank_score": 0.18744444444444444
                          }
                        ],
                        "final_score": 62.56753750169537,
                        "metadata": {
                          "provenance": [
                            {
                              "source": "youtube",
                              "subquery_label": "primary",
                              "native_rank": 13,
                              "item_id": "qxOeWuAHOiw"
                            }
                          ]
                        },
                        "rerank_score": 88.58,
                        "explanation": "Directly discusses the query's entity or question",
                        "computed": {
                          "relevance": {
                            "score": 0.85,
                            "on_topic": true,
                            "entity": 0.97
                          },
                          "stance": {
                            "label": "positive",
                            "probabilities": {
                              "positive": 0.95,
                              "negative": 0.03,
                              "neutral": 0.02,
                              "no_opinion": 0
                            },
                            "confidence": 0.93
                          }
                        },
                        "cluster_id": "cluster-2"
                      }
                    ],
                    "items_by_source": {
                      "youtube-hashtag": [
                        {
                          "item_id": "jSrQBGbw4jo",
                          "source": "youtube-hashtag",
                          "title": "Sample comment text (redacted).",
                          "body": "Sample comment text (redacted).",
                          "url": "https://www.youtube.com/watch?v=jSrQBGbw4jo",
                          "author": "user_1114db",
                          "published_at": "2026-05-02T12:48:09.564Z",
                          "date_confidence": "med",
                          "engagement": {
                            "views": 1816022
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "Sample comment text (redacted).",
                          "metadata": {},
                          "media": {
                            "thumbnail_url": "https://i.ytimg.com/vi/jSrQBGbw4jo/hq720.jpg?sqp=-oaymwFBCNAFEJQDSFryq4qpAzMIARUAAIhCGAHYAQHiAQoIGBACGAY4AUAB8AEB-AH-CYAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLDqUfH2OrVPMbTsimnFaqOqdtlCZA",
                            "video_url": null,
                            "duration_s": 310,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": "https://example.com/avatars/user_8cfd54.png",
                            "favicon_url": null
                          },
                          "local_relevance": 0.19841269841269837,
                          "freshness": 0,
                          "engagement_score": 50,
                          "source_quality": 0.85,
                          "local_rank_score": 0.17896825396825394
                        }
                      ],
                      "youtube": [
                        {
                          "item_id": "PsO6ZnUZI0g",
                          "source": "youtube",
                          "title": "Sample comment text (redacted).",
                          "body": "Sample comment text (redacted).",
                          "url": "https://www.youtube.com/watch?v=PsO6ZnUZI0g",
                          "author": "user_609f62",
                          "published_at": "2009-10-02T12:48:09.738Z",
                          "date_confidence": "med",
                          "engagement": {
                            "views": 558565305
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "Sample comment text (redacted).",
                          "metadata": {
                            "top_comments": [
                              {
                                "score": 50,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_28677c",
                                "url": null,
                                "date": "2026-09-19T05:56:11.000Z"
                              },
                              {
                                "score": 11,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_4eaf1d",
                                "url": null,
                                "date": "2026-09-24T20:35:45.000Z"
                              }
                            ]
                          },
                          "media": {
                            "thumbnail_url": "https://i.ytimg.com/vi/PsO6ZnUZI0g/hq720.jpg?sqp=-oaymwEnCNAFEJQDSFryq4qpAxkIARUAAIhCGAHYAQHiAQoIGBACGAY4AUAB&rs=AOn4CLCk_duirSSQANf5RrOjzwWqGNVNRg",
                            "video_url": null,
                            "duration_s": 267,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": "https://example.com/avatars/user_9b9273.png",
                            "favicon_url": null
                          },
                          "local_relevance": 0.2222222222222222,
                          "freshness": 0,
                          "engagement_score": 100,
                          "source_quality": 0.85,
                          "local_rank_score": 0.24444444444444444
                        },
                        {
                          "item_id": "6vwNcNOTVzY",
                          "source": "youtube",
                          "title": "Sample comment text (redacted).",
                          "body": "Sample comment text (redacted).",
                          "url": "https://www.youtube.com/watch?v=6vwNcNOTVzY",
                          "author": "user_609f62",
                          "published_at": "2009-10-02T12:48:09.738Z",
                          "date_confidence": "med",
                          "engagement": {
                            "views": 425271144
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "Sample comment text (redacted).",
                          "metadata": {
                            "top_comments": [
                              {
                                "score": 7,
                                "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_876555",
                                "url": null,
                                "date": "2026-09-10T12:39:36.000Z"
                              },
                              {
                                "score": 3,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_7ed478",
                                "url": null,
                                "date": "2026-09-29T18:48:17.000Z"
                              }
                            ]
                          },
                          "media": {
                            "thumbnail_url": "https://i.ytimg.com/vi/6vwNcNOTVzY/hq720.jpg?sqp=-oaymwEnCNAFEJQDSFryq4qpAxkIARUAAIhCGAHYAQHiAQoIGBACGAY4AUAB&rs=AOn4CLAJlkmdS4UoEq0Dq4w21KP9oBy3sg",
                            "video_url": null,
                            "duration_s": 222,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": "https://example.com/avatars/user_9b9273.png",
                            "favicon_url": null
                          },
                          "local_relevance": 0.2222222222222222,
                          "freshness": 0,
                          "engagement_score": 95,
                          "source_quality": 0.85,
                          "local_rank_score": 0.23944444444444443
                        }
                      ],
                      "reddit": [
                        {
                          "item_id": "1wv1ox9",
                          "source": "reddit",
                          "title": "Sample comment text (redacted).",
                          "body": "Sample comment text (redacted).",
                          "url": "https://www.reddit.com/r/Music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled/",
                          "author": "user_d83d82",
                          "published_at": "2026-10-01T14:59:27.000Z",
                          "date_confidence": "low",
                          "engagement": {
                            "score": 782,
                            "num_comments": 68
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "Sample comment text (redacted).",
                          "metadata": {
                            "top_comments": [
                              {
                                "score": 544,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_8164a5",
                                "url": "https://example.com/redacted",
                                "date": "2026-10-01T15:42:25.433Z"
                              },
                              {
                                "score": 216,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_f3bf8b",
                                "url": "https://example.com/redacted",
                                "date": "2026-10-01T15:52:14.228Z"
                              }
                            ]
                          },
                          "media": {
                            "thumbnail_url": null,
                            "video_url": null,
                            "duration_s": null,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": null,
                            "favicon_url": null
                          },
                          "local_relevance": 0.2222222222222222,
                          "freshness": 89,
                          "engagement_score": 77,
                          "source_quality": 0.6,
                          "local_rank_score": 0.4439444444444444
                        },
                        {
                          "item_id": "1wqtof6",
                          "source": "reddit",
                          "title": "Sample comment text (redacted).",
                          "body": "Sample comment text (redacted).",
                          "url": "https://www.reddit.com/r/hiphopheads/comments/1wqtof6/kanye_west_joins_chris_brown_and_usher_for/",
                          "author": "user_f971f7",
                          "published_at": "2026-09-26T15:41:54.000Z",
                          "date_confidence": "low",
                          "engagement": {
                            "score": 1102,
                            "num_comments": 250
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "Sample comment text (redacted).",
                          "metadata": {
                            "top_comments": [
                              {
                                "score": 1341,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_75c03e",
                                "url": "https://example.com/redacted",
                                "date": "2026-09-26T15:52:58.895Z"
                              },
                              {
                                "score": 1174,
                                "excerpt": "Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_b81fcb",
                                "url": "https://example.com/redacted",
                                "date": "2026-09-26T15:46:45.381Z"
                              }
                            ]
                          },
                          "media": {
                            "thumbnail_url": null,
                            "video_url": null,
                            "duration_s": null,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": null,
                            "favicon_url": null
                          },
                          "local_relevance": 0.21555555555555553,
                          "freshness": 82,
                          "engagement_score": 93,
                          "source_quality": 0.6,
                          "local_rank_score": 0.4381111111111111
                        }
                      ]
                    },
                    "clusters": [
                      {
                        "cluster_id": "cluster-1",
                        "title": "Kanye West's sold-out Russia concerts canceled",
                        "candidate_ids": [
                          "https://reddit.com/r/music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled"
                        ],
                        "representative_ids": [
                          "https://reddit.com/r/music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled"
                        ],
                        "sources": [
                          "reddit"
                        ],
                        "score": 66.20088914137315,
                        "uncertainty": null
                      },
                      {
                        "cluster_id": "cluster-2",
                        "title": "Joe Rogan Experience #1554 - Kanye West",
                        "candidate_ids": [
                          "https://youtube.com/watch?v=qxoewuahoiw"
                        ],
                        "representative_ids": [
                          "https://youtube.com/watch?v=qxoewuahoiw"
                        ],
                        "sources": [
                          "youtube"
                        ],
                        "score": 62.56753750169537,
                        "uncertainty": null
                      }
                    ],
                    "sources_called": [
                      "youtube-hashtag",
                      "youtube"
                    ],
                    "sources_failed": {},
                    "sources_succeeded": [
                      "youtube-hashtag",
                      "youtube"
                    ],
                    "sources_pruned": {
                      "github": 0.04
                    },
                    "coverage": 1,
                    "topic_coverage": {
                      "verdict": "ok",
                      "best_p": 0.86
                    },
                    "partial_failure": false,
                    "relevance": {
                      "mode": "score",
                      "rows": 17,
                      "judged": 17,
                      "unjudged": 0,
                      "off_topic": 0,
                      "off_topic_ids": [],
                      "methodology_version": "search-everywhere-relevance/1"
                    },
                    "stance_split": {
                      "methodology_version": "search-everywhere-stance/1",
                      "confidence_floor": 0.5,
                      "overall": {
                        "posts": 17,
                        "counted": 7,
                        "positive": 3,
                        "negative": 4,
                        "neutral": 0,
                        "shares": {
                          "positive": 0.429,
                          "negative": 0.571,
                          "neutral": 0
                        },
                        "no_opinion": 5,
                        "uncertain": 5,
                        "unjudged": 0,
                        "ids": {
                          "positive": [
                            "https://youtube.com/watch?v=qxoewuahoiw",
                            "https://youtube.com/watch?v=zohhamvk-xm"
                          ],
                          "negative": [
                            "https://reddit.com/r/music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled",
                            "https://reddit.com/r/nostupidquestions/comments/1tt2tfu/how_did_kanye_west_become_uncancellable"
                          ],
                          "neutral": [],
                          "no_opinion": [
                            "https://youtube.com/watch?v=l63jt6__agw",
                            "https://youtube.com/watch?v=dr_ytq0syva"
                          ],
                          "uncertain": [
                            "https://reddit.com/r/hiphopheads/comments/1wqtof6/kanye_west_joins_chris_brown_and_usher_for",
                            "https://reddit.com/r/kanye/comments/1wufnn0/50_cent_baby_mama_daphne_joy_confirms_the_rumor"
                          ],
                          "unjudged": []
                        }
                      },
                      "by_platform": {
                        "reddit": {
                          "posts": 7,
                          "counted": 3,
                          "positive": 0,
                          "negative": 3,
                          "neutral": 0,
                          "shares": {
                            "positive": 0,
                            "negative": 1,
                            "neutral": 0
                          },
                          "no_opinion": 0,
                          "uncertain": 4,
                          "unjudged": 0,
                          "ids": {
                            "positive": [],
                            "negative": [
                              "https://reddit.com/r/music/comments/1wv1ox9/kanye_wests_soldout_russia_concerts_canceled",
                              "https://reddit.com/r/nostupidquestions/comments/1tt2tfu/how_did_kanye_west_become_uncancellable"
                            ],
                            "neutral": [],
                            "no_opinion": [],
                            "uncertain": [
                              "https://reddit.com/r/hiphopheads/comments/1wqtof6/kanye_west_joins_chris_brown_and_usher_for",
                              "https://reddit.com/r/kanye/comments/1wufnn0/50_cent_baby_mama_daphne_joy_confirms_the_rumor"
                            ],
                            "unjudged": []
                          }
                        },
                        "youtube": {
                          "posts": 10,
                          "counted": 4,
                          "positive": 3,
                          "negative": 1,
                          "neutral": 0,
                          "shares": {
                            "positive": 0.75,
                            "negative": 0.25,
                            "neutral": 0
                          },
                          "no_opinion": 5,
                          "uncertain": 1,
                          "unjudged": 0,
                          "ids": {
                            "positive": [
                              "https://youtube.com/watch?v=qxoewuahoiw",
                              "https://youtube.com/watch?v=zohhamvk-xm"
                            ],
                            "negative": [
                              "https://youtube.com/watch?v=6vwncnotvzy"
                            ],
                            "neutral": [],
                            "no_opinion": [
                              "https://youtube.com/watch?v=l63jt6__agw",
                              "https://youtube.com/watch?v=dr_ytq0syva"
                            ],
                            "uncertain": [
                              "https://youtube.com/watch?v=pso6znuzi0g"
                            ],
                            "unjudged": []
                          }
                        }
                      }
                    },
                    "dropped": 0
                  },
                  "credits_used": 20,
                  "request_id": "req_example000000",
                  "cached": false,
                  "pagination": {
                    "next_cursor": null,
                    "has_more": false,
                    "page_size": 17
                  },
                  "credits_remaining": 9999
                }
              }
            }
          },
          "400": {
            "description": "Invalid request - missing or malformed parameters",
            "x-error-codes": [
              "INVALID_REQUEST",
              "COHORT_MEMBER_LIMIT_EXCEEDED",
              "COHORT_LIMIT_EXCEEDED",
              "COHORT_IDENTITY_PLATFORM_UNSUPPORTED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INVALID_REQUEST",
                    "message": "Invalid request - missing or malformed parameters",
                    "status": 400,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid API key",
            "x-error-codes": [
              "MISSING_API_KEY",
              "INVALID_API_KEY"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "MISSING_API_KEY",
                    "message": "Unauthorized - missing or invalid API key",
                    "status": 401,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "402": {
            "description": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
            "x-error-codes": [
              "INSUFFICIENT_CREDITS",
              "KEY_BUDGET_EXCEEDED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INSUFFICIENT_CREDITS",
                    "message": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
                    "status": 402,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "404": {
            "description": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
            "x-error-codes": [
              "ENDPOINT_NOT_FOUND",
              "RESOURCE_NOT_FOUND",
              "RUN_NOT_FOUND",
              "SCHEDULE_NOT_FOUND",
              "STREAM_NOT_FOUND"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "ENDPOINT_NOT_FOUND",
                    "message": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
                    "status": 404,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed - wrong HTTP verb for this endpoint",
            "x-error-codes": [
              "METHOD_NOT_ALLOWED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "METHOD_NOT_ALLOWED",
                    "message": "Method not allowed - wrong HTTP verb for this endpoint",
                    "status": 405,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_CONFLICT",
              "IDEMPOTENCY_IN_PROGRESS",
              "IDEMPOTENCY_REPLAY_UNAVAILABLE",
              "COHORT_IDENTITY_CONFLICT",
              "COHORT_QUERY_NOT_CANCELLABLE",
              "COHORT_QUERY_NOT_READY",
              "RUN_STATE_CONFLICT",
              "STREAM_STATE_CONFLICT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_CONFLICT",
                    "message": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
                    "status": 409,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "410": {
            "description": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
            "x-error-codes": [
              "RUN_EXPIRED",
              "CURSOR_EXPIRED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RUN_EXPIRED",
                    "message": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
                    "status": 410,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
            "x-error-codes": [
              "PAYLOAD_TOO_LARGE",
              "COHORT_RESULT_TOO_LARGE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "PAYLOAD_TOO_LARGE",
                    "message": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
                    "status": 413,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
              "NEEDS_ASYNC"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
                    "message": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
                    "status": 422,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
            "x-error-codes": [
              "RATE_LIMITED",
              "CONCURRENCY_LIMIT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RATE_LIMITED",
                    "message": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
                    "status": 429,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
            "x-error-codes": [
              "INTERNAL_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INTERNAL_ERROR",
                    "message": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
                    "status": 500,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "502": {
            "description": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 502,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "SERVICE_UNAVAILABLE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 503,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "504": {
            "description": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
                    "status": 504,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          }
        }
      }
    },
    "/search/forums": {
      "get": {
        "summary": "Fused forum search across Reddit, Hacker News, and Naver 지식iN/카페, with top comments inline on hero threads by default.",
        "description": "Fans your topic across Reddit, Hacker News, and Korean forums, RRF-fuses + clusters the threads, and enriches hero threads with their top comments by default (East + West). Naver threads are labeled raw (no comment endpoint). Returns a fused `items[]`, raw per-source buckets, thread clusters, and a deterministic computed block (question_share, top_communities). Each row of `items[].top_comments[]` is `{ score, excerpt, truncated, author, url, date }`. The body is `excerpt`, not `text`: this is the search-lane enrichment shape, not the canonical Comment archetype, and it is clipped to 300 characters on a word boundary, with an ellipsis and `truncated: true` when it was cut. `date` is the comment ISO timestamp. Flat 10cr with coverage-based partial refund. A search no forum has a thread for answers 200 with an empty `items` and `empty_reason: no_matches`, at 0 credits.",
        "tags": [
          "search"
        ],
        "operationId": "get_search_forums",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-credit-tier": "standard",
        "x-credit-cost": 10,
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "Search query (2-256 chars), forwarded to every forum search.",
            "schema": {
              "type": "string"
            },
            "example": "airpods pro 3 battery"
          },
          {
            "name": "sources",
            "in": "query",
            "required": false,
            "description": "Optional CSV allowlist of forum sources (reddit, hackernews, naver_kin, naver_cafe). Mutually exclusive with exclude.",
            "schema": {
              "type": "string"
            },
            "example": "reddit,hackernews,naver_kin"
          },
          {
            "name": "exclude",
            "in": "query",
            "required": false,
            "description": "Optional CSV blocklist of forum sources. Mutually exclusive with sources.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "comments",
            "in": "query",
            "required": false,
            "description": "Comment enrichment toggle (on|off, default on). 'off' returns thread-only.",
            "schema": {
              "type": "string"
            },
            "example": "on"
          },
          {
            "name": "timeframe",
            "in": "query",
            "required": false,
            "description": "Recency window passed to Reddit; HN filtered client-side (all|day|week|month|year, default all).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lookback_days",
            "in": "query",
            "required": false,
            "description": "Alt recency window in days (1-365); HN filtered client-side.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "relevance",
            "in": "query",
            "required": false,
            "description": "Optional. Without it every thread already carries items[].computed.relevance ({ p, sense, on_topic }: is the thread about what your query means, or a different thing that shares its words?), free, in the fused order (see judgments). score also reorders threads by relevance blended with their fused rank. filter also drops the threads that are not on topic, lists them in data.relevance.dropped_ids, and counts stance_split, question_share and top_communities over the threads it kept. A thread that could not be judged, or is too short to judge, is never dropped and carries relevance: null. Omit it to keep every thread in the fused order. Included in the flat 10 credits.",
            "schema": {
              "type": "string",
              "enum": [
                "score",
                "filter"
              ]
            }
          },
          {
            "name": "relevance_threshold",
            "in": "query",
            "required": false,
            "description": "Optional, only with relevance. The probability (0 to 1) a thread must reach to count as on topic. Default 0.5. Lower keeps more threads, higher keeps fewer.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "judgments",
            "in": "query",
            "required": false,
            "description": "Optional. on (default) or off. On, every thread also carries items[].computed.relevance ({ p, sense, on_topic }) from the same stance judgment, with data.relevance (mode default) counting it; the fused order is kept and nothing is dropped (relevance=score or filter reorders and drops). off returns the response without it. Included in the flat 10 credits.",
            "schema": {
              "type": "string",
              "enum": [
                "on",
                "off"
              ]
            }
          },
          {
            "name": "max_age_s",
            "in": "query",
            "required": false,
            "description": "The oldest cached copy you accept, in seconds. A copy that old or younger is served for 0 credits, with its age in `age_s` and the `X-Cache-Age` header. Without it a copy up to 120 seconds old is served. A lower value fetches fresh (billed) when the copy is older, and 0 always fetches live, like `Cache-Control: no-cache`.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 120
            }
          },
          {
            "name": "Cache-Control",
            "in": "header",
            "required": false,
            "description": "Send `no-cache` to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the `no-cache` directive triggers this. To accept an older cached copy, or to require a younger one, send the `max_age_s` query parameter instead. See the Response Schema guide for details.",
            "schema": {
              "type": "string"
            },
            "example": "no-cache"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives `409 IDEMPOTENCY_IN_PROGRESS` with a `Retry-After` of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: `credits_used` becomes 0, `idempotent_replay` becomes true, and `credits_remaining` is refreshed to the current balance. A known current balance appears in both the body and `X-Credits-Remaining` header; no balance row resolves to 0. On a transient lookup failure, body `credits_remaining` is null and `X-Credits-Remaining` is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use `Accept: application/json` when sending this header. The unsupported key-plus-SSE combination is rejected before billing.",
            "schema": {
              "type": "string"
            },
            "example": "7a5e1b4c-2d8f-4a3b-9c1e-6e8b4d2a1f3c"
          },
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "Send `respond-async` to run this GET in the background instead of waiting on the socket (or add `?async=true` to the query). The answer is 202 with `data.job_id`, a `Location` header and `Retry-After`; read the result free at `GET /v1/prism/jobs/{job_id}`, where `results[0].response` is exactly what this call returns. Nothing is held at submit: the call is validated now and billed as this call when it runs. Use it for calls that can outlast your client's timeout (MCP and many HTTP clients stop at 30 s). `Idempotency-Key` returns the same job on a retry.",
            "schema": {
              "type": "string"
            },
            "example": "respond-async"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-Credits-Used": {
                "description": "Net credits charged for this response. Idempotency replays report 0.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Credits-Remaining": {
                "description": "Current authoritative balance. Free cache hits and idempotency replays omit this header when the balance cannot be determined; body `credits_remaining` is null instead.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Key-Credits-Remaining": {
                "description": "Only when the API key has a credit limit: the credits this key may still spend under that limit, after this call (never below 0). Absent for a key with no limit. `GET /v1/keys/current` has the limit and what is used.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Idempotent-Replay": {
                "description": "Present with value `true` only when this response replays a settled idempotency record.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "Idempotent-Replayed": {
                "description": "Present with value `true` only when this response replays a settled idempotency record. Same meaning as `X-Idempotent-Replay`.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Whether the request succeeded",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "description": "Platform name",
                      "example": "search"
                    },
                    "endpoint": {
                      "type": "string",
                      "description": "API endpoint path",
                      "example": "/v1/search/forums"
                    },
                    "data": {
                      "type": "object",
                      "description": "Platform-specific response data",
                      "properties": {
                        "metrics": {
                          "type": "object",
                          "description": "Key performance metrics",
                          "properties": {
                            "total_views": {
                              "type": "integer",
                              "description": "Total view count"
                            },
                            "total_likes": {
                              "type": "integer",
                              "description": "Total like count"
                            },
                            "total_comments": {
                              "type": "integer",
                              "description": "Total comment count"
                            },
                            "engagement_rate": {
                              "type": "number",
                              "description": "Computed engagement rate (0-1)"
                            }
                          }
                        },
                        "period": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Time period for the analytics data"
                        },
                        "breakdown": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "description": "Per-item or per-period breakdown",
                          "items": {
                            "type": "object",
                            "description": "Breakdown entry"
                          }
                        },
                        "_warnings": {
                          "type": "array",
                          "description": "Non-fatal notices about this response (field-map drift, clamped computed values). Advisory only: its presence never means the request failed. Omitted entirely when there is nothing to report, so treat absent as 'no warnings'.",
                          "items": {
                            "type": "string",
                            "description": "One advisory notice."
                          }
                        }
                      }
                    },
                    "credits_used": {
                      "type": "integer",
                      "description": "Number of credits consumed",
                      "example": 1
                    },
                    "credits_remaining": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.",
                      "example": 4999
                    },
                    "credits_remaining_note": {
                      "type": "string",
                      "description": "Present only when `credits_remaining` is null by design, as on a free cache hit: says why the balance was not read and where to read it.",
                      "example": "not read on cache hits (credits_used is 0); call GET /v1/credits/balance for the current balance"
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Unique request identifier for support",
                      "example": "req-abc123"
                    },
                    "cached": {
                      "type": "boolean",
                      "description": "Whether the response was served from cache",
                      "example": false
                    },
                    "age_s": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Present only on a cache hit (`cached: true`): whole seconds since this copy was fetched, also sent as the `X-Cache-Age` header. Null for a copy stored before ages were recorded. Send `max_age_s` to set how old a copy you accept: a profile or post copy up to an hour old is served for 0 credits, and a lower value fetches fresh.",
                      "example": 340
                    },
                    "idempotent_replay": {
                      "type": "boolean",
                      "description": "True only when this response is an idempotency replay",
                      "example": true
                    },
                    "meta": {
                      "type": "object",
                      "description": "Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.",
                      "properties": {
                        "hint": {
                          "type": "object",
                          "description": "One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat | batch_comments | batch_jobs",
                              "example": "search_multi"
                            },
                            "message": {
                              "type": "string",
                              "description": "One sentence for a person or an agent to read.",
                              "example": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged."
                            },
                            "method": {
                              "type": "string",
                              "description": "GET or POST.",
                              "example": "GET"
                            },
                            "path": {
                              "type": "string",
                              "description": "The call the hint points to.",
                              "example": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "platform",
                    "endpoint",
                    "data",
                    "credits_used",
                    "credits_remaining",
                    "request_id",
                    "cached"
                  ]
                },
                "example": {
                  "success": true,
                  "platform": "search",
                  "endpoint": "/v1/search/forums",
                  "data": {
                    "items": [
                      {
                        "title": "Do Airpods Pro 3 really have terrible battery life?",
                        "url": "https://www.reddit.com/r/AirpodsPro/comments/1w63726/do_airpods_pro_3_really_have_terrible_battery_life/",
                        "source": "reddit",
                        "container": "r/AirpodsPro",
                        "enrichable": true,
                        "post": {
                          "item_id": "1w63726",
                          "source": "reddit",
                          "title": "Do Airpods Pro 3 really have terrible battery life?",
                          "body": "The charging case continues to lose battery even when the AirPods are not in use for several days. Charging the AirPods from 84% to 100% also consumes around 20% of the case’s battery. It's a brand new Airpods Pro 3.",
                          "url": "https://www.reddit.com/r/AirpodsPro/comments/1w63726/do_airpods_pro_3_really_have_terrible_battery_life/",
                          "author": "user_79c0e5",
                          "published_at": "2026-09-03T10:09:52.000Z",
                          "date_confidence": "low",
                          "engagement": {
                            "score": 25,
                            "num_comments": 54
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "",
                          "metadata": {
                            "enrichable": true,
                            "top_comments": [
                              {
                                "score": 42,
                                "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_5beea1",
                                "url": "https://example.com/redacted",
                                "date": "2026-09-03T10:27:53.966Z"
                              },
                              {
                                "score": 16,
                                "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_51150e",
                                "url": "https://example.com/redacted",
                                "date": "2026-09-03T12:36:21.327Z"
                              }
                            ]
                          },
                          "media": {
                            "thumbnail_url": null,
                            "video_url": null,
                            "duration_s": null,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": null,
                            "favicon_url": null
                          },
                          "container": "r/AirpodsPro",
                          "local_relevance": 0.7964285714285714,
                          "freshness": 51,
                          "engagement_score": 64,
                          "source_quality": 0.6,
                          "local_rank_score": 0.7091785714285714
                        },
                        "top_comments": [
                          {
                            "score": 42,
                            "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "truncated": false,
                            "author": "user_5beea1",
                            "url": "https://example.com/redacted",
                            "date": "2026-09-03T10:27:53.966Z"
                          },
                          {
                            "score": 16,
                            "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "truncated": false,
                            "author": "user_51150e",
                            "url": "https://example.com/redacted",
                            "date": "2026-09-03T12:36:21.327Z"
                          }
                        ],
                        "rrf_score": 0.01639344262295082,
                        "cluster_id": "cluster-1",
                        "computed": {
                          "stance": {
                            "label": "negative",
                            "confidence": 1
                          },
                          "relevance": {
                            "p": 0.96,
                            "sense": "target",
                            "on_topic": true
                          }
                        }
                      },
                      {
                        "title": "Ask HN: How can I make wired Airpods Pro?",
                        "url": null,
                        "source": "hackernews",
                        "container": "Hacker News",
                        "enrichable": true,
                        "post": {
                          "item_id": "29185994",
                          "source": "hackernews",
                          "title": "Ask HN: How can I make wired Airpods Pro?",
                          "body": "I mostly use my Airpods Pro for their Active Noise Cancelling whilst working at my desk for ~8 hours a day.<p>I&#x27;m finding their relatively short battery life and gradually deteriorating capacity highly frustrating (and ultimately wasteful).<p>Is there a way to power these in wired mode? Surely something like a USB-C cable can do this?<p>For comparison, I still have and use my original wired EarPods with their 3.5mm jack from back in the day - which work perfectly after many years of heavy use.<p>I wish Apple would release a USB-C wired version of these with Active Noise Cancelling like in their AirPods Pro.<p>It would be helluva practical for those long work sessions and also better for the environment.<p>My next best bet is the Bose QC20 - but even these have a quasi-battery solution which ultimately depletes.",
                          "url": null,
                          "author": "user_02ee93",
                          "published_at": "2021-11-11T09:05:52.000Z",
                          "date_confidence": "low",
                          "engagement": {
                            "points": 15,
                            "comments": 20
                          },
                          "relevance_hint": 0.5,
                          "why_relevant": "",
                          "snippet": "",
                          "metadata": {
                            "enrichable": true,
                            "top_comments": [
                              {
                                "score": null,
                                "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                "truncated": true,
                                "author": "user_68d2e3",
                                "url": "https://example.com/redacted",
                                "date": "2021-11-11T09:52:04.000Z"
                              },
                              {
                                "score": null,
                                "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                "truncated": false,
                                "author": "user_765036",
                                "url": "https://example.com/redacted",
                                "date": "2021-11-11T11:12:28.000Z"
                              }
                            ]
                          },
                          "media": {
                            "thumbnail_url": null,
                            "video_url": null,
                            "duration_s": null,
                            "image_urls": [],
                            "aspect_ratio": null,
                            "author_avatar_url": null,
                            "favicon_url": null
                          },
                          "container": "Hacker News",
                          "local_relevance": 0.6393333333333333,
                          "freshness": 0,
                          "engagement_score": 100,
                          "source_quality": 0.8,
                          "local_rank_score": 0.5155666666666666
                        },
                        "top_comments": [
                          {
                            "score": null,
                            "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "truncated": true,
                            "author": "user_68d2e3",
                            "url": "https://example.com/redacted",
                            "date": "2021-11-11T09:52:04.000Z"
                          },
                          {
                            "score": null,
                            "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "truncated": false,
                            "author": "user_765036",
                            "url": "https://example.com/redacted",
                            "date": "2021-11-11T11:12:28.000Z"
                          }
                        ],
                        "rrf_score": 0.01639344262295082,
                        "cluster_id": "cluster-1",
                        "computed": {
                          "stance": {
                            "label": "negative",
                            "confidence": 0.89
                          },
                          "relevance": {
                            "p": 0.63,
                            "sense": "target",
                            "on_topic": true
                          }
                        }
                      }
                    ],
                    "items_by_source": {
                      "hackernews": {
                        "items": [
                          {
                            "item_id": "29185994",
                            "source": "hackernews",
                            "title": "Sample comment text (redacted).",
                            "body": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "url": "",
                            "author": "user_02ee93",
                            "published_at": "2021-11-11T09:05:52.000Z",
                            "date_confidence": "low",
                            "engagement": {
                              "points": 15,
                              "comments": 20
                            },
                            "relevance_hint": 0.5,
                            "why_relevant": "",
                            "snippet": "Sample comment text (redacted).",
                            "metadata": {
                              "enrichable": true,
                              "top_comments": [
                                {
                                  "score": null,
                                  "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                  "truncated": true,
                                  "author": "user_68d2e3",
                                  "url": "https://example.com/redacted",
                                  "date": "2021-11-11T09:52:04.000Z"
                                },
                                {
                                  "score": null,
                                  "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_765036",
                                  "url": "https://example.com/redacted",
                                  "date": "2021-11-11T11:12:28.000Z"
                                }
                              ]
                            },
                            "media": {
                              "thumbnail_url": null,
                              "video_url": null,
                              "duration_s": null,
                              "image_urls": [],
                              "aspect_ratio": null,
                              "author_avatar_url": null,
                              "favicon_url": null
                            },
                            "container": "Hacker News",
                            "local_relevance": 0.6393333333333333,
                            "freshness": 0,
                            "engagement_score": 100,
                            "source_quality": 0.8,
                            "local_rank_score": 0.5155666666666666
                          },
                          {
                            "item_id": "42610644",
                            "source": "hackernews",
                            "title": "Sample comment text (redacted).",
                            "body": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "url": "https://github.com/user_837162/aln",
                            "author": "user_aff807",
                            "published_at": "2025-01-06T14:07:21.000Z",
                            "date_confidence": "low",
                            "engagement": {
                              "points": 3,
                              "comments": 2
                            },
                            "relevance_hint": 0.5,
                            "why_relevant": "",
                            "snippet": "Sample comment text (redacted).",
                            "metadata": {
                              "enrichable": true,
                              "top_comments": [
                                {
                                  "score": null,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_818c06",
                                  "url": "https://example.com/redacted",
                                  "date": "2025-01-06T19:20:01.000Z"
                                },
                                {
                                  "score": null,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_e5d0d6",
                                  "url": "https://example.com/redacted",
                                  "date": "2025-01-06T19:39:30.000Z"
                                }
                              ]
                            },
                            "media": {
                              "thumbnail_url": null,
                              "video_url": null,
                              "duration_s": null,
                              "image_urls": [],
                              "aspect_ratio": null,
                              "author_avatar_url": null,
                              "favicon_url": null
                            },
                            "container": "Hacker News",
                            "local_relevance": 0.48514784946236555,
                            "freshness": 0,
                            "engagement_score": 28,
                            "source_quality": 0.8,
                            "local_rank_score": 0.3433461021505376
                          }
                        ],
                        "enrichable": true
                      },
                      "naver_kin": {
                        "items": [],
                        "enrichable": false,
                        "raw": true
                      },
                      "reddit": {
                        "items": [
                          {
                            "item_id": "1w63726",
                            "source": "reddit",
                            "title": "Sample comment text (redacted).",
                            "body": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "url": "https://www.reddit.com/r/AirpodsPro/comments/1w63726/do_airpods_pro_3_really_have_terrible_battery_life/",
                            "author": "user_79c0e5",
                            "published_at": "2026-09-03T10:09:52.000Z",
                            "date_confidence": "low",
                            "engagement": {
                              "score": 25,
                              "num_comments": 54
                            },
                            "relevance_hint": 0.5,
                            "why_relevant": "",
                            "snippet": "Sample comment text (redacted).",
                            "metadata": {
                              "enrichable": true,
                              "top_comments": [
                                {
                                  "score": 42,
                                  "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_5beea1",
                                  "url": "https://example.com/redacted",
                                  "date": "2026-09-03T10:27:53.966Z"
                                },
                                {
                                  "score": 16,
                                  "excerpt": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_51150e",
                                  "url": "https://example.com/redacted",
                                  "date": "2026-09-03T12:36:21.327Z"
                                }
                              ]
                            },
                            "media": {
                              "thumbnail_url": null,
                              "video_url": null,
                              "duration_s": null,
                              "image_urls": [],
                              "aspect_ratio": null,
                              "author_avatar_url": null,
                              "favicon_url": null
                            },
                            "container": "r/AirpodsPro",
                            "local_relevance": 0.7964285714285714,
                            "freshness": 51,
                            "engagement_score": 64,
                            "source_quality": 0.6,
                            "local_rank_score": 0.7091785714285714
                          },
                          {
                            "item_id": "1ws7b1y",
                            "source": "reddit",
                            "title": "Sample comment text (redacted).",
                            "body": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "url": "https://www.reddit.com/r/airpods/comments/1ws7b1y/worst_experience_in_my_life_with_airpods_pro_3/",
                            "author": "user_517fb2",
                            "published_at": "2026-09-28T06:43:40.000Z",
                            "date_confidence": "low",
                            "engagement": {
                              "score": 0,
                              "num_comments": 18
                            },
                            "relevance_hint": 0.5,
                            "why_relevant": "",
                            "snippet": "Sample comment text (redacted).",
                            "metadata": {
                              "enrichable": true,
                              "top_comments": [
                                {
                                  "score": 11,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_2f89ca",
                                  "url": "https://example.com/redacted",
                                  "date": "2026-09-28T07:00:02.855Z"
                                },
                                {
                                  "score": 5,
                                  "excerpt": "Sample comment text (redacted).",
                                  "truncated": false,
                                  "author": "user_000cfd",
                                  "url": "https://example.com/redacted",
                                  "date": "2026-09-28T07:48:17.877Z"
                                }
                              ]
                            },
                            "media": {
                              "thumbnail_url": null,
                              "video_url": null,
                              "duration_s": null,
                              "image_urls": [],
                              "aspect_ratio": null,
                              "author_avatar_url": null,
                              "favicon_url": null
                            },
                            "container": "r/airpods",
                            "local_relevance": 0.5208333333333333,
                            "freshness": 84,
                            "engagement_score": 0,
                            "source_quality": 0.6,
                            "local_rank_score": 0.5485416666666666
                          }
                        ],
                        "enrichable": true
                      }
                    },
                    "clusters": [
                      {
                        "cluster_id": "cluster-1",
                        "title": "Do Airpods Pro 3 really have terrible battery life?",
                        "candidate_ids": [
                          "https://reddit.com/r/airpodspro/comments/1w63726/do_airpods_pro_3_really_have_terrible_battery_life",
                          "hackernews:29185994"
                        ],
                        "representative_ids": [
                          "https://reddit.com/r/airpodspro/comments/1w63726/do_airpods_pro_3_really_have_terrible_battery_life",
                          "hackernews:29185994"
                        ],
                        "sources": [
                          "hackernews",
                          "reddit"
                        ],
                        "score": 16.393442622950822,
                        "uncertainty": "thin-evidence"
                      },
                      {
                        "cluster_id": "cluster-3",
                        "title": "Worst experience in my life with AirPods Pro 3",
                        "candidate_ids": [
                          "https://reddit.com/r/airpods/comments/1ws7b1y/worst_experience_in_my_life_with_airpods_pro_3"
                        ],
                        "representative_ids": [
                          "https://reddit.com/r/airpods/comments/1ws7b1y/worst_experience_in_my_life_with_airpods_pro_3"
                        ],
                        "sources": [
                          "reddit"
                        ],
                        "score": 16.129032258064516,
                        "uncertainty": "single-source"
                      }
                    ],
                    "computed": {
                      "question_share": 0.5,
                      "question_share_method": "Sample comment text (redacted).",
                      "stance_split": {
                        "positive": 0,
                        "negative": 1,
                        "neutral": 0
                      },
                      "stance_coverage": {
                        "threads": 10,
                        "counted": 4,
                        "no_opinion": 3,
                        "uncertain": 3,
                        "unjudged": 0
                      },
                      "top_communities": [
                        {
                          "container": "r/airpods",
                          "thread_count": 5
                        },
                        {
                          "container": "Hacker News",
                          "thread_count": 3
                        }
                      ]
                    },
                    "legs": [
                      {
                        "endpoint": "/v1/hackernews/search",
                        "status": 200,
                        "credits_used": 1,
                        "latency_ms": 576,
                        "error": null
                      },
                      {
                        "endpoint": "/v1/naver/kin/search",
                        "status": 200,
                        "credits_used": 0,
                        "latency_ms": 1713,
                        "error": null
                      }
                    ],
                    "sources_called": [
                      "hackernews",
                      "naver_kin"
                    ],
                    "sources_succeeded": [
                      "hackernews",
                      "naver_kin"
                    ],
                    "coverage": 1,
                    "partial_failure": false,
                    "methodology_version": "search-forums/1.1",
                    "relevance": {
                      "mode": "default",
                      "threshold": 0.5,
                      "threads": 10,
                      "scored": 10,
                      "kept": 10,
                      "dropped": 0,
                      "dropped_ids": [],
                      "unjudged": 0,
                      "too_short": 0,
                      "reordered": false,
                      "methodology_version": "search-forums-relevance/1"
                    },
                    "dropped": 0
                  },
                  "credits_used": 10,
                  "request_id": "req_example000000",
                  "cached": false,
                  "pagination": {
                    "next_cursor": null,
                    "has_more": false,
                    "page_size": 10
                  },
                  "credits_remaining": 9999
                }
              }
            }
          },
          "400": {
            "description": "Invalid request - missing or malformed parameters",
            "x-error-codes": [
              "INVALID_REQUEST",
              "COHORT_MEMBER_LIMIT_EXCEEDED",
              "COHORT_LIMIT_EXCEEDED",
              "COHORT_IDENTITY_PLATFORM_UNSUPPORTED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INVALID_REQUEST",
                    "message": "Invalid request - missing or malformed parameters",
                    "status": 400,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid API key",
            "x-error-codes": [
              "MISSING_API_KEY",
              "INVALID_API_KEY"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "MISSING_API_KEY",
                    "message": "Unauthorized - missing or invalid API key",
                    "status": 401,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "402": {
            "description": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
            "x-error-codes": [
              "INSUFFICIENT_CREDITS",
              "KEY_BUDGET_EXCEEDED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INSUFFICIENT_CREDITS",
                    "message": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
                    "status": 402,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "404": {
            "description": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
            "x-error-codes": [
              "ENDPOINT_NOT_FOUND",
              "RESOURCE_NOT_FOUND",
              "RUN_NOT_FOUND",
              "SCHEDULE_NOT_FOUND",
              "STREAM_NOT_FOUND"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "ENDPOINT_NOT_FOUND",
                    "message": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
                    "status": 404,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed - wrong HTTP verb for this endpoint",
            "x-error-codes": [
              "METHOD_NOT_ALLOWED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "METHOD_NOT_ALLOWED",
                    "message": "Method not allowed - wrong HTTP verb for this endpoint",
                    "status": 405,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_CONFLICT",
              "IDEMPOTENCY_IN_PROGRESS",
              "IDEMPOTENCY_REPLAY_UNAVAILABLE",
              "COHORT_IDENTITY_CONFLICT",
              "COHORT_QUERY_NOT_CANCELLABLE",
              "COHORT_QUERY_NOT_READY",
              "RUN_STATE_CONFLICT",
              "STREAM_STATE_CONFLICT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_CONFLICT",
                    "message": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
                    "status": 409,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "410": {
            "description": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
            "x-error-codes": [
              "RUN_EXPIRED",
              "CURSOR_EXPIRED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RUN_EXPIRED",
                    "message": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
                    "status": 410,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
            "x-error-codes": [
              "PAYLOAD_TOO_LARGE",
              "COHORT_RESULT_TOO_LARGE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "PAYLOAD_TOO_LARGE",
                    "message": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
                    "status": 413,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
              "NEEDS_ASYNC"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
                    "message": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
                    "status": 422,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
            "x-error-codes": [
              "RATE_LIMITED",
              "CONCURRENCY_LIMIT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RATE_LIMITED",
                    "message": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
                    "status": 429,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
            "x-error-codes": [
              "INTERNAL_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INTERNAL_ERROR",
                    "message": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
                    "status": 500,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "502": {
            "description": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 502,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "SERVICE_UNAVAILABLE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 503,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "504": {
            "description": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
                    "status": 504,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          }
        }
      }
    },
    "/search/creators": {
      "get": {
        "summary": "Fused creator discovery across TikTok, Threads, and Instagram, ranked by relevance, followers, and verification. YouTube, X, and Facebook people are opt-in via sources=.",
        "description": "Fans a niche query across TikTok user search, Threads user search, and Instagram profile search by default, then merges matching creators into one deterministically ranked list. Ranking is a published formula of query relevance, follower scale, and verification. No LLM rerank by default. Pass `sources=youtube`, `twitter`, or `facebook` (or a CSV of any of the six) to add those profile searches; omitting `sources` keeps the original three-platform walk so existing callers do not change. Pass `brief=` (what you are looking for, in your own words) to have the first 40 creators judged from their name, handle and bio: each gets `brief_match` ({ fits_brief, account_kind, account_kind_confidence, brief_score }) and the list is re-ranked so creators who post about your brief lead, with brands, shops, academies and repost pages below them; `data.brief` reports what was judged and the ranking version. `relevance=filter` also drops creators that do not fit and lists them in `data.brief.dropped_ids`. Pass `country` (CL, AR, MX, CO, PE, EC, UY, ES, BR) to find the creators who post about your query in that market, on TikTok and Instagram, instead of searching account names. The market's own name is added to your query (`inteligencia artificial` with CL searches `inteligencia artificial chile`, returned as `data.country.by_source.<source>.query_sent`). On TikTok the result is the creators behind the videos whose own region is the market and whose text is about your query, with their follower counts. On Instagram it is the profiles a Google search from the market finds, each read from its About this account panel and kept only when the creator declares that country, with followers and bio. Each creator then carries `country` (`{ value, source }`, where source is `post_region` on TikTok and `declared_country` on Instagram) and `evidence` (up to 3 posts or the profile text that found it, with links), and `data.country` counts per source what was kept and what was dropped as another country, off topic or with no country declared. `min_followers`, `verified_only`, `sort` and `brief` work as they do without it. Flat 10 credits with a coverage-based partial refund; with `country`, the searches it runs are billed on top at their own price.",
        "tags": [
          "search"
        ],
        "operationId": "get_search_creators",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-credit-tier": "standard",
        "x-credit-cost": 10,
        "x-credit-cost-min": 10,
        "x-credit-cost-max": 24,
        "x-credit-cost-formula": "10 credits flat, with a coverage-based partial refund. A search no source has a creator for answers 200 with an empty `creators` and `empty_reason: no_matches`, at 0 credits. Adding brief= adds 2 credits, refunded when the judging step could not answer for every judged creator. With country=, the searches and lookups it runs are billed on top, each at its own endpoint's price: 1 credit for the TikTok search page, 1 for the Google page and 1 per Instagram profile looked up (at most 10, and free for a profile looked up recently), so at most 12 more. data.legs lists each one with its credits, and the 10 are refunded when no creator is found. A cached page is free.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "Niche or topic (2-256 chars), forwarded to every profile search.",
            "schema": {
              "type": "string"
            },
            "example": "skincare routine"
          },
          {
            "name": "sources",
            "in": "query",
            "required": false,
            "description": "Optional CSV allowlist of creator sources (tiktok, threads, instagram, youtube, twitter, facebook). Mutually exclusive with exclude. Omit to keep the default TikTok + Threads + Instagram walk. With country, only tiktok and instagram (the default), and any other source is a free 400.",
            "schema": {
              "type": "string"
            },
            "example": "tiktok,instagram"
          },
          {
            "name": "exclude",
            "in": "query",
            "required": false,
            "description": "Optional CSV blocklist of creator sources. Mutually exclusive with sources.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "min_followers",
            "in": "query",
            "required": false,
            "description": "Drop fused creators whose follower count is below this integer floor.",
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "example": 50000
          },
          {
            "name": "verified_only",
            "in": "query",
            "required": false,
            "description": "When true, keep only verified creators after fusion.",
            "schema": {
              "type": "boolean"
            },
            "example": false
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Which axis dominates rank: relevance (default), followers, or verification.",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "followers",
                "verification"
              ]
            },
            "example": "relevance"
          },
          {
            "name": "brief",
            "in": "query",
            "required": false,
            "description": "Optional. What you want to find, in your own words (3-300 chars), for example brief=Korean creators who review skincare products. The first 40 creators are judged from their name, handle and bio: does the account post about your brief (fits_brief, 0 to 1), and what kind of account is it (individual_creator, brand_or_business, media_or_publisher, fan_or_repost_page, cannot_tell; null when unsure). With sort=relevance (the default) they are re-ranked so creators who fit and are individual people lead; other sorts keep their order and only gain the labels. These are signals to review, not a finding. Adds 2 credits.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "relevance",
            "in": "query",
            "required": false,
            "description": "Optional, only with brief. score (default) ranks and labels; filter also drops judged creators that do not fit the brief and lists them in data.brief.dropped_ids. A creator that could not be judged is never dropped.",
            "schema": {
              "type": "string",
              "enum": [
                "score",
                "filter"
              ]
            }
          },
          {
            "name": "judgments",
            "in": "query",
            "required": false,
            "description": "Optional. on (default) or off. On, the first 40 creators also carry account ({ account_kind: individual_creator, brand_or_business, media_or_publisher, fan_or_repost_page, cannot_tell or null when unsure, account_kind_confidence, named_person }), judged from their name, handle and bio, and data.account_kinds reports how many were judged. The order is unchanged and it is free. off returns the response without it.",
            "schema": {
              "type": "string",
              "enum": [
                "on",
                "off"
              ]
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Optional. Two-letter market code (CL, AR, MX, CO, PE, EC, UY, ES, BR) to find the creators who post about your query in that market, instead of searching account names. Runs on TikTok and Instagram: the market's name is added to your query, TikTok creators are kept when the video's own region is the market and its text is about your query, and Instagram creators when they declare that country on their About this account panel. Each creator carries country and evidence, and data.country reports the query sent and what was kept and dropped per source. The searches and lookups it runs are billed on top at their own price, at most 12 credits. Any other code is a free 400.",
            "schema": {
              "type": "string",
              "enum": [
                "CL",
                "AR",
                "MX",
                "CO",
                "PE",
                "EC",
                "UY",
                "ES",
                "BR"
              ]
            }
          },
          {
            "name": "max_age_s",
            "in": "query",
            "required": false,
            "description": "The oldest cached copy you accept, in seconds. A copy that old or younger is served for 0 credits, with its age in `age_s` and the `X-Cache-Age` header. Without it a copy up to 120 seconds old is served. A lower value fetches fresh (billed) when the copy is older, and 0 always fetches live, like `Cache-Control: no-cache`.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 120
            }
          },
          {
            "name": "Cache-Control",
            "in": "header",
            "required": false,
            "description": "Send `no-cache` to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the `no-cache` directive triggers this. To accept an older cached copy, or to require a younger one, send the `max_age_s` query parameter instead. See the Response Schema guide for details.",
            "schema": {
              "type": "string"
            },
            "example": "no-cache"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives `409 IDEMPOTENCY_IN_PROGRESS` with a `Retry-After` of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: `credits_used` becomes 0, `idempotent_replay` becomes true, and `credits_remaining` is refreshed to the current balance. A known current balance appears in both the body and `X-Credits-Remaining` header; no balance row resolves to 0. On a transient lookup failure, body `credits_remaining` is null and `X-Credits-Remaining` is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use `Accept: application/json` when sending this header. The unsupported key-plus-SSE combination is rejected before billing.",
            "schema": {
              "type": "string"
            },
            "example": "7a5e1b4c-2d8f-4a3b-9c1e-6e8b4d2a1f3c"
          },
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "Send `respond-async` to run this GET in the background instead of waiting on the socket (or add `?async=true` to the query). The answer is 202 with `data.job_id`, a `Location` header and `Retry-After`; read the result free at `GET /v1/prism/jobs/{job_id}`, where `results[0].response` is exactly what this call returns. Nothing is held at submit: the call is validated now and billed as this call when it runs. Use it for calls that can outlast your client's timeout (MCP and many HTTP clients stop at 30 s). `Idempotency-Key` returns the same job on a retry.",
            "schema": {
              "type": "string"
            },
            "example": "respond-async"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-Credits-Used": {
                "description": "Net credits charged for this response. Idempotency replays report 0.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Credits-Remaining": {
                "description": "Current authoritative balance. Free cache hits and idempotency replays omit this header when the balance cannot be determined; body `credits_remaining` is null instead.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Key-Credits-Remaining": {
                "description": "Only when the API key has a credit limit: the credits this key may still spend under that limit, after this call (never below 0). Absent for a key with no limit. `GET /v1/keys/current` has the limit and what is used.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Idempotent-Replay": {
                "description": "Present with value `true` only when this response replays a settled idempotency record.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "Idempotent-Replayed": {
                "description": "Present with value `true` only when this response replays a settled idempotency record. Same meaning as `X-Idempotent-Replay`.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Whether the request succeeded",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "description": "Platform name",
                      "example": "search"
                    },
                    "endpoint": {
                      "type": "string",
                      "description": "API endpoint path",
                      "example": "/v1/search/creators"
                    },
                    "data": {
                      "type": "object",
                      "description": "Platform-specific response data",
                      "properties": {
                        "metrics": {
                          "type": "object",
                          "description": "Key performance metrics",
                          "properties": {
                            "total_views": {
                              "type": "integer",
                              "description": "Total view count"
                            },
                            "total_likes": {
                              "type": "integer",
                              "description": "Total like count"
                            },
                            "total_comments": {
                              "type": "integer",
                              "description": "Total comment count"
                            },
                            "engagement_rate": {
                              "type": "number",
                              "description": "Computed engagement rate (0-1)"
                            }
                          }
                        },
                        "period": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Time period for the analytics data"
                        },
                        "breakdown": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "description": "Per-item or per-period breakdown",
                          "items": {
                            "type": "object",
                            "description": "Breakdown entry"
                          }
                        },
                        "_warnings": {
                          "type": "array",
                          "description": "Non-fatal notices about this response (field-map drift, clamped computed values). Advisory only: its presence never means the request failed. Omitted entirely when there is nothing to report, so treat absent as 'no warnings'.",
                          "items": {
                            "type": "string",
                            "description": "One advisory notice."
                          }
                        }
                      }
                    },
                    "credits_used": {
                      "type": "integer",
                      "description": "Number of credits consumed",
                      "example": 1
                    },
                    "credits_remaining": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.",
                      "example": 4999
                    },
                    "credits_remaining_note": {
                      "type": "string",
                      "description": "Present only when `credits_remaining` is null by design, as on a free cache hit: says why the balance was not read and where to read it.",
                      "example": "not read on cache hits (credits_used is 0); call GET /v1/credits/balance for the current balance"
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Unique request identifier for support",
                      "example": "req-abc123"
                    },
                    "cached": {
                      "type": "boolean",
                      "description": "Whether the response was served from cache",
                      "example": false
                    },
                    "age_s": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Present only on a cache hit (`cached: true`): whole seconds since this copy was fetched, also sent as the `X-Cache-Age` header. Null for a copy stored before ages were recorded. Send `max_age_s` to set how old a copy you accept: a profile or post copy up to an hour old is served for 0 credits, and a lower value fetches fresh.",
                      "example": 340
                    },
                    "idempotent_replay": {
                      "type": "boolean",
                      "description": "True only when this response is an idempotency replay",
                      "example": true
                    },
                    "meta": {
                      "type": "object",
                      "description": "Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.",
                      "properties": {
                        "hint": {
                          "type": "object",
                          "description": "One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat | batch_comments | batch_jobs",
                              "example": "search_multi"
                            },
                            "message": {
                              "type": "string",
                              "description": "One sentence for a person or an agent to read.",
                              "example": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged."
                            },
                            "method": {
                              "type": "string",
                              "description": "GET or POST.",
                              "example": "GET"
                            },
                            "path": {
                              "type": "string",
                              "description": "The call the hint points to.",
                              "example": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "platform",
                    "endpoint",
                    "data",
                    "credits_used",
                    "credits_remaining",
                    "request_id",
                    "cached"
                  ]
                },
                "example": {
                  "success": true,
                  "platform": "search",
                  "endpoint": "/v1/search/creators",
                  "data": {
                    "creators": [
                      {
                        "author": {
                          "id": "user_058794",
                          "username": "user_1cb194",
                          "display_name": "user_a15759",
                          "bio": null,
                          "followers": 6045690,
                          "verified": false,
                          "avatar_url": "https://example.com/avatars/user_805cd1.png",
                          "url": "https://example.com/user_d7235c"
                        },
                        "sources": [
                          "tiktok"
                        ],
                        "relevance": 0.44999999999999996,
                        "follower_rank": 1,
                        "verified": false,
                        "rrf_score": 0.017897727272727273,
                        "account": {
                          "account_kind": "individual_creator",
                          "account_kind_confidence": 1,
                          "named_person": 0.87
                        }
                      }
                    ],
                    "creators_by_source": {
                      "tiktok": [
                        {
                          "id": "user_b598dc",
                          "username": "user_4d9b4a",
                          "display_name": "user_67c672",
                          "bio": null,
                          "followers": 36,
                          "verified": false,
                          "avatar_url": "https://example.com/avatars/user_ea00c5.png",
                          "url": "https://example.com/user_c06400"
                        },
                        {
                          "id": "user_a8ec20",
                          "username": "user_7b906f",
                          "display_name": "user_3af5a8",
                          "bio": null,
                          "followers": 5085,
                          "verified": false,
                          "avatar_url": "https://example.com/avatars/user_676794.png",
                          "url": "https://example.com/user_e80546"
                        }
                      ],
                      "threads": [],
                      "instagram": [
                        {
                          "id": "user_d64a0b",
                          "username": "user_c1e003",
                          "display_name": "user_2c8d0f",
                          "bio": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                          "followers": 22456,
                          "verified": false,
                          "avatar_url": "https://example.com/avatars/user_99e358.png",
                          "url": "https://example.com/user_60d233"
                        },
                        {
                          "id": "user_9a0493",
                          "username": "user_d61117",
                          "display_name": "user_c043e7",
                          "bio": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                          "followers": 28396,
                          "verified": false,
                          "avatar_url": "https://example.com/avatars/user_88de7a.png",
                          "url": "https://example.com/user_995add"
                        }
                      ],
                      "youtube": [],
                      "twitter": [],
                      "facebook": []
                    },
                    "computed": {
                      "platform_spread": {
                        "tiktok": 30,
                        "instagram": 44
                      },
                      "verified_share": 0,
                      "follower_distribution": {
                        "p50": 6045690,
                        "p90": 6045690
                      }
                    },
                    "legs": [
                      {
                        "endpoint": "/v1/tiktok/search/users",
                        "status": 200,
                        "credits_used": 1,
                        "latency_ms": 1941,
                        "error": null
                      },
                      {
                        "endpoint": "/v1/instagram/search/profiles",
                        "status": 200,
                        "credits_used": 1,
                        "latency_ms": 7963,
                        "error": null
                      }
                    ],
                    "sources_called": [
                      "tiktok",
                      "instagram"
                    ],
                    "sources_succeeded": [
                      "tiktok",
                      "instagram"
                    ],
                    "coverage": 1,
                    "partial_failure": false,
                    "methodology_version": "search-creators/1.0",
                    "account_kinds": {
                      "methodology_version": "creators-account-kind/1",
                      "status": "complete",
                      "judged": 1,
                      "unjudged": 0
                    }
                  },
                  "credits_used": 10,
                  "request_id": "req_example000000",
                  "cached": false,
                  "credits_remaining": 9999
                }
              }
            }
          },
          "400": {
            "description": "Invalid request - missing or malformed parameters",
            "x-error-codes": [
              "INVALID_REQUEST",
              "COHORT_MEMBER_LIMIT_EXCEEDED",
              "COHORT_LIMIT_EXCEEDED",
              "COHORT_IDENTITY_PLATFORM_UNSUPPORTED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INVALID_REQUEST",
                    "message": "Invalid request - missing or malformed parameters",
                    "status": 400,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid API key",
            "x-error-codes": [
              "MISSING_API_KEY",
              "INVALID_API_KEY"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "MISSING_API_KEY",
                    "message": "Unauthorized - missing or invalid API key",
                    "status": 401,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "402": {
            "description": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
            "x-error-codes": [
              "INSUFFICIENT_CREDITS",
              "KEY_BUDGET_EXCEEDED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INSUFFICIENT_CREDITS",
                    "message": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
                    "status": 402,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "404": {
            "description": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
            "x-error-codes": [
              "ENDPOINT_NOT_FOUND",
              "RESOURCE_NOT_FOUND",
              "RUN_NOT_FOUND",
              "SCHEDULE_NOT_FOUND",
              "STREAM_NOT_FOUND"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "ENDPOINT_NOT_FOUND",
                    "message": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
                    "status": 404,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed - wrong HTTP verb for this endpoint",
            "x-error-codes": [
              "METHOD_NOT_ALLOWED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "METHOD_NOT_ALLOWED",
                    "message": "Method not allowed - wrong HTTP verb for this endpoint",
                    "status": 405,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_CONFLICT",
              "IDEMPOTENCY_IN_PROGRESS",
              "IDEMPOTENCY_REPLAY_UNAVAILABLE",
              "COHORT_IDENTITY_CONFLICT",
              "COHORT_QUERY_NOT_CANCELLABLE",
              "COHORT_QUERY_NOT_READY",
              "RUN_STATE_CONFLICT",
              "STREAM_STATE_CONFLICT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_CONFLICT",
                    "message": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
                    "status": 409,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "410": {
            "description": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
            "x-error-codes": [
              "RUN_EXPIRED",
              "CURSOR_EXPIRED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RUN_EXPIRED",
                    "message": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
                    "status": 410,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
            "x-error-codes": [
              "PAYLOAD_TOO_LARGE",
              "COHORT_RESULT_TOO_LARGE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "PAYLOAD_TOO_LARGE",
                    "message": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
                    "status": 413,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
              "NEEDS_ASYNC"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
                    "message": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
                    "status": 422,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
            "x-error-codes": [
              "RATE_LIMITED",
              "CONCURRENCY_LIMIT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RATE_LIMITED",
                    "message": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
                    "status": 429,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
            "x-error-codes": [
              "INTERNAL_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INTERNAL_ERROR",
                    "message": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
                    "status": 500,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "502": {
            "description": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 502,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "SERVICE_UNAVAILABLE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 503,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "504": {
            "description": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
                    "status": 504,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          }
        }
      }
    },
    "/search/multi": {
      "get": {
        "summary": "One query, each platform's own search results, in one call at each platform's own price.",
        "description": "Runs the same query on several platforms' native search endpoints at once and returns their rows together: TikTok (`/v1/tiktok/search`), Instagram reels (`/v1/instagram/search/reels`), YouTube (`/v1/youtube/search`), Reddit (`/v1/reddit/search`), Threads (`/v1/threads/search`), X (`/v1/twitter/search/tweets`), Facebook (`/v1/facebook/search/posts`), LinkedIn (`/v1/linkedin/search/posts`) and Telegram (`/v1/telegram/search`, whose rows are channels under `author`, not posts, deduped by handle). `platforms` picks them (default tiktok,instagram,youtube,reddit,threads). Each platform is searched by calling that platform's own endpoint, so every row in `data.items` is exactly the row a direct call returns, with its `post` and `computed` blocks, plus `platform`, and each platform is billed exactly as a direct call would be. Rows are grouped by platform in the order you asked for them, in each platform's own order, and a post URL that already appeared is dropped (`data.duplicates_removed`). Each platform's own filters pass through with a platform prefix, for example `tiktok.region=US` or `reddit.sort=new`. `since` and `until` keep only posts published inside a date window on every platform; a row without a date is kept. Each platform is also sent the native date filter that fits the window, so its one page holds the right posts: Threads and Facebook `start_date` and `end_date`, the X `since:` and `until:` operators, and on TikTok, YouTube and Reddit the narrowest rolling bucket (`date_posted`, `uploadDate`, `timeframe`) that still reaches `since`, for example `tiktok.date_posted=last-3-months` for a date 44 days back. A filter you send yourself is never changed, and `data._warnings` says `window_unreachable` when it cannot reach `since`. On Instagram and LinkedIn the bucket is only suggested, because their date filter changes what the platform returns (Instagram reels lose their view counts). `data.window` reports what each platform was sent (`native`, `origin`, `reaches_since`, `suggested`) and how many of its rows fell outside the window. A newest-first page that ends before `since` (`reddit.sort=new`, X) says `since_not_reached` and names the cursor to continue with. `data.sources` reports each platform: `status` (`ok`, `empty` or `failed`), the rows it returned and kept, the credits it cost, its own `request_id` and `warnings` (for example the note that a Threads query was expanded), and its `next_cursor`, which you send as `cursor` to that platform's own endpoint (listed in `endpoint`) for its next page. This endpoint does not page itself. Native search matches your words literally; `expand=context` also runs up to three short searches written from your query and `relevant_to` (how sellers and posters phrase the same thing), merges them with your query's rows, tags each row with `matched_query`, and reports the searches in `data.expansion`. Pair it with `relevance=filter` and `relevant_to` to keep only the rows about what you mean. `instagram.include=creator` adds each Instagram creator's declared country, followers and public email, billed by the reel search as on a direct call. For a planned, reranked and clustered answer across more sources, use /v1/search/everywhere.",
        "tags": [
          "search"
        ],
        "operationId": "get_search_multi",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-credit-tier": "standard",
        "x-credit-cost": 0,
        "x-credit-cost-min": 0,
        "x-credit-cost-max": 30,
        "x-credit-cost-formula": "Metered, usually 1-14 credits: each platform is billed at its own endpoint's price, per platform, exactly as a direct call to that endpoint is billed (TikTok, Instagram, YouTube, Reddit, Threads, X and Facebook 1 credit a page, Telegram 2, LinkedIn 5). A platform whose page found nothing or failed costs nothing, and a platform page served from cache is free. A Threads phrase that Threads does not recognise is expanded into narrower searches, as on /v1/threads/search, and costs 1 credit per search that returned posts. With expand=context every platform runs your phrase plus expand_queries planned searches (3 by default, 3 at most), each billed as its own page, so the range above is multiplied by 1 plus expand_queries and the estimate quotes it that way. The searches inside a platform judge their rows for free; relevant_to= or label= is billed once on the request, for the rows of the merged page. data.sources.<platform>.credits shows each platform's charge and credits_used the total. Relevance against your query (by default, or with relevance=) is free. Adding relevant_to= holds 8 extra credits and refunds down to 1 credit per started 25 rows that were newly judged: rows already judged for the same topic are free, a page where nothing could be judged refunds the whole extra, and a cached page is free. The default labels (sponsored, intent, niche) are free. label=mention, quality, ai_style, ai_written, injection, or label=intent with offer=, holds 8 extra credits and refunds down to 1 credit per started 25 posts that were newly judged: posts already labelled are free, a page where nothing could be judged refunds the whole extra, and a cached page is free.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "Keyword or phrase, sent unchanged to every platform (1-500 characters). Each platform matches it the way its own search endpoint does: Reddit matches any of the words unless you wrap a phrase in double quotes, and a phrase Threads does not recognise is expanded into narrower searches.",
            "schema": {
              "type": "string"
            },
            "example": "matcha latte"
          },
          {
            "name": "platforms",
            "in": "query",
            "required": false,
            "description": "Comma-separated platforms to search: tiktok, instagram, youtube, reddit, threads, twitter, facebook, linkedin, telegram. Default tiktok,instagram,youtube,reddit,threads. Each one costs its own endpoint's page price, and only when its page came back with rows.",
            "schema": {
              "type": "string"
            },
            "example": "tiktok,instagram,youtube"
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Keep only posts published on or after this date on every platform: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. A row with no date is kept. A platform page trimmed to nothing still costs its page, as it would on that platform's own endpoint. When you do not send a platform's own date filter, the narrowest one that reaches this date is sent for you on TikTok, YouTube and Reddit (an exact date on Threads, Facebook and X); data.window says which.",
            "schema": {
              "type": "string"
            },
            "example": "2026-09-01"
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "Keep only posts published on or before this date on every platform: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. A row with no date is kept. Sent natively as Threads and Facebook end_date and the X until: operator; the other platforms have no upper bound of their own, so their newer rows are dropped from the page and still cost the page. Use since and until together for a calendar month.",
            "schema": {
              "type": "string"
            },
            "example": "2026-09-30"
          },
          {
            "name": "expand",
            "in": "query",
            "required": false,
            "description": "Optional. context also searches up to three short phrases written from your query and, when you send it, relevant_to: the words the people who wrote the posts actually use. Native search reads a query literally, so a long phrase such as fake byd spare part sellers scam misses a seller who writes BYD spare parts Sharjah. Your own query always runs as well. Every row carries matched_query, the search that found it; data.expansion lists the searches with the rows each one added and its credits; data.sources.<platform>.by_query has each search's own cursor. Each extra search is billed on each platform exactly like your query (1 credit a page with rows, LinkedIn 5), and writing the searches is free. If they cannot be written in time, one search is made from the product words in your query (data._warnings says expand_fallback), or, when there are none to drop, only your query runs (expand_unavailable). Each search on each platform is one in-flight request on your API key, so one expanded call on six platforms holds up to 24 of the key's 50 at once; a search the limit refuses costs nothing and data._warnings says searches_limited.",
            "schema": {
              "type": "string",
              "enum": [
                "context"
              ]
            }
          },
          {
            "name": "expand_queries",
            "in": "query",
            "required": false,
            "description": "Optional, only with expand=context. How many extra searches to run, 1 to 3 (default 3). Each one can cost up to one more page per platform.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 3
            }
          },
          {
            "name": "tiktok.date_posted",
            "in": "query",
            "required": false,
            "description": "TikTok only. Sent to /v1/tiktok/search as `date_posted`, exactly as that endpoint takes it. One of: yesterday, this-week, this-month, last-3-months, last-6-months, all-time.",
            "schema": {
              "type": "string",
              "enum": [
                "yesterday",
                "this-week",
                "this-month",
                "last-3-months",
                "last-6-months",
                "all-time"
              ]
            }
          },
          {
            "name": "tiktok.sort_by",
            "in": "query",
            "required": false,
            "description": "TikTok only. Sent to /v1/tiktok/search as `sort_by`, exactly as that endpoint takes it. One of: relevance, most-liked, date-posted.",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "most-liked",
                "date-posted"
              ]
            }
          },
          {
            "name": "tiktok.region",
            "in": "query",
            "required": false,
            "description": "TikTok only. Sent to /v1/tiktok/search as `region`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            },
            "example": "US"
          },
          {
            "name": "instagram.date_posted",
            "in": "query",
            "required": false,
            "description": "Instagram only. Sent to /v1/instagram/search/reels as `date_posted`, exactly as that endpoint takes it. One of: last-week, last-month, last-year.",
            "schema": {
              "type": "string",
              "enum": [
                "last-week",
                "last-month",
                "last-year"
              ]
            }
          },
          {
            "name": "instagram.include",
            "in": "query",
            "required": false,
            "description": "Instagram only. Sent to /v1/instagram/search/reels as `include`, exactly as that endpoint takes it. One of: creator.",
            "schema": {
              "type": "string",
              "enum": [
                "creator"
              ]
            }
          },
          {
            "name": "youtube.uploadDate",
            "in": "query",
            "required": false,
            "description": "YouTube only. Sent to /v1/youtube/search as `uploadDate`, exactly as that endpoint takes it. One of: today, this_week, this_month, this_year.",
            "schema": {
              "type": "string",
              "enum": [
                "today",
                "this_week",
                "this_month",
                "this_year"
              ]
            }
          },
          {
            "name": "youtube.sortBy",
            "in": "query",
            "required": false,
            "description": "YouTube only. Sent to /v1/youtube/search as `sortBy`, exactly as that endpoint takes it. One of: relevance, popular.",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "popular"
              ]
            }
          },
          {
            "name": "youtube.type",
            "in": "query",
            "required": false,
            "description": "YouTube only. Sent to /v1/youtube/search as `type`, exactly as that endpoint takes it. One of: videos, shorts.",
            "schema": {
              "type": "string",
              "enum": [
                "videos",
                "shorts"
              ]
            }
          },
          {
            "name": "youtube.duration",
            "in": "query",
            "required": false,
            "description": "YouTube only. Sent to /v1/youtube/search as `duration`, exactly as that endpoint takes it. One of: under_3_min, between_3_and_20_min, over_20_min.",
            "schema": {
              "type": "string",
              "enum": [
                "under_3_min",
                "between_3_and_20_min",
                "over_20_min"
              ]
            }
          },
          {
            "name": "youtube.region",
            "in": "query",
            "required": false,
            "description": "YouTube only. Sent to /v1/youtube/search as `region`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reddit.sort",
            "in": "query",
            "required": false,
            "description": "Reddit only. Sent to /v1/reddit/search as `sort`, exactly as that endpoint takes it. One of: relevance, new, top, comment_count.",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "new",
                "top",
                "comment_count"
              ]
            }
          },
          {
            "name": "reddit.timeframe",
            "in": "query",
            "required": false,
            "description": "Reddit only. Sent to /v1/reddit/search as `timeframe`, exactly as that endpoint takes it. One of: all, day, week, month, year.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "day",
                "week",
                "month",
                "year"
              ]
            }
          },
          {
            "name": "threads.start_date",
            "in": "query",
            "required": false,
            "description": "Threads only. Sent to /v1/threads/search as `start_date`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "threads.end_date",
            "in": "query",
            "required": false,
            "description": "Threads only. Sent to /v1/threads/search as `end_date`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "twitter.sort",
            "in": "query",
            "required": false,
            "description": "X only. Sent to /v1/twitter/search/tweets as `sort`, exactly as that endpoint takes it. One of: latest, top.",
            "schema": {
              "type": "string",
              "enum": [
                "latest",
                "top"
              ]
            }
          },
          {
            "name": "facebook.start_date",
            "in": "query",
            "required": false,
            "description": "Facebook only. Sent to /v1/facebook/search/posts as `start_date`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "facebook.end_date",
            "in": "query",
            "required": false,
            "description": "Facebook only. Sent to /v1/facebook/search/posts as `end_date`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "facebook.recent_posts",
            "in": "query",
            "required": false,
            "description": "Facebook only. Sent to /v1/facebook/search/posts as `recent_posts`, exactly as that endpoint takes it.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "facebook.location_uid",
            "in": "query",
            "required": false,
            "description": "Facebook only. Sent to /v1/facebook/search/posts as `location_uid`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "linkedin.sort_by",
            "in": "query",
            "required": false,
            "description": "LinkedIn only. Sent to /v1/linkedin/search/posts as `sort_by`, exactly as that endpoint takes it. One of: date_posted, relevance.",
            "schema": {
              "type": "string",
              "enum": [
                "date_posted",
                "relevance"
              ]
            }
          },
          {
            "name": "linkedin.date_posted",
            "in": "query",
            "required": false,
            "description": "LinkedIn only. Sent to /v1/linkedin/search/posts as `date_posted`, exactly as that endpoint takes it. One of: past_24h, past_week, past_month.",
            "schema": {
              "type": "string",
              "enum": [
                "past_24h",
                "past_week",
                "past_month"
              ]
            }
          },
          {
            "name": "linkedin.content_type",
            "in": "query",
            "required": false,
            "description": "LinkedIn only. Sent to /v1/linkedin/search/posts as `content_type`, exactly as that endpoint takes it. One of: videos, photos, jobs, live_videos, documents, collaborative_articles.",
            "schema": {
              "type": "string",
              "enum": [
                "videos",
                "photos",
                "jobs",
                "live_videos",
                "documents",
                "collaborative_articles"
              ]
            }
          },
          {
            "name": "telegram.date_posted",
            "in": "query",
            "required": false,
            "description": "Telegram only. Sent to /v1/telegram/search as `date_posted`, exactly as that endpoint takes it. One of: last-hour, last-day, last-week, last-month, last-year.",
            "schema": {
              "type": "string",
              "enum": [
                "last-hour",
                "last-day",
                "last-week",
                "last-month",
                "last-year"
              ]
            }
          },
          {
            "name": "telegram.region",
            "in": "query",
            "required": false,
            "description": "Telegram only. Sent to /v1/telegram/search as `region`, exactly as that endpoint takes it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "relevance",
            "in": "query",
            "required": false,
            "description": "Optional. Without this param every row already carries computed.relevance against your query, free ({ p, sense, depth, spam }: is this row about what your query means, or a different thing that shares its words?), and nothing is dropped or reordered. score asks for it explicitly and waits for every row; filter also drops the rows that are not about your query, and lists their ids in data.relevance.dropped_ids. Your query is the topic; nothing to configure. A row that could not be judged is never dropped and carries relevance: null. Pagination is unchanged, so a filtered page can hold fewer rows. Free with your query as the topic; with relevant_to it adds 1 credit per started 25 newly judged rows (rows already judged for the same topic are free, and so is a cached page).",
            "schema": {
              "type": "string",
              "enum": [
                "score",
                "filter"
              ]
            }
          },
          {
            "name": "relevance_threshold",
            "in": "query",
            "required": false,
            "description": "Optional, only with relevance. The probability (0 to 1) a row must reach to be kept by relevance=filter. Default 0.5. Lower keeps more rows, higher keeps fewer.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "relevant_to",
            "in": "query",
            "required": false,
            "description": "Optional, only with relevance. Up to 200 characters describing what you mean, used as the topic instead of the query. Use it when the query is ambiguous, for example query=cleopatra with relevant_to=Cleopatra, the IGT slot game.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "judgments",
            "in": "query",
            "required": false,
            "description": "Optional, on (the default) or off. By default every row gains free SocialCrawl judgments (computed.labels, and computed.relevance on search endpoints), reported in data.labels (mode default) and data.relevance (origin default), each with a status (complete, partial or skipped) and pending: the rows still being judged when the page was sent, which carry null now and are filled on your next call or cached read. Default judgments never add credits, never change an existing field, and never drop or reorder a row. off returns the page exactly as before, with none of those keys. label=none does the same.",
            "schema": {
              "type": "string",
              "enum": [
                "on",
                "off"
              ]
            }
          },
          {
            "name": "dry_run",
            "in": "query",
            "required": false,
            "description": "Optional. When 1, return a cost preview for this labelled or relevance-filtered request without fetching the page or judging any row. data.estimate reports rows_expected, rows_cached, label_credits_min, label_credits_max and base_credits. 0 credits charged.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          },
          {
            "name": "fit",
            "in": "query",
            "required": false,
            "description": "Optional. When goal, keep the rows and fields needed for the goal you pass in goal= (plus any that are uncertain, and the first and last), and replace the rest with a stub. data.held_back lists the held ids and a recall id that re-reads the full page from cache at no extra charge. Without this param the page is unchanged.",
            "schema": {
              "type": "string",
              "enum": [
                "goal"
              ]
            }
          },
          {
            "name": "goal",
            "in": "query",
            "required": false,
            "description": "Required by fit=goal. What you are trying to do, in your own words, up to 300 characters.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fit_tokens",
            "in": "query",
            "required": false,
            "description": "Optional, only with fit=goal. Soft cap on how much of the page to keep, in tokens. Uncertain blocks and the first and last block are kept even if they exceed it.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "label",
            "in": "query",
            "required": false,
            "description": "Optional CSV of SocialCrawl labels to add to every post. Without this param every page already carries sponsored, intent and niche, free; label= adds the labels you name to them (the defaults keep running). sponsored, intent and niche are free when asked for too; mention, quality, ai_style, intent with offer=, and injection add 1 credit per started 25 newly judged posts. judgments=off (or label=none) turns the default labels off. sponsored: is the post a paid or gifted promotion (p, 0 to 1), did it carry a disclosure marker such as #ad or 광고 (disclosed), is it likely paid with no marker (undisclosed), and which of the accounts it mentions does it promote (brand, or null). These are signals to review, never a finding. mention (needs brand=): is the post about that brand rather than something that shares its name (about_brand, 0 to 1), how it feels about the brand on five levels (sentiment_level 0 to 4 and sentiment_score 0 to 1, null when the post is not about the brand), is it sarcastic, which aspect it talks about (taste_or_quality, price_or_value, availability_or_delivery, health_or_safety, advertising_or_campaign, customer_service, none), and did the author buy or use it (first_hand). intent: what the author is mainly doing (label: asking_for_recommendation, comparing_options, switching_away, complaining, promoting, news_or_discussion, other, or null when unsure, with confidence), whether they read as a potential buyer rather than a seller (buyer, seller), how pressing the need is (urgency, 0 to 3), and, when you pass offer=, whether your offer would plausibly help them (fits_offer). niche: which of the 33 niches of the published taxonomy sc-niche-v1 the caption belongs to, or personal_no_niche, or other (label, confidence, taxonomy), with label null when the caption is too thin to tell or the pick is unsure. It reads the caption only, not the video. quality: how much checkable detail the caption carries (fact_density 0 to 3), whether it mainly asks for likes, replies, shares, follows or tags (engagement_bait, 0 to 1), whether it is written to provoke anger as a way to get engagement (rage_bait, 0 to 1; about the writing, never the side taken), whether it only repeats someone else's news or view (secondhand, 0 to 1), and what the post is mainly doing (post_aim: inform, opinion, sell, entertain, provoke, other). exclude=engagement_bait drops posts whose engagement_bait is 0.8 or higher. ai_style: writing patterns common in AI-generated text, judged on the text alone. It does not say who wrote the post, and a person who writes in this style is flagged too. Six patterns are judged, each a probability (0 to 1): binary_contrast (\"This is not X. It's Y.\"), faux_insight (\"Here's what nobody tells you\" and throat-clearing openers), colon_reveal (\"The best part: it learns.\"), profound_kicker (ends on an aphorism or mic-drop line), puffery (\"marks a pivotal moment\", \"highlighting the importance of\") and rhetorical_setup (\"What if I told you\", a question the post answers itself, \"Not a X. Not a Y. A Z.\"). Four are counted in the text: slop_words (words and phrases such as delve, leverage, robust, game changer, at the end of the day), em_dashes, emoji_bullets (lines that start with an emoji or a symbol bullet) and one_line_paragraphs (paragraphs that are one short line). pattern_count is how many patterns are present (a judged pattern at 0.8 or higher, slop_words 1 or more, em_dashes 2 or more, emoji_bullets 2 or more, one_line_paragraphs 5 or more) and markers lists their names, comma-separated. A post with less than about eight words of text is only counted, with every judged pattern 0. The judged patterns read the first 400 and the last 150 characters of a long post, and the counts read the whole post. exclude=ai_style drops posts with 2 or more patterns. ai_written: how likely the post was written by an AI model, from SocialCrawl's own text classifier, reading the opening of the post (about 1,000 characters): p (0 to 1, calibrated), level (likely (p 0.95 or higher), possible (p 0.71 or higher) or unlikely) and model (the model name; a new name means a new scale). A post under 8 words is too short to read: p null, level too_short. It is a probability, not proof: a person can be flagged and an AI-written post can pass, and the shorter the post the less certain it is. exclude=ai_written drops likely posts. injection flags text that addresses an AI system and tries to direct it (flagged, p); it never drops or rewrites a row. A post that could not be judged carries labels: null. Posts already labelled for anyone are free, and so is a cached page. data.labels reports what was judged and billed.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exclude",
            "in": "query",
            "required": false,
            "description": "Optional CSV (engagement_bait, ai_style, ai_written). engagement_bait, only with label=quality, drops posts whose engagement_bait probability is 0.8 or higher. ai_style, only with label=ai_style, drops posts that show 2 or more of its writing patterns (pattern_count 2 or higher). ai_written, only with label=ai_written, drops posts whose level is likely (p 0.95 or higher), or whose p reaches your ai_written_threshold; a post too short to read is never dropped. Dropped posts are listed in data.labels.dropped_ids. A post that could not be judged is never dropped.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ai_written_threshold",
            "in": "query",
            "required": false,
            "description": "Optional, only with label=ai_written and exclude=ai_written. The p (0 to 1) at which exclude=ai_written drops a post. Default 0.95 (level likely). 0.71 also drops possible posts: more AI posts go, and more posts by people with them.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "description": "Required by label=mention, ignored otherwise. The brand or product the posts are judged against, up to 300 characters, for example brand=Buldak. Without it label=mention is skipped with the warning label_mention_needs_brand and is not billed.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "brand_description",
            "in": "query",
            "required": false,
            "description": "Optional, with label=mention. One plain sentence saying what the brand is, for example brand_description=Samyang's spicy instant noodle brand. Use it when the name is also an ordinary word or another company's name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offer",
            "in": "query",
            "required": false,
            "description": "Optional, with label=intent. One or two plain sentences saying what you sell, up to 300 characters, for example offer=A web design agency that builds websites for small businesses. Adds fits_offer to every post; without it fits_offer is null.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "label_evidence",
            "in": "query",
            "required": false,
            "description": "Optional, only with label=. When 1, every labelled row also carries computed.labels_evidence.<preset> = { quote, sentence_index }: the sentence in the row that most clearly shows the label, copied verbatim. Absent or null when no single sentence shows it.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          },
          {
            "name": "max_age_s",
            "in": "query",
            "required": false,
            "description": "The oldest cached copy you accept, in seconds. A copy that old or younger is served for 0 credits, with its age in `age_s` and the `X-Cache-Age` header. Without it a copy up to 300 seconds old is served. A lower value fetches fresh (billed) when the copy is older, and 0 always fetches live, like `Cache-Control: no-cache`.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 300
            }
          },
          {
            "name": "Cache-Control",
            "in": "header",
            "required": false,
            "description": "Send `no-cache` to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the `no-cache` directive triggers this. To accept an older cached copy, or to require a younger one, send the `max_age_s` query parameter instead. See the Response Schema guide for details.",
            "schema": {
              "type": "string"
            },
            "example": "no-cache"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives `409 IDEMPOTENCY_IN_PROGRESS` with a `Retry-After` of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: `credits_used` becomes 0, `idempotent_replay` becomes true, and `credits_remaining` is refreshed to the current balance. A known current balance appears in both the body and `X-Credits-Remaining` header; no balance row resolves to 0. On a transient lookup failure, body `credits_remaining` is null and `X-Credits-Remaining` is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use `Accept: application/json` when sending this header. The unsupported key-plus-SSE combination is rejected before billing.",
            "schema": {
              "type": "string"
            },
            "example": "7a5e1b4c-2d8f-4a3b-9c1e-6e8b4d2a1f3c"
          },
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "Send `respond-async` to run this GET in the background instead of waiting on the socket (or add `?async=true` to the query). The answer is 202 with `data.job_id`, a `Location` header and `Retry-After`; read the result free at `GET /v1/prism/jobs/{job_id}`, where `results[0].response` is exactly what this call returns. Nothing is held at submit: the call is validated now and billed as this call when it runs. Use it for calls that can outlast your client's timeout (MCP and many HTTP clients stop at 30 s). `Idempotency-Key` returns the same job on a retry.",
            "schema": {
              "type": "string"
            },
            "example": "respond-async"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-Credits-Used": {
                "description": "Net credits charged for this response. Idempotency replays report 0.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Credits-Remaining": {
                "description": "Current authoritative balance. Free cache hits and idempotency replays omit this header when the balance cannot be determined; body `credits_remaining` is null instead.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Key-Credits-Remaining": {
                "description": "Only when the API key has a credit limit: the credits this key may still spend under that limit, after this call (never below 0). Absent for a key with no limit. `GET /v1/keys/current` has the limit and what is used.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Idempotent-Replay": {
                "description": "Present with value `true` only when this response replays a settled idempotency record.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "Idempotent-Replayed": {
                "description": "Present with value `true` only when this response replays a settled idempotency record. Same meaning as `X-Idempotent-Replay`.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Whether the request succeeded",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "description": "Platform name",
                      "example": "search"
                    },
                    "endpoint": {
                      "type": "string",
                      "description": "API endpoint path",
                      "example": "/v1/search/multi"
                    },
                    "data": {
                      "type": "object",
                      "description": "Platform-specific response data",
                      "properties": {
                        "metrics": {
                          "type": "object",
                          "description": "Key performance metrics",
                          "properties": {
                            "total_views": {
                              "type": "integer",
                              "description": "Total view count"
                            },
                            "total_likes": {
                              "type": "integer",
                              "description": "Total like count"
                            },
                            "total_comments": {
                              "type": "integer",
                              "description": "Total comment count"
                            },
                            "engagement_rate": {
                              "type": "number",
                              "description": "Computed engagement rate (0-1)"
                            }
                          }
                        },
                        "period": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Time period for the analytics data"
                        },
                        "breakdown": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "description": "Per-item or per-period breakdown",
                          "items": {
                            "type": "object",
                            "description": "Breakdown entry"
                          }
                        },
                        "labels": {
                          "type": "object",
                          "description": "Present when the page's rows were put through labelling: the default labels on a list that carries them, and any labels you named with `label=`. Absent with `judgments=off`. Reports what was judged, what is still pending and what it cost.",
                          "properties": {
                            "presets": {
                              "type": "array",
                              "description": "The labels this report covers.",
                              "items": {
                                "type": "string",
                                "description": "A label name.",
                                "example": "sentiment"
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "description": "Rows on the page before any drop.",
                              "example": 50
                            },
                            "labelled": {
                              "type": "integer",
                              "description": "Rows that carry every label this report covers, freshly judged or from the shared store.",
                              "example": 50
                            },
                            "cached": {
                              "type": "integer",
                              "description": "Of `labelled`, rows served entirely from the shared per-row label store.",
                              "example": 0
                            },
                            "skipped": {
                              "type": "integer",
                              "description": "Deleted or empty rows. They are never sent for judging or billed and carry `labels: null`.",
                              "example": 0
                            },
                            "unjudged": {
                              "type": "integer",
                              "description": "Rows that could not be judged this time (a failure, or past the number of rows one call judges). They carry `labels: null` and are never billed.",
                              "example": 0
                            },
                            "dropped": {
                              "type": "integer",
                              "description": "Rows removed by an `exclude=` you asked for. Default labels never drop a row.",
                              "example": 0
                            },
                            "dropped_ids": {
                              "type": "array",
                              "description": "Ids of the rows counted in `dropped`.",
                              "items": {
                                "type": "string",
                                "description": "A row id."
                              }
                            },
                            "extra_credits": {
                              "type": "integer",
                              "description": "Credits the labels added to this call. Always 0 for the default labels.",
                              "example": 0
                            },
                            "methodology_version": {
                              "type": "string",
                              "description": "The version of the label questions, so you can tell when they change.",
                              "example": "labels/1"
                            },
                            "mode": {
                              "type": "string",
                              "enum": [
                                "default",
                                "requested"
                              ],
                              "description": "`default` when you sent no `label=` and the free default labels ran, `requested` when you named labels.",
                              "example": "default"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "complete",
                                "partial",
                                "skipped"
                              ],
                              "description": "`complete`: every judgeable row carries its labels. `partial`: some rows carry `labels: null`, still being judged (see `pending`) or not judged this time. `skipped`: default judging was switched off for this request by a capacity guard, and the page is exactly as it was before labels existed.",
                              "example": "complete"
                            },
                            "pending": {
                              "type": "integer",
                              "description": "Default labels only: rows still being judged when the page was sent. They ship with `labels: null`, keep being judged afterwards, and your next call for the same page carries them.",
                              "example": 0
                            },
                            "pending_ids": {
                              "type": "array",
                              "description": "Ids of the rows counted in `pending`.",
                              "items": {
                                "type": "string",
                                "description": "A row id."
                              }
                            },
                            "cached_page": {
                              "type": "boolean",
                              "description": "Present and true when the whole page came from the response cache, so this call judged nothing and charged nothing.",
                              "example": true
                            },
                            "default": {
                              "type": "object",
                              "description": "Present when you named some labels with `label=`: the report of the default labels you did not name, with its own `mode`, `status`, `pending` and `pending_ids`. Absent when you named every default.",
                              "properties": {
                                "presets": {
                                  "type": "array",
                                  "description": "The labels this report covers.",
                                  "items": {
                                    "type": "string",
                                    "description": "A label name.",
                                    "example": "sentiment"
                                  }
                                },
                                "rows": {
                                  "type": "integer",
                                  "description": "Rows on the page before any drop.",
                                  "example": 50
                                },
                                "labelled": {
                                  "type": "integer",
                                  "description": "Rows that carry every label this report covers, freshly judged or from the shared store.",
                                  "example": 50
                                },
                                "cached": {
                                  "type": "integer",
                                  "description": "Of `labelled`, rows served entirely from the shared per-row label store.",
                                  "example": 0
                                },
                                "skipped": {
                                  "type": "integer",
                                  "description": "Deleted or empty rows. They are never sent for judging or billed and carry `labels: null`.",
                                  "example": 0
                                },
                                "unjudged": {
                                  "type": "integer",
                                  "description": "Rows that could not be judged this time (a failure, or past the number of rows one call judges). They carry `labels: null` and are never billed.",
                                  "example": 0
                                },
                                "dropped": {
                                  "type": "integer",
                                  "description": "Rows removed by an `exclude=` you asked for. Default labels never drop a row.",
                                  "example": 0
                                },
                                "dropped_ids": {
                                  "type": "array",
                                  "description": "Ids of the rows counted in `dropped`.",
                                  "items": {
                                    "type": "string",
                                    "description": "A row id."
                                  }
                                },
                                "extra_credits": {
                                  "type": "integer",
                                  "description": "Credits the labels added to this call. Always 0 for the default labels.",
                                  "example": 0
                                },
                                "methodology_version": {
                                  "type": "string",
                                  "description": "The version of the label questions, so you can tell when they change.",
                                  "example": "labels/1"
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "default",
                                    "requested"
                                  ],
                                  "description": "`default` when you sent no `label=` and the free default labels ran, `requested` when you named labels.",
                                  "example": "default"
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "complete",
                                    "partial",
                                    "skipped"
                                  ],
                                  "description": "`complete`: every judgeable row carries its labels. `partial`: some rows carry `labels: null`, still being judged (see `pending`) or not judged this time. `skipped`: default judging was switched off for this request by a capacity guard, and the page is exactly as it was before labels existed.",
                                  "example": "complete"
                                },
                                "pending": {
                                  "type": "integer",
                                  "description": "Default labels only: rows still being judged when the page was sent. They ship with `labels: null`, keep being judged afterwards, and your next call for the same page carries them.",
                                  "example": 0
                                },
                                "pending_ids": {
                                  "type": "array",
                                  "description": "Ids of the rows counted in `pending`.",
                                  "items": {
                                    "type": "string",
                                    "description": "A row id."
                                  }
                                },
                                "cached_page": {
                                  "type": "boolean",
                                  "description": "Present and true when the whole page came from the response cache, so this call judged nothing and charged nothing.",
                                  "example": true
                                }
                              }
                            }
                          }
                        },
                        "relevance": {
                          "type": "object",
                          "description": "Present on a list that scores its rows against your query: free by default, or when you send `relevance=score` or `relevance=filter`. Absent with `judgments=off`. Reports what was scored, what a `filter` dropped and what it cost.",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "enum": [
                                "score",
                                "filter"
                              ],
                              "description": "`score`: rows carry `computed.relevance` and none is dropped. `filter`: rows judged off topic are also dropped.",
                              "example": "score"
                            },
                            "topic_source": {
                              "type": "string",
                              "enum": [
                                "query",
                                "relevant_to"
                              ],
                              "description": "Where the topic came from: your search query, or the `relevant_to` you sent.",
                              "example": "query"
                            },
                            "origin": {
                              "type": "string",
                              "enum": [
                                "default",
                                "requested"
                              ],
                              "description": "`default` when you sent no `relevance=` (score only, free, never drops or reorders), `requested` when you asked.",
                              "example": "default"
                            },
                            "rows": {
                              "type": "integer",
                              "description": "Rows on the page before any drop.",
                              "example": 30
                            },
                            "scored": {
                              "type": "integer",
                              "description": "Rows that carry a relevance value, freshly judged or from the shared store.",
                              "example": 30
                            },
                            "cached": {
                              "type": "integer",
                              "description": "Of `scored`, rows served from the shared store.",
                              "example": 0
                            },
                            "kept": {
                              "type": "integer",
                              "description": "Rows left on the page.",
                              "example": 30
                            },
                            "dropped": {
                              "type": "integer",
                              "description": "Rows removed by `relevance=filter`.",
                              "example": 0
                            },
                            "dropped_ids": {
                              "type": "array",
                              "description": "Ids of the rows counted in `dropped`.",
                              "items": {
                                "type": "string",
                                "description": "A row id."
                              }
                            },
                            "unjudged": {
                              "type": "integer",
                              "description": "Rows the judgment could not answer for this time. They are kept and carry `relevance: null`.",
                              "example": 0
                            },
                            "too_short": {
                              "type": "integer",
                              "description": "Rows with too little text to judge. They are kept.",
                              "example": 0
                            },
                            "threshold": {
                              "type": "number",
                              "description": "The probability a row needs to be kept by `relevance=filter`: 0.5, or the `relevance_threshold` you sent.",
                              "example": 0.5
                            },
                            "extra_credits": {
                              "type": "integer",
                              "description": "Credits the judgment added to this call. 0 with your query as the topic.",
                              "example": 0
                            },
                            "methodology_version": {
                              "type": "string",
                              "description": "The version of the relevance questions.",
                              "example": "relevance/2"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "complete",
                                "partial",
                                "skipped"
                              ],
                              "description": "`complete`: every row was scored. `partial`: some rows carry `relevance: null`. `skipped`: default scoring was switched off by a capacity guard.",
                              "example": "complete"
                            },
                            "pending": {
                              "type": "integer",
                              "description": "Rows still being judged when the page was sent.",
                              "example": 0
                            },
                            "pending_ids": {
                              "type": "array",
                              "description": "Ids of the rows counted in `pending`.",
                              "items": {
                                "type": "string",
                                "description": "A row id."
                              }
                            },
                            "cached_page": {
                              "type": "boolean",
                              "description": "Present and true when the whole page came from the response cache, so nothing was judged or charged."
                            },
                            "unjudged_dropped": {
                              "type": "object",
                              "description": "Present on a merged multi-platform search under `relevance=filter`: rows dropped because they could not be judged in time, counted per platform."
                            },
                            "context_hash": {
                              "type": "string",
                              "description": "Present on a leg of a merged multi-platform search: a hash of the topic judged."
                            },
                            "fresh_ids": {
                              "type": "array",
                              "description": "Present on a leg of a merged multi-platform search: the rows judged afresh on this leg.",
                              "items": {
                                "type": "string",
                                "description": "A row id."
                              }
                            }
                          }
                        },
                        "estimate": {
                          "type": "object",
                          "description": "Present only on a dry run (`dry_run=1`). A dry run charges 0 credits, fetches nothing and returns `data.valid`, `data.normalized_params` and this `estimate` in place of the usual rows. An invalid request is the normal free 400 instead.",
                          "properties": {
                            "kind": {
                              "type": "string",
                              "description": "Always `estimate`.",
                              "example": "estimate"
                            },
                            "version": {
                              "type": "integer",
                              "description": "The version of this estimate shape.",
                              "example": 1
                            },
                            "id": {
                              "type": "string",
                              "description": "The endpoint, as `platform/resource`."
                            },
                            "method": {
                              "type": "string",
                              "description": "The HTTP method.",
                              "example": "GET"
                            },
                            "valid": {
                              "type": "boolean",
                              "description": "True when the request would pass every check made before billing.",
                              "example": true
                            },
                            "hold": {
                              "type": "integer",
                              "description": "Exactly what the router would deduct up front for this request."
                            },
                            "expected_min": {
                              "type": "integer",
                              "description": "The least a successful call settles at."
                            },
                            "expected_max": {
                              "type": "integer",
                              "description": "The most a call can settle at. Unused hold is refunded."
                            },
                            "unit": {
                              "type": "string",
                              "description": "Always `credits`.",
                              "example": "credits"
                            },
                            "pricing": {
                              "type": "string",
                              "enum": [
                                "flat",
                                "metered"
                              ],
                              "description": "`flat`: the same price every call. `metered`: the price depends on the work done, and unused hold is refunded.",
                              "example": "flat"
                            },
                            "formula": {
                              "type": "string",
                              "description": "How the price is worked out, in words."
                            },
                            "levers": {
                              "type": "array",
                              "description": "Params that change the price, each with the hold for the same request with that one change.",
                              "items": {
                                "type": "object",
                                "description": "One lever.",
                                "properties": {
                                  "param": {
                                    "type": "string",
                                    "description": "The param to change."
                                  },
                                  "hold": {
                                    "type": "integer",
                                    "description": "The hold for the same request with this one change."
                                  },
                                  "effect": {
                                    "type": "string",
                                    "description": "What the change does."
                                  }
                                }
                              }
                            },
                            "cached_likely": {
                              "type": "boolean",
                              "description": "Always false: a dry run does not read the cache.",
                              "example": false
                            },
                            "normalized_params": {
                              "type": "object",
                              "description": "The params the router prices, after its own normalisation."
                            },
                            "notes": {
                              "type": "array",
                              "description": "Plain-English notes about this quote.",
                              "items": {
                                "type": "string",
                                "description": "One note."
                              }
                            },
                            "warnings": {
                              "type": "array",
                              "description": "Notices about the quote, such as a page count that had to be assumed.",
                              "items": {
                                "type": "string",
                                "description": "One notice."
                              }
                            },
                            "rows_expected": {
                              "type": "integer",
                              "description": "Judged lists only: the most rows one call judges on this endpoint."
                            },
                            "rows_cached": {
                              "type": "integer",
                              "description": "Judged lists only: rows already judged and free. 0 on a dry run, which sees no rows."
                            },
                            "label_credits_min": {
                              "type": "integer",
                              "description": "Judged lists only: the least the paid labels add. 0 on a dry run, which sees no rows."
                            },
                            "label_credits_max": {
                              "type": "integer",
                              "description": "Judged lists only: the most the paid labels can add. 0 when you asked for no paid label."
                            },
                            "base_credits": {
                              "type": "integer",
                              "description": "Judged lists only: the call's price without the label and relevance holds."
                            }
                          }
                        },
                        "held_back": {
                          "type": "object",
                          "description": "Present when you sent `fit=goal` with a `goal` and at least one block of the page was not needed for it. The held rows (or fields) stay in place as stubs of `{ id, held: true }`; this block lists them.",
                          "properties": {
                            "ids": {
                              "type": "array",
                              "description": "Ids of the rows or fields that were held back.",
                              "items": {
                                "type": "string",
                                "description": "A row id."
                              }
                            },
                            "recall": {
                              "type": "string",
                              "description": "A recall id for the full page, which re-reads it from cache at no extra charge.",
                              "example": "fit_3f9a1c0b7d2e4a58"
                            }
                          }
                        },
                        "_warnings": {
                          "type": "array",
                          "description": "Non-fatal notices about this response (field-map drift, clamped computed values). Advisory only: its presence never means the request failed. Omitted entirely when there is nothing to report, so treat absent as 'no warnings'.",
                          "items": {
                            "type": "string",
                            "description": "One advisory notice."
                          }
                        }
                      }
                    },
                    "credits_used": {
                      "type": "integer",
                      "description": "Number of credits consumed",
                      "example": 1
                    },
                    "credits_remaining": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.",
                      "example": 4999
                    },
                    "credits_remaining_note": {
                      "type": "string",
                      "description": "Present only when `credits_remaining` is null by design, as on a free cache hit: says why the balance was not read and where to read it.",
                      "example": "not read on cache hits (credits_used is 0); call GET /v1/credits/balance for the current balance"
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Unique request identifier for support",
                      "example": "req-abc123"
                    },
                    "cached": {
                      "type": "boolean",
                      "description": "Whether the response was served from cache",
                      "example": false
                    },
                    "age_s": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Present only on a cache hit (`cached: true`): whole seconds since this copy was fetched, also sent as the `X-Cache-Age` header. Null for a copy stored before ages were recorded. Send `max_age_s` to set how old a copy you accept: a profile or post copy up to an hour old is served for 0 credits, and a lower value fetches fresh.",
                      "example": 340
                    },
                    "idempotent_replay": {
                      "type": "boolean",
                      "description": "True only when this response is an idempotency replay",
                      "example": true
                    },
                    "meta": {
                      "type": "object",
                      "description": "Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.",
                      "properties": {
                        "hint": {
                          "type": "object",
                          "description": "One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat | batch_comments | batch_jobs",
                              "example": "search_multi"
                            },
                            "message": {
                              "type": "string",
                              "description": "One sentence for a person or an agent to read.",
                              "example": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged."
                            },
                            "method": {
                              "type": "string",
                              "description": "GET or POST.",
                              "example": "GET"
                            },
                            "path": {
                              "type": "string",
                              "description": "The call the hint points to.",
                              "example": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "platform",
                    "endpoint",
                    "data",
                    "credits_used",
                    "credits_remaining",
                    "request_id",
                    "cached"
                  ]
                },
                "example": {
                  "success": true,
                  "platform": "search",
                  "endpoint": "/v1/search/multi",
                  "data": {
                    "query": "matcha latte",
                    "platforms": [
                      "tiktok",
                      "instagram"
                    ],
                    "since": "2026-09-01",
                    "sources": {
                      "tiktok": {
                        "endpoint": "/v1/tiktok/search",
                        "status": "ok",
                        "http_status": 200,
                        "rows": 30,
                        "rows_kept": 30,
                        "credits": 1,
                        "next_cursor": "sc.eyJ2IjoyLCJjIjoic2MyLmV5SnpJam9pYUNJc0ltTWlPaUp6WXpFdVpYbEtha2xxYjJsTmVrRnBURU5LZWtscWNHSkphbU15VDBSck1rMVVRWGxPVkVVeFRrUlJNRTE2UlRSUFZGRnBURU5KTTA1cWEzaE9SRTB4VFhwSk1VMUVVWGhPZW1ONlQwUk5ORWxwZDJsT2VsazFUVlJuZDA5VVdYaFBSR2Q1VGxSQk5FOUVTVFJPYVVselNXcGpNazlVUlRKTlZFMDBUa1JSTTA1NlVYcE9WR2Q2VFVSTmFVeERTVE5PYW10NFQwUkJNazFxUVhsTmFsRXhUbnBKTlU1VVVUVkphWGRwVG5wWk5VMVVaM2RPYWxGNFRrUlpNVTE2V1RSUFZFVjNUME5KYzBscVl6SlBWRVV6VDFSamVFNUVUWGhPZWxGM1RucE5NazFFVFdsTVEwa3pUbXByZUU5RVJUTk9SR3QzVGtSSmVVMTZTWGROZW1zelNXbDNhVTU2V1RWTmFrRjRUVlJyTVUxRVdUQlBWRVY0VG5wck5FNURTWE5KYW1NeVQwUm5NRTVxWnpOTlZGRjRUMVJSZVU1NlZUSk5WRkZwVEVOSk0wNXFhM2hQUkd0NlRrUnJNazlFWnpWT2VsVXlUMVJWTkVscGQybE9lbGsxVFZSbk5FNTZSWGxPUkdkM1RtcGplazE2UVRST2FVbHpTV3BqTWs5VVJUVlBSRTE1VGxSWmQwOVVRWGRQUkZreVRsUm5hVXhEU1ROT2FtYzFUa1JqTkUxRVRUUlBSRmsxVDBSTk5VMVVUVEZKYVhkcFRucFpOVTFVWjNsTlJFa3lUbFJKTWs5RWEzZE9la2swVFdsSmMwbHFZekpQVkVVd1RucEZOVTFFVlhsUFJGa3hUMFJyTTAxRWEybE1RMGt6VG1wcmVFOVVaelZPVkdzMFRYcE5kMDU2WnpGTlJGRjVTV2wzYVU1NldUVk5WR015VFhwTmQwMTZhek5OZW1zMFRWUlJNMDFUU1hOSmFtTXlUMVJGTlU1cWF6Tk9lbGsxVG1wQmVVNXFSWHBQVkZscFRFTkpNMDVxYTNkTmFrRXlUa1JSTlU1RVkzcE5SRTE0VGtSTk0wbHBkMmxPZWxrMVRWUmpNRTFVV1hoUFJFazFUa1JCTWs1cVVUSk5hVWx6U1dwak1rOVVSVFJPYWxFd1RrUlJkMDE2U1hsUFZFRjNUbXBGYVV4RFNUTk9hbXQzVGtSRk1FOVVaekJPZWswMVQwUk5NVTFVVVRWSmFYZHBUbnBaTlUxcVFYcE5SRWwzVFdwRmVrMTZZM2hOYWtVeFRVTkpjMGxxWXpKUFZFVTFUWHBqZWs1NlJYbE9hbEY0VFdwWmVVMXFSV2xNUTBrelRtcHJlRTlFVFhkTmVsVXpUMFJCZDAxNlNUQk5lbGt4U1dsM2FVNTZXVFZOVkdkNFRWUm5OVTFxWXpKT2VrRXhUVlJCZWs5RFNYTkphbU15VDFSRk1VMUVRVEJQVkZVeVRYcG5lRTVVVVRGTlZGRnBURU5KTTA1cWEzbE5SRWw0VFhwamVrNTZSWGRQVkVWNVRucHJkMGxwZDJsT2VsazFUVlJuTWs1RVNYZE9lbGsxVGxSbk0wNVVUWHBPUTBwa1psRWlmUSIsImUiOiJ0aWt0b2svc2VhcmNoIiwicCI6ImN1cnNvciJ9",
                        "has_more": true,
                        "request_id": "req-NYkUiAP5oZcUvguR",
                        "warnings": []
                      },
                      "instagram": {
                        "endpoint": "/v1/instagram/search/reels",
                        "status": "ok",
                        "http_status": 200,
                        "rows": 30,
                        "rows_kept": 30,
                        "credits": 1,
                        "next_cursor": "sc.eyJ2IjoyLCJjIjoic2MxLmV5SmpJam9pTWlJc0ltc2lPaUl4Ym5SNVpXeHZNVFZ0TlRFek5qQmxPWEF6ZEdZeGNHaGljRzA1TURJMWRtSmphREUyTjJkcFpUZ3dNRGh5TW5abE1XeGtPR05pT0RCdVlXTnRPV3N3ZFRadFoyTnZNVGxxTjJoaU56RjVabTl5TW5Nd1kzZHdOVzQyTUhsdGJUaHZOekZzYjJONmJ6Y3diemQ1YVd0eU1YTmlOWGt3Y1RBd2FtWm9iemN4YjJzM01XVnhNV1Z2TmpremF6RTFkR05zYUhreGMzQnFhWGQ1TUhGMFkza3pPREZwTVROeloyNHdOR0Z4ZG5WMU1XSjRaV0ZqTXpBeU9EbDZhbmN4YVRWd2J6WjNNSGN3TVhFMGREQndkbWxuT1cwaWZRIiwiZSI6Imluc3RhZ3JhbS9zZWFyY2gvcmVlbHMiLCJwIjoicGFnZSIsInMiOiJpIn0",
                        "has_more": true,
                        "request_id": "user_a1936a",
                        "warnings": []
                      },
                      "youtube": {
                        "endpoint": "/v1/youtube/search",
                        "status": "ok",
                        "http_status": 200,
                        "rows": 35,
                        "rows_kept": 10,
                        "credits": 1,
                        "next_cursor": "sc.eyJ2IjoyLCJjIjoic2MxLmV5SmpJam9pUlc5elFrVm5lSFJaV0ZKcVlVZEZaMkpIUmpCa1IxVmhaVVpPUTFVd1RrSlZXRkpZVkcxd1QyRnNSbGxoU0VaVVZrWktjbFZzYkVwUmEwMTZZVWQ0YTFORlduQlZWRVpIVFRBNVdXTkljRzVhTUZaTlZsWmtNR05YVm5KUFZrWllWa1ZLYzFVd1VsUlJNRVpTWkVaa1dXVlVSbkZYYkdNMVRXeFNWbFpzVmxOWFZXeERVa1phUzFKV1duRlhXSEJhVFVWWk1GbFhkSEpOUm5CR1ZqTnNRbFZXYkV4UmEwWnVVMnRXUWxSSVJrSlZWa1pLVVZkb1FsZHhRVU5DUW1sQ05FOW5XVWxuZEhwYVYwWjVXVEpuZEZwdFZteGFRU1V6UkNVelJDSXNJbk1pT2xzaVZqWXpZMEY0YWtrMFpFVWlMQ0o0WlhSeFlrTlJkemw2Y3lJc0lsRnJhbnBQVUZrd1pVZzBJaXdpVmw4dFkyVnZkazFGVkVVaUxDSk5la2xsYmpabVUxRjNRU0lzSWxoTVoyZEZSVUpwZUZCVklpd2lURU5HTVRCWFgzUjFhV2NpTENKNFRrVkhjems0UjFCV1RTSXNJblk1UzBaWVMycHhhR2RaSWl3aVFWVmhTbEpYVnkxMk5UQWlMQ0k1VmpjeE5GWlBTak5PV1NJc0lsQnBSa0U0WjBjd1psWmpJaXdpVlRreVRWQm5YM0JqWVZraUxDSldjR1JNTmw5RGRGVkVRU0lzSWt3NGRuZGpZMU5UYW1kaklpd2lNVlp4V0hOSWNERmlWRGdpTENJMk1Xd3dMVUZ0WkRkclRTSXNJa2RVYm1KbmNWSkJRVGxKSWl3aVJrNHRaelJNYzJWUmFrRWlMQ0o0ZFhWM1MwSlZWVVpGYXlJc0lsSnpSVzFuZEhSUVl6SmpJaXdpWW1KcVJGRm9TM0JKZW5jaUxDSjZNWFU1VFZZMlpXZFpRU0lzSWpCRVVFNTNVa2h0U2sxQklpd2lZMkpDT1ZSNmRGaElSREFpTENJMlV6azNNWGxWUW5ST1l5SXNJakI2T1hvMU1IWnlWMmRGSWl3aVZWWm9NMmhPTFhSM0xWa2lMQ0pSVlVSUVRuVXpTRlZIYXlJc0lrWXhVRWxoTVVkdFZtNVpJaXdpTVZGQlptRk9XRW90VUc4aUxDSmplVkZ0TkY5WFEzUXdZeUlzSWswM1psTmtZbmhVVjJacklpd2lkRzFRYTJSRlUyWjNTa1VpTENKNk1ITXlXVmhFUkhZelRTSmRmUSIsImUiOiJ5b3V0dWJlL3NlYXJjaCIsInAiOiJjb250aW51YXRpb25Ub2tlbiJ9",
                        "has_more": true,
                        "request_id": "req-MucMX1cKwtm6CKc5",
                        "warnings": []
                      }
                    },
                    "methodology_version": "search-multi/1.0",
                    "search_status": "complete",
                    "items": [
                      {
                        "platform": "tiktok",
                        "post": {
                          "id": "7689610251544431894",
                          "url": "https://www.tiktok.com/@user_6f3010/video/7689610251544431894",
                          "content": {
                            "text": "Sample comment text (redacted).",
                            "media_urls": "https://v16m.tiktokcdn-us.com/d8a85367f29323ee0eee2a18b7a97a99/6abffcac/video/tos/no1a/tos-no1a-ve-0068-no/ooALUIfDqWOH9IVEAGGzlQc2LgSQQIeGfRrWte/?a=1233&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&&bt=1173&ft=BIcq8V~3wUxl7K2gUtIvk84jWLpir61.QjKJd15hgG0P3-I&mime_type=video_mp4&rc=ZWk8NmY4NThmaTk5ODs5ZkBpajU2dGs5cmxpZDMzbzczNUA1NTUzY2JjX2ExYy0xMTEwYSM0XmovMmRraG9hLS1kMTFzcw%3D%3D&vvpl=1&l=20261002124836D0E7AAEDC1B9D7C2FA3D&btag=e000c8000",
                            "thumbnail_url": "https://p19-common-sign.tiktokcdn-us.com/tos-no1a-p-0037-no/oE3RUVL2IIGrVECASeIAerIWqtQlGRDWQN9feG~tplv-tiktokx-cropcenter:500:800.jpeg?biz_tag=musically_video.video_cover&dr=9638&idc=useast5&ps=13740610&refresh_token=c0f05148&shcp=9b759fb9&shp=c1333099&t=4d5b0474&x-expires=1790964000&x-signature=Li0Bg9IAbu6HKLacOQdWKUpSrQw%3D",
                            "duration_seconds": 39.2
                          },
                          "author": {
                            "username": "user_6f3010",
                            "display_name": "user_6f3010",
                            "avatar_url": "https://example.com/avatars/user_358d85.png",
                            "verified": false
                          },
                          "engagement": {
                            "views": 376020,
                            "likes": 40156,
                            "comments": 82,
                            "shares": 2065,
                            "saves": 11178
                          },
                          "flags": {
                            "nsfw": null,
                            "spoiler": null,
                            "pinned": false,
                            "deleted": false
                          },
                          "published_at": "2026-09-25T22:55:22.000Z",
                          "ext": {
                            "music_id": "7369368914394056720",
                            "author_id": "user_92ee5c",
                            "author_followers": 4213,
                            "download_count": 245,
                            "region": "GB",
                            "published_at_epoch": 1790376922
                          }
                        },
                        "computed": {
                          "engagement_rate": 0.112502,
                          "language": "en",
                          "content_category": "other",
                          "estimated_reach": 451224,
                          "relevance": {
                            "p": 0.55,
                            "sense": "target",
                            "depth": 2.11,
                            "spam": 0.27
                          },
                          "labels": {
                            "sponsored": {
                              "p": 0.05,
                              "disclosed": false,
                              "undisclosed": false,
                              "brand": null
                            },
                            "intent": {
                              "label": "news_or_discussion",
                              "confidence": 0.71,
                              "buyer": false,
                              "seller": 0.17,
                              "fits_offer": null,
                              "urgency": 0.01
                            },
                            "niche": {
                              "label": "food_cooking",
                              "confidence": 0.95,
                              "taxonomy": "sc-niche-v1"
                            }
                          }
                        }
                      },
                      {
                        "platform": "tiktok",
                        "post": {
                          "id": "7691435325041773838",
                          "url": "https://www.tiktok.com/@user_86c45b/video/7691435325041773838",
                          "content": {
                            "text": "Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted). Sample comment text (redacted).",
                            "media_urls": "https://v16m.tiktokcdn-us.com/bd2936538782e9aea9fece68ae47283c/6abffccf/video/tos/useast5/tos-useast5-ve-0068c003-tx/o8be6A5mXSg95EIqVvFfDBgjl7zCciQERTDtEq/?a=1233&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&&bt=1053&ft=BIcq8V~3wUxl7K2gUtIvk84jWLpir61.QjKJd15hgG0P3-I&mime_type=video_mp4&rc=ZzgzZWVoOTczZjM8aDw3NEBpamxtNnA5cmRxZDMzZzczNEBhMzAwXmFjNl4xNWEzLTRhYSNsbWNlMmRrYnJhLS1kMS9zcw%3D%3D&vvpl=1&l=20261002124836D0E7AAEDC1B9D7C2FA3D&btag=e00090000",
                            "thumbnail_url": "https://p19-common-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/oYgGqeFaczVuRFEIre5OezFAIrIu1LRQ3AeLG3~tplv-tiktokx-cropcenter:500:800.jpeg?biz_tag=musically_video.video_cover&dr=9638&idc=useast5&ps=13740610&refresh_token=d61c701f&shcp=9b759fb9&shp=c1333099&t=4d5b0474&x-expires=1790964000&x-signature=1odM1%2FZJT69VooNGEf%2BUjBy7H88%3D",
                            "duration_seconds": 74
                          },
                          "author": {
                            "username": "user_86c45b",
                            "display_name": "user_8df0f8",
                            "avatar_url": "https://example.com/avatars/user_4a20ab.png",
                            "verified": true
                          },
                          "engagement": {
                            "views": 1633375,
                            "likes": 160113,
                            "comments": 923,
                            "shares": 7309,
                            "saves": 14030
                          },
                          "flags": {
                            "nsfw": null,
                            "spoiler": null,
                            "pinned": false,
                            "deleted": false
                          },
                          "published_at": "2026-09-30T20:57:31.000Z",
                          "ext": {
                            "music_id": "7691435337419098894",
                            "author_id": "user_b73841",
                            "author_followers": 17733411,
                            "download_count": 285,
                            "region": "US",
                            "published_at_epoch": 1790801851
                          }
                        },
                        "computed": {
                          "engagement_rate": 0.103066,
                          "language": null,
                          "content_category": "other",
                          "estimated_reach": 1960050,
                          "relevance": {
                            "p": 0.85,
                            "sense": "target",
                            "depth": 2.71,
                            "spam": 0.16
                          },
                          "labels": null
                        }
                      }
                    ],
                    "total": 70,
                    "duplicates_removed": 0,
                    "credits_charged": 3,
                    "relevance": {
                      "mode": "score",
                      "topic_source": "query",
                      "rows": 70,
                      "scored": 48,
                      "cached": 12,
                      "kept": 70,
                      "dropped": 0,
                      "dropped_ids": [],
                      "unjudged": 0,
                      "too_short": 1,
                      "threshold": 0.5,
                      "extra_credits": 0,
                      "methodology_version": "relevance/2",
                      "origin": "default",
                      "pending": 21,
                      "pending_ids": [
                        "3998326576725417611",
                        "3995380615447696723"
                      ],
                      "status": "partial"
                    },
                    "labels": {
                      "presets": [
                        "sponsored",
                        "intent"
                      ],
                      "rows": 70,
                      "labelled": 12,
                      "cached": 12,
                      "skipped": 0,
                      "unjudged": 10,
                      "dropped": 0,
                      "dropped_ids": [],
                      "extra_credits": 0,
                      "methodology_version": "labels/1",
                      "mode": "default",
                      "status": "partial",
                      "pending": 48,
                      "pending_ids": [
                        "7691435325041773838",
                        "7691809618825088286"
                      ]
                    },
                    "dropped": 0
                  },
                  "credits_used": 3,
                  "request_id": "req_example000000",
                  "cached": false,
                  "pagination": {
                    "next_cursor": null,
                    "has_more": false,
                    "page_size": 70
                  },
                  "credits_remaining": 9999
                }
              }
            }
          },
          "400": {
            "description": "Invalid request - missing or malformed parameters",
            "x-error-codes": [
              "INVALID_REQUEST",
              "COHORT_MEMBER_LIMIT_EXCEEDED",
              "COHORT_LIMIT_EXCEEDED",
              "COHORT_IDENTITY_PLATFORM_UNSUPPORTED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INVALID_REQUEST",
                    "message": "Invalid request - missing or malformed parameters",
                    "status": 400,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid API key",
            "x-error-codes": [
              "MISSING_API_KEY",
              "INVALID_API_KEY"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "MISSING_API_KEY",
                    "message": "Unauthorized - missing or invalid API key",
                    "status": 401,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "402": {
            "description": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
            "x-error-codes": [
              "INSUFFICIENT_CREDITS",
              "KEY_BUDGET_EXCEEDED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INSUFFICIENT_CREDITS",
                    "message": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
                    "status": 402,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "404": {
            "description": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
            "x-error-codes": [
              "ENDPOINT_NOT_FOUND",
              "RESOURCE_NOT_FOUND",
              "RUN_NOT_FOUND",
              "SCHEDULE_NOT_FOUND",
              "STREAM_NOT_FOUND"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "ENDPOINT_NOT_FOUND",
                    "message": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
                    "status": 404,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed - wrong HTTP verb for this endpoint",
            "x-error-codes": [
              "METHOD_NOT_ALLOWED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "METHOD_NOT_ALLOWED",
                    "message": "Method not allowed - wrong HTTP verb for this endpoint",
                    "status": 405,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_CONFLICT",
              "IDEMPOTENCY_IN_PROGRESS",
              "IDEMPOTENCY_REPLAY_UNAVAILABLE",
              "COHORT_IDENTITY_CONFLICT",
              "COHORT_QUERY_NOT_CANCELLABLE",
              "COHORT_QUERY_NOT_READY",
              "RUN_STATE_CONFLICT",
              "STREAM_STATE_CONFLICT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_CONFLICT",
                    "message": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
                    "status": 409,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "410": {
            "description": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
            "x-error-codes": [
              "RUN_EXPIRED",
              "CURSOR_EXPIRED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RUN_EXPIRED",
                    "message": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
                    "status": 410,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
            "x-error-codes": [
              "PAYLOAD_TOO_LARGE",
              "COHORT_RESULT_TOO_LARGE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "PAYLOAD_TOO_LARGE",
                    "message": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
                    "status": 413,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
              "NEEDS_ASYNC"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
                    "message": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
                    "status": 422,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
            "x-error-codes": [
              "RATE_LIMITED",
              "CONCURRENCY_LIMIT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RATE_LIMITED",
                    "message": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
                    "status": 429,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
            "x-error-codes": [
              "INTERNAL_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INTERNAL_ERROR",
                    "message": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
                    "status": 500,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "502": {
            "description": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 502,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "SERVICE_UNAVAILABLE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 503,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "504": {
            "description": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
                    "status": 504,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          }
        }
      }
    },
    "/search/news": {
      "get": {
        "summary": "Planned multi-country news search: one query, localized and fanned out across two independent news indexes in a single call.",
        "description": "Plans your query into search angles, localizes each angle into the language of every requested country edition (one combined LLM call, fail-open), then fans out up to 12 parallel legs per engine and merges the articles into one deduplicated list. Two independent news indexes are available through `engines`: `google` (the default, 50 country editions) and `bing` (49 of those editions). They overlap very little in practice, so asking for both roughly doubles the distinct articles a query returns and is the way to get a text snippet on most rows: the google engine returns headline, publisher, link, image and an exact publish time but rarely a snippet, while the bing engine returns a description on effectively every row. Every article carries `engine` provenance and a `published_at_precision` of `exact` or `approximate`, because the two indexes do not report publish times with the same fidelity. Every leg reports truthful localization provenance: `query_source` says whether its keyword was `translated`, confirmed `original`, or a `fallback_original` after a localization failure. Supports streaming via `Accept: text/event-stream` (the `plan_refined` chunk always carries the expanded legs with per-leg provenance before any leg settles) and sync via `Accept: application/json`. Filters: `publisher` and `from`/`to` exact date windows (google engine only; they pin its legs to the primary source), `time_range` recency, `depth` per-leg article depth, `sort` result ordering, `max_legs` cost cap. Billing is metered and settles down to the work actually done; empty, skipped and failed legs bill 0.",
        "tags": [
          "search"
        ],
        "operationId": "get_search_news",
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-credit-tier": "standard",
        "x-credit-cost": 2,
        "x-credit-cost-min": 2,
        "x-credit-cost-max": 62,
        "x-credit-cost-formula": "2 credits + 1 credit per google leg that returns at least one article (upfront hold 2 + min(5 x countries, max_legs, 12), maximum 14 on the default engine). Adding the bing engine adds 1 credit per 5 articles it returns, because that engine is priced per article rather than per call; the absolute ceiling with both engines is 62. The hold always settles down to the actual charge, and empty, skipped or failed legs bill 0.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "News topic or question (1-500 chars). Boolean AND/OR/NOT and quoted phrases are supported; Google advanced operators (site:, intitle:, before:) are rejected.",
            "schema": {
              "type": "string"
            },
            "example": "samsung galaxy launch"
          },
          {
            "name": "countries",
            "in": "query",
            "required": false,
            "description": "CSV of ISO 3166-1 alpha-2 country codes to search (1-12 of the 50 supported editions, default US). Each country searches its news edition in its default language; duplicates collapse.",
            "schema": {
              "type": "string"
            },
            "example": "KR,US,JP"
          },
          {
            "name": "engines",
            "in": "query",
            "required": false,
            "description": "CSV of news indexes to search: google (default) and bing. Asking for both runs the same plan on each and merges the results, which roughly doubles distinct articles and adds a snippet to most rows. The bing engine serves 49 of the 50 editions (not CN) and is priced per article; `publisher` and `from`/`to` are google-only.",
            "schema": {
              "type": "string"
            },
            "example": "google,bing"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Ordering of the merged articles: relevance (default, each engine's own ranking) or date (newest first, undated articles last).",
            "schema": {
              "type": "string",
              "enum": [
                "relevance",
                "date"
              ]
            },
            "example": "date"
          },
          {
            "name": "time_range",
            "in": "query",
            "required": false,
            "description": "Recency window (day | week | month | year, default day). Ignored when from/to is present.",
            "schema": {
              "type": "string",
              "enum": [
                "day",
                "week",
                "month",
                "year"
              ]
            },
            "example": "week"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Lower publish-date bound, YYYY-MM-DD or Unix seconds. Pins every leg to the primary news source.",
            "schema": {
              "type": "string"
            },
            "example": "2026-07-01"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Upper publish-date bound, YYYY-MM-DD or Unix seconds. Pins every leg to the primary news source.",
            "schema": {
              "type": "string"
            },
            "example": "2026-07-31"
          },
          {
            "name": "publisher",
            "in": "query",
            "required": false,
            "description": "Bare publisher domain filter (e.g. bbc.com; no scheme or path). Pins every leg to the primary news source.",
            "schema": {
              "type": "string"
            },
            "example": "bbc.com"
          },
          {
            "name": "depth",
            "in": "query",
            "required": false,
            "description": "Articles requested per leg (10-100 in steps of 10, default 10). The google engine is priced per call, so depth is free there; the bing engine is priced per article and caps its own legs at 20.",
            "schema": {
              "type": "integer",
              "minimum": 10,
              "maximum": 100
            },
            "example": 10
          },
          {
            "name": "max_legs",
            "in": "query",
            "required": false,
            "description": "Hard cap on billable legs (1-12, default 12). The upfront hold shrinks with it.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            },
            "example": 4
          },
          {
            "name": "group",
            "in": "query",
            "required": false,
            "description": "Optional. stories groups the articles that report the same event across editions, outlets and languages into data.stories[] ({ id, head_id, member_ids, size, outlets, outlet_count, countries, languages, first_seen, last_seen, judged }), where every id is an article's canonical_url (or url). items[] and its order are unchanged. data.story_grouping reports how many articles were judged and what it cost. An article that could not be judged is its own story with judged: false; if grouping is unavailable, stories is null and data._warnings says stories_unavailable. JSON responses only (ignored on the event stream). Grouping is on by default now (see judgments); group=stories asks for it explicitly with a longer time budget. Free.",
            "schema": {
              "type": "string",
              "enum": [
                "stories"
              ]
            }
          },
          {
            "name": "judgments",
            "in": "query",
            "required": false,
            "description": "Optional. on (default) or off. On, JSON responses also carry data.stories and data.story_grouping (see group), grouped under a short time budget; when grouping does not finish in time, stories is null and data._warnings says stories_pending (stories_unavailable when it failed). items[], their order and the price are unchanged. off returns the response without them.",
            "schema": {
              "type": "string",
              "enum": [
                "on",
                "off"
              ]
            }
          },
          {
            "name": "max_age_s",
            "in": "query",
            "required": false,
            "description": "The oldest cached copy you accept, in seconds. A copy that old or younger is served for 0 credits, with its age in `age_s` and the `X-Cache-Age` header. Without it a copy up to 300 seconds old is served. A lower value fetches fresh (billed) when the copy is older, and 0 always fetches live, like `Cache-Control: no-cache`.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 300
            }
          },
          {
            "name": "Cache-Control",
            "in": "header",
            "required": false,
            "description": "Send `no-cache` to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the `no-cache` directive triggers this. To accept an older cached copy, or to require a younger one, send the `max_age_s` query parameter instead. See the Response Schema guide for details.",
            "schema": {
              "type": "string"
            },
            "example": "no-cache"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives `409 IDEMPOTENCY_IN_PROGRESS` with a `Retry-After` of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: `credits_used` becomes 0, `idempotent_replay` becomes true, and `credits_remaining` is refreshed to the current balance. A known current balance appears in both the body and `X-Credits-Remaining` header; no balance row resolves to 0. On a transient lookup failure, body `credits_remaining` is null and `X-Credits-Remaining` is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use `Accept: application/json` when sending this header. The unsupported key-plus-SSE combination is rejected before billing.",
            "schema": {
              "type": "string"
            },
            "example": "7a5e1b4c-2d8f-4a3b-9c1e-6e8b4d2a1f3c"
          },
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "Send `respond-async` to run this GET in the background instead of waiting on the socket (or add `?async=true` to the query). The answer is 202 with `data.job_id`, a `Location` header and `Retry-After`; read the result free at `GET /v1/prism/jobs/{job_id}`, where `results[0].response` is exactly what this call returns. Nothing is held at submit: the call is validated now and billed as this call when it runs. Use it for calls that can outlast your client's timeout (MCP and many HTTP clients stop at 30 s). `Idempotency-Key` returns the same job on a retry.",
            "schema": {
              "type": "string"
            },
            "example": "respond-async"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "headers": {
              "X-Credits-Used": {
                "description": "Net credits charged for this response. Idempotency replays report 0.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Credits-Remaining": {
                "description": "Current authoritative balance. Free cache hits and idempotency replays omit this header when the balance cannot be determined; body `credits_remaining` is null instead.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Key-Credits-Remaining": {
                "description": "Only when the API key has a credit limit: the credits this key may still spend under that limit, after this call (never below 0). Absent for a key with no limit. `GET /v1/keys/current` has the limit and what is used.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "X-Idempotent-Replay": {
                "description": "Present with value `true` only when this response replays a settled idempotency record.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              },
              "Idempotent-Replayed": {
                "description": "Present with value `true` only when this response replays a settled idempotency record. Same meaning as `X-Idempotent-Replay`.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Whether the request succeeded",
                      "example": true
                    },
                    "platform": {
                      "type": "string",
                      "description": "Platform name",
                      "example": "search"
                    },
                    "endpoint": {
                      "type": "string",
                      "description": "API endpoint path",
                      "example": "/v1/search/news"
                    },
                    "data": {
                      "type": "object",
                      "description": "Platform-specific response data",
                      "properties": {
                        "metrics": {
                          "type": "object",
                          "description": "Key performance metrics",
                          "properties": {
                            "total_views": {
                              "type": "integer",
                              "description": "Total view count"
                            },
                            "total_likes": {
                              "type": "integer",
                              "description": "Total like count"
                            },
                            "total_comments": {
                              "type": "integer",
                              "description": "Total comment count"
                            },
                            "engagement_rate": {
                              "type": "number",
                              "description": "Computed engagement rate (0-1)"
                            }
                          }
                        },
                        "period": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Time period for the analytics data"
                        },
                        "breakdown": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "description": "Per-item or per-period breakdown",
                          "items": {
                            "type": "object",
                            "description": "Breakdown entry"
                          }
                        },
                        "_warnings": {
                          "type": "array",
                          "description": "Non-fatal notices about this response (field-map drift, clamped computed values). Advisory only: its presence never means the request failed. Omitted entirely when there is nothing to report, so treat absent as 'no warnings'.",
                          "items": {
                            "type": "string",
                            "description": "One advisory notice."
                          }
                        }
                      }
                    },
                    "credits_used": {
                      "type": "integer",
                      "description": "Number of credits consumed",
                      "example": 1
                    },
                    "credits_remaining": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.",
                      "example": 4999
                    },
                    "credits_remaining_note": {
                      "type": "string",
                      "description": "Present only when `credits_remaining` is null by design, as on a free cache hit: says why the balance was not read and where to read it.",
                      "example": "not read on cache hits (credits_used is 0); call GET /v1/credits/balance for the current balance"
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Unique request identifier for support",
                      "example": "req-abc123"
                    },
                    "cached": {
                      "type": "boolean",
                      "description": "Whether the response was served from cache",
                      "example": false
                    },
                    "age_s": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Present only on a cache hit (`cached: true`): whole seconds since this copy was fetched, also sent as the `X-Cache-Age` header. Null for a copy stored before ages were recorded. Send `max_age_s` to set how old a copy you accept: a profile or post copy up to an hour old is served for 0 credits, and a lower value fetches fresh.",
                      "example": 340
                    },
                    "idempotent_replay": {
                      "type": "boolean",
                      "description": "True only when this response is an idempotency replay",
                      "example": true
                    },
                    "meta": {
                      "type": "object",
                      "description": "Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.",
                      "properties": {
                        "hint": {
                          "type": "object",
                          "description": "One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat | batch_comments | batch_jobs",
                              "example": "search_multi"
                            },
                            "message": {
                              "type": "string",
                              "description": "One sentence for a person or an agent to read.",
                              "example": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged."
                            },
                            "method": {
                              "type": "string",
                              "description": "GET or POST.",
                              "example": "GET"
                            },
                            "path": {
                              "type": "string",
                              "description": "The call the hint points to.",
                              "example": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "success",
                    "platform",
                    "endpoint",
                    "data",
                    "credits_used",
                    "credits_remaining",
                    "request_id",
                    "cached"
                  ]
                },
                "example": {
                  "success": true,
                  "platform": "search",
                  "endpoint": "/v1/search/news",
                  "data": {
                    "query": "samsung electronics",
                    "search_status": "succeeded",
                    "plan": {
                      "topic": "samsung electronics",
                      "source": "llm",
                      "degraded": false,
                      "subqueries": [
                        {
                          "id": "sq0",
                          "label": "Samsung Electronics 재무 실적",
                          "search_query": "Samsung Electronics quarterly results revenue profit guidance",
                          "ranking_query": "Focus on earnings, revenue/profit trends, guidance, and investor updates reported by major outlets.",
                          "weight": 1
                        }
                      ],
                      "notes": [
                        "llm-plan"
                      ]
                    },
                    "legs": [
                      {
                        "leg_id": "sq0|KR",
                        "country": "KR",
                        "language": "ko",
                        "angle_id": "sq0",
                        "angle_label": "Samsung Electronics 재무 실적",
                        "effective_query": "삼성전자 실적 매출 이익 전망",
                        "query_source": "translated",
                        "status": "succeeded",
                        "article_count": 10,
                        "quarantined_count": 0,
                        "credits_used": 1,
                        "latency_ms": 1452,
                        "error": null
                      },
                      {
                        "leg_id": "sq0|US",
                        "country": "US",
                        "language": "en",
                        "angle_id": "sq0",
                        "angle_label": "Samsung Electronics 재무 실적",
                        "effective_query": "Samsung Electronics earnings revenue profit guidance",
                        "query_source": "translated",
                        "status": "succeeded",
                        "article_count": 10,
                        "quarantined_count": 0,
                        "credits_used": 1,
                        "latency_ms": 3177,
                        "error": null
                      }
                    ],
                    "items": [
                      {
                        "id": "gn_9599da30",
                        "title": "키움증권 \"삼성전자 3분기 영업이익 120조 전망, 메모리 가격 20% 오를 것\"",
                        "url": "https://www.businesspost.co.kr/BP?command=article_view&num=443626",
                        "canonical_url": "https://www.businesspost.co.kr/BP?command=article_view&num=443626",
                        "source_name": "비즈니스포스트",
                        "domain": "www.businesspost.co.kr",
                        "snippet": null,
                        "image_url": "https://www.businesspost.co.kr/news/photo/202306/20230629221229_98416.jpg",
                        "published_at": "2026-07-31T00:57:26.000Z",
                        "rank": 1,
                        "placement": "news_search",
                        "country_code": "KR",
                        "language_code": "ko",
                        "angle_id": "sq0",
                        "effective_query": "삼성전자 실적 매출 이익 전망",
                        "query_source": "translated",
                        "legs_returned": [
                          "sq0|KR"
                        ]
                      },
                      {
                        "id": "gn_2c3f9190",
                        "title": "Samsung Sees Chip Crunch Through 2028 as Profit Soars to Record",
                        "url": "https://www.wsj.com/tech/samsungs-chip-earnings-push-net-profit-to-record-cf8711bc",
                        "canonical_url": "https://www.wsj.com/tech/samsungs-chip-earnings-push-net-profit-to-record-cf8711bc",
                        "source_name": "WSJ",
                        "domain": "www.wsj.com",
                        "snippet": null,
                        "image_url": "https://images.wsj.net/im-46577202?width=700&height=466",
                        "published_at": "2026-07-30T08:59:00.000Z",
                        "rank": 1,
                        "placement": "news_search",
                        "country_code": "US",
                        "language_code": "en",
                        "angle_id": "sq0",
                        "effective_query": "Samsung Electronics earnings revenue profit guidance",
                        "query_source": "translated",
                        "legs_returned": [
                          "sq0|US"
                        ]
                      }
                    ],
                    "total_articles": 20,
                    "countries_searched": [
                      "KR",
                      "US"
                    ],
                    "credits_charged": 4,
                    "methodology_version": "search-news/1.0"
                  },
                  "credits_used": 4,
                  "credits_remaining": 9999,
                  "request_id": "req_example000000",
                  "cached": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid request - missing or malformed parameters",
            "x-error-codes": [
              "INVALID_REQUEST",
              "COHORT_MEMBER_LIMIT_EXCEEDED",
              "COHORT_LIMIT_EXCEEDED",
              "COHORT_IDENTITY_PLATFORM_UNSUPPORTED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INVALID_REQUEST",
                    "message": "Invalid request - missing or malformed parameters",
                    "status": 400,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - missing or invalid API key",
            "x-error-codes": [
              "MISSING_API_KEY",
              "INVALID_API_KEY"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "MISSING_API_KEY",
                    "message": "Unauthorized - missing or invalid API key",
                    "status": 401,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "402": {
            "description": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
            "x-error-codes": [
              "INSUFFICIENT_CREDITS",
              "KEY_BUDGET_EXCEEDED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INSUFFICIENT_CREDITS",
                    "message": "Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit",
                    "status": 402,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "404": {
            "description": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
            "x-error-codes": [
              "ENDPOINT_NOT_FOUND",
              "RESOURCE_NOT_FOUND",
              "RUN_NOT_FOUND",
              "SCHEDULE_NOT_FOUND",
              "STREAM_NOT_FOUND"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "ENDPOINT_NOT_FOUND",
                    "message": "Not found - the endpoint does not exist, or the requested resource was not found upstream",
                    "status": 404,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed - wrong HTTP verb for this endpoint",
            "x-error-codes": [
              "METHOD_NOT_ALLOWED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "METHOD_NOT_ALLOWED",
                    "message": "Method not allowed - wrong HTTP verb for this endpoint",
                    "status": 405,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_CONFLICT",
              "IDEMPOTENCY_IN_PROGRESS",
              "IDEMPOTENCY_REPLAY_UNAVAILABLE",
              "COHORT_IDENTITY_CONFLICT",
              "COHORT_QUERY_NOT_CANCELLABLE",
              "COHORT_QUERY_NOT_READY",
              "RUN_STATE_CONFLICT",
              "STREAM_STATE_CONFLICT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_CONFLICT",
                    "message": "Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation",
                    "status": 409,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "410": {
            "description": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
            "x-error-codes": [
              "RUN_EXPIRED",
              "CURSOR_EXPIRED"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RUN_EXPIRED",
                    "message": "Gone - the discover run's retention passed and its rows were deleted; start a new run. On the events feed, the cursor is older than the 30-day retention; restart from cursor=oldest",
                    "status": 410,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
            "x-error-codes": [
              "PAYLOAD_TOO_LARGE",
              "COHORT_RESULT_TOO_LARGE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "PAYLOAD_TOO_LARGE",
                    "message": "Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling",
                    "status": 413,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "422": {
            "description": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
            "x-error-codes": [
              "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
              "NEEDS_ASYNC"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH",
                    "message": "Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)",
                    "status": 422,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
            "x-error-codes": [
              "RATE_LIMITED",
              "CONCURRENCY_LIMIT"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "RATE_LIMITED",
                    "message": "Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.",
                    "status": 429,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
            "x-error-codes": [
              "INTERNAL_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "INTERNAL_ERROR",
                    "message": "Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit",
                    "status": 500,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "502": {
            "description": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 502,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
            "x-error-codes": [
              "SERVICE_UNAVAILABLE"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge",
                    "status": 503,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          },
          "504": {
            "description": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
            "x-error-codes": [
              "UPSTREAM_ERROR"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "success": false,
                  "error": {
                    "type": "UPSTREAM_ERROR",
                    "message": "Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After",
                    "status": 504,
                    "doc_url": "https://www.socialcrawl.dev/docs/errors"
                  },
                  "credits_used": 0,
                  "credits_remaining": null,
                  "request_id": "req-abc123"
                }
              }
            }
          }
        }
      }
    }
  },
  "x-full-spec": "https://www.socialcrawl.dev/v1/openapi.json"
}
