{"openapi":"3.1.0","info":{"title":"SnitchFeed Public API","version":"1.0.0","description":"Keyword search across social platforms. All documented endpoints require a valid organization API key: send `Authorization: Bearer sf_api_...`. Create keys in the platform under Integrations → API keys.\n\n**Credits:** Search endpoints deduct credits from your organization on each **successful** response. See https://snitchfeed.com/docs/api/credits for current amounts. The same values are also exposed as `components.schemas.SnitchFeedCreditRates` in this document for code generators."},"security":[{"bearerAuth":[]}],"tags":[{"name":"Twitter","description":"Search and read public posts on X (Twitter)."},{"name":"LinkedIn","description":"Search and read public LinkedIn posts, companies, comments, and reactions.","x-displayName":"LinkedIn"},{"name":"Billing","description":"Credit usage for the current billing period (`GET /billing/usage`). This call is read-only and does not consume credits. Metered prices (including per-search costs): https://snitchfeed.com/docs/api/credits. Product-wide credits: https://snitchfeed.com/docs/credits."},{"name":"Webhooks","description":"Outbound events SnitchFeed POSTs to URLs you configure in the platform."}],"servers":[{"url":"https://api.snitchfeed.com/v1","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sf_api_<secret>","description":"Organization API key from Integrations → API keys."}},"schemas":{"SnitchFeedCreditRates":{"type":"object","title":"SnitchFeedCreditRates","description":"Credit amounts deducted for metered SnitchFeed work (mirrors `CREDIT_COSTS` in `@repo/shared`). Human-readable table and API-specific notes: https://snitchfeed.com/docs/api/credits. The public v1 HTTP API bills successful search/company requests at `apiTwitterSearchPerRequest` and `apiLinkedInSearchPerRequest`, and LinkedIn comment/reaction scrapes per returned item at `apiLinkedInPostCommentsPerComment` / `apiLinkedInPostReactionsPerReaction`; other properties cover platform and background usage for the same organization credit pool.","properties":{"apiTwitterSearchPerRequest":{"type":"integer","const":2,"description":"Credits charged for each successful `POST /v1/data/twitter/tweets/search`."},"apiLinkedInSearchPerRequest":{"type":"integer","const":4,"description":"Credits charged for each successful `POST /v1/data/linkedin/posts/search` and `POST /v1/data/linkedin/company/get`."},"apiLinkedInPostCommentsPerComment":{"type":"integer","const":1,"description":"Credits charged per comment returned by a successful `POST /v1/data/linkedin/posts/comments`."},"apiLinkedInPostReactionsPerReaction":{"type":"integer","const":1,"description":"Credits charged per reaction returned by a successful `POST /v1/data/linkedin/posts/reactions`."},"twitterPollPerKeywordScan":{"type":"integer","const":2,"description":"Scheduled listener keyword scan on X (platform; not this HTTP API)."},"linkedinPollPerKeywordScan":{"type":"integer","const":4,"description":"Scheduled listener keyword scan on LinkedIn (platform; not this HTTP API)."},"mentionAiScoringPerMention":{"type":"number","const":0.5,"description":"Credits per mention when AI relevance scoring runs (platform / workers)."},"chatWithMentionsPerDeeplink":{"type":"integer","const":100,"description":"Credits when a workspace generates a Chat with mentions deeplink (platform)."},"mentionsExportCsvPerExport":{"type":"integer","const":100,"description":"Flat credits per mentions CSV export, regardless of row count (platform)."},"mentionResponseGenerationPerGeneration":{"type":"integer","const":5,"description":"Credits per AI mention response generated from the Respond dialog (platform). Transforms are free."}},"required":["apiTwitterSearchPerRequest","apiLinkedInSearchPerRequest","apiLinkedInPostCommentsPerComment","apiLinkedInPostReactionsPerReaction","twitterPollPerKeywordScan","linkedinPollPerKeywordScan","mentionAiScoringPerMention","chatWithMentionsPerDeeplink","mentionsExportCsvPerExport","mentionResponseGenerationPerGeneration"],"additionalProperties":false}},"parameters":{}},"paths":{"/data/twitter/tweets/search":{"post":{"operationId":"tweets/search","tags":["Twitter"],"summary":"Search Tweets","description":"Search public posts on X (Twitter).\n\n### Credits\n\nEach **successful** response deducts **2 credits** from your organization. Requests that fail (4xx / 5xx) are not billed.\n\nSee the [credits documentation](https://snitchfeed.com/docs/api/credits) for the full rate table.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Search keywords for posts on X."},"cursor":{"type":"string","maxLength":1024,"description":"Opaque cursor from a previous response `meta.nextCursor`."},"count":{"type":"integer","minimum":1,"maximum":20,"default":20,"description":"Maximum tweets to return (capped at 20)."},"category":{"type":"string","enum":["Top","Latest","People","Photos","Videos"],"description":"Search tab / category on X."},"filters":{"type":"object","properties":{"lang":{"type":"string","maxLength":32,"description":"BCP 47 language filter."},"since":{"type":"string","maxLength":32,"description":"Start of time window (upstream format)."},"until":{"type":"string","maxLength":32,"description":"End of time window (upstream format)."},"exactSentence":{"type":"string","maxLength":512,"description":"Exact phrase match (defaults to main query if omitted upstream)."},"anyOfTheseWords":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Match if any of these words appear."},"noneOfTheseWords":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Exclude posts containing these words."},"hashtags":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":30,"description":"Hashtag filters without leading `#`."},"fromTheseAccounts":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":30,"description":"Only posts from these screen names or handles."},"toTheseAccounts":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":30,"description":"Posts directed at these accounts."},"mentionsTheseAccounts":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":30,"description":"Posts mentioning these accounts."},"removePostsWithLinks":{"type":"boolean","description":"Exclude posts with URLs."},"onlyPostsWithLinks":{"type":"boolean","description":"Only posts with URLs."},"removeReplies":{"type":"boolean","description":"Exclude replies."},"onlyReplies":{"type":"boolean","description":"Only replies."},"removePostsWithMedia":{"type":"boolean","description":"Exclude posts with media."},"onlyPostsWithMedia":{"type":"boolean","description":"Only posts with media."},"removePostsWithVideo":{"type":"boolean","description":"Exclude posts with video."},"onlyPostsWithVideo":{"type":"boolean","description":"Only posts with video."},"removePostsWithPhotos":{"type":"boolean","description":"Exclude posts with photos."},"onlyPostsWithPhotos":{"type":"boolean","description":"Only posts with photos."},"linksInclude":{"type":"string","maxLength":200,"description":"Posts must include a link matching this substring."},"minimumRepliesCount":{"type":"integer","minimum":0,"description":"Minimum reply count."},"minimumRetweetsCount":{"type":"integer","minimum":0,"description":"Minimum repost/retweet count."},"minimumLikesCount":{"type":"integer","minimum":0,"description":"Minimum like count."},"geocode":{"type":"string","maxLength":120,"description":"Location bias string for geographic search."},"radius":{"type":"number","description":"Radius used with geocode (upstream units)."}},"additionalProperties":false,"description":"Additional structured filters (subset of upstream search)."}},"required":["query"],"additionalProperties":false,"description":"Request body for `POST /data/twitter/tweets/search`."}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable post identifier from X."},"body":{"type":"string","description":"Full text of the post."},"author":{"type":"string","description":"Author handle without `@`."},"name":{"type":"string","description":"Display name of the author."},"timestamp":{"type":"string","description":"When the post was created (ISO 8601)."},"url":{"type":"string","description":"Canonical URL to the post on X."},"images":{"type":"array","items":{"type":"string"},"description":"Image URLs attached to the post."},"video":{"type":["string","null"],"description":"Video URL when present; otherwise null."},"engagements":{"type":"object","properties":{"bookmarkCount":{"type":"number","description":"Bookmark count."},"favoriteCount":{"type":"number","description":"Like/favorite count."},"quoteCount":{"type":"number","description":"Quote-post count."},"replyCount":{"type":"number","description":"Reply count."},"retweetCount":{"type":"number","description":"Repost/retweet count."},"viewsCount":{"type":"number","description":"View count when available."}},"required":["bookmarkCount","favoriteCount","quoteCount","replyCount","retweetCount","viewsCount"],"additionalProperties":false,"description":"Engagement metrics for this post."}},"required":["id","body","author","name","timestamp","url","images","video","engagements"],"additionalProperties":false,"description":"One normalized tweet/post from the search results."},"description":"Matching posts for this page."},"meta":{"type":"object","properties":{"returnedCount":{"type":"integer","minimum":0,"description":"Number of posts returned in this response."},"hasMore":{"type":"boolean","description":"Whether more results exist beyond this page."},"nextCursor":{"type":"string","description":"Pass as `cursor` in the next request to fetch the next page."}},"required":["returnedCount","hasMore"],"additionalProperties":false,"description":"Pagination metadata for tweet search."}},"required":["requestId","posts","meta"],"additionalProperties":false,"description":"Successful `POST /data/twitter/tweets/search` response."}}}},"400":{"description":"Validation or bad request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dot-separated path to the invalid field (e.g. `filters.lang`)."},"message":{"type":"string","description":"Human-readable description of the issue."}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message","issues"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Validation error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"validation_error","message":"query: String must contain at least 1 character(s)","issues":[{"path":"query","message":"String must contain at least 1 character(s)"}]}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"retryAfter":{"type":"integer","exclusiveMinimum":0,"description":"Seconds until the rate limit resets (same value as the `Retry-After` response header)."}},"required":["code","message","retryAfter"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Rate limited"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"rate_limited","message":"Rate limit exceeded for linkedin. Try again later.","retryAfter":42}}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["upstream_error"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Upstream error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"upstream_error","message":"Upstream request failed."}}}}}}}},"/data/linkedin/industries":{"get":{"operationId":"industries/search","tags":["LinkedIn"],"summary":"Search LinkedIn industries","description":"Search LinkedIn industry codes by name or category. Returns matching industries with their numeric ID, label, and hierarchy path.\n\nUse the returned `id` values as the `author_industry` filter when calling `POST /data/linkedin/posts/search`.\n\n**Read-only** — this endpoint does not consume credits.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100,"description":"Search term to filter industries by name, hierarchy, or description.","example":"software"},"required":false,"description":"Search term to filter industries by name, hierarchy, or description.","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"default":1,"description":"Page number (1-indexed). Defaults to 1."},"required":false,"description":"Page number (1-indexed). Defaults to 1.","name":"page","in":"query"}],"responses":{"200":{"description":"Matching industries","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"industries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","description":"Numeric LinkedIn industry ID."},"label":{"type":"string","description":"Industry display name."},"hierarchy":{"type":"string","description":"Full hierarchy path (e.g. 'Technology, Information and Media > Software Development')."}},"required":["id","label","hierarchy"],"additionalProperties":false}},"meta":{"type":"object","properties":{"total":{"type":"integer","description":"Total matching industries for this query."},"page":{"type":"integer","description":"Current page (1-indexed)."},"pageCount":{"type":"integer","description":"Total number of pages."},"pageSize":{"type":"integer","description":"Results per page (always 25)."}},"required":["total","page","pageCount","pageSize"],"additionalProperties":false}},"required":["requestId","industries","meta"],"additionalProperties":false,"description":"Successful `GET /data/linkedin/industries` response."}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}}}}},"/data/linkedin/posts/search":{"post":{"operationId":"posts/search","tags":["LinkedIn"],"summary":"Search LinkedIn posts","description":"Search public LinkedIn posts.\n\n> **Recommended client timeout: 90 seconds.** Most requests resolve in 2-5 seconds, but set your HTTP client timeout to at least 90 seconds to avoid false timeouts on slower queries.\n\n### Credits\n\nEach **successful** response deducts **4 credits** from your organization. Requests that fail (4xx / 5xx) are not billed.\n\nSee the [credits documentation](https://snitchfeed.com/docs/api/credits) for the full rate table.","x-recommended-client-timeout-seconds":90,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Keywords / search terms (text you would put in the LinkedIn search bar)."},"page":{"type":"integer","minimum":1,"default":1,"description":"Page number (1-based)."},"sort_by":{"type":"string","enum":["recent","relevant"],"default":"recent","description":"Sort order for this page. Mapped upstream to `relevance` (top match) or `date_posted` (latest)."},"count":{"type":"integer","minimum":1,"maximum":20,"default":20,"description":"Maximum posts to return from this response (capped at 20)."},"author_job_title":{"type":"string","maxLength":80,"description":"Rough text matching the author's job title (e.g. CEO). Maps to upstream `author_job_title`."},"content_type":{"type":"string","enum":["photos","videos","liveVideos","collaborativeArticles","documents"],"description":"Require posts to include this content type. Maps to upstream `content_type`."},"from_member":{"type":"string","maxLength":120,"description":"Person URNs who authored the post, comma-separated. Maps to upstream `from_member`."},"from_organization":{"type":"string","maxLength":120,"description":"Organization ids that posted the post, comma-separated. Maps to upstream `from_organization`."},"author_company":{"type":"string","maxLength":120,"description":"Company ids where the author works, comma-separated. Maps to upstream `author_company`."},"author_industry":{"type":"array","items":{"type":"integer"},"maxItems":5,"description":"Numeric industry IDs to filter by author industry (max 5). Use [GET /data/linkedin/industries](/docs/api/linkedin/industries/search) to find valid IDs."},"mentions_member":{"type":"string","maxLength":120,"description":"Person URNs mentioned in the post, comma-separated. Maps to upstream `mentions_member`."},"mentions_organization":{"type":"string","maxLength":120,"description":"Organization ids mentioned in the post, comma-separated. Maps to upstream `mentions_organization`."}},"required":["query"],"additionalProperties":false,"description":"Request body for `POST /data/linkedin/posts/search`."}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"posts":{"type":"array","items":{"type":"object","properties":{"share_url":{"type":"string","description":"Public URL to open this post on LinkedIn."},"actor":{"type":"object","properties":{"actor_image":{"type":"string","description":"Profile image URL."},"actor_description":{"type":"string","description":"Headline or short bio text from the profile."},"actor_name":{"type":"string","description":"Display name of the author."},"actor_subDescription":{"type":"string","description":"Secondary line (e.g. connection degree or subtitle)."},"actor_navigationContext":{"type":"string","description":"URN or path used for deep links to the actor."}},"required":["actor_image","actor_description","actor_name","actor_subDescription","actor_navigationContext"],"additionalProperties":false,"description":"Author / actor block for a LinkedIn feed item."},"commentary":{"type":"string","description":"Post body / commentary text."},"social_details":{"type":"object","properties":{"numLikes":{"type":"number","description":"Like count."},"numComments":{"type":"number","description":"Comment count."},"numShares":{"type":"number","description":"Share / repost count."},"reactionTypeCounts":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Reaction type key from LinkedIn."},"count":{"type":"number","description":"Count for this reaction type."}},"required":["type","count"],"additionalProperties":false},"description":"Breakdown of reactions by type when provided."}},"required":["numLikes","numComments","numShares","reactionTypeCounts"],"additionalProperties":false,"description":"Engagement summary for the post."},"postedAt":{"type":"string","description":"When the post was published (ISO 8601 when parsed from upstream)."},"imageComponent":{"type":"array","items":{"type":"string"},"description":"Image URLs for image attachments."},"urn":{"type":"string","description":"LinkedIn activity URN for this post."},"reactionsUrn":{"type":"string","description":"URN for the reactions collection on this activity."},"commentsUrn":{"type":"string","description":"URN for the comments collection on this activity."},"repostsUrn":{"type":"string","description":"URN for reposts / reshares of this activity."},"articleComponent":{"type":"object","properties":{"title":{"type":"string","description":"Article title."},"subtitle":{"type":"string","description":"Article subtitle or domain line."},"navigationContext":{"type":"string","description":"Link context for opening the article."},"smallImage":{"type":"string","description":"Thumbnail image URL."},"description":{"type":"string","description":"Article description or excerpt when provided."}},"required":["title","subtitle","navigationContext","smallImage"],"additionalProperties":false,"description":"Article preview when the post includes a linked article."},"linkedInVideoComponent":{"type":"object","properties":{"thumbnail":{"type":"string","description":"Video thumbnail URL."},"duration":{"type":"number","description":"Duration in seconds (when known)."},"provider":{"type":"string","description":"Video host / provider name."}},"required":["thumbnail","duration","provider"],"additionalProperties":false,"description":"Native video metadata when the post includes LinkedIn video."},"documentComponent":{"type":"object","properties":{"title":{"type":"string","description":"Document title."},"transcribedDocumentUrl":{"type":"string","description":"URL to the transcribed or downloadable document."},"coverPages":{"type":"array","items":{"type":"object","properties":{"width":{"type":"number","description":"Cover page width in pixels."},"height":{"type":"number","description":"Cover page height in pixels."},"imageUrls":{"type":"array","items":{"type":"string"},"description":"Preview image URLs for this cover page."}},"required":["width","height","imageUrls"],"additionalProperties":false},"description":"Document cover page previews."}},"required":["title","transcribedDocumentUrl","coverPages"],"additionalProperties":false,"description":"Document attachment when the post includes a PDF or carousel."},"pollComponent":{"type":"object","properties":{"question":{"type":"string","description":"Poll question text."},"visibilityInfo":{"type":"string","description":"Visibility notice shown with the poll."},"showPollSummaryInfo":{"type":"boolean","description":"Whether LinkedIn shows poll summary info."},"pollOptions":{"type":"array","items":{"type":"object","properties":{"option":{"type":"string","description":"Poll option label."},"votes":{"type":"number","description":"Vote count for this option."}},"required":["option","votes"],"additionalProperties":false},"description":"Poll choices and vote counts."},"totalVotes":{"type":"number","description":"Total votes across all options."},"closed":{"type":"boolean","description":"Whether the poll is closed."},"remainingDuration":{"type":"string","description":"Human-readable time remaining (e.g. 1 week left)."}},"required":["question","visibilityInfo","showPollSummaryInfo","pollOptions","totalVotes","closed","remainingDuration"],"additionalProperties":false,"description":"Poll attachment when the post includes a LinkedIn poll."}},"required":["share_url","actor","commentary","social_details","postedAt","urn","reactionsUrn","commentsUrn","repostsUrn"],"additionalProperties":false,"description":"One normalized LinkedIn post from the search results."},"description":"Matching posts for this page."},"meta":{"type":"object","properties":{"returnedCount":{"type":"integer","minimum":0,"description":"Number of posts returned in this response."},"page":{"type":"integer","minimum":1,"description":"Page number echoed from the request (1-based)."}},"required":["returnedCount","page"],"additionalProperties":false,"description":"Pagination metadata for LinkedIn post search."}},"required":["requestId","posts","meta"],"additionalProperties":false,"description":"Successful `POST /data/linkedin/posts/search` response."}}}},"400":{"description":"Validation or bad request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dot-separated path to the invalid field (e.g. `filters.lang`)."},"message":{"type":"string","description":"Human-readable description of the issue."}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message","issues"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Validation error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"validation_error","message":"query: String must contain at least 1 character(s)","issues":[{"path":"query","message":"String must contain at least 1 character(s)"}]}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"retryAfter":{"type":"integer","exclusiveMinimum":0,"description":"Seconds until the rate limit resets (same value as the `Retry-After` response header)."}},"required":["code","message","retryAfter"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Rate limited"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"rate_limited","message":"Rate limit exceeded for linkedin. Try again later.","retryAfter":42}}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["upstream_error"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Upstream error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"upstream_error","message":"LinkedIn search could not be completed. You won't be charged for this request."}}}}},"503":{"description":"LinkedIn search temporarily unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["linkedin_unavailable"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"LinkedIn search temporarily unavailable"},"example":{"requestId":"ce8f36c6-c9e6-4ab1-93b3-d11bbbe886aa","error":{"code":"linkedin_unavailable","message":"LinkedIn search is temporarily unavailable. Retry later. You won't be charged for this request."}}}}}}}},"/data/linkedin/company/get":{"post":{"operationId":"company/get","tags":["LinkedIn"],"summary":"Get LinkedIn company","description":"Fetch a public LinkedIn company profile by company page URL.\n\n> **Recommended client timeout: 90 seconds.** Most requests resolve in 2-5 seconds, but set your HTTP client timeout to at least 90 seconds to avoid false timeouts on slower lookups.\n\n### Credits\n\nEach **successful** response deducts **4 credits** from your organization. Requests that fail (4xx / 5xx) are not billed.\n\nSee the [credits documentation](https://snitchfeed.com/docs/api/credits) for the full rate table.","x-recommended-client-timeout-seconds":90,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"Public LinkedIn company page URL, e.g. `https://www.linkedin.com/company/snitchfeed`."}},"required":["url"],"additionalProperties":false,"description":"Request body for `POST /data/linkedin/company/get`."}}}},"responses":{"200":{"description":"Company profile","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"company":{"type":"object","properties":{"id":{"type":"string","description":"Stable LinkedIn company identifier."},"name":{"type":"string","description":"Company display name."},"universalName":{"type":["string","null"],"description":"LinkedIn universal name / slug when provided."},"linkedinUrl":{"type":["string","null"],"description":"Canonical LinkedIn company URL."},"description":{"type":["string","null"],"description":"Company profile description."},"tagline":{"type":["string","null"],"description":"Company tagline when provided."},"websiteUrl":{"type":["string","null"],"description":"Company website URL."},"industry":{"type":["string","null"],"description":"Primary industry name."},"foundedYear":{"type":["integer","null"],"description":"Founded year when provided."},"followerCount":{"type":"integer","minimum":0,"description":"LinkedIn follower count."},"employeeCount":{"type":"integer","minimum":0,"description":"Employee count when provided."},"employeeCountRange":{"type":["object","null"],"properties":{"start":{"type":"integer","minimum":0,"description":"Lower bound of the employee count range."},"end":{"type":["integer","null"],"minimum":0,"description":"Upper bound of the employee count range, or null when open-ended."}},"required":["start","end"],"additionalProperties":false,"description":"LinkedIn company employee count range."},"headquarter":{"type":["object","null"],"properties":{"country":{"type":["string","null"],"description":"Country code or name when provided."},"city":{"type":["string","null"],"description":"City name when provided."},"geographicArea":{"type":["string","null"],"description":"Region, state, or geographic area."},"postalCode":{"type":["string","null"],"description":"Postal code when provided."},"line1":{"type":["string","null"],"description":"First street address line."},"line2":{"type":["string","null"],"description":"Second street address line."},"description":{"type":["string","null"],"description":"Location description when provided."},"headquarter":{"type":"boolean","description":"Whether this location is marked as headquarters."}},"required":["country","city","geographicArea","postalCode","line1","line2","description","headquarter"],"additionalProperties":false,"description":"Normalized LinkedIn company location."},"locations":{"type":"array","items":{"type":"object","properties":{"country":{"type":["string","null"],"description":"Country code or name when provided."},"city":{"type":["string","null"],"description":"City name when provided."},"geographicArea":{"type":["string","null"],"description":"Region, state, or geographic area."},"postalCode":{"type":["string","null"],"description":"Postal code when provided."},"line1":{"type":["string","null"],"description":"First street address line."},"line2":{"type":["string","null"],"description":"Second street address line."},"description":{"type":["string","null"],"description":"Location description when provided."},"headquarter":{"type":"boolean","description":"Whether this location is marked as headquarters."}},"required":["country","city","geographicArea","postalCode","line1","line2","description","headquarter"],"additionalProperties":false,"description":"Normalized LinkedIn company location."},"description":"Known company locations."},"specialities":{"type":"array","items":{"type":"string"},"description":"Company specialties listed on LinkedIn."},"logoUrl":{"type":["string","null"],"description":"Company logo URL."}},"required":["id","name","universalName","linkedinUrl","description","tagline","websiteUrl","industry","foundedYear","followerCount","employeeCount","employeeCountRange","headquarter","locations","specialities","logoUrl"],"additionalProperties":false,"description":"One normalized LinkedIn company profile."}},"required":["requestId","company"],"additionalProperties":false,"description":"Successful `POST /data/linkedin/company/get` response."}}}},"400":{"description":"Validation or bad request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dot-separated path to the invalid field (e.g. `filters.lang`)."},"message":{"type":"string","description":"Human-readable description of the issue."}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message","issues"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Validation error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"validation_error","message":"query: String must contain at least 1 character(s)","issues":[{"path":"query","message":"String must contain at least 1 character(s)"}]}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"retryAfter":{"type":"integer","exclusiveMinimum":0,"description":"Seconds until the rate limit resets (same value as the `Retry-After` response header)."}},"required":["code","message","retryAfter"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Rate limited"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"rate_limited","message":"Rate limit exceeded for linkedin. Try again later.","retryAfter":42}}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["upstream_error"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Upstream error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"upstream_error","message":"LinkedIn search could not be completed. You won't be charged for this request."}}}}},"503":{"description":"LinkedIn company lookup temporarily unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["linkedin_unavailable"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"LinkedIn search temporarily unavailable"},"example":{"requestId":"ce8f36c6-c9e6-4ab1-93b3-d11bbbe886aa","error":{"code":"linkedin_unavailable","message":"LinkedIn search is temporarily unavailable. Retry later. You won't be charged for this request."}}}}}}}},"/data/linkedin/posts/comments":{"post":{"operationId":"posts/comments","tags":["LinkedIn"],"summary":"Get LinkedIn post comments","description":"Fetch commenters and comment text for a public LinkedIn post by post URL.\n\nReturns up to `maxComments` comments (default 100, max 1000).\n\n> **Recommended client timeout: 90 seconds.** Larger `maxComments` values take longer because multiple pages are fetched.\n\n### Credits\n\nEach **successful** response deducts **1 credit per comment returned**. Requests that fail (4xx / 5xx) are not billed.\n\nSee the [credits documentation](https://snitchfeed.com/docs/api/credits) for the full rate table.","x-recommended-client-timeout-seconds":90,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"postUrl":{"type":"string","minLength":1,"maxLength":2048,"description":"Public LinkedIn post URL (e.g. `https://www.linkedin.com/posts/...` or a `feed/update/urn:li:activity:...` URL)."},"maxComments":{"type":"integer","minimum":100,"maximum":1000,"description":"Maximum comments to return (100-1000). Default 100. Charged at 1 credit per comment returned."}},"required":["postUrl"],"additionalProperties":false,"description":"Request body for `POST /data/linkedin/posts/comments`."}}}},"responses":{"200":{"description":"Post comments","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"comments":{"type":"array","items":{"type":"object","properties":{"profileUrl":{"type":"string","description":"Commenter LinkedIn profile URL."},"authorName":{"type":"string","description":"Commenter display name."},"authorHeadline":{"type":"string","description":"Commenter headline / position."},"text":{"type":"string","description":"Comment text."},"timestamp":{"type":"string","description":"ISO 8601 timestamp when the comment was created."},"permalink":{"type":"string","description":"Permalink to the comment on LinkedIn."}},"required":["profileUrl","authorName","authorHeadline","text","timestamp","permalink"],"additionalProperties":false,"description":"A single LinkedIn post comment."},"description":"Comments returned for this request (up to `maxComments`)."},"meta":{"type":"object","properties":{"returnedCount":{"type":"integer","description":"Number of comments in this response."},"total":{"type":"integer","description":"Total comments reported by LinkedIn for this post when available."},"creditsCharged":{"type":"integer","description":"Credits deducted for this successful request."}},"required":["returnedCount","total","creditsCharged"],"additionalProperties":false}},"required":["requestId","comments","meta"],"additionalProperties":false,"description":"Successful `POST /data/linkedin/posts/comments` response."}}}},"400":{"description":"Validation or bad request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dot-separated path to the invalid field (e.g. `filters.lang`)."},"message":{"type":"string","description":"Human-readable description of the issue."}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message","issues"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Validation error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"validation_error","message":"query: String must contain at least 1 character(s)","issues":[{"path":"query","message":"String must contain at least 1 character(s)"}]}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"retryAfter":{"type":"integer","exclusiveMinimum":0,"description":"Seconds until the rate limit resets (same value as the `Retry-After` response header)."}},"required":["code","message","retryAfter"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Rate limited"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"rate_limited","message":"Rate limit exceeded for linkedin. Try again later.","retryAfter":42}}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["upstream_error"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Upstream error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"upstream_error","message":"LinkedIn search could not be completed. You won't be charged for this request."}}}}},"503":{"description":"LinkedIn comments scrape temporarily unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["linkedin_unavailable"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"LinkedIn search temporarily unavailable"},"example":{"requestId":"ce8f36c6-c9e6-4ab1-93b3-d11bbbe886aa","error":{"code":"linkedin_unavailable","message":"LinkedIn search is temporarily unavailable. Retry later. You won't be charged for this request."}}}}}}}},"/data/linkedin/posts/reactions":{"post":{"operationId":"posts/reactions","tags":["LinkedIn"],"summary":"Get LinkedIn post reactions","description":"Fetch people who reacted to a public LinkedIn post (likes, celebrates, and other reaction types) by post URL.\n\nReturns up to `maxReactions` reactions (default 100, max 1000).\n\nProfile URLs from reactions are often ID-based (`/in/ACoAA...`), not public vanity slugs.\n\n> **Recommended client timeout: 90 seconds.** Larger `maxReactions` values take longer because multiple pages are fetched.\n\n### Credits\n\nEach **successful** response deducts **1 credit per reaction returned**. Requests that fail (4xx / 5xx) are not billed.\n\nSee the [credits documentation](https://snitchfeed.com/docs/api/credits) for the full rate table.","x-recommended-client-timeout-seconds":90,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"postUrl":{"type":"string","minLength":1,"maxLength":2048,"description":"Public LinkedIn post URL (e.g. `https://www.linkedin.com/posts/...` or a `feed/update/urn:li:activity:...` URL)."},"maxReactions":{"type":"integer","minimum":100,"maximum":1000,"description":"Maximum reactions to return (100-1000). Default 100. Charged at 1 credit per reaction returned."}},"required":["postUrl"],"additionalProperties":false,"description":"Request body for `POST /data/linkedin/posts/reactions`."}}}},"responses":{"200":{"description":"Post reactions","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"reactions":{"type":"array","items":{"type":"object","properties":{"profileUrl":{"type":"string","description":"Reactor LinkedIn profile URL."},"authorName":{"type":"string","description":"Reactor display name."},"authorHeadline":{"type":"string","description":"Reactor headline / position."},"reactionType":{"type":"string","description":"LinkedIn reaction type (e.g. LIKE, EMPATHY, PRAISE, INTEREST, MAYBE)."}},"required":["profileUrl","authorName","authorHeadline","reactionType"],"additionalProperties":false,"description":"A single LinkedIn post reaction."},"description":"Reactions returned for this request (up to `maxReactions`)."},"meta":{"type":"object","properties":{"returnedCount":{"type":"integer","description":"Number of reactions in this response."},"total":{"type":"integer","description":"Total reactions reported by LinkedIn for this post when available."},"creditsCharged":{"type":"integer","description":"Credits deducted for this successful request."}},"required":["returnedCount","total","creditsCharged"],"additionalProperties":false}},"required":["requestId","reactions","meta"],"additionalProperties":false,"description":"Successful `POST /data/linkedin/posts/reactions` response."}}}},"400":{"description":"Validation or bad request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dot-separated path to the invalid field (e.g. `filters.lang`)."},"message":{"type":"string","description":"Human-readable description of the issue."}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message","issues"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Validation error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"validation_error","message":"query: String must contain at least 1 character(s)","issues":[{"path":"query","message":"String must contain at least 1 character(s)"}]}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"retryAfter":{"type":"integer","exclusiveMinimum":0,"description":"Seconds until the rate limit resets (same value as the `Retry-After` response header)."}},"required":["code","message","retryAfter"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Rate limited"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"rate_limited","message":"Rate limit exceeded for linkedin. Try again later.","retryAfter":42}}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["upstream_error"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Upstream error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"upstream_error","message":"LinkedIn search could not be completed. You won't be charged for this request."}}}}},"503":{"description":"LinkedIn reactions scrape temporarily unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["linkedin_unavailable"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"LinkedIn search temporarily unavailable"},"example":{"requestId":"ce8f36c6-c9e6-4ab1-93b3-d11bbbe886aa","error":{"code":"linkedin_unavailable","message":"LinkedIn search is temporarily unavailable. Retry later. You won't be charged for this request."}}}}}}}},"/data/hackernews/search":{"post":{"operationId":"hackernews/search","tags":["HackerNews"],"summary":"Search HackerNews","description":"Search HackerNews stories and comments (via Algolia's HN index).\n\n### Query syntax\n\n`query` supports HN's native search qualifiers in addition to plain keywords: `author:USERNAME` / `by:USERNAME` (filter by author), `story:ID` (filter to one story's items), `points>N` / `points<N`, `comments>N` / `comments<N`, `\"exact phrase\"`, and `-word` (exclude). A query can be qualifiers-only with no keywords, e.g. `author:pg points>500`.\n\n### Credits\n\nEach **successful** response deducts **2 credits** from your organization. Requests that fail (4xx / 5xx) are not billed.\n\nSee the [credits documentation](https://snitchfeed.com/docs/api/credits) for the full rate table.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Search keywords for HackerNews stories/comments. Also supports HN's native search qualifiers: `author:USERNAME` or `by:USERNAME` (filter by author), `story:ID` (filter to one story's items), `points>N` / `points<N` (filter by points), `comments>N` / `comments<N` (filter by comment count), `\"exact phrase\"`, and `-word` (exclude a word). Can be qualifiers-only with no keywords, e.g. \"author:pg points>500\"."},"tags":{"type":"array","items":{"type":"string","enum":["story","comment"]},"description":"Restrict to stories, comments, or both (default both)."},"page":{"type":"integer","minimum":0,"description":"Zero-indexed page number for pagination."},"hitsPerPage":{"type":"integer","minimum":1,"maximum":100,"description":"Results per page (capped at 100)."}},"required":["query"],"additionalProperties":false,"description":"Request body for `POST /data/hackernews/search`."}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"posts":{"type":"array","items":{"type":"object","properties":{"objectID":{"type":"string","description":"Stable HN item identifier."},"type":{"type":"string","enum":["story","comment"],"description":"Story or comment."},"title":{"type":"string","description":"Story title (stories only)."},"body":{"type":"string","description":"Story text or comment text (plain text)."},"url":{"type":"string","description":"Canonical URL to the item on HackerNews."},"author":{"type":"string","description":"HackerNews username of the author."},"points":{"type":"number","description":"Story points (stories only)."},"numComments":{"type":"number","description":"Comment count (stories only)."},"createdAt":{"type":"string","description":"When the item was created (ISO 8601)."},"storyId":{"type":"string","description":"Parent story's objectID (comments only)."},"storyTitle":{"type":"string","description":"Parent story's title (comments only)."}},"required":["objectID","type","body","url","author","createdAt"],"additionalProperties":false},"description":"Matching items for this page."},"meta":{"type":"object","properties":{"returnedCount":{"type":"integer","minimum":0,"description":"Number of items returned in this response."},"hasMore":{"type":"boolean","description":"Whether more results exist beyond this page."},"nextPage":{"type":"integer","description":"Pass as `page` in the next request to fetch the next page."}},"required":["returnedCount","hasMore"],"additionalProperties":false,"description":"Pagination metadata for HackerNews search."}},"required":["requestId","posts","meta"],"additionalProperties":false,"description":"Successful `POST /data/hackernews/search` response."}}}},"400":{"description":"Validation or bad request","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dot-separated path to the invalid field (e.g. `filters.lang`)."},"message":{"type":"string","description":"Human-readable description of the issue."}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message","issues"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Validation error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"validation_error","message":"query: String must contain at least 1 character(s)","issues":[{"path":"query","message":"String must contain at least 1 character(s)"}]}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"retryAfter":{"type":"integer","exclusiveMinimum":0,"description":"Seconds until the rate limit resets (same value as the `Retry-After` response header)."}},"required":["code","message","retryAfter"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Rate limited"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"rate_limited","message":"Rate limit exceeded for linkedin. Try again later.","retryAfter":42}}}}},"502":{"description":"Upstream error","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["upstream_error"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Upstream error"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"upstream_error","message":"Upstream request failed."}}}}}}}},"/billing/usage":{"get":{"operationId":"usage","tags":["Billing"],"summary":"Get billing usage","description":"Returns credits consumed in the current billing period, the total credit limit, and when the period resets.\n\n**Read-only** — this endpoint does not consume credits.\n\nSee [metered prices](https://snitchfeed.com/docs/api/credits) for current per-search rates.","responses":{"200":{"description":"Credit usage summary for the current billing period","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string"},"creditsUsedThisPeriod":{"type":"number","description":"Credits consumed in the current billing period."},"creditsLimit":{"type":"number","description":"Total credit allowance for this period (plan recurring allowance plus top-up capacity counted toward the cap)."},"billingPeriodEndsAt":{"type":"string","description":"ISO 8601 instant when the current billing period ends for credit usage; counters roll forward after this time."}},"required":["requestId","creditsUsedThisPeriod","creditsLimit","billingPeriodEndsAt"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Unauthorized"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"unauthorized","message":"Invalid or revoked API key."}}}}},"502":{"description":"Billing or subscription data unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"requestId":{"type":"string","description":"Server-generated id for this request (logging / support)."},"error":{"type":"object","properties":{"code":{"type":"string","enum":["billing_unavailable"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["requestId","error"],"additionalProperties":false,"description":"Billing or subscription data unavailable"},"example":{"requestId":"01HXYZABCDEF","error":{"code":"billing_unavailable","message":"Could not load credit balance for this organization. Ensure the workspace has an active subscription."}}}}}}}}},"webhooks":{"match-created":{"post":{"tags":["Webhooks"],"summary":"New mention","description":"SnitchFeed POSTs this payload to your HTTPS endpoint each time a new mention is processed. Configure your endpoint URL in the platform under **Integrations → Webhooks**.\n\n- Only `match-created` is currently emitted.\n- Return any `2xx` status to acknowledge delivery — the response body is ignored.\n- Failed deliveries are retried with exponential backoff.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"matchId":{"type":"integer"},"listenerId":{"type":"integer"},"organizationId":{"type":"integer"},"event":{"type":"object","properties":{"id":{"type":"string","description":"Unique event id for this delivery."},"type":{"type":"string","enum":["match.created"]},"timestamp":{"type":"string","description":"ISO 8601 date-time string (JSON serialization of `Date`)."},"version":{"type":"string","enum":["1.0"]}},"required":["id","type","timestamp","version"],"additionalProperties":false},"platform":{"type":"string","enum":["reddit","twitter","bluesky","linkedin","hackernews"]},"datePosted":{"type":"string","description":"When the post was published."},"dateFound":{"type":"string","description":"When SnitchFeed detected the match."},"ai":{"type":"object","properties":{"summary":{"type":"string"},"relevance":{"type":"integer"},"relevanceReason":{"type":"string"},"sentiment":{"type":"integer"},"sentimentReason":{"type":"string"},"whyItMatters":{"type":"string"},"recommendedAction":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"language":{"type":"string"}},"required":["summary","relevance","relevanceReason","sentiment","sentimentReason","whyItMatters","recommendedAction","tags","language"],"additionalProperties":false},"reddit":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["post","comment"]},"subreddit":{"type":"string"},"isNsfw":{"type":"boolean"},"url":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"comment":{"type":"string"},"author":{"type":"string"},"engagement":{"type":"object","properties":{"score":{"type":"number"},"comments":{"type":"number"},"awards":{"type":"number"}},"required":["score"],"additionalProperties":false},"images":{"type":"array","items":{"type":"string"}},"videos":{"type":"array","items":{"type":"string"}},"parentPost":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"author":{"type":"string"},"datePosted":{"type":"string","description":"ISO 8601 date-time string (JSON serialization of `Date`)."},"engagement":{"type":"object","properties":{"score":{"type":"number"},"comments":{"type":"number"}},"required":["score","comments"],"additionalProperties":false}},"required":["id","title","body","author","datePosted","engagement"],"additionalProperties":false},"parentComment":{"type":"object","properties":{"id":{"type":"string"},"author":{"type":"string"},"comment":{"type":"string"},"datePosted":{"type":"string","description":"ISO 8601 date-time string (JSON serialization of `Date`)."},"engagement":{"type":"object","properties":{"score":{"type":"number"}},"required":["score"],"additionalProperties":false}},"required":["id","author","comment","datePosted","engagement"],"additionalProperties":false},"keywords":{"type":"array","items":{"type":"string"}}},"required":["id","type","subreddit","isNsfw","url","author","engagement","keywords"],"additionalProperties":false},"linkedin":{"type":"object","properties":{"urn":{"type":"string"},"url":{"type":"string"},"commentary":{"type":"string"},"author":{"type":"object","properties":{"name":{"type":"string"},"headline":{"type":"string"},"profileUrl":{"type":"string"},"avatarUrl":{"type":"string"}},"required":["name","headline","profileUrl","avatarUrl"],"additionalProperties":false},"engagement":{"type":"object","properties":{"likes":{"type":"number"},"comments":{"type":"number"},"shares":{"type":"number"},"reactions":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"count":{"type":"number"}},"required":["type","count"],"additionalProperties":false}}},"required":["likes","comments","shares","reactions"],"additionalProperties":false},"images":{"type":"array","items":{"type":"string"}},"article":{"type":"object","properties":{"title":{"type":"string"},"subtitle":{"type":"string"},"url":{"type":"string"},"thumbnailUrl":{"type":"string"}},"required":["title","subtitle","url","thumbnailUrl"],"additionalProperties":false},"video":{"type":"object","properties":{"thumbnailUrl":{"type":"string"},"duration":{"type":"number"},"provider":{"type":"string"}},"required":["thumbnailUrl","duration","provider"],"additionalProperties":false},"keywords":{"type":"array","items":{"type":"string"}}},"required":["urn","url","commentary","author","engagement","keywords"],"additionalProperties":false},"x":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"body":{"type":"string"},"author":{"type":"object","properties":{"username":{"type":"string"},"screenName":{"type":"string"}},"required":["username","screenName"],"additionalProperties":false},"engagement":{"type":"object","properties":{"likes":{"type":"number"},"retweets":{"type":"number"},"replies":{"type":"number"}},"additionalProperties":false},"images":{"type":"array","items":{"type":"string"}},"video":{"type":"string"},"keywords":{"type":"array","items":{"type":"string"}}},"required":["id","url","body","author","keywords"],"additionalProperties":false},"bluesky":{"type":"object","properties":{"url":{"type":"string"},"body":{"type":"string"},"author":{"type":"object","properties":{"username":{"type":"string"}},"required":["username"],"additionalProperties":false},"keywords":{"type":"array","items":{"type":"string"}}},"required":["url","body","author","keywords"],"additionalProperties":false}},"required":["matchId","listenerId","organizationId","event","platform","datePosted","dateFound","ai"],"additionalProperties":false}}}},"responses":{"200":{"description":"Return 2xx to acknowledge delivery. Response body is not interpreted."}}}}}}