# Apinoa Social media API > The Social media API: public profiles, posts, comments and media from TikTok, Instagram, YouTube, Reddit, X, Threads and LinkedIn, as normalized JSON. Every page of its documentation, in one file. Requests go to https://gateway.apinoa.com with the API key in an `x-api-key` header. A JSON answer is `{"success": true, "data": ...}`; an error is `{"success": false, "error": {"code", "message"}, "requestId"}`, and a request that fails is not billed. More: [Getting Started](https://apinoa.com/en/docs-raw/getting-started), [Authentication](https://apinoa.com/en/docs-raw/authentication), [Errors](https://apinoa.com/en/docs-raw/errors), [SDKs and MCP](https://apinoa.com/en/docs-raw/sdks); every operation as OpenAPI 3.1: https://apinoa.com/openapi.json. The other API families: https://apinoa.com/llms.txt. ## Contents - [SNS API](https://apinoa.com/en/docs-raw/api-reference/sns): Reddit, TikTok, YouTube, Instagram, Threads, LinkedIn and X through one set of operations and one social schema. - [Response Schema](https://apinoa.com/en/docs-raw/api-reference/sns/response-schema): Account, Post, Comment, Group and Page — the types every SNS platform returns, field by field. - [Reddit](https://apinoa.com/en/docs-raw/api-reference/reddit): Reddit through the shared SNS operations: users, posts, comment trees, communities and the popular feed. - [Profile](https://apinoa.com/en/docs-raw/api-reference/reddit/profile): Get a Reddit user's profile. - [Profiles](https://apinoa.com/en/docs-raw/api-reference/reddit/profiles): Search Reddit users by keyword. - [Post](https://apinoa.com/en/docs-raw/api-reference/reddit/post): Get one Reddit post. - [Posts](https://apinoa.com/en/docs-raw/api-reference/reddit/posts): List posts from any of Reddit's listings: a user, a community, a search, specific ids, or the popular feed. - [Comments](https://apinoa.com/en/docs-raw/api-reference/reddit/comments): Get a Reddit post's comment tree, the replies under one comment, or a user's comments. - [Group](https://apinoa.com/en/docs-raw/api-reference/reddit/group): Get a Reddit community. - [Groups](https://apinoa.com/en/docs-raw/api-reference/reddit/groups): Search Reddit communities, autocomplete a community name, or list the communities a user is active in. - [TikTok](https://apinoa.com/en/docs-raw/api-reference/tiktok): TikTok through the shared SNS operations: creators, videos and the video file itself, comments, followers, hashtags, sounds and the explore feed. - [Profile](https://apinoa.com/en/docs-raw/api-reference/tiktok/profile): Get a TikTok creator's profile. - [Profiles](https://apinoa.com/en/docs-raw/api-reference/tiktok/profiles): List a TikTok creator's followers or the accounts they follow. - [Post](https://apinoa.com/en/docs-raw/api-reference/tiktok/post): Get one TikTok video. - [Posts](https://apinoa.com/en/docs-raw/api-reference/tiktok/posts): List TikTok videos: a creator's, a hashtag's, a sound's, a playlist's, or the explore feed. - [Comments](https://apinoa.com/en/docs-raw/api-reference/tiktok/comments): Get a TikTok video's comments, or one comment's replies. - [Group](https://apinoa.com/en/docs-raw/api-reference/tiktok/group): Get a TikTok hashtag or sound. - [Groups](https://apinoa.com/en/docs-raw/api-reference/tiktok/groups): List a TikTok creator's playlists. - [Media](https://apinoa.com/en/docs-raw/api-reference/tiktok/media): Download a TikTok post's file, base64-encoded: a video's MP4, or one picture of a photo post. - [YouTube](https://apinoa.com/en/docs-raw/api-reference/youtube): YouTube through the shared SNS operations: channels, videos and Shorts, comments, search, related videos, hashtags and the trending charts. - [Profile](https://apinoa.com/en/docs-raw/api-reference/youtube/profile): Get a YouTube channel. - [Profiles](https://apinoa.com/en/docs-raw/api-reference/youtube/profiles): Search YouTube channels by keyword. - [Post](https://apinoa.com/en/docs-raw/api-reference/youtube/post): Get one YouTube video. - [Posts](https://apinoa.com/en/docs-raw/api-reference/youtube/posts): List YouTube videos: a channel's uploads, a search, a hashtag, related videos, or the trending charts. - [Comments](https://apinoa.com/en/docs-raw/api-reference/youtube/comments): Get a YouTube video's comments, or one comment's replies. - [Groups](https://apinoa.com/en/docs-raw/api-reference/youtube/groups): List a YouTube channel's playlists. - [Instagram](https://apinoa.com/en/docs-raw/api-reference/instagram): Instagram through the shared SNS operations: profiles, posts and reels, comments, highlights, hashtags and locations. - [Profile](https://apinoa.com/en/docs-raw/api-reference/instagram/profile): Get an Instagram account's profile. - [Post](https://apinoa.com/en/docs-raw/api-reference/instagram/post): Get one Instagram post or reel. - [Posts](https://apinoa.com/en/docs-raw/api-reference/instagram/posts): List Instagram posts: an account's posts or reels, a hashtag's top posts, or a location's recent posts. - [Comments](https://apinoa.com/en/docs-raw/api-reference/instagram/comments): Get an Instagram post's comments, newest first. - [Group](https://apinoa.com/en/docs-raw/api-reference/instagram/group): Get an Instagram hashtag or location. - [Groups](https://apinoa.com/en/docs-raw/api-reference/instagram/groups): List an Instagram creator's highlights. - [Threads](https://apinoa.com/en/docs-raw/api-reference/threads): Threads through the shared SNS operations: profiles, posts, reposts, replies, search and topic tags. - [Profile](https://apinoa.com/en/docs-raw/api-reference/threads/profile): Get a Threads account's profile. - [Post](https://apinoa.com/en/docs-raw/api-reference/threads/post): Get one Threads post. - [Posts](https://apinoa.com/en/docs-raw/api-reference/threads/posts): List Threads posts: an account's threads, reposts or replies, a search, or a topic tag. - [Comments](https://apinoa.com/en/docs-raw/api-reference/threads/comments): Get a Threads post's replies. - [LinkedIn](https://apinoa.com/en/docs-raw/api-reference/linkedin): LinkedIn through the shared SNS operations: member profiles, company pages, their recent posts and comments, plus job postings. - [Profile](https://apinoa.com/en/docs-raw/api-reference/linkedin/profile): Get a LinkedIn member's public profile. - [Post](https://apinoa.com/en/docs-raw/api-reference/linkedin/post): Get one LinkedIn post. - [Posts](https://apinoa.com/en/docs-raw/api-reference/linkedin/posts): List a LinkedIn member's or company's recent posts. - [Comments](https://apinoa.com/en/docs-raw/api-reference/linkedin/comments): Get a LinkedIn post's top comments. - [Group](https://apinoa.com/en/docs-raw/api-reference/linkedin/group): Get a LinkedIn company page. - [Job](https://apinoa.com/en/docs-raw/api-reference/linkedin/job): Get one LinkedIn job posting. - [Jobs](https://apinoa.com/en/docs-raw/api-reference/linkedin/jobs): Search LinkedIn job postings. - [X](https://apinoa.com/en/docs-raw/api-reference/x): X through the shared SNS operations: profiles, posts, an account's recent posts and communities. - [Profile](https://apinoa.com/en/docs-raw/api-reference/x/profile): Get an X account's profile. - [Post](https://apinoa.com/en/docs-raw/api-reference/x/post): Get one X post. - [Posts](https://apinoa.com/en/docs-raw/api-reference/x/posts): List an X account's recent posts. - [Group](https://apinoa.com/en/docs-raw/api-reference/x/group): Get an X community. --- # SNS API > Reddit, TikTok, YouTube, Instagram, Threads, LinkedIn and X through one set of operations and one social schema. Source: https://apinoa.com/en/docs-raw/api-reference/sns The SNS API serves seven social platforms through **the same eight operations and one schema**. An operation is named by what it returns; what you pass decides what it reads. A TikTok creator and a YouTube channel are both a `profile`. A subreddit's posts, a hashtag's videos and an account's reels are all `posts`. The code that reads one platform reads all of them. ```bash curl "https://gateway.apinoa.com/v1/tiktok/posts?username=tiktok" -H "x-api-key: $APINOA_API_KEY" curl "https://gateway.apinoa.com/v1/youtube/posts?username=@mkbhd&type=shorts" -H "x-api-key: $APINOA_API_KEY" curl "https://gateway.apinoa.com/v1/reddit/posts?community=technology&sort=top" -H "x-api-key: $APINOA_API_KEY" ``` ## Operations | Operation | Returns | What It Reads, by What You Pass | |---|---|---| | `profile` | `Account` | One account: `username` (or `userId`) | | `profiles` | `Page` | Accounts: a search (`query`), or an account's followers/following | | `post` | `Post` | One post: `id` | | `posts` | `Page` | Posts: an account's (`username`), a search (`query`), a `hashtag`, `community`, `sound`, `location`, `company` or `playlist`, posts `relatedTo` one — or, with nothing, the platform's trending feed | | `comments` | `Page` | A `post`'s comments, one `comment`'s replies, or an account's comments | | `group` | `Group` | One community, hashtag, sound, location or company | | `groups` | `Page` | Communities by search, or an account's playlists, highlights or communities | | `media` | Media file | A post's media file | ## Which Platform Has Which | | profile | profiles | post | posts | comments | group | groups | media | |---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| | [Reddit](/docs/api-reference/reddit) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | [TikTok](/docs/api-reference/tiktok) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [YouTube](/docs/api-reference/youtube) | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ | | | [Instagram](/docs/api-reference/instagram) | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | | | [Threads](/docs/api-reference/threads) | ✓ | | ✓ | ✓ | ✓ | | | | | [LinkedIn](/docs/api-reference/linkedin) | ✓ | | ✓ | ✓ | ✓ | ✓ | | | | [X](/docs/api-reference/x) | ✓ | | ✓ | ✓ | | ✓ | | | LinkedIn also has `job` and `jobs`, the one record no other platform has. Each platform's page lists exactly which inputs every operation takes there. ## Inputs One name means one thing on every platform: | Input | Meaning | |---|---| | `username` | an account's handle (with or without `@`, `u/`, `in/`) | | `userId` | an account's own id (TikTok secUid, YouTube UC… id, X/Threads numeric id) — saves a lookup where a platform needs one | | `id` | the thing the operation returns: a post's id or shortcode, a job's id | | `post`, `comment` | the post (or comment) whose comments to read | | `query` | keywords; `prefix` for autocomplete | | `hashtag` `community` `sound` `location` `company` `playlist` | the group whose posts — or details — to read | | `relatedTo` | a post; returns posts related to it | | `type` | which listing of a source: `reels`, `shorts`, `reposts`, `likes`, `followers`… | | `sort` `period` `country` | ordering, time window, and the country of a regional feed | | `include` | extra reads attached under `ext` (a Reddit community's `rules`), billed per read | | `limit` | items per page, where the platform lets you choose | | `cursor` | the next page | Every identifier also takes the page URL. Paste a profile, post or community link wherever its id goes. Pass one source per call; two (or none, where the operation needs one) answer `400 INVALID_PARAMS` naming the choices. ## What Is the Same Everywhere - **Shapes.** Every operation returns one of four types — `Account`, `Post`, `Comment`, `Group` — or a `Page` of them, described in the [Response Schema](/docs/api-reference/sns/response-schema). What only one platform has (a TikTok sound's music id, a Reddit post's score) is in that object's `ext`. - **Paging.** A list answers with an opaque `cursor`. For the next page, call the same operation with `cursor` alone — it carries everything the first call asked for. No `cursor` means there is no next page. - **Absent is not zero.** A count the platform hides is left out, never reported as `0`. Times are ISO 8601, UTC. - **Price.** $0.001 per unit. Most calls are one unit; each operation's page says when it can cost more. ## Errors The same envelope and codes as the rest of the API — see [Errors](/docs/errors). A private, deleted or age-restricted account, post or community answers `404 NOT_FOUND`; where the platform shows a missing page the same way it shows a blocked one, it answers with an error rather than an empty result. ## Reference - [Response Schema](/docs/api-reference/sns/response-schema): every field of every type - [Errors](/docs/errors): every error code --- # Response Schema > Account, Post, Comment, Group and Page — the types every SNS platform returns, field by field. Source: https://apinoa.com/en/docs-raw/api-reference/sns/response-schema Five types cover every SNS operation, and a field means the same thing on every platform. Optional fields are genuinely optional: **absent means the platform did not say**. An absent `metrics.likes` is a hidden count, not zero likes. Times are ISO 8601, UTC. Every object carries `platform`, and may carry `ext`: the facts only that platform has, under that platform's own names. The smaller shapes inside an object can carry their own `ext` too, down to a mention, a link preview, a poll, a place or a sound. ## Account A person, creator, channel or page. | Field | Type | Notes | |---|---|---| | `platform` | string | `reddit` `tiktok` `youtube` `instagram` `threads` `linkedin` `x` | | `handle` | string | the @name, or the platform's equivalent | | `url` | string | the profile page | | `id` | string? | the platform's stable id | | `displayName` `bio` | string? | | | `avatarUrl` `bannerUrl` | string? | | | `verified` | boolean? | | | `createdAt` | string? | when the account was created | | `counts` | object? | `{followers?, following?, posts?}` | | `links` | array? | `{url, title?}` — the links on the profile | | `private` | boolean? | a private or protected account: its posts are visible only to approved followers | | `category` | string? | the account's own category label, verbatim (`Musician/Band`, `Media & News Company`) | | `location` | string? | where the account says it is, verbatim as shown (`San Francisco Bay Area`); not geocoded | | `ext` | object? | platform-only facts | ## Post A post, video, reel, short, thread or tweet. | Field | Type | Notes | |---|---|---| | `id` `url` | string | | | `author` | AccountRef | `{platform, id?, handle?, displayName?, url?, avatarUrl?, verified?, counts?}` | | `title` | string? | where the platform has titles (Reddit, YouTube) | | `text` | string? | the body or caption | | `createdAt` `editedAt` | string? | | | `edited` | boolean? | the platform marks the post edited; `editedAt` says when, where the platform states it | | `lang` | string? | | | `media` | Media[] | images, GIFs, videos and embeds — see below | | `metrics` | object? | `{likes?, comments?, shares?, views?, reposts?, quotes?, saves?}` | | `entities` | object? | `{mentions?, urls?, hashtags?}` found in the text | | `linkPreview` | object? | `{url, title?, description?, thumbnailUrl?, domain?}` | | `poll` | object? | `{options: [{text, votes?}], totalVotes?, endsAt?}` | | `place` | object? | `{name, id?, type?, lat?, lng?, address?, city?, country?}` | | `audio` | object? | `{id?, title?, artist?, album?, url?, coverUrl?, durationSec?, original?}` — a TikTok sound, a reel's audio | | `live` | boolean? | a live stream | | `broadcast` | object? | `{status}` — the stream's lifecycle: `scheduled`, `live` or `ended`. YouTube's times (`scheduledAt`, `startedAt`, `endedAt`) are its `ext` | | `repostOf` `quoteOf` | Post? | the post this one reposts or quotes | | `inReplyTo` | object? | `{id, url?, author?}` — the post this one replies to | | `sponsored` | boolean? | a paid or branded-content post | | `pinned` | boolean? | pinned by its author to the top of their profile | | `aiGenerated` | boolean? | the platform labels it AI-generated | | `sensitive` | boolean? | the platform marks it sensitive or NSFW | | `ext` | object? | platform-only facts | What each platform counts as `views` differs: TikTok and YouTube report plays, X reports impressions. Reddit's `score` is not likes, so it is in `ext`, never in `metrics.likes`. `shares` counts shares and sends only: `reposts` and `quotes` have their own counts, and `saves` is bookmarks. YouTube's audience watching a stream right now is the post's `ext.liveViewers`, never `views`. The `true`/`false` flags (`sponsored`, `pinned`, `aiGenerated`, `sensitive`, `edited`, `byAuthor`, …) follow the same rule as counts: absent means the platform did not say. `audio.coverUrl` is the track's cover art, and `audio.durationSec` the whole track's length, not the part the post uses. `audio.original: true` is the poster's own original sound rather than a catalogue track; it is omitted, never `false`, when the platform does not say. `author` points at the account rather than holding the whole profile. When the post states more about its author, the same fields as on [Account](#account) come with it: `bio`, `bannerUrl`, `createdAt`, `links`, `private`, `category`, `location`. None is guaranteed; `profile` returns the full account. ### Media | Field | Type | Notes | |---|---|---| | `type` | `image` \| `gif` \| `video` \| `embed` | | | `id` | string? | the platform's own id for this media item | | `url` | string | | | `width` `height` | number? | | | `thumbnailUrl` | string? | | | `durationSec` | number? | | | `title` | string? | the item's own title, where the platform gives one | | `hasAudio` | boolean? | whether a video has sound, where the platform says | | `variants` | array? | other renditions: `{url, width?, height?, bitrate?, contentType?, codec?, sizeBytes?, fps?, quality?}` — `quality` is the platform's own label for the rendition (`720p`, `hd`) | | `altText` `caption` | string? | | | `tags` | array? | accounts tagged in this item: `{account}` — an AccountRef. Where Instagram places the tag on the picture is its `ext` (`x`, `y`: fractions of the width and height, from the top left) | | `captions` | array? | the video's caption and subtitle tracks: `{url, lang?, format?}` — `format` such as `webvtt` | ## Comment | Field | Type | Notes | |---|---|---| | `id` `postId` | string | | | `parentId` | string? | the comment this one replies to | | `author` | AccountRef | | | `text` | string | | | `entities` | object? | `{mentions?, urls?, hashtags?}` found in the text, as on a post | | `createdAt` `editedAt` `lang` | string? | | | `edited` | boolean? | the platform marks the comment edited; `editedAt` says when, where the platform states it | | `pinned` | boolean? | | | `byAuthor` | boolean? | written by the post's author | | `likedByAuthor` | boolean? | the post's author liked or hearted it | | `metrics` | object? | `{likes?, replies?}` | | `media` | Media[]? | | | `replies` | Comment[] | replies included with this comment | | `moreReplies` | object? | `{count?, cursor?}` — what was left unloaded; load it with `comments`: `comment=` the cursor (YouTube) or the comment's `id` (Reddit, TikTok) | ## Group Anything posts gather under. | Field | Type | Notes | |---|---|---| | `kind` | string | `community` `channel` `company` `hashtag` `sound` `topic` `location` `list` | | `id` `name` `url` | string | | | `description` | string? | | | `avatarUrl` `bannerUrl` | string? | | | `createdAt` | string? | | | `counts` | object? | `{members?, posts?}` | | `sensitive` | boolean? | the platform marks the group sensitive or NSFW | ## Page Every list. ```json { "platform": "tiktok", "items": [ /* Post, Comment, Account or Group */ ], "cursor": "…", "total": 1640 } ``` Call the same operation with `cursor` alone for the next page. No `cursor` means this is the last page. `total`, when present, is how many items the whole list holds, exactly as the platform states it. It is omitted when the platform gives no exact count — and lists of accounts and of groups never carry it: no platform states one. It is not a promise that every item is reachable: platforms cap how far a list pages, and the list ends when the `cursor` does. `order`, when present, is the order the platform actually served the list in, under the platform's own name: a Reddit comment sort (`confidence`, `new`), or X's `latest` or `popular`. It reports what was served, which is not always what you asked for. Lists of accounts do not carry it. A comment page can also carry `post` (the post the comments are on — Reddit and YouTube return it, Threads with `include=post`) and `ext.more` (top-level comments the platform left unloaded — Reddit). --- # Reddit > Reddit through the shared SNS operations: users, posts, comment trees, communities and the popular feed. Source: https://apinoa.com/en/docs-raw/api-reference/reddit ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/reddit/profile) | `GET \| POST /v1/reddit/profile` | `Account` | $0.001–$0.002 | | [Profiles](/docs/api-reference/reddit/profiles) | `GET \| POST /v1/reddit/profiles` | `Page` | $0.001 | | [Post](/docs/api-reference/reddit/post) | `GET \| POST /v1/reddit/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/reddit/posts) | `GET \| POST /v1/reddit/posts` | `Page` | $0.001 | | [Comments](/docs/api-reference/reddit/comments) | `GET \| POST /v1/reddit/comments` | `Page` | $0.001 | | [Group](/docs/api-reference/reddit/group) | `GET \| POST /v1/reddit/group` | `Group` | $0.001–$0.003 | | [Groups](/docs/api-reference/reddit/groups) | `GET \| POST /v1/reddit/groups` | `Page` | $0.001 | --- # Profile > Get a Reddit user's profile. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/profile ```http GET | POST /v1/reddit/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/profile?username=spez" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "spez" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/profile", params={"username": "spez"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The user's profile | `include=trophies` adds their trophy case under `ext.trophies` (+1 unit) | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `include` | string list | | Extra reads to attach under `ext`: trophies (+1 unit). | | `username` | string | | Username, with or without u/, or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "id": "1w72", "handle": "spez", "displayName": "spez", "bio": "Reddit CEO", "url": "https://www.reddit.com/user/spez/", "avatarUrl": "https://styles.redditmedia.com/t5_3k30p/styles/profileIcon_uj015iwx9s7g1.png?width=256&height=256&crop=256:256,smart&s=…", "bannerUrl": "https://b.thumbs.redditmedia.com/KWeEpVxXOGLoloMbM0IxGt9EiKPXizpwFgcSeWqtpZM.png", "verified": true, "createdAt": "2005-06-06T04:00:00.000Z", "ext": { "fullname": "t2_1w72", "karma": { "post": 184587, "comment": 756538, "total": 941125 }, "contributions": 4068, "moderatorOf": [ { "name": "announcements", "id": "2r0ij", "iconUrl": "https://styles.redditmedia.com/t5_2r0ij/styles/communityIcon_yor9myhxz5x11.png?width=64&frame=1&auto=webp&s=…", "members": 302607039 }, { "name": "blog", "id": "2qh49", "iconUrl": "https://styles.redditmedia.com/t5_2qh49/styles/communityIcon_357lawpgz5x11.png?width=64&frame=1&auto=webp&s=…", "members": 18750174 }, { "name": "programming", "id": "2fwo", "iconUrl": "https://styles.redditmedia.com/t5_2fwo/styles/communityIcon_1bqa1ibfp8q11.png?width=64&frame=1&auto=webp&s=…", "members": 6930767 } ], "employee": true, "moderator": true, "premium": true, "hasVerifiedEmail": true, "acceptsFollowers": true, "iconUrl": "https://styles.redditmedia.com/t5_3k30p/styles/profileIcon_uj015iwx9s7g1.png?width=256&height=256&crop=256:256,smart&s=…" } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 4 more, so $0.005 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Profiles > Search Reddit users by keyword. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/profiles ```http GET | POST /v1/reddit/profiles ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/profiles?query=python&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ query: "python", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/profiles?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/profiles", params={"query": "python", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `query` | A user search | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `limit` | integer 1–100 | | Items per page, 1–100. | | `query` | string | | Keywords to search accounts for. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "items": [ { "platform": "reddit", "id": "32tit", "handle": "python", "url": "https://www.reddit.com/user/python/", "avatarUrl": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_5.png", "verified": true, "createdAt": "2008-01-28T15:10:46.000Z", "ext": { "fullname": "t2_32tit", "karma": { "post": 1, "comment": 0 }, "hasVerifiedEmail": false, "acceptsFollowers": true, "iconUrl": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_5.png" } }, { "platform": "reddit", "id": "s6onk5we", "handle": "python-python-python", "url": "https://www.reddit.com/user/python-python-python/", "avatarUrl": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_6.png", "verified": true, "createdAt": "2022-09-04T05:54:45.000Z", "ext": { "fullname": "t2_s6onk5we", "karma": { "post": 1, "comment": 12 }, "hasVerifiedEmail": true, "acceptsFollowers": false, "hideFromRobots": true, "iconUrl": "https://www.redditstatic.com/avatars/defaults/v2/avatar_default_6.png" } } ] } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one Reddit post. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/post ```http GET | POST /v1/reddit/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/post?id=1wtm5mp" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "1wtm5mp" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/post", params={"id": "1wtm5mp"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The post | An id, a `t3_` fullname, or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Post id (base36), fullname (t3_…), or the post URL (reddit.com, old.reddit.com, redd.it). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "id": "1wtm5mp", "url": "https://www.reddit.com/r/technology/comments/1wtm5mp/mcdonalds_is_reportedly_using_ai_to_dynamically/", "author": { "platform": "reddit", "handle": "AdSpecialist6598", "id": "cc0n0rs5" }, "title": "McDonald's Is Reportedly Using AI To \"Dynamically\" Price Its Burgers", "createdAt": "2026-09-29T21:06:04.000Z", "media": [], "metrics": { "comments": 3406 }, "linkPreview": { "url": "https://www.engadget.com/2272211/mcdonalds-is-reportedly-using-ai-to-dynamically-price-its-burgers/", "domain": "engadget.com", "thumbnailUrl": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?auto=webp&s=b396d5d14e8ed04fcfdafd4db…" }, "sensitive": false, "ext": { "fullname": "t3_1wtm5mp", "score": 19516, "ups": 19516, "upvoteRatio": 0.94, "numCrossposts": 6, "awards": 0, "flair": "Business", "flairTextColor": "dark", "flairTemplateId": "49cac61c-a816-11e9-be34-0ebbab5890a0", "kind": "link", "preview": { "source": { "url": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?auto=webp&s=b396d5d14e8ed04fcfdafd4db…", "width": 1600, "height": 898 }, "resolutions": [ { "url": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?width=108&crop=smart&auto=webp&s=300b…", "width": 108, "height": 60 }, { "url": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?width=216&crop=smart&auto=webp&s=74aa…", "width": 216, "height": 121 } ], "enabled": false }, "thumbnailUrl": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?width=320&crop=smart&auto=webp&s=7d75…", "spoiler": false, "locked": false, "archived": false, "community": { "name": "technology", "id": "2qh16", "subscribers": 20595712, "type": "public" } } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List posts from any of Reddit's listings: a user, a community, a search, specific ids, or the popular feed. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/posts ```http GET | POST /v1/reddit/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/posts?community=technology&sort=top&period=week&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ community: "technology", sort: "top", period: "week", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/posts", params={"community": "technology", "sort": "top", "period": "week", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | A user's posts | `sort`: `new`, `hot`, `top`, `controversial` | | `community` | A community's posts | `sort`: `hot`, `new`, `top`, `rising`, `controversial` | | `query` | A post search | `sort`: `relevance`, `hot`, `top`, `new`, `comments`; add `community` to search inside one | | `ids` | Specific posts, up to 100 in one call | | | nothing | The popular feed | `country` picks the country's feed; `sort`: `hot`, `new`, `top`, `rising` | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `community` | string | | A community's posts: name (with or without r/) or URL. With `query`, narrows the search to it. | | `country` | string | | Default feed only: the country whose popular feed to read (ISO alpha-2). | | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `ids` | string list | | Specific posts: ids, fullnames (t3_…) or URLs, 1–100 in one call. | | `limit` | integer 1–100 | | Items per page, 1–100. | | `period` | enum | | Time window for sort top or controversial: hour, day, week, month, year or all. `hour` `day` `week` `month` `year` `all` | | `query` | string | | Search posts by keyword. | | `sort` | enum | | Order. username: new, hot, top, controversial · community: hot, new, top, rising, controversial · query: relevance, hot, top, new, comments · default feed: hot, new, top, rising. `hot` `new` `top` `rising` `controversial` `relevance` `comments` | | `username` | string | | A user's posts: username (with or without u/) or profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "items": [ { "platform": "reddit", "id": "1xcg8as", "url": "https://www.reddit.com/r/technology/comments/1xcg8as/pure_arrogance_anger_in_finland_as_google/", "author": { "platform": "reddit", "handle": "WombatusMighty", "id": "5dv971n4" }, "title": "‘Pure arrogance’: anger in Finland as Google illegally fells 250,000 trees for datacentre", "createdAt": "2026-10-22T11:41:24.000Z", "media": [], "metrics": { "comments": 1760 }, "linkPreview": { "url": "https://www.theguardian.com/environment/ng-interactive/2026/oct/22/finland-google-felling-trees-datacentre", "domain": "theguardian.com", "thumbnailUrl": "https://external-preview.redd.it/lFXQEMQFV6biLNRdb5GCAM5QH6hE_uoy07Oh_R_8gGY.jpeg?auto=webp&s=c2e26eb42ca63eb3b645fb216…" }, "sensitive": false, "ext": { "fullname": "t3_1xcg8as", "score": 43304, "ups": 43304, "upvoteRatio": 0.97, "numCrossposts": 13, "awards": 0, "flair": "Society", "flairTextColor": "dark", "flairTemplateId": "80187d9a-a816-11e9-a79b-0ea66e3761e6", "kind": "link", "preview": { "source": { "url": "https://external-preview.redd.it/lFXQEMQFV6biLNRdb5GCAM5QH6hE_uoy07Oh_R_8gGY.jpeg?auto=webp&s=c2e26eb42ca63eb3b645fb216…", "width": 1200, "height": 630 }, "resolutions": [ { "url": "https://external-preview.redd.it/lFXQEMQFV6biLNRdb5GCAM5QH6hE_uoy07Oh_R_8gGY.jpeg?width=108&crop=smart&auto=webp&s=207c…", "width": 108, "height": 56 }, { "url": "https://external-preview.redd.it/lFXQEMQFV6biLNRdb5GCAM5QH6hE_uoy07Oh_R_8gGY.jpeg?width=216&crop=smart&auto=webp&s=4886…", "width": 216, "height": 113 } ], "enabled": false }, "thumbnailUrl": "https://external-preview.redd.it/lFXQEMQFV6biLNRdb5GCAM5QH6hE_uoy07Oh_R_8gGY.jpeg?width=320&crop=smart&auto=webp&s=34e6…", "spoiler": false, "locked": false, "archived": false, "community": { "name": "technology", "id": "2qh16", "subscribers": 20595712, "type": "public" } } } ], "cursor": "VScWoTDcqFrJzxjNiQLrLiERD67YI2Z7BDybCfuuuw7Y1fj0I93Td2ktHpxH3S9F2oDtrW8sALbYe5XxRjBp60ZNmeeKaDtyJYHrrIWz545u3odld5-ZK0P…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - `period` (`hour` … `all`) applies with `sort=top` or `sort=controversial`. --- # Comments > Get a Reddit post's comment tree, the replies under one comment, or a user's comments. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/comments ```http GET | POST /v1/reddit/comments ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/comments?post=1wtm5mp" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "1wtm5mp" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/comments?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/comments", params={"post": "1wtm5mp"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | A post's comment tree | Top-level comments with the replies Reddit nests under them; the post is in `post`. `sort`: `confidence` (default), `top`, `new`, `controversial`, `old`, `qa` | | `post` + `comment` | The replies under one comment | That comment, with its replies nested | | `username` | A user's comments | `sort`: `new`, `hot`, `top`, `controversial` | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `comment` | string | | With `post`: the comment whose replies to load (base36 id or t1_ fullname) — e.g. one whose `moreReplies` says replies were held back. | | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `limit` | integer 1–100 | | Items per page, 1–100. | | `period` | enum | | Time window for sort top or controversial: hour, day, week, month, year or all. `hour` `day` `week` `month` `year` `all` | | `post` | string | | A post's comments: post id, fullname (t3_…) or URL. | | `sort` | enum | | Order. post: confidence (Reddit's 'best'), top, new, controversial, old, qa · username: new, hot, top, controversial. `confidence` `top` `new` `controversial` `old` `qa` `hot` | | `username` | string | | A user's comments: username or profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Comment`](/docs/api-reference/sns/response-schema#comment) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "items": [ { "platform": "reddit", "id": "pcvg4r0", "url": "https://www.reddit.com/r/technology/comments/1wtm5mp/comment/pcvg4r0/", "postId": "1wtm5mp", "author": { "platform": "reddit", "handle": "bryancald", "avatarUrl": "https://styles.redditmedia.com/t5_21dyao/styles/profileIcon_snoo96d39f88-0d0d-4954-a766-4738a4900b3a-headshot.png?width…" }, "text": "I truly hope this leads to the demise of McDonalds and any other company that uses this business model.", "createdAt": "2026-09-29T21:14:47.455Z", "replies": [], "moreReplies": { "count": 114, "cursor": "L4XGv5gQ_FjNqfTT50wyH8HLEFcVKbYmFyUeCUqK7sWTOyfFoRJhjidTb3_j1nbWbQFGMKsNt5HrRLGMOg0FKTXRRGR0E7PbYOr0toK3-hr569AwBmuPKON…" }, "ext": { "fullname": "t1_pcvg4r0", "parentFullname": "t3_1wtm5mp", "depth": 0, "score": 2311, "awards": 4, "community": "technology" } } ], "cursor": "uLbhrTSCxojEb5jzOX2Bo3KUoyHedf6jaMv9hj7OlvK_HdPrLWt8_nE12KPBUV3ilwsATxuZi_45UdCtRMCxSMjSdrBmRFU_oHiRvSHt1R3A7S1Qzdg5n-J…", "post": { "platform": "reddit", "id": "1wtm5mp", "url": "https://www.reddit.com/r/technology/comments/1wtm5mp/mcdonalds_is_reportedly_using_ai_to_dynamically/", "author": { "platform": "reddit", "handle": "AdSpecialist6598", "id": "cc0n0rs5" }, "title": "McDonald's Is Reportedly Using AI To \"Dynamically\" Price Its Burgers", "createdAt": "2026-09-29T21:06:04.000Z", "media": [], "metrics": { "comments": 3406 }, "linkPreview": { "url": "https://www.engadget.com/2272211/mcdonalds-is-reportedly-using-ai-to-dynamically-price-its-burgers/", "domain": "engadget.com", "thumbnailUrl": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?auto=webp&s=b396d5d14e8ed04fcfdafd4db…" }, "sensitive": false, "ext": { "fullname": "t3_1wtm5mp", "score": 19516, "ups": 19516, "upvoteRatio": 0.94, "numCrossposts": 6, "awards": 0, "flair": "Business", "flairTextColor": "dark", "flairTemplateId": "49cac61c-a816-11e9-be34-0ebbab5890a0", "kind": "link", "preview": { "source": { "url": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?auto=webp&s=b396d5d14e8ed04fcfdafd4db…", "width": 1600, "height": 898 }, "resolutions": [ { "url": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?width=108&crop=smart&auto=webp&s=300b…", "width": 108, "height": 60 }, { "url": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?width=216&crop=smart&auto=webp&s=74aa…", "width": 216, "height": 121 } ], "enabled": false }, "thumbnailUrl": "https://external-preview.redd.it/AQiUEhcGHE3YfA3sQBeQ19JM5rWJBxMI7qHIwZZXKCE.jpeg?width=320&crop=smart&auto=webp&s=7d75…", "spoiler": false, "locked": false, "archived": false, "community": { "name": "technology", "id": "2qh16", "subscribers": 20595712, "type": "public" } } } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 2 more, so $0.003 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - **A post's comments come in Reddit's own pages.** The first page holds Reddit's top 25 comments and the replies it nests under them; each `cursor` page loads the next batch, as Reddit's "more comments" does. `ext.more.count` says how many top-level comments are still to load. `limit` does not apply to a post's comments. - **Replies Reddit held back.** A comment whose replies were not all included carries `moreReplies.count`. Pass its `id` as `comment` (with the same `post`) to load them: the answer is that comment with its replies, and `cursor` continues its direct replies. - `comment` takes a base36 id or a `t1_` fullname. A comment the post does not have answers `404 NOT_FOUND`. - `period` (`hour` … `all`) applies to a user's comments with `sort=top` or `sort=controversial`; `sort=hot` is for a user's comments only. --- # Group > Get a Reddit community. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/group ```http GET | POST /v1/reddit/group ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/group?community=technology&include=rules" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ community: "technology", include: "rules" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/group?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/group", params={"community": "technology", "include": "rules"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `community` | The community | `include=rules,style` adds its rules and style under `ext` (+1 unit each) | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `community` | string | | Community name (with or without r/) or URL. | | `include` | string list | | Extra reads to attach under `ext`: rules (+1 unit). The community's style is always in `ext.style` (it comes with the community), so `style` is accepted and free. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "kind": "community", "id": "2qh16", "name": "technology", "url": "https://www.reddit.com/r/technology/", "description": "Subreddit dedicated to the news and discussions about the creation and use of technology and its surrounding issues.", "avatarUrl": "https://b.thumbs.redditmedia.com/J_fCwTYJkoM-way-eaOHv8AOHoF_jNXNqOvPrQ7bINY.png", "createdAt": "2008-01-25T03:27:55.000Z", "counts": { "members": 20595712 }, "sensitive": false, "ext": { "fullname": "t5_2qh16", "title": "/r/Technology ", "sidebar": "/r/Technology is a place to share and discuss the latest developments, happenings and curiosities in the world of techn…", "type": "public", "language": "en", "submissionType": "link", "advertiserCategory": "Local", "submitText": "* Submissions must be primarily news and developments relating to technology. Do not submit content older than 2 weeks.…", "settings": { "allowImages": false, "allowVideos": false, "allowVideoGifs": false, "allowPolls": false, "allowGalleries": false, "spoilersEnabled": false, "allowDiscovery": true, "restrictPosting": true, "restrictCommenting": false, "allOriginalContent": false, "linkFlairEnabled": true, "userFlairEnabled": true, "crosspostable": false, "archivePosts": true, "commentScoreHideMins": 0, "wikiEnabled": true }, "style": { "keyColor": "#0dd3bb", "iconUrl": "https://b.thumbs.redditmedia.com/J_fCwTYJkoM-way-eaOHv8AOHoF_jNXNqOvPrQ7bINY.png", "headerImageUrl": "https://a.thumbs.redditmedia.com/VwBugImhQhFTJhC0HjM9IWyEEEF898HHtI2AunD5SW4.png", "headerTitle": "r/Technology" }, "rules": { "platform": "reddit", "community": "technology", "rules": [ { "priority": 0, "shortName": "Submissions must be about technology", "description": "Submissions must be primarily news and developments relating to technology.\n\n[Self posts](https://www.reddit.com/r/tech…", "appliesTo": "posts", "violationReason": "Not related to technology", "createdAt": "2022-05-19T15:51:02.000Z" } ], "siteRules": [ "Spam", "Personal and confidential information" ] } } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Groups > Search Reddit communities, autocomplete a community name, or list the communities a user is active in. Source: https://apinoa.com/en/docs-raw/api-reference/reddit/groups ```http GET | POST /v1/reddit/groups ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/reddit/groups?query=photography&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ query: "photography", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/reddit/groups?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/reddit/groups", params={"query": "photography", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `query` | A community search | | | `prefix` | Name autocomplete: communities whose name starts with it | `includeNsfw`; one page | | `username` | The communities a user is active in | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `includeNsfw` | boolean | | prefix only: include over-18 communities. | | `limit` | integer 1–100 | | Items per page, 1–100. | | `prefix` | string | | Autocomplete: communities whose name starts with this (fast, one page). | | `query` | string | | Search communities by keyword. | | `username` | string | | The communities a user is active in: username or profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "reddit", "items": [ { "platform": "reddit", "kind": "community", "id": "2qh2a", "name": "photography", "url": "https://www.reddit.com/r/photography/", "description": "/r/photography is a place to politely discuss the tools, technique, art and culture of photography and to post topics t…", "avatarUrl": "https://styles.redditmedia.com/t5_2qh2a/styles/communityIcon_ewee979e9tib1.png?width=256&s=98f37a3e36d9c6c3631fe569571f…", "bannerUrl": "https://styles.redditmedia.com/t5_2qh2a/styles/bannerBackgroundImage_quu3wdl77tib1.png?width=4000&s=c4b33e56a54192ba98c…", "createdAt": "2008-01-25T05:32:49.000Z", "counts": { "members": 5668327 }, "sensitive": false, "ext": { "fullname": "t5_2qh2a", "title": "Photography", "sidebar": "/r/photography is a place to politely discuss the tools, technique, art and culture of photography and to post topics t…", "type": "public", "language": "en", "submissionType": "any", "advertiserCategory": "Lifestyles", "submitText": "**PLEASE REMEMBER TO FLAIR YOUR POSTS**\n\n* This sub is for discussing photography, not just sharing your work. We have…", "settings": { "allowImages": false, "allowVideos": false, "allowVideoGifs": false, "allowPolls": false, "allowGalleries": false, "spoilersEnabled": true, "allowDiscovery": true, "restrictPosting": true, "restrictCommenting": false, "allOriginalContent": false, "linkFlairEnabled": true, "userFlairEnabled": false, "crosspostable": false, "archivePosts": false, "commentScoreHideMins": 180, "suggestedCommentSort": "confidence", "wikiEnabled": true, "allowedMediaInComments": [ "giphy", "static" ] } } } ], "cursor": "RjvzT7CZ0WloEEGA_XTHSRLU2Ia7PEAPgIHxnz5MuTkxEAed4QiaxwGSMV4GjEyZuFRoNHN7XBfL0ccvbyKMrSdBmcbPTkJZWrF51xxHeqeRbGWY1xuM6tm…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # TikTok > TikTok through the shared SNS operations: creators, videos and the video file itself, comments, followers, hashtags, sounds and the explore feed. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/tiktok/profile) | `GET \| POST /v1/tiktok/profile` | `Account` | $0.001 | | [Profiles](/docs/api-reference/tiktok/profiles) | `GET \| POST /v1/tiktok/profiles` | `Page` | $0.001–$0.002 | | [Post](/docs/api-reference/tiktok/post) | `GET \| POST /v1/tiktok/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/tiktok/posts) | `GET \| POST /v1/tiktok/posts` | `Page` | $0.001–$0.002 | | [Comments](/docs/api-reference/tiktok/comments) | `GET \| POST /v1/tiktok/comments` | `Page` | $0.001 | | [Group](/docs/api-reference/tiktok/group) | `GET \| POST /v1/tiktok/group` | `Group` | $0.001 | | [Groups](/docs/api-reference/tiktok/groups) | `GET \| POST /v1/tiktok/groups` | `Page` | $0.001–$0.002 | | [Media](/docs/api-reference/tiktok/media) | `GET \| POST /v1/tiktok/media` | file | $0.002 | --- # Profile > Get a TikTok creator's profile. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/profile ```http GET | POST /v1/tiktok/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/profile?username=tiktok" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "tiktok" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/profile", params={"username": "tiktok"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The creator's profile | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "id": "107955", "handle": "tiktok", "displayName": "TikTok", "bio": "Your next discovery is waiting on TikTok.", "url": "https://www.tiktok.com/@tiktok", "avatarUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/ba67b11de451691939223e9d978e613a~tplv-tiktokx-cropcent…", "verified": true, "createdAt": "2015-02-28T17:22:29.000Z", "counts": { "followers": 96416004, "following": 1, "posts": 1512 }, "links": [ { "url": "https://tiktok.com/discovermore" } ], "private": false, "category": "Others", "ext": { "secUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM", "commerceUser": true, "isOrganization": true, "showPlaylistTab": true, "nickNameModifiedAt": "2021-12-03T19:26:40.000Z", "language": "en", "totalLikes": 466043853, "friendCount": 1 } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Profiles > List a TikTok creator's followers or the accounts they follow. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/profiles ```http GET | POST /v1/tiktok/profiles ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/profiles?username=tiktok&type=followers&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "tiktok", type: "followers", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/profiles?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/profiles", params={"username": "tiktok", "type": "followers", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | The creator's followers or following | `type`: `followers` or `following` (required) | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `limit` | integer 1–30 | | Items per page, 1–30. | | `type` | enum | | Which list: followers or following. `followers` `following` | | `userId` | string | | Creator secUid. Pass it instead of a username to save the lookup (1 unit instead of 2). | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "items": [ { "platform": "tiktok", "id": "7651672077083001872", "handle": "8_.bb2", "displayName": "Sana🪽", "url": "https://www.tiktok.com/@8_.bb2", "avatarUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-alisg-avt-0068/fed157f43458b599f7b81bd4799d0cc9~tplv-tiktokx-cropcenter:10…", "counts": { "followers": 1, "following": 16, "posts": 0 }, "private": true, "ext": { "secUid": "MS4wLjABAAAAKL9ua3uVT6GJrdgHm4DKeOvw6bx2VuMVurOM7_jddNL9Br1eP66TaawahpsasELo", "totalLikes": 0, "likesGiven": 182, "friendCount": 0 } } ], "cursor": "fPnN2iYq-3kvLCt6ANxmLXJf1aAzHKFbffLTUqzrvC4OoR3FZIhUoq9NMXwBuzOaZT_5WI_8P-Rw2hz3CL5chscH2UBm8AwGXnwSXHOxla9_MOaDL5RNS3d…", "ext": { "listCount": 96414142 } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one TikTok video. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/post ```http GET | POST /v1/tiktok/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/post?id=7698770783367171359" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "7698770783367171359" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/post", params={"id": "7698770783367171359"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The video | A numeric id, the URL or a share link | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Numeric video id, or the video URL / share link (vm.tiktok.com/…). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "id": "7698770783367171359", "url": "https://www.tiktok.com/@tiktok/video/769877078336…", "author": { "platform": "tiktok", "id": "107955", "handle": "tiktok", "displayName": "TikTok", "url": "https://www.tiktok.com/@tiktok", "avatarUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "verified": true, "counts": { "followers": 96400000, "following": 1, "posts": 1512 }, "ext": { "secUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBS…", "signature": "Your next discovery is waiting on TikTok.", "totalLikes": 466000000, "likesGiven": 4377 } }, "text": "The throwback sounds we didn’t know we were missi…", "createdAt": "2026-10-20T15:23:03.000Z", "lang": "en", "media": [ { "type": "video", "url": "https://www.tiktok.com/aweme/v1/play/?faid=1988&f…", "width": 720, "height": 1280, "thumbnailUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-usea…", "durationSec": 105, "variants": [ { "url": "https://www.tiktok.com/aweme/v1/play/?faid=1988&f…", "width": 720, "height": 1280, "bitrate": 1710350, "contentType": "video/mp4" } ], "ext": { "playAddr": "https://v16-webapp-prime.us.tiktok.com/video/tos/…", "downloadAddr": "https://v16-webapp-prime.us.tiktok.com/video/tos/…", "dynamicCover": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "definition": "720p", "videoQuality": "normal", "ratio": "720p", "codec": "h264", "format": "mp4", "bitrate": 1710350, "sizeBytes": 22592237, "loudness": -23.6, "peak": 0.53703, "hasOriginalAudio": true, "autoCaption": true, "bitrateVariants": [ { "gearName": "normal_720_0", "fps": 30, "codec": "h264", "sizeBytes": 22592237 } ], "subtitles": [ { "lang": "eng-US", "langId": "2", "url": "https://v16m-webapp.tiktokcdn-us.com/33b86e5d3f3c…", "format": "webvtt", "source": "ASR" } ] } } ], "metrics": { "likes": 5229, "comments": 1640, "shares": 503, "views": 351700, "reposts": 0, "saves": 450 }, "entities": { "mentions": [ { "handle": "adambarrera", "id": "6707847482024723461" } ] }, "audio": { "id": "7698770883132853023", "title": "original sound", "artist": "TikTok", "url": "https://v16m.tiktokcdn-us.com/c8470014c6bdd52cea2…" }, "ext": { "music": { "original": true, "coverUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "durationSec": 105, "isCommerceMusic": true }, "duetEnabled": true, "stitchEnabled": true, "diversificationLabels": [ "Music" ], "locationCreated": "US", "suggestedWords": [ "nostalgia sounds" ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List TikTok videos: a creator's, a hashtag's, a sound's, a playlist's, or the explore feed. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/posts ```http GET | POST /v1/tiktok/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/posts?username=tiktok&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "tiktok", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/posts", params={"username": "tiktok", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | A creator's videos | `type`: `posts` (default), `reposts`, `likes` (when public) | | `hashtag` | Videos under a hashtag | A name, or its numeric id (saves a lookup) | | `sound` | Videos using a sound | | | `playlist` | The videos in a playlist | | | nothing | The explore feed | `category` (default 120) | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `category` | string | | Default feed only: explore category id (default 120). | | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `hashtag` | string | | Videos under a hashtag: its name, or its numeric id (saves the lookup). A hashtag that is itself a number takes its # (#2024). | | `limit` | integer 1–30 | | Items per page, 1–30. | | `playlist` | string | | Videos in a playlist: id or URL (…/playlist/-). | | `sound` | string | | Videos using a sound: sound id or URL (…/music/-). | | `type` | enum | | username/userId: the creator's posts (default), reposts or likes. `posts` `reposts` `likes` | | `userId` | string | | Creator secUid. Pass it instead of a username to save the lookup (1 unit instead of 2). | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "items": [ { "platform": "tiktok", "id": "7700009319382650142", "url": "https://www.tiktok.com/@tiktok/video/770000931938…", "author": { "platform": "tiktok", "id": "107955", "handle": "tiktok", "displayName": "TikTok", "url": "https://www.tiktok.com/@tiktok", "avatarUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "verified": true, "counts": { "followers": 96400000, "following": 1, "posts": 1512 }, "ext": { "secUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBS…", "signature": "Your next discovery is waiting on TikTok.", "totalLikes": 466000000, "likesGiven": 4377 } }, "text": "The best part of searching a new city on TikTok?…", "createdAt": "2026-10-23T23:29:02.000Z", "lang": "en", "media": [ { "type": "video", "url": "https://www.tiktok.com/aweme/v1/play/?faid=1988&f…", "width": 720, "height": 1280, "thumbnailUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "durationSec": 107, "variants": [ { "url": "https://www.tiktok.com/aweme/v1/play/?faid=1988&f…", "width": 720, "height": 1280, "bitrate": 740138, "contentType": "video/mp4" } ], "ext": { "playAddr": "https://v16-webapp-prime.us.tiktok.com/video/tos/…", "downloadAddr": "https://v16-webapp-prime.us.tiktok.com/video/tos/…", "dynamicCover": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "definition": "720p", "videoQuality": "normal", "ratio": "720p", "codec": "h264", "format": "mp4", "bitrate": 740138, "sizeBytes": 9949494, "loudness": -19.9, "peak": 1, "hasOriginalAudio": true, "autoCaption": true, "bitrateVariants": [ { "gearName": "normal_720_0", "fps": 23, "codec": "h264", "sizeBytes": 9949494 } ], "subtitles": [ { "lang": "eng-US", "langId": "2", "url": "https://v16m-webapp.tiktokcdn-us.com/be8291ee2919…", "format": "webvtt", "source": "ASR" } ] } } ], "metrics": { "likes": 2235, "comments": 553, "shares": 144, "views": 122800, "reposts": 0, "saves": 132 }, "entities": { "mentions": [ { "handle": "morimatcha__", "id": "7547085538516485175" } ] }, "audio": { "id": "7700009421400869662", "title": "original sound", "artist": "TikTok", "url": "https://v16m.tiktokcdn-us.com/b9eda378f913298c1de…" }, "ext": { "music": { "original": true, "coverUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-usea…", "durationSec": 107, "isCommerceMusic": true, "appleMusicId": "1543888610", "spotifyId": "5Cf5U4MLpSJQb29IqY8bWA" }, "duetEnabled": true, "stitchEnabled": true } } ], "cursor": "z3_ejXLXnHrW_fwkl8jd8OBVtLZI0s7eC6UysxOBxhQMNFiYF…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - `userId` is the creator's `secUid`. Passing it instead of `username` saves a lookup: 1 unit instead of 2. --- # Comments > Get a TikTok video's comments, or one comment's replies. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/comments ```http GET | POST /v1/tiktok/comments ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/comments?post=7698770783367171359&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "7698770783367171359", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/comments?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/comments", params={"post": "7698770783367171359", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | The video's comments | A creator-pinned comment carries `pinned: true` | | `post` + `comment` | The replies under one comment | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `comment` | string | | With `post`: the comment whose replies to load (its id). | | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `limit` | integer 1–50 | | Items per page, 1–50. | | `post` | string | | The video's comments: numeric video id or URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Comment`](/docs/api-reference/sns/response-schema#comment) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "items": [ { "platform": "tiktok", "id": "7699995835177992974", "postId": "7698770783367171359", "author": { "platform": "tiktok", "id": "7489662053765334062", "handle": "it_isno_secret", "displayName": "🫰🏼Pierce.-.the.-.Bail bc!!", "url": "https://www.tiktok.com/@it_isno_secret", "avatarUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/e72b606bb39e85714c3b07f1d252d885~tplv-tiktokx-cropcent…", "ext": { "secUid": "MS4wLjABAAAAqHRwSRBsJrJwwu7Cp-8mtS24cHPddjR7WkyEvVebLd06LUrIJCGkNTyadnRNNJVn" } }, "text": "Can I please get the update", "replies": [], "createdAt": "2026-10-23T22:37:14.000Z", "lang": "en", "metrics": { "likes": 1 } } ], "cursor": "uHQDKupPSaV7esWOVsa9XqNJUReHIbjgDfCFmc0uwH88ed5FFM_ti8Cfd4yckTE0hWg4qx-gNhZAtKVKVbD7CFgIRxhSHn1gxjD_YYLraAJ2JR6J7QD6PyH…", "ext": { "commentCount": 1640 } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Group > Get a TikTok hashtag or sound. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/group ```http GET | POST /v1/tiktok/group ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/group?hashtag=fyp" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ hashtag: "fyp" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/group?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/group", params={"hashtag": "fyp"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `hashtag` | The hashtag | | | `sound` | The sound | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `hashtag` | string | | A hashtag: its name, or its numeric id. A hashtag that is itself a number takes its # (#2024). | | `sound` | string | | A sound: id or URL (…/music/-). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "kind": "hashtag", "id": "229207", "name": "fyp", "url": "https://www.tiktok.com/tag/fyp", "counts": { "posts": 9444954929 }, "ext": { "viewCount": 130457421095866 } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Groups > List a TikTok creator's playlists. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/groups ```http GET | POST /v1/tiktok/groups ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/groups?username=tiktok" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "tiktok" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/groups?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/groups", params={"username": "tiktok"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | The creator's playlists | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `limit` | integer 1–30 | | Items per page, 1–30. | | `type` | enum | | playlists (the only list TikTok has). `playlists` | | `userId` | string | | Creator secUid. Pass it instead of a username to save the lookup (1 unit instead of 2). | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "items": [ { "platform": "tiktok", "kind": "list", "id": "7681171537575824159", "name": "Songs Of The Summer 2026", "url": "https://www.tiktok.com/@tiktok/playlist/Songs%20Of%20The%20Summer%202026-7681171537575824159", "avatarUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/o8UZ7AA11Ciogu5XByiiAPBcCSAIMnAIEBfaK7~tplv-tiktokx-ori…", "counts": { "posts": 3 }, "ext": { "mixId": "7681171537575824159", "creatorHandle": "tiktok", "creatorId": "107955", "creatorSecUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM" } } ] } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Media > Download a TikTok post's file, base64-encoded: a video's MP4, or one picture of a photo post. Source: https://apinoa.com/en/docs-raw/api-reference/tiktok/media ```http GET | POST /v1/tiktok/media ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/tiktok/media?post=7698770783367171359" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "7698770783367171359" }); const res = await fetch(`https://gateway.apinoa.com/v1/tiktok/media?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/tiktok/media", params={"post": "7698770783367171359"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | The video's MP4, or one picture of a photo post | `index` picks the picture: 1-based, default 1 | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `index` | integer 1–100 | | Photo posts: which picture, 1-based (default 1). | | `post` | string | | The post whose file to download: numeric id or URL. A video gives its MP4, a photo post one picture. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns a media file in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "tiktok", "postId": "7698770783367171359", "contentType": "video/mp4", "bytes": 22592237, "encoding": "base64", "data": "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAVYbbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AABnMkAAQAAAQAAAAAAAAAAAAAAAAEAAAA…" } } ``` For a photo post, `index` picks the picture and the answer adds `index` and `count`, the number of pictures in the post. `?post=7681723633164717325&index=2` answers: ```json { "success": true, "data": { "platform": "tiktok", "postId": "7681723633164717325", "contentType": "image/jpeg", "bytes": 198005, "encoding": "base64", "data": "/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAEOKADAAQAAAA…", "index": 2, "count": 2 } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.002 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - The response is `{postId, contentType, bytes, encoding: "base64", data}`, plus `index` and `count` for a photo post. Decode `data` to get the file: the MP4 of a video, or the picture (`contentType` says which, e.g. `image/jpeg`). - An `index` past the last picture answers `400 INVALID_PARAMS` with the post's picture count. A video has one file, so any `index` above 1 is refused the same way. - Files over 64 MB answer `400 VIDEO_TOO_LARGE`. A call costs 2 units. --- # YouTube > YouTube through the shared SNS operations: channels, videos and Shorts, comments, search, related videos, hashtags and the trending charts. Source: https://apinoa.com/en/docs-raw/api-reference/youtube ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/youtube/profile) | `GET \| POST /v1/youtube/profile` | `Account` | $0.001–$0.002 | | [Profiles](/docs/api-reference/youtube/profiles) | `GET \| POST /v1/youtube/profiles` | `Page` | $0.001 | | [Post](/docs/api-reference/youtube/post) | `GET \| POST /v1/youtube/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/youtube/posts) | `GET \| POST /v1/youtube/posts` | `Page` | $0.001–$0.002 | | [Comments](/docs/api-reference/youtube/comments) | `GET \| POST /v1/youtube/comments` | `Page` | $0.001–$0.002 | | [Groups](/docs/api-reference/youtube/groups) | `GET \| POST /v1/youtube/groups` | `Page` | $0.001–$0.002 | --- # Profile > Get a YouTube channel. Source: https://apinoa.com/en/docs-raw/api-reference/youtube/profile ```http GET | POST /v1/youtube/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/youtube/profile?username=%40mkbhd" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "@mkbhd" }); const res = await fetch(`https://gateway.apinoa.com/v1/youtube/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/youtube/profile", params={"username": "@mkbhd"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | The channel | `username` is the @handle; `userId` is the `UC…` id | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `include` | string list | | about: also read the channel's About panel — join date (createdAt), exact video count, total views, country and every link (+1 unit). | | `userId` | string | | Channel id (UC…). | | `username` | string | | Channel @handle (with or without @), or the channel URL (/@handle, /channel/UC…, /c/…, /user/…). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "youtube", "id": "UCBJycsmduvYEL83R_U4JriQ", "handle": "mkbhd", "displayName": "Marques Brownlee", "bio": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics | Tech Head | Internet Personality!\n\nbusiness@MKBHD…", "url": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ", "avatarUrl": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s900-c-k-c…", "bannerUrl": "https://yt3.googleusercontent.com/zi_48HwHU4s0Hnb6tZuvRzTfCPHrLEnrtIMDLzMauDEyDmURh9JZ4wrNd3lKr7m9uVnT4YjYKw=w2560-fcro…", "verified": true, "counts": { "followers": 21400000, "posts": 1800 }, "links": [ { "url": "http://twitter.com/MKBHD", "title": "X" } ], "ext": { "keywords": [ "MKBHD", "MarquesBrownlee" ], "vanityUrl": "http://www.youtube.com/@mkbhd", "rssUrl": "https://www.youtube.com/feeds/videos.xml?channel_id=UCBJycsmduvYEL83R_U4JriQ", "availableCountryCodes": [ "BH", "GG" ], "isFamilySafe": true } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 2 more, so $0.003 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Profiles > Search YouTube channels by keyword. Source: https://apinoa.com/en/docs-raw/api-reference/youtube/profiles ```http GET | POST /v1/youtube/profiles ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/youtube/profiles?query=cooking" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ query: "cooking" }); const res = await fetch(`https://gateway.apinoa.com/v1/youtube/profiles?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/youtube/profiles", params={"query": "cooking"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `query` | A channel search | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `query` | string | | Search channels by keyword. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "youtube", "items": [ { "platform": "youtube", "id": "UC1rIOwTqDuWkFj87HZYRFOg", "handle": "NYTCooking", "displayName": "NYT Cooking", "url": "https://www.youtube.com/channel/UC1rIOwTqDuWkFj87HZYRFOg", "avatarUrl": "https://yt3.googleusercontent.com/ytc/AIdro_kXK0r3_p-Ht_8QNz7t2diayNQ78E7mRy6F-pu9iTO6zTk=s176-c-k-c0x00ffffff-no-rj-mo", "verified": true, "counts": { "followers": 1350000 }, "ext": { "snippet": "All the food that's fit to eat (yes, it's an official New York Times production)." } }, { "platform": "youtube", "id": "UCk3JZr7eS3pg5AGEvBdEvFg", "handle": "VillageCookingChannel", "displayName": "Village Cooking Channel", "url": "https://www.youtube.com/channel/UCk3JZr7eS3pg5AGEvBdEvFg", "avatarUrl": "https://yt3.ggpht.com/66OTTHSdZwqnz75I-z_sCFmf-EKQ9q4_OZsluCDm3KqPrcauc16Si1gGQuUgqe82Pi05Y2vnpw=s176-c-k-c0x00ffffff-n…", "verified": true, "counts": { "followers": 31000000 }, "ext": { "snippet": "Village grandpa cooking traditional village food, country foods, and tasty recipes for foodies, children, villagers, an…" } } ], "cursor": "HHhez86rexLDovLSzqlvHHmX9hejB6aNlzglpAk200amQeVQYbpFShjsCBIjRclZ0PTLtIkTSEqMar4xYMDOdPLtYWkJW-4oVLEYrVptjNMQIK2A3W713ua…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one YouTube video. Source: https://apinoa.com/en/docs-raw/api-reference/youtube/post ```http GET | POST /v1/youtube/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/youtube/post?id=dQw4w9WgXcQ" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "dQw4w9WgXcQ" }); const res = await fetch(`https://gateway.apinoa.com/v1/youtube/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/youtube/post", params={"id": "dQw4w9WgXcQ"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The video | An 11-character id or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Video id (11 chars), or the video URL (watch?v=…, youtu.be/…, /shorts/…). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "youtube", "id": "dQw4w9WgXcQ", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "author": { "platform": "youtube", "id": "UCuAXFkgsw1L7xaCfnd5JJOw", "handle": "RickAstleyYT", "displayName": "Rick Astley", "url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw" }, "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)", "text": "The official video for “Never Gonna Give You Up” by Rick Astley. \n\nNever: The Autobiography 📚 OUT NOW! \nFollow this lin…", "createdAt": "2009-10-25T06:57:33Z", "media": [ { "type": "video", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "thumbnailUrl": "https://i.ytimg.com/vi_webp/dQw4w9WgXcQ/maxresdefault.webp", "durationSec": 213 } ], "metrics": { "views": 1830040413, "likes": 19495047 }, "ext": { "category": "Music", "keywords": [ "rick astley", "Never Gonna Give You Up" ], "availableCountries": [ "AD", "AE" ], "isFamilySafe": true } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List YouTube videos: a channel's uploads, a search, a hashtag, related videos, or the trending charts. Source: https://apinoa.com/en/docs-raw/api-reference/youtube/posts ```http GET | POST /v1/youtube/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/youtube/posts?username=%40mkbhd&type=shorts" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "@mkbhd", type: "shorts" }); const res = await fetch(`https://gateway.apinoa.com/v1/youtube/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/youtube/posts", params={"username": "@mkbhd", "type": "shorts"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | A channel's uploads | `type`: `videos` (default), `shorts`, `live`, `community` | | `query` | A video search | `type`: `videos` (default) or `shorts` | | `hashtag` | Videos under a hashtag | | | `relatedTo` | The videos YouTube recommends beside one | | | nothing | The trending charts | `country` (default US); 2 units | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `country` | string | | Default feed only: the country whose trending feed to read (ISO alpha-2, default US). | | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `hashtag` | string | | Videos under a hashtag, with or without #. | | `query` | string | | Search videos by keyword. | | `relatedTo` | string | | A video id or URL; returns the videos YouTube recommends beside it. | | `type` | enum | | username/userId: which channel tab — videos (default), shorts, live or community · query: videos (default) or shorts. `videos` `shorts` `live` `community` | | `userId` | string | | Channel id (UC…). | | `username` | string | | Channel @handle (with or without @), or the channel URL (/@handle, /channel/UC…, /c/…, /user/…). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "youtube", "items": [ { "platform": "youtube", "id": "_4ELeWAgMwo", "url": "https://www.youtube.com/watch?v=_4ELeWAgMwo", "author": { "platform": "youtube", "id": "UCBJycsmduvYEL83R_U4JriQ", "handle": "mkbhd", "displayName": "Marques Brownlee", "url": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ", "avatarUrl": "https://yt3.googleusercontent.com/qu4TmIaYUlS41-dJ9gZ7DUR3nilvmB5_11i6OKSdvNnBNiyOusZP1bMN6ICnuxtjFBb6ioKgRQ=s900-c-k-c…" }, "title": "ASMR iPhone Duo Unboxing", "media": [ { "type": "video", "url": "https://www.youtube.com/watch?v=_4ELeWAgMwo", "thumbnailUrl": "https://i.ytimg.com/vi/_4ELeWAgMwo/oar3.jpg?sqp=-oaymwEdCJUDENAFSFWQAgHyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLDEzqDprq0dEj0…" } ], "metrics": { "views": 2100000 }, "ext": { "isShort": true } } ], "cursor": "4PUpJI-hNYFf8QYTuifBDYgNyLZERTjzoZKnbWwvxtxd6TFzjKx55Gw3YS9-IN4MUE1IAmpHzO19I7UGyZlIYr_d0r7eOHkiDMA6R0H8z6gujuSriodxpkF…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Comments > Get a YouTube video's comments, or one comment's replies. Source: https://apinoa.com/en/docs-raw/api-reference/youtube/comments ```http GET | POST /v1/youtube/comments ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/youtube/comments?post=dQw4w9WgXcQ" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "dQw4w9WgXcQ" }); const res = await fetch(`https://gateway.apinoa.com/v1/youtube/comments?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/youtube/comments", params={"post": "dQw4w9WgXcQ"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | The video's comments | | | `comment` | The replies under one comment | Pass the comment's `moreReplies.cursor` | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `comment` | string | | A comment's replies: the comment's `moreReplies.cursor`. | | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `post` | string | | The video's comments: video id or URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Comment`](/docs/api-reference/sns/response-schema#comment) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "youtube", "items": [ { "platform": "youtube", "id": "UgwxEqSh_78DU_MOKpt4AaABAg", "postId": "dQw4w9WgXcQ", "author": { "platform": "youtube", "id": "UCTfgDEMJhUnGz24yinDMenQ", "handle": "Hushoo", "url": "https://www.youtube.com/channel/UCTfgDEMJhUnGz24yinDMenQ", "avatarUrl": "https://yt3.ggpht.com/P9RPosH04c98bezAE4mu4YdgOHEtBOnDTfrrP1jWMyor_75pjbDedjPhrnos2JrFS3cSsCcv=s88-c-k-c0x00ffffff-no-rj" }, "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&lc=UgwxEqSh_78DU_MOKpt4AaABAg", "text": "Never thought the video was taken down, not even for a second. I just wanted to hear my boy Rick Astley again.", "metrics": { "likes": 8800, "replies": 56 }, "replies": [], "moreReplies": { "count": 56, "cursor": "Eg0SC2RRdzR3OVdnWGNRGAYygwEaUBIaVWd3eEVxU2hfNzhEVV9NT0twdDRBYUFCQWciAggAKhhVQ3VBWEZrZ3N3MUw3eGFDZm5kNUpKT3cyC2RRdzR3OVd…" }, "ext": { "publishedTime": "2 months ago" } } ], "cursor": "fWtM9OdtTGvNZO8XzAg9URvLjj1sGB7endioxe1hwTIq6H96l5s0stIq60va4k-Swq93GAxmyCjOaOGWh7HuwkzYtmSPF6SVy5Vc0tbpNzBLJrvQGkiTGOV…", "total": 2460495, "post": { "platform": "youtube", "id": "dQw4w9WgXcQ", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "author": { "platform": "youtube", "id": "UCuAXFkgsw1L7xaCfnd5JJOw", "handle": "RickAstleyYT", "displayName": "Rick Astley", "url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw", "avatarUrl": "https://yt3.ggpht.com/_ShEGOdg-t5YGJse14Ooq6FYBZqX_QSlhaTNjG06miYusm5lWm1UroLyVxnYtahADfRTVLtuVQ=s176-c-k-c0x00ffffff-n…", "verified": true, "counts": { "followers": 4550000 } }, "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)", "text": "The official video for “Never Gonna Give You Up” by Rick Astley. \n\nNever: The Autobiography 📚 OUT NOW! \nFollow this lin…", "media": [ { "type": "video", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg" } ], "metrics": { "views": 1830040413, "likes": 19495047, "comments": 2460495 }, "ext": { "dateText": "Oct 25, 2009", "relativeDate": "16 years ago" } } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Groups > List a YouTube channel's playlists. Source: https://apinoa.com/en/docs-raw/api-reference/youtube/groups ```http GET | POST /v1/youtube/groups ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/youtube/groups?username=%40mkbhd" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "@mkbhd" }); const res = await fetch(`https://gateway.apinoa.com/v1/youtube/groups?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/youtube/groups", params={"username": "@mkbhd"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | The channel's playlists | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `type` | enum | | playlists (a channel's playlists). `playlists` | | `userId` | string | | Channel id (UC…). | | `username` | string | | Channel @handle (with or without @), or the channel URL (/@handle, /channel/UC…, /c/…, /user/…). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "youtube", "items": [ { "platform": "youtube", "kind": "list", "id": "PLBsP89CPrMeMV1oP42Zn2DrWpnFoSaufA", "name": "Retro Tech", "url": "https://www.youtube.com/playlist?list=PLBsP89CPrMeMV1oP42Zn2DrWpnFoSaufA", "avatarUrl": "https://i9.ytimg.com/s_p/PLBsP89CPrMeMV1oP42Zn2DrWpnFoSaufA/landscape_maxresdefault.jpg?sqp=CLS889YGir7X7AMICI_G--4FEAE…", "counts": { "posts": 6 } }, { "platform": "youtube", "kind": "list", "id": "PLBsP89CPrMeP1Xi1zQX87mq3mhkvFHWZ4", "name": "Retro Tech", "url": "https://www.youtube.com/playlist?list=PLBsP89CPrMeP1Xi1zQX87mq3mhkvFHWZ4", "avatarUrl": "https://i.ytimg.com/vi/Oy8zSYKkczI/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLCg6EpaTY_KSrK57S…", "counts": { "posts": 1 } } ] } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Instagram > Instagram through the shared SNS operations: profiles, posts and reels, comments, highlights, hashtags and locations. Source: https://apinoa.com/en/docs-raw/api-reference/instagram ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/instagram/profile) | `GET \| POST /v1/instagram/profile` | `Account` | $0.001 | | [Post](/docs/api-reference/instagram/post) | `GET \| POST /v1/instagram/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/instagram/posts) | `GET \| POST /v1/instagram/posts` | `Page` | $0.001 | | [Comments](/docs/api-reference/instagram/comments) | `GET \| POST /v1/instagram/comments` | `Page` | $0.001 | | [Group](/docs/api-reference/instagram/group) | `GET \| POST /v1/instagram/group` | `Group` | $0.001 | | [Groups](/docs/api-reference/instagram/groups) | `GET \| POST /v1/instagram/groups` | `Page` | $0.001 | --- # Profile > Get an Instagram account's profile. Source: https://apinoa.com/en/docs-raw/api-reference/instagram/profile ```http GET | POST /v1/instagram/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/instagram/profile?username=natgeo" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "natgeo" }); const res = await fetch(`https://gateway.apinoa.com/v1/instagram/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/instagram/profile", params={"username": "natgeo"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The profile | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `include` | string list | | Attach from the same page, at no extra cost: posts (the creator's latest posts, ext.posts). | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "instagram", "id": "787132", "handle": "natgeo", "displayName": "National Geographic", "bio": "Step into wonder and find your inner explorer with National Geographic 🌎", "url": "https://www.instagram.com/natgeo/", "avatarUrl": "https://scontent-lga3-1.cdninstagram.com/v/t51.82787-19/683576066_18653628823019133_9051036240972105113_n.jpg?stp=dst-j…", "verified": true, "counts": { "followers": 268291786, "following": 195 }, "links": [ { "url": "http://visitstore.bio/natgeo" }, { "url": "https://ngmdomsubs.nationalgeographic.com/servlet/OrdersGateway?cds_mag_code=NGM&cds_page_id=283562&cds_response_key=I5…", "title": "Subscribe Here!" } ], "private": false, "ext": { "pk": "787132", "fbid": "17841400573960012", "highlightsCount": 1, "highlights": [ { "platform": "instagram", "kind": "list", "id": "18023864549864045", "name": "BOTW 2027", "url": "https://www.instagram.com/stories/highlights/18023864549864045/", "avatarUrl": "https://scontent-lga3-2.cdninstagram.com/v/t58.9792-6/859997535_2631174661043575_6410428937125336621_n.jpg?stp=dst-jpg_…", "ext": { "listType": "highlight_reel", "owner": "natgeo" } } ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one Instagram post or reel. Source: https://apinoa.com/en/docs-raw/api-reference/instagram/post ```http GET | POST /v1/instagram/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/instagram/post?id=DeuOR-CjKE9" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "DeuOR-CjKE9" }); const res = await fetch(`https://gateway.apinoa.com/v1/instagram/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/instagram/post", params={"id": "DeuOR-CjKE9"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The post | A shortcode or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Post shortcode, or the post URL (…/p//, …/reel//, …/tv//). | | `include` | string list | | Attach from the same page, at no extra cost: comments (the first comments, ext.comments), authorPosts (the author's other recent posts, ext.authorPosts). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "instagram", "id": "4012207125530714429", "url": "https://www.instagram.com/p/DeuOR-CjKE9/", "author": { "platform": "instagram", "id": "787132", "handle": "natgeo", "displayName": "National Geographic", "url": "https://www.instagram.com/natgeo/", "avatarUrl": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-19/683576066_18653628823019133_9051036240972105113_n.jpg?stp=dst-j…", "verified": true }, "text": "Some of the best reasons to travel in 2027 are far from the usual destinations. 🌎\n\nNational Geographic’s picks for Best…", "createdAt": "2026-10-20T16:06:30.000Z", "media": [ { "type": "image", "url": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-15/858921974_18710195065019133_277441153414192961_n.jpg?stp=dst-jp…", "width": 1080, "height": 1350, "variants": [ { "url": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-15/858921974_18710195065019133_277441153414192961_n.jpg?stp=dst-jp…", "width": 1080, "height": 1350 } ], "altText": "Photo by National Geographic on October 20, 2026. May be an image of outdoors and text." } ], "metrics": { "likes": 14226, "comments": 190 }, "entities": { "hashtags": [ "BestOfTheWorld" ] }, "ext": { "code": "DeuOR-CjKE9", "pk": "4012207125530714429", "productType": "feed", "mediaType": 1, "usertags": [ { "username": "natgeotravel", "id": "23947096", "fullName": "National Geographic Travel" } ], "coauthors": [ { "platform": "instagram", "id": "23947096", "handle": "natgeotravel", "displayName": "National Geographic Travel", "url": "https://www.instagram.com/natgeotravel/", "avatarUrl": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-19/685024507_18593567491011097_8135647783480608234_n.jpg?stp=dst-j…", "verified": true } ], "relatedTopics": [ "national geographic travel", "top 25 travel destinations" ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List Instagram posts: an account's posts or reels, a hashtag's top posts, or a location's recent posts. Source: https://apinoa.com/en/docs-raw/api-reference/instagram/posts ```http GET | POST /v1/instagram/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/instagram/posts?username=natgeo" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "natgeo" }); const res = await fetch(`https://gateway.apinoa.com/v1/instagram/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/instagram/posts", params={"username": "natgeo"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | A creator's posts | `type`: `posts` (default) or `reels` | | `hashtag` | Top posts under a hashtag | | | `location` | Recent posts at a location | A numeric location id or URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `hashtag` | string | | Top posts under a hashtag: with or without #, or its page URL. | | `location` | string | | Posts at a location: numeric location id or URL (…/explore/locations//). One page: Instagram shows the rest only to signed-in users. | | `type` | enum | | username: the creator's posts (default) or reels. `posts` `reels` | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "instagram", "items": [ { "platform": "instagram", "id": "4012207125530714429", "url": "https://www.instagram.com/p/DeuOR-CjKE9/", "author": { "platform": "instagram", "id": "787132", "handle": "natgeo", "displayName": "National Geographic", "url": "https://www.instagram.com/natgeo/", "avatarUrl": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-19/683576066_18653628823019133_9051036240972105113_n.jpg?stp=dst-j…", "verified": true }, "text": "Some of the best reasons to travel in 2027 are far from the usual destinations. 🌎\n\nNational Geographic’s picks for Best…", "media": [ { "type": "image", "url": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-15/858921974_18710195065019133_277441153414192961_n.jpg?stp=dst-jp…", "altText": "Photo by National Geographic on October 20, 2026. May be an image of outdoors and text." } ], "entities": { "hashtags": [ "BestOfTheWorld" ] }, "ext": { "code": "DeuOR-CjKE9", "pk": "4012207125530714429", "productType": "feed", "mediaType": 1 } } ], "cursor": "0GWpK_Oa_P5Zvj8DNEztXhzp3kgvgvUDKr1WOtHVY5Ijmkf8MpfCfXxIs6M5DnbCgCuWdbaY9d2TzVbzd70-042QggBFYjD4KgTproeiGlBmfbC_4GiuzdC…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Comments > Get an Instagram post's comments, newest first. Source: https://apinoa.com/en/docs-raw/api-reference/instagram/comments ```http GET | POST /v1/instagram/comments ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/instagram/comments?post=DeuOR-CjKE9" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "DeuOR-CjKE9" }); const res = await fetch(`https://gateway.apinoa.com/v1/instagram/comments?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/instagram/comments", params={"post": "DeuOR-CjKE9"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | The post's comments, newest first | Comments by the post's owner carry `byAuthor: true` | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `post` | string | | The post's comments: shortcode or URL. | | `sort` | enum | | recent (newest first) — the only order Instagram serves logged-out visitors. `recent` | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Comment`](/docs/api-reference/sns/response-schema#comment) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "instagram", "items": [ { "platform": "instagram", "id": "18064044170629629", "postId": "4012207125530714429", "author": { "platform": "instagram", "id": "14838741487", "handle": "siliconheistofficial", "url": "https://www.instagram.com/siliconheistofficial/", "avatarUrl": "https://scontent-sjc3-1.cdninstagram.com/v/t51.82787-19/858283466_18167394880493488_2539987097808111411_n.jpg?stp=dst-j…" }, "text": "😍😍😍", "replies": [], "createdAt": "2026-10-24T15:33:20.000Z", "metrics": { "likes": 0 }, "ext": { "pk": "18064044170629629" } } ], "cursor": "f8fJMiwSzgxGX8VNfbO2xxsPLzg-8JzdiZNSgNSuyKhQyJ_pNo3cStYvMgP0ebn7Xt6JX7yuOuLtwpFDh4NxyXYBp_P8VuA_QRBUc5WDnTjUF8DvspPFsQ3…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - **Newest first is the only order** (`sort=recent`). Instagram ranks comments by popularity only for signed-in viewers. - An age-restricted post answers `404 NOT_FOUND` with the reason; Instagram does not show it to logged-out visitors. --- # Group > Get an Instagram hashtag or location. Source: https://apinoa.com/en/docs-raw/api-reference/instagram/group ```http GET | POST /v1/instagram/group ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/instagram/group?hashtag=travel" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ hashtag: "travel" }); const res = await fetch(`https://gateway.apinoa.com/v1/instagram/group?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/instagram/group", params={"hashtag": "travel"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `hashtag` | The hashtag | | | `location` | The place | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `hashtag` | string | | A hashtag: with or without #, or its page URL. | | `include` | string list | | Attach from the same page, at no extra cost: posts (the tag's top posts / the location's posts, ext.posts). | | `location` | string | | A location: numeric id or URL (…/explore/locations//). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "instagram", "kind": "hashtag", "id": "travel", "name": "travel", "url": "https://www.instagram.com/explore/tags/travel/", "description": "Travel is the movement of people between different places for work, study, tourism, or personal reasons. It can be done…", "ext": { "relatedKeywords": [ "transfer travel", "time travel real" ], "sourceUris": [ "https://simple.m.wikipedia.org/wiki/Voyage", "https://www.gomeltourist.com/what-is-travel/" ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Groups > List an Instagram creator's highlights. Source: https://apinoa.com/en/docs-raw/api-reference/instagram/groups ```http GET | POST /v1/instagram/groups ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/instagram/groups?username=natgeo" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "natgeo" }); const res = await fetch(`https://gateway.apinoa.com/v1/instagram/groups?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/instagram/groups", params={"username": "natgeo"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The creator's highlight reels | The stories inside are login-only | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `type` | enum | | highlights (a creator's highlight reels). `highlights` | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "instagram", "items": [ { "platform": "instagram", "kind": "list", "id": "18023864549864045", "name": "BOTW 2027", "url": "https://www.instagram.com/stories/highlights/18023864549864045/", "avatarUrl": "https://scontent-iad6-1.cdninstagram.com/v/t58.9792-6/859997535_2631174661043575_6410428937125336621_n.jpg?stp=dst-jpg_…", "ext": { "listType": "highlight_reel", "owner": "natgeo" } } ] } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Threads > Threads through the shared SNS operations: profiles, posts, reposts, replies, search and topic tags. Source: https://apinoa.com/en/docs-raw/api-reference/threads ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/threads/profile) | `GET \| POST /v1/threads/profile` | `Account` | $0.001–$0.002 | | [Post](/docs/api-reference/threads/post) | `GET \| POST /v1/threads/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/threads/posts) | `GET \| POST /v1/threads/posts` | `Page` | $0.001 | | [Comments](/docs/api-reference/threads/comments) | `GET \| POST /v1/threads/comments` | `Page` | $0.001 | --- # Profile > Get a Threads account's profile. Source: https://apinoa.com/en/docs-raw/api-reference/threads/profile ```http GET | POST /v1/threads/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/threads/profile?username=zuck" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "zuck" }); const res = await fetch(`https://gateway.apinoa.com/v1/threads/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/threads/profile", params={"username": "zuck"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The profile | | | `userId` | The same, by numeric user id | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `include` | string list | | username only. Attach from the same page, at no extra cost: posts (the creator's latest threads, ext.posts). | | `userId` | string | | Numeric Threads user id. | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "threads", "id": "63055343223", "handle": "zuck", "displayName": "Mark Zuckerberg", "bio": "Mostly superintelligence and MMA takes", "url": "https://www.threads.com/@zuck", "avatarUrl": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-19/825322135_17989325280103224_1252773933700107438_n.jpg?stp=dst-j…", "verified": true, "counts": { "followers": 5753766 }, "private": false, "ext": { "profileTags": [ { "name": "aithreads", "displayName": "AI Threads", "id": "18399895213044171" }, { "name": "ufcthreads", "displayName": "UFC Threads", "id": "18398478472015746" } ], "profilePicVersions": [ { "width": 320, "height": 320, "url": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-19/825322135_17989325280103224_1252773933700107438_n.jpg?stp=dst-j…" } ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one Threads post. Source: https://apinoa.com/en/docs-raw/api-reference/threads/post ```http GET | POST /v1/threads/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/threads/post?id=DeZtp-TkQHh" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "DeZtp-TkQHh" }); const res = await fetch(`https://gateway.apinoa.com/v1/threads/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/threads/post", params={"id": "DeZtp-TkQHh"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The post | A shortcode or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Post shortcode, or the post URL (…/@user/post/ or …/t/). | | `include` | string list | | Attach from the same page, at no extra cost: comments (the first replies, top order, ext.comments), related (the related threads Threads suggests beside it, ext.related). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "threads", "id": "4006434140014576097", "url": "https://www.threads.com/@zuck/post/DeZtp-TkQHh", "author": { "platform": "threads", "id": "63055343223", "handle": "zuck", "displayName": "Mark Zuckerberg", "url": "https://www.threads.com/@zuck", "avatarUrl": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-19/825322135_17989325280103224_1252773933700107438_n.jpg?stp=dst-j…", "verified": true }, "text": "Introducing Muse Wonder, our new family of frontier models with state of the art performance for personal and professio…", "createdAt": "2026-10-12T16:56:29.000Z", "media": [ { "type": "image", "url": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-15/844965867_17991705567103224_8296143909108287920_n.webp?_nc_cat=…", "width": 2160, "height": 3260, "variants": [ { "url": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-15/844965867_17991705567103224_8296143909108287920_n.webp?_nc_cat=…", "width": 2160, "height": 3260 } ] } ], "metrics": { "likes": 2117, "comments": 550, "shares": 145, "reposts": 168, "quotes": 60, "views": 168740 }, "ext": { "code": "DeZtp-TkQHh", "mediaType": 1, "replyControl": "everyone" } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List Threads posts: an account's threads, reposts or replies, a search, or a topic tag. Source: https://apinoa.com/en/docs-raw/api-reference/threads/posts ```http GET | POST /v1/threads/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/threads/posts?username=zuck" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "zuck" }); const res = await fetch(`https://gateway.apinoa.com/v1/threads/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/threads/posts", params={"username": "zuck"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | A creator's threads | `type`: `posts` (default), `reposts`, `replies` | | `query` | A post search (one page) | `sort`: `top` (default) or `recent` | | `hashtag` | Posts under a topic tag (one page) | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `hashtag` | string | | Posts for a topic tag, with or without # (one page). Threads often answers a tag as a keyword match over post text and topic names; the page's `ext.matchedBy` says `tag` or `keyword`. | | `include` | string list | | username only. Attach from the same page, at no extra cost: profile (the creator's profile, ext.profile). | | `query` | string | | Search posts by keyword (one page). | | `sort` | enum | | query only: top (default) or recent. `top` `recent` | | `type` | enum | | username: the creator's threads (default), reposts or replies. `posts` `reposts` `replies` | | `username` | string | | Creator @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "threads", "items": [ { "platform": "threads", "id": "4006434140014576097", "url": "https://www.threads.com/@zuck/post/DeZtp-TkQHh", "author": { "platform": "threads", "id": "63055343223", "handle": "zuck", "displayName": "Mark Zuckerberg", "url": "https://www.threads.com/@zuck", "avatarUrl": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-19/825322135_17989325280103224_1252773933700107438_n.jpg?stp=dst-j…", "verified": true }, "text": "Introducing Muse Wonder, our new family of frontier models with state of the art performance for personal and professio…", "createdAt": "2026-10-12T16:56:29.000Z", "media": [ { "type": "image", "url": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-15/844965867_17991705567103224_8296143909108287920_n.webp?_nc_cat=…", "width": 2160, "height": 3260, "variants": [ { "url": "https://scontent-iad6-1.cdninstagram.com/v/t51.82787-15/844965867_17991705567103224_8296143909108287920_n.webp?_nc_cat=…", "width": 2160, "height": 3260 } ] } ], "metrics": { "likes": 2117, "comments": 550, "shares": 145, "reposts": 168, "quotes": 60 }, "ext": { "code": "DeZtp-TkQHh", "mediaType": 1, "replyControl": "everyone", "selfThreadIndex": 0, "selfThreadSize": 4 } } ], "cursor": "Gs36BDWiPDJe0VPmI7U4baxcdC58rWMYV5H7psEjv0MYhbfdiqASGVlCk0zQCRy0KrTNDL1Vpdi3w-NI9JywIUEQRbxyczLHaaMydmyXc06-Zmr0KmQCssI…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Comments > Get a Threads post's replies. Source: https://apinoa.com/en/docs-raw/api-reference/threads/comments ```http GET | POST /v1/threads/comments ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/threads/comments?post=DeZtp-TkQHh" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "DeZtp-TkQHh" }); const res = await fetch(`https://gateway.apinoa.com/v1/threads/comments?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/threads/comments", params={"post": "DeZtp-TkQHh"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | The replies under the post | `sort`: `top` (default) or `recent` | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `include` | string list | | Top order only. Attach from the same page, at no extra cost: post (the post itself, in `post`), related (the related threads Threads suggests beside it, ext.related). | | `post` | string | | The post's replies: shortcode or URL. | | `sort` | enum | | top (default) or recent. `top` `recent` | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Comment`](/docs/api-reference/sns/response-schema#comment) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "threads", "items": [ { "platform": "threads", "id": "4006435708155479455", "postId": "4006434140014576097", "author": { "platform": "threads", "id": "63095976534", "handle": "_randomdev001", "displayName": "Peter", "url": "https://www.threads.com/@_randomdev001", "avatarUrl": "https://scontent-sjc6-1.cdninstagram.com/v/t51.82787-19/641717925_17951034903096535_856164541309490688_n.jpg?_nc_cat=10…" }, "text": "Impressive stuff.\nDoes it beat OpenAIs Dots though?", "replies": [], "url": "https://www.threads.com/@_randomdev001/post/DeZuAywDEWf", "createdAt": "2026-10-12T16:59:36.000Z", "metrics": { "likes": 0, "replies": 0 }, "ext": { "code": "DeZuAywDEWf", "mediaType": 19, "replyControl": "everyone", "rootPostAuthor": "zuck", "isReply": true, "replyToAuthor": "zuck", "repostCount": 0, "quoteCount": 0 } } ], "cursor": "lAN05PmThHV5d_4EObm8BmFGaNGocdIooNh_Z85tntT5rpg_NMcnVNmzy199HayXQIcJ2VrswItRfwjL8Wh3-4y3Wo-eJ_YXbunI-wgS2iDZxlJK-t50wHv…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # LinkedIn > LinkedIn through the shared SNS operations: member profiles, company pages, their recent posts and comments, plus job postings. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/linkedin/profile) | `GET \| POST /v1/linkedin/profile` | `Account` | $0.001 | | [Post](/docs/api-reference/linkedin/post) | `GET \| POST /v1/linkedin/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/linkedin/posts) | `GET \| POST /v1/linkedin/posts` | `Page` | $0.001 | | [Comments](/docs/api-reference/linkedin/comments) | `GET \| POST /v1/linkedin/comments` | `Page` | $0.001 | | [Group](/docs/api-reference/linkedin/group) | `GET \| POST /v1/linkedin/group` | `Group` | $0.001 | | [Job](/docs/api-reference/linkedin/job) | `GET \| POST /v1/linkedin/job` | `Job` | $0.001 | | [Jobs](/docs/api-reference/linkedin/jobs) | `GET \| POST /v1/linkedin/jobs` | `Page` | $0.001 | --- # Profile > Get a LinkedIn member's public profile. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/profile ```http GET | POST /v1/linkedin/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/profile?username=williamhgates" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "williamhgates" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/profile", params={"username": "williamhgates"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The profile | The vanity handle (`in/…`) or URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `username` | string | | Person vanity handle (with or without in/, e.g. williamhgates), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "id": "williamhgates", "handle": "williamhgates", "displayName": "Bill Gates", "bio": "Chair of the Gates Foundation. Founder of Breakthrough Energy. Co-founder of Microsoft. Voracious reader. Avid traveler…", "url": "https://www.linkedin.com/in/williamhgates", "avatarUrl": "https://media.licdn.com/dms/image/v2/D5603AQF-RYZP55jmXA/profile-displayphoto-shrink_200_200/B56ZRi8g.aGsAY-/0/17368268…", "bannerUrl": "https://media.licdn.com/dms/image/v2/D5616AQEjhPbTCeblYg/profile-displaybackgroundimage-shrink_200_800/B56ZcytR5SGsAc-/…", "counts": { "followers": 40747885 }, "links": [ { "url": "https://gatesnot.es/sourcecode-li", "title": "Blog" } ], "ext": { "memberId": "251749025", "headline": "Chair, Gates Foundation and Founder, Breakthrough Energy", "badges": [ "Creator", "Top Voice" ], "connections": 8, "jobTitles": [ "Co-chair", "Founder" ], "location": "Seattle, Washington, United States", "country": "US", "worksFor": [ { "name": "Gates Foundation", "url": "https://www.linkedin.com/company/gates-foundation", "start": "2000", "startYear": 2000 }, { "name": "Breakthrough Energy", "url": "https://www.linkedin.com/company/breakthrough-energy", "start": "2015", "startYear": 2015 } ], "experience": [ { "title": "Co-chair", "company": "Gates Foundation", "companyUrl": "https://www.linkedin.com/company/gates-foundation", "logoUrl": "https://media.licdn.com/dms/image/v2/D560BAQEgMqqFTd40Tg/company-logo_100_100/company-logo_100_100/0/1736784969376/bill…", "start": "2000", "current": true, "duration": "26 years" }, { "title": "Founder", "company": "Breakthrough Energy", "companyUrl": "https://www.linkedin.com/company/breakthrough-energy", "logoUrl": "https://media.licdn.com/dms/image/v2/D560BAQFRMYiQN7-2kA/company-logo_100_100/B56ZoI4SGPI0AQ-/0/1761085563539/breakthro…", "start": "2015", "current": true, "duration": "11 years" } ], "education": [ { "school": "Harvard University", "url": "https://www.linkedin.com/school/harvard-university", "logoUrl": "https://media.licdn.com/dms/image/v2/C4E0BAQF5t62bcL0e9g/company-logo_100_100/company-logo_100_100/0/1631318058235?e=21…", "start": "1973", "end": "1975" }, { "school": "Lakeside School", "url": "https://www.linkedin.com/school/lakeside-school", "logoUrl": "https://media.licdn.com/dms/image/v2/D560BAQGFmOQmzpxg9A/company-logo_100_100/company-logo_100_100/0/1683732883164/lake…" } ], "recentPosts": [ { "platform": "linkedin", "id": "7519788335226302464", "url": "https://www.linkedin.com/posts/williamhgates_6-things-you-should-know-on-world-polio-day-activity-7519788335226302464-G…", "author": { "platform": "linkedin", "handle": "williamhgates", "displayName": "Bill Gates", "url": "https://www.linkedin.com/in/williamhgates", "avatarUrl": "https://media.licdn.com/dms/image/v2/D5603AQF-RYZP55jmXA/profile-displayphoto-shrink_200_200/B56ZRi8g.aGsAY-/0/17368268…", "ext": { "type": "person" } }, "text": "In 1988, polio was endemic in 125 countries. Today, on World Polio Day, it's endemic in just two: Afghanistan and Pakis…", "createdAt": "2026-10-24T15:54:10.029Z", "media": [], "metrics": { "likes": 201, "comments": 41 } } ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one LinkedIn post. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/post ```http GET | POST /v1/linkedin/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/post?id=7508925724787941376" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "7508925724787941376" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/post", params={"id": "7508925724787941376"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The post | An activity id, `urn:li:activity:…` or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Activity id, urn:li:activity:, or the post URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "id": "7508925724787941376", "url": "https://www.linkedin.com/posts/microsoft_the-path-to-quantum-computing-isnt-a-single-activity-7508925724787941376-6ivK", "author": { "platform": "linkedin", "handle": "microsoft", "displayName": "Microsoft", "url": "https://www.linkedin.com/company/microsoft", "avatarUrl": "https://media.licdn.com/dms/image/v2/D560BAQH32RJQCl3dDQ/company-logo_100_100/B56ZYQ0mrGGoAU-/0/1744038948046/microsoft…", "counts": { "followers": 29361628 }, "ext": { "type": "organization" } }, "text": "The path to quantum computing isn’t a single breakthrough. It’s a journey.\n\nIn Maryland, our new quantum research cente…", "createdAt": "2026-09-24T16:30:01.882Z", "media": [ { "type": "image", "url": "https://media.licdn.com/dms/image/v2/D4E10AQGUDhS8AxswqQ/image-shrink_800/B4EaDUEwfFHoAg-/0/1790264413236?e=2147483647&…", "altText": "Vertical view of a gold cylinder above a Microsoft-branded display. A clear panel in front shows a silicon wafer, compo…" }, { "type": "image", "url": "https://media.licdn.com/dms/image/v2/D4E10AQGB_4QDqZzB8w/image-shrink_800/B4EaDUEzd1KsAg-/0/1790264425501?e=2147483647&…", "altText": "Close-up of a gold and silver quantum computing assembly hanging from the ceiling. It has stacked round plates, coiled…" } ], "metrics": { "likes": 490, "comments": 35 }, "entities": { "urls": [ { "url": "https://msft.it/6001a9EAJ" } ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List a LinkedIn member's or company's recent posts. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/posts ```http GET | POST /v1/linkedin/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/posts?company=microsoft&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ company: "microsoft", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/posts", params={"company": "microsoft", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | A member's recent posts | | | `company` | A company's recent posts | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `company` | string | | Company vanity name (with or without company/, e.g. microsoft), or the company URL. | | `limit` | integer 1–50 | | Most posts to return (LinkedIn shows the most recent few). | | `username` | string | | Person vanity handle (with or without in/, e.g. williamhgates), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "items": [ { "platform": "linkedin", "id": "7519053939393224704", "url": "https://www.linkedin.com/feed/update/urn:li:activity:7519053939393224704/", "author": { "platform": "linkedin", "handle": "microsoft", "displayName": "Microsoft", "url": "https://www.linkedin.com/company/microsoft", "ext": { "type": "organization" } }, "createdAt": "2026-10-22T15:15:56.418Z", "media": [], "repostOf": { "platform": "linkedin", "id": "urn:li:ugcPost:7518982647881048064", "url": "https://www.linkedin.com/feed/update/urn:li:ugcPost:7518982647881048064/", "author": { "platform": "linkedin", "handle": "satyanadella", "displayName": "Satya Nadella", "url": "https://www.linkedin.com/in/satyanadella", "avatarUrl": "https://media.licdn.com/dms/image/v2/C5603AQHHUuOSlRVA1w/profile-displayphoto-shrink_400_400/profile-displayphoto-shrin…", "ext": { "type": "person", "headline": "Chairman and CEO at Microsoft" } }, "text": "Keeping over a million elevators and escalators running smoothly is no small task.\n\nToday in Cologne, I heard about how…", "media": [ { "type": "video", "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/mp4-720p-30fp-crf28/B56aFjK4XmKoB4-/0/1792665181541?e=2147483…", "thumbnailUrl": "https://media.licdn.com/dms/image/v2/D5605AQGAHHJsMz2u9g/videocover-high/B56aFjK4XmKoBI-/0/1792665171774?e=2147483647&v…", "variants": [ { "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/mp4-640p-30fp-crf28/B56aFjK4XmKoBg-/0/1792665181541?e=2147483…", "bitrate": 376115, "contentType": "video/mp4" }, { "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/mp4-720p-30fp-crf28/B56aFjK4XmKoB4-/0/1792665181541?e=2147483…", "bitrate": 494998, "contentType": "video/mp4" } ], "ext": { "captionsUrl": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/video-auto-caption-webvtt-acs-singleton/B56aFjK4XmKoEA-/0/179…" } } ], "metrics": { "likes": 7819, "comments": 300 }, "entities": { "mentions": [ { "handle": "tke-global", "displayName": "TK Elevator" } ], "urls": [ { "url": "https://lnkd.in/gEjFzJWC" } ] }, "ext": { "mentions": [ { "handle": "tke-global", "url": "https://de.linkedin.com/company/tke-global", "type": "organization" } ] } } } ] } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - LinkedIn shows logged-out visitors the most recent few posts; there is no deeper paging. `limit` caps how many come back. --- # Comments > Get a LinkedIn post's top comments. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/comments ```http GET | POST /v1/linkedin/comments ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/comments?post=7508925724787941376&limit=3" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ post: "7508925724787941376", limit: "3" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/comments?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/comments", params={"post": "7508925724787941376", "limit": "3"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `post` | The post's top comments | `limit` caps how many | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `limit` | integer 1–50 | | Most comments to return (LinkedIn shows a post's top few). | | `post` | string | | The post's comments: activity id, urn:li:activity:, or URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Comment`](/docs/api-reference/sns/response-schema#comment) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "items": [ { "platform": "linkedin", "id": "urn:li:comment:(urn:li:ugcPost:7508925723823243264,7512465132208254976)", "postId": "7508925724787941376", "author": { "platform": "linkedin", "handle": "deusdeditruhangariyo2010", "displayName": "Deusdedit Ruhangariyo", "url": "https://www.linkedin.com/in/deusdeditruhangariyo2010", "avatarUrl": "https://media.licdn.com/dms/image/v2/D5603AQGR9OrfrQjtFg/profile-displayphoto-shrink_400_400/profile-displayphoto-shrin…", "ext": { "type": "person" } }, "text": "Microsoft: From the Global AI Liability Consortium [GAILC] lens, independent testing is especially important when emerg…", "createdAt": "2026-10-04T10:54:22.371Z", "metrics": { "likes": 0 }, "replies": [] } ], "total": 35 } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Group > Get a LinkedIn company page. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/group ```http GET | POST /v1/linkedin/group ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/group?company=microsoft" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ company: "microsoft" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/group?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/group", params={"company": "microsoft"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `company` | The company | The vanity name or URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `company` | string | | Company vanity name (with or without company/, e.g. microsoft), or the company URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "kind": "company", "id": "microsoft", "name": "Microsoft", "url": "https://www.linkedin.com/company/microsoft", "description": "Every company has a mission. What's ours? To empower every person and every organization to achieve more. We believe te…", "avatarUrl": "https://media.licdn.com/dms/image/v2/D560BAQH32RJQCl3dDQ/company-logo_200_200/B56ZYQ0mrGGoAM-/0/1744038948046/microsoft…", "bannerUrl": "https://media.licdn.com/dms/image/v2/D4E3DAQGWOa_gAs1qXg/image-scale_325_1920/B4EZ8ZTX5SJEAI-/0/1782835937311/microsoft…", "counts": { "members": 29361628 }, "ext": { "orgId": "1035", "industry": "Software Development", "sizeBand": "10,001+ employees", "membersOnLinkedIn": 231136, "headquarters": "Redmond, Washington", "organizationType": "Public Company", "specialties": [ "Business Software", "Developer Tools" ], "websites": [ "https://news.microsoft.com/" ], "address": { "street": "1 Microsoft Way", "city": "Redmond", "region": "Washington", "postalCode": "98052", "country": "US" }, "recentPosts": [ { "platform": "linkedin", "id": "7519053939393224704", "url": "https://www.linkedin.com/feed/update/urn:li:activity:7519053939393224704/", "author": { "platform": "linkedin", "handle": "microsoft", "displayName": "Microsoft", "url": "https://www.linkedin.com/company/microsoft", "ext": { "type": "organization" } }, "createdAt": "2026-10-22T15:15:56.418Z", "media": [], "repostOf": { "platform": "linkedin", "id": "urn:li:ugcPost:7518982647881048064", "url": "https://www.linkedin.com/feed/update/urn:li:ugcPost:7518982647881048064/", "author": { "platform": "linkedin", "handle": "satyanadella", "displayName": "Satya Nadella", "url": "https://www.linkedin.com/in/satyanadella", "avatarUrl": "https://media.licdn.com/dms/image/v2/C5603AQHHUuOSlRVA1w/profile-displayphoto-shrink_400_400/profile-displayphoto-shrin…", "ext": { "type": "person", "headline": "Chairman and CEO at Microsoft" } }, "text": "Keeping over a million elevators and escalators running smoothly is no small task.\n\nToday in Cologne, I heard about how…", "media": [ { "type": "video", "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/mp4-720p-30fp-crf28/B56aFjK4XmKoB4-/0/1792665181541?e=2147483…", "thumbnailUrl": "https://media.licdn.com/dms/image/v2/D5605AQGAHHJsMz2u9g/videocover-high/B56aFjK4XmKoBI-/0/1792665171774?e=2147483647&v…", "variants": [ { "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/mp4-640p-30fp-crf28/B56aFjK4XmKoBg-/0/1792665181541?e=2147483…", "bitrate": 376115, "contentType": "video/mp4" }, { "url": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/mp4-720p-30fp-crf28/B56aFjK4XmKoB4-/0/1792665181541?e=2147483…", "bitrate": 494998, "contentType": "video/mp4" } ], "ext": { "captionsUrl": "https://dms.licdn.com/playlist/vid/v2/D5605AQGAHHJsMz2u9g/video-auto-caption-webvtt-acs-singleton/B56aFjK4XmKoEA-/0/179…" } } ], "metrics": { "likes": 7819, "comments": 300 }, "entities": { "mentions": [ { "handle": "tke-global", "displayName": "TK Elevator" } ], "urls": [ { "url": "https://lnkd.in/gEjFzJWC" } ] }, "ext": { "mentions": [ { "handle": "tke-global", "url": "https://de.linkedin.com/company/tke-global", "type": "organization" } ] } } } ] } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Job > Get one LinkedIn job posting. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/job ```http GET | POST /v1/linkedin/job ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/job?id=4419969671" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "4419969671" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/job?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/job", params={"id": "4419969671"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The job | A numeric id, `urn:li:jobPosting:…` or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Numeric job id, urn:li:jobPosting:, or the job URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns `Job` in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "id": "4419969671", "url": "https://www.linkedin.com/jobs/view/senior-software-engineer-%E2%80%93-go-golang-at-general-motors-4419969671", "title": "Senior Software Engineer – Go (Golang)", "company": { "name": "General Motors", "slug": "general-motors", "url": "https://www.linkedin.com/company/general-motors", "logoUrl": "https://media.licdn.com/dms/image/v2/D4E0BAQEfAZWzerj03w/company-logo_100_100/B4EZdkPGXYGcAQ-/0/1749733370529/general_m…" }, "location": "Warren, MI", "postedText": "2 weeks ago", "applicants": 197, "seniority": "Not Applicable", "employmentType": "Full-time", "industries": "Motor Vehicle Manufacturing, Appliances, Electrical, and Electronics Manufacturing, and IT Services and IT Consulting", "description": "Job Description\n\nAs a Senior Software Engineer – Go (Golang), you will design, develop, and deliver high-performance mi…", "descriptionHtml": "Job Description

As a Senior Software Engineer – Go (Golang), you will design, develop, and deli…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - A LinkedIn-only record; its fields are shown in the response. --- # Jobs > Search LinkedIn job postings. Source: https://apinoa.com/en/docs-raw/api-reference/linkedin/jobs ```http GET | POST /v1/linkedin/jobs ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/linkedin/jobs?query=software+engineer&location=United+States" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ query: "software engineer", location: "United States" }); const res = await fetch(`https://gateway.apinoa.com/v1/linkedin/jobs?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/linkedin/jobs", params={"query": "software engineer", "location": "United States"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `query` | Job postings matching the keywords | `location` narrows to a place (default worldwide) | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `location` | string | | Location name (e.g. United States). Default: worldwide. | | `query` | string | | Job search keywords (e.g. software engineer). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of `Job` in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "linkedin", "items": [ { "platform": "linkedin", "id": "4419969671", "url": "https://www.linkedin.com/jobs/view/senior-software-engineer-%E2%80%93-go-golang-at-general-motors-4419969671", "title": "Senior Software Engineer – Go (Golang)", "company": { "name": "General Motors", "url": "https://www.linkedin.com/company/general-motors" }, "location": "Warren, MI", "listedAt": "2026-10-04T00:00:00.000Z", "logoUrl": "https://media.licdn.com/dms/image/v2/D4E0BAQEfAZWzerj03w/company-logo_100_100/B4EZdkPGXYGcAQ-/0/1749733370529/general_m…" } ], "cursor": "h_TeY5EWj-37w_ujJXXHN6eeZOrORkaeSsEUKA69tm4TPSluwQfHvBfTozUFn5_nbiNu-IDKi84g4OL33eFYlGA42NNn9alAFWwQyWLmbZkF3r6nNl10nnG…" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. ## Notes - A LinkedIn-only record; its fields are shown in the response. --- # X > X through the shared SNS operations: profiles, posts, an account's recent posts and communities. Source: https://apinoa.com/en/docs-raw/api-reference/x ## Operations | Operation | Endpoint | Returns | Price | |---|---|---|---| | [Profile](/docs/api-reference/x/profile) | `GET \| POST /v1/x/profile` | `Account` | $0.001 | | [Post](/docs/api-reference/x/post) | `GET \| POST /v1/x/post` | `Post` | $0.001 | | [Posts](/docs/api-reference/x/posts) | `GET \| POST /v1/x/posts` | `Page` | $0.001–$0.002 | | [Group](/docs/api-reference/x/group) | `GET \| POST /v1/x/group` | `Group` | $0.001 | --- # Profile > Get an X account's profile. Source: https://apinoa.com/en/docs-raw/api-reference/x/profile ```http GET | POST /v1/x/profile ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/x/profile?username=nasa" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "nasa" }); const res = await fetch(`https://gateway.apinoa.com/v1/x/profile?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/x/profile", params={"username": "nasa"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` | The profile | | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `username` | string | | @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Account`](/docs/api-reference/sns/response-schema#account) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "x", "id": "11348282", "handle": "NASA", "displayName": "NASA", "bio": "Making the seemingly impossible, possible. ✨", "url": "https://x.com/NASA", "avatarUrl": "https://pbs.twimg.com/profile_images/1321163587679784960/0ZxKlEKB.jpg", "bannerUrl": "https://pbs.twimg.com/profile_banners/11348282/1788992290", "verified": true, "createdAt": "2007-12-19T20:20:32.000Z", "counts": { "followers": 92311215, "following": 115, "posts": 74453 }, "links": [ { "url": "http://www.nasa.gov/", "title": "nasa.gov" } ], "private": false, "location": "Pale Blue Dot", "ext": { "blueVerified": true, "verifiedType": "Government", "affiliatesCount": 85, "highlightedTweetsCount": 287, "birthdate": { "day": 1, "month": 10, "year": 1958 } } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Post > Get one X post. Source: https://apinoa.com/en/docs-raw/api-reference/x/post ```http GET | POST /v1/x/post ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/x/post?id=2113693409772761305" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ id: "2113693409772761305" }); const res = await fetch(`https://gateway.apinoa.com/v1/x/post?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/x/post", params={"id": "2113693409772761305"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `id` | The post | A numeric id or the URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `id` | string | | Numeric post id, or the post URL (x.com//status/). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "x", "id": "2113693409772761305", "url": "https://x.com/NASA/status/2113693409772761305", "author": { "platform": "x", "id": "11348282", "handle": "NASA", "displayName": "NASA", "url": "https://x.com/NASA", "avatarUrl": "https://pbs.twimg.com/profile_images/1321163587679784960/0ZxKlEKB.jpg", "verified": true, "counts": { "followers": 92311215, "following": 115, "posts": 74453 }, "ext": { "blueVerified": true, "verifiedType": "Government" } }, "text": "LIVE: @NASAAdmin and agency leaders are sharing the latest updates on next year's Artemis III mission and our plans to…", "createdAt": "2026-10-23T18:05:54.000Z", "lang": "en", "media": [], "metrics": { "likes": 2130, "comments": 152, "views": 932721, "reposts": 403, "quotes": 54, "saves": 168 }, "entities": { "mentions": [ { "handle": "NASAAdmin", "id": "2000593641480605696" } ], "urls": [ { "url": "https://x.com/i/broadcasts/1RJZzBdZYQgJB", "displayUrl": "x.com/i/broadcasts/1…" } ] }, "linkPreview": { "url": "https://x.com/i/broadcasts/1RJZzBdZYQgJB", "title": "Artemis Acceleration", "thumbnailUrl": "https://pbs.twimg.com/card_img/2113725032149233664/e3OSIF1X?format=jpg&name=orig" }, "live": true, "broadcast": { "status": "ended" } } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Posts > List an X account's recent posts. Source: https://apinoa.com/en/docs-raw/api-reference/x/posts ```http GET | POST /v1/x/posts ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/x/posts?username=nasa&limit=5" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ username: "nasa", limit: "5" }); const res = await fetch(`https://gateway.apinoa.com/v1/x/posts?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/x/posts", params={"username": "nasa", "limit": "5"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `username` or `userId` | The account's recent posts | `userId` saves a lookup | Pass one source per call. Every identifier also takes the page URL. ## Which list you get Logged-out X serves accounts one of two lists, and the page tells you which in `order`: - `latest`: the account's posts, newest first, about 20 per page with a `cursor` for the next page. - `popular`: for some accounts X serves their most-liked posts instead, about 100 of them in one page, in no date order and with no `cursor`. The account's pinned post comes first on the first page, marked `pinned: true`, and does not repeat on later pages. X decides the page size, so `limit` is a hint only. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `cursor` | string | | Opaque cursor from the previous page's `cursor`. Pass it alone for the next page. | | `limit` | integer 1–100 | | Items per page, 1–100 — a hint only: X decides the page size (about 20, or ~100 for the most-liked list). | | `userId` | string | | Numeric user id. Pass it instead of a username to save the lookup. | | `username` | string | | @handle (with or without @), or the profile URL. | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Page`](/docs/api-reference/sns/response-schema#page) of [`Post`](/docs/api-reference/sns/response-schema#post) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "x", "items": [ { "platform": "x", "id": "2113776971603689874", "url": "https://x.com/NASA/status/2113776971603689874", "author": { "platform": "x", "id": "11348282", "handle": "NASA", "displayName": "NASA", "url": "https://x.com/NASA", "avatarUrl": "https://pbs.twimg.com/profile_images/1321163587679784960/0ZxKlEKB.jpg", "verified": true, "counts": { "followers": 92311241, "following": 115, "posts": 74453 }, "ext": { "blueVerified": true, "verifiedType": "Government" } }, "text": "We are not slowing down. 🚀\n\nOur Artemis III mission will send four astronauts to low Earth orbit next year to test crit…", "createdAt": "2026-10-23T23:37:56.000Z", "lang": "en", "media": [ { "type": "video", "url": "https://video.twimg.com/amplify_video/2113776813121941504/vid/avc1/1920x1080/oa29OYgVBG7qAyEB.mp4?tag=16", "thumbnailUrl": "https://pbs.twimg.com/media/HVWk812WIAAg_hz.jpg?name=orig", "width": 3840, "height": 2160, "durationSec": 59.893, "variants": [ { "url": "https://video.twimg.com/amplify_video/2113776813121941504/pl/Sws2JLpHl8xdzMyH.m3u8?tag=16&v=ab6", "contentType": "application/x-mpegURL" }, { "url": "https://video.twimg.com/amplify_video/2113776813121941504/vid/avc1/480x270/CK1pQpicyNC7ryVp.mp4?tag=16", "bitrate": 288000, "contentType": "video/mp4" } ] } ], "metrics": { "likes": 5396, "comments": 236, "views": 900353, "reposts": 680, "quotes": 59, "saves": 259 }, "entities": { "urls": [ { "url": "https://go.nasa.gov/4jzartX", "displayUrl": "go.nasa.gov/4jzartX" }, { "url": "https://go.nasa.gov/4zV3TLc", "displayUrl": "go.nasa.gov/4zV3TLc" } ] }, "ext": { "conversationId": "2113776971603689874" }, "pinned": true } ], "cursor": "LssW7FrvIb2W_z-EPjiVogYoj3-70ruy8A1hYTEVJNyV1xfWjamuub5cCUPOolr5oPAzKDidQINisvCy-drXkJvvPVGst8_JWWGhxGuKr_D5Ykq9D8H5vhr…", "order": "latest" } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_CURSOR` | The `cursor` is not one this operation returned. Start again without it. | | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call, plus $0.001 for each extra call it makes — at most 1 more, so $0.002 in total. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day. --- # Group > Get an X community. Source: https://apinoa.com/en/docs-raw/api-reference/x/group ```http GET | POST /v1/x/group ``` Send parameters as a query string with `GET`, or as a JSON body with `POST`. Both are equivalent. ## Request ```bash tab="cURL" curl "https://gateway.apinoa.com/v1/x/group?community=1601841656147345410" \ -H "x-api-key: $APINOA_API_KEY" ``` ```js tab="JavaScript" const params = new URLSearchParams({ community: "1601841656147345410" }); const res = await fetch(`https://gateway.apinoa.com/v1/x/group?${params}`, { headers: { "x-api-key": process.env.APINOA_API_KEY }, }); const { success, data, error } = await res.json(); ``` ```python tab="Python" import os import requests res = requests.get( "https://gateway.apinoa.com/v1/x/group", params={"community": "1601841656147345410"}, headers={"x-api-key": os.environ["APINOA_API_KEY"]}, ) body = res.json() ``` ## What to Pass | Pass | Reads | Notes | |---|---|---| | `community` | The community | A numeric id or URL | Pass one source per call. Every identifier also takes the page URL. ## Parameters | Parameter | Type | Required | Notes | |---|---|---|---| | `community` | string | | Numeric community id, or the community URL (x.com/i/communities/). | The same parameters, and every response type, are in the OpenAPI document: https://apinoa.com/openapi.json ## Response Returns [`Group`](/docs/api-reference/sns/response-schema#group) in `data`. A real response, shortened: arrays keep their first entries and long text is cut. ```json { "success": true, "data": { "platform": "x", "kind": "community", "id": "1601841656147345410", "name": "Generative AI", "url": "https://x.com/i/communities/1601841656147345410", "description": "Share AI-generated creations, news, tips and more." } } ``` ## Errors | Status | Code | Meaning | |---|---|---| | 400 | `INVALID_PARAMS` | A parameter is missing, unknown or out of range. The message names it. | | 401 | `UNAUTHORIZED` | The `x-api-key` header is missing, or the key is revoked or unknown. | | 402 | `INSUFFICIENT_BALANCE` | The balance does not cover this call. Top up in the dashboard. | | 404 | `NOT_FOUND` | The account, post or group does not exist, or is private, deleted or age-restricted. | | 429 | `MARKETPLACE_SATURATED` | Too many concurrent calls. Retry after the `Retry-After` seconds. | | 502 | `UPSTREAM_ERROR` | The platform answered with something unusable. Retry with backoff. | Every code is listed in [Errors](/docs/errors). Failed calls are not billed. ## Pricing **Price** $0.001 per call. [List price](https://apinoa.com/en/pricing); the rate steps down above 1,000 calls a day.