# StableSocial Pay-per-request social data. Use the OpenAPI schema for exact request fields. There are two kinds of routes: - **Scrape Creators routes** under `/api/sc/...` — synchronous. One paid POST returns the data directly (`200`). No polling. Covers TikTok, Instagram, YouTube, Twitter/X, LinkedIn, Facebook, Reddit, Threads, Truth Social, Bluesky, Pinterest, Twitch, Snapchat, GitHub, Spotify, SoundCloud, Rumble, Kwai, Pinterest, ad libraries (Facebook/Google/LinkedIn/TikTok/Reddit), TikTok Shop, link-in-bio pages, and more. - **Data365 routes** under `/api/{tiktok,instagram,facebook,reddit}/...` and **Lightreel** under `/api/lightreel/...` — asynchronous job flow (see Core Flow below). Prefer a `/api/sc/...` route when one matches the resource — it returns immediately and needs no SIWX polling. ## Scrape Creators (sc/*) Flow Make one paid POST to the `/api/sc/...` route. All inputs go in the JSON body (never the URL). The response is the upstream Scrape Creators JSON, returned directly with `200`. Most identifier-style routes accept a `handle`, a `url`, a `user_id`, or a query depending on the platform — check the route's body schema. Paginate by passing the `cursor`/`after`/`continuationToken`/`max_id` value from the previous response back in a new paid POST. A non-2xx response means payment did not settle. ## Core Flow (Data365 + Lightreel) Make one paid POST. It returns `202 Accepted` with `jobId`, `pollUrl`, and usually `retryAfterSeconds`. Poll `GET /api/jobs/{jobId}` with SIWX from the same wallet. Do not repeat the paid POST while pending; poll every 3-5 seconds and back off. ## Job Responses `pending` includes `retryAfterSeconds`; `finished` includes `data`; `failed` includes `error`. If the initial paid POST returns non-2xx, payment is not settled. If an accepted job later fails, treat `status: "failed"` as terminal. ## Recovering Jobs Use `GET /api/jobs?limit=20&cursor=...` with SIWX to list the caller's durable jobs. Use this if the original 202 response was lost. Only the paying wallet can list or poll its jobs. ## Resource Ordering Some resources depend on fresher parent data. Trigger and finish the parent first: profile before followers/following/posts; profile/posts before post comments when required; post comments before comment replies. ## Pagination When a finished response includes `page_info.cursor` and `page_info.has_next_page`, request the next page by making a new paid POST with that cursor. Each page is a new job with its own `jobId`. ## Lightreel - Lightreel POSTs run live UGC research and can take minutes. They return `202` with `jobId`, `pollUrl`, and `retryAfterSeconds`; poll the job with SIWX. - Prefer typed Lightreel routes over `/api/lightreel/chat` whenever one matches. The typed routes internally request structured fields, so finished job data is `{ answer: { ... }, conversationId }`. - Discovery/content routes: `/api/lightreel/top-hooks` for hooks/opening lines; `/video-search` for source TikToks/Reels, URLs, examples, breakout posts; `/creator-search` for UGC creators, influencers, emails/contact info; `/trends` for TikTok/Instagram/X trends and formats. - Strategy routes: `/api/lightreel/account-feedback` for account audits and underperforming accounts; `/competitor-strategy` for rival accounts and marketing strategy; `/creator-performance` for tracking creators and deciding what to brief next. - Creative production routes: `/api/lightreel/script-ideas` for UGC/ad scripts and creator prompts; `/video-ideas` for content angles; `/video-feedback` for drafts, hooks, pacing, retention, conversion; `/ugc-brief` for creator briefs and shot lists; `/content-calendar` for posting plans. - Monitoring route: `/api/lightreel/brand-mentions` for brand/product/competitor mentions, sentiment, and earned UGC. - Use `POST /api/lightreel/chat` only when no typed route fits. Body: `{ "question": string, "conversation_id"?: string, "response_fields"?: { ... } }`. - With `response_fields`, finished `answer` is an object containing only the requested top-level keys. Each field must be `type: "string"` or `type: "array"`; arrays are returned as arrays and typed routes ask Lightreel to format array items as compact strings. - Without `response_fields`, finished `answer` may be a plain string. - Pass `conversationId` as `conversation_id` in a new paid Lightreel request to continue the same conversation. - `GET /api/lightreel/chats` lists wallet-owned Lightreel chats created through StableSocial. `GET /api/lightreel/chat/{conversationId}` fetches a transcript. Both require SIWX from the paying wallet. ## Auth - Paid POST endpoints require x402 or MPP payment. - Job polling and listing require SIWX wallet auth, not an API key. - Wrong-wallet polling returns 403. Missing or invalid SIWX returns 401. ## Practical Agent Rule For any user request, choose the smallest endpoint that matches the requested resource, make exactly one paid POST, poll the returned `pollUrl` until terminal, then return the finished data or failed error.