# APITube Help Center URL: https://support.apitube.io ## Ask News URL: https://support.apitube.io/en/articles/account-and-dashboard/ask-news Ask News is the AI chat in your APITube dashboard: ask about current events in plain language and get answers grounded in real News API articles, with sources. ![](/images/collections/ai.svg) # Ask News Ask about the news in plain language. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Jacob 1 author 3 articles * [How to Ask Questions with Ask News](/en/articles/account-and-dashboard/ask-news/using-ask-news) * [How to share an Ask News conversation](/en/articles/account-and-dashboard/ask-news/share-ask-news) * [What is Ask News?](/en/articles/account-and-dashboard/ask-news/what-is-ask-news) --- ## How to share an Ask News conversation URL: https://support.apitube.io/en/articles/account-and-dashboard/ask-news/share-ask-news Share an Ask News conversation from your APITube dashboard as a public read-only link: copy it from the chat menu, send it to anyone, and disable the link… # How to share an Ask News conversation Turn any saved Ask News chat into a public, read-only link — and disable it whenever you want ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 Updated July 21, 2026 # How to share an Ask News conversation[#](#how-to-share-an-ask-news-conversation) To share an Ask News conversation, open the saved chat in your APITube dashboard and click **Share** — the link is copied to your clipboard automatically, and anyone you send it to can open a public, **read-only** copy of the conversation without signing in. You can turn the link off again at any time with **Disable link**, which revokes access immediately. Sharing works on a chat you have already used: [Ask News](/en/articles/account-and-dashboard/ask-news/what-is-ask-news) saves each conversation to your account and gives it an automatic title from your first question, and only a saved conversation can be shared. Ask a question first, then the Share option is available. ## How do you create a share link for a conversation?[#](#how-do-you-create-a-share-link-for-a-conversation) Open **Ask News** from the dashboard sidebar, then create or open the chat you want to share. There are two places to start sharing: 1. In the chat itself, click **Share** in the top-right corner of the conversation. 2. Or, in the history list on the left, open the **⋯** menu next to a conversation and choose **Share**. A confirmation dialog titled **“Share this conversation?”** spells out what happens — anyone with the link will be able to read the conversation, and you can disable the link at any time: ![The Share this conversation dialog in Ask News with the Cancel and Create link buttons](/images/article/dashboard-ask-news-share.png) Click **Create link**, and APITube creates the public link and **copies it to your clipboard** right away — you will see a “Share link copied” confirmation. The link points at a page under your dashboard’s `/shared/` path with a long random token, for example: ``` https://dashboard.apitube.io/shared/3f9a1c7e0b2d4f68a1c3e5079b2d4f61 ``` Paste that link into an email, a message, or a document to share the conversation. Nothing about the chat is public until you create this link. ## What can people who open the link see?[#](#what-can-people-who-open-the-link-see) The link opens a **read-only** page showing the conversation’s title and the full message thread — your questions and the AI’s answers, including the source links Ask News cited. The page header carries the APITube logo and a “Shared chat · read-only” label, and the footer links back to the [APITube News API](/en/articles/getting-started/what-is-apitube-news-api) site. Visitors do **not** need an APITube account or a login to read it — the link alone is enough. Because the page is read-only, there is no message box on it: people with the link cannot continue the chat, reply, or edit anything. They see the conversation exactly as it was when you shared it. The shared page is also marked so search engines will not index it, so it will not appear in Google — it is reachable only by the exact link you send. ## How do you copy the link again or stop sharing?[#](#how-do-you-copy-the-link-again-or-stop-sharing) Once a conversation is shared, the button changes from **Share** to **Copy share link**. Clicking it copies the _same_ link again — sharing is idempotent, so a conversation keeps one stable link for as long as it stays shared. You can hand the same link to more people without generating a new one. To stop sharing, open the **⋯** menu on the conversation and choose **Disable link**. Access is removed immediately: the token stops resolving, so anyone who opens the old link now gets a “not found” page, and you will see a “Sharing disabled” confirmation. If you share the same conversation again later, APITube mints a **brand-new** link — the disabled one stays dead and cannot be reused. ## Who can share a conversation, and what stays private?[#](#who-can-share-a-conversation-and-what-stays-private) Conversations in Ask News are **personal to your account**, so only you can create or disable a share link for your own chats — sharing is tied to the account that owns the conversation. By default every conversation is private; nothing leaves your account until you deliberately create a link. The share link is a long random token, so it cannot be guessed — only the people you send it to can open the page. Treat the link like a password: anyone who has it can read that one conversation until you disable it. Disabling the link is the way to revoke access when a chat should no longer be public. # Common Questions[#](#common-questions) ## Can people reply to or edit a shared conversation?[#](#can-people-reply-to-or-edit-a-shared-conversation) No. A shared conversation is strictly read-only. The public page has no input box, so visitors can only read your questions and the AI’s answers — they cannot continue the chat, add messages, or change anything. To keep the conversation going, use it yourself in the dashboard; the shared copy just reflects what was there when you shared. ## Will a shared conversation show up in Google?[#](#will-a-shared-conversation-show-up-in-google) No. The shared page is set to no-index and no-follow, so search engines will not list it. It is reachable only through the exact link you send. That said, the page itself is public to anyone who has the link, so share it only with people you want to see the conversation. ## Does re-sharing create a new link each time?[#](#does-re-sharing-create-a-new-link-each-time) Not while the chat is already shared. Clicking **Share** (or **Copy share link**) on a conversation that is currently shared copies the same, stable link. A new link is created only if you first **Disable link** and then share again — at which point the previous link stays permanently disabled. ## Can I share a chat before I’ve asked anything?[#](#can-i-share-a-chat-before-ive-asked-anything) No. Only a saved conversation can be shared, and a conversation is saved once you have asked at least one question — Ask News stores it automatically and titles it from your first message. Start the chat, send a question, and the Share option becomes available. * * * ## Related Articles * [What is Ask News?](/en/articles/account-and-dashboard/ask-news/what-is-ask-news) * [What is the APITube MCP server?](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) * [What is APITube News API?](/en/articles/getting-started/what-is-apitube-news-api) --- ## How to Ask Questions with Ask News URL: https://support.apitube.io/en/articles/account-and-dashboard/ask-news/using-ask-news How to use Ask News in your APITube dashboard: type a question about current events, read the sourced answer, follow suggested questions, and reuse a search. # How to Ask Questions with Ask News Type a plain-language question in your dashboard and get a sourced answer built from live News API articles ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 Updated July 21, 2026 # How to ask questions with Ask News[#](#how-to-ask-questions-with-ask-news) To ask a question with Ask News, open **Ask News** from your APITube dashboard sidebar, type a plain-language question about current events into the box at the bottom, and press **Enter**. Ask News searches the News API for matching articles and writes a short answer with **numbered source links** you can click straight through to the publisher. There is no query syntax to learn — you write the way you would ask a person. When you open a fresh chat, the screen shows _“Ask anything about the news”_ and three ready-made example questions — **Latest news about Tesla**, **What’s happening with AI regulation?**, and **Summarize today’s top business headlines**. Click any one to send it instantly, or ignore them and type your own. ## How do you send a question?[#](#how-do-you-send-a-question) The message box sits at the bottom of the chat, with the placeholder _“Ask about the news…”_. Type your question and send it in one of two ways: * Press **Enter** to send. * Press **Shift + Enter** to add a line break without sending, for a longer, multi-line question. While Ask News is working, the send arrow turns into a **Stop** button — click it to cut a long answer short. Clear, event- or topic-focused questions work best, because each one maps onto a news search: _“What’s the latest on SpaceX?”_ or _“Recent news about AI regulation in Europe”_ both work well. ## How do you read the answer and its sources?[#](#how-do-you-read-the-answer-and-its-sources) Ask News answers in a step-by-step timeline so you can see what it did. First it may show **“Looking up references…”** while it resolves a name (like a company or person) to an ID, then **“Searching APITube News API…”** with your search terms in quotes, followed by **“Searched APITube News API”** once results come back. If a search finds nothing, it shows **“No results”** instead of guessing. Below the steps comes a **Sources** block: numbered cards, each with the article’s headline, its publisher domain, the publish date, and a thumbnail. Every card links to the original article and opens it in a new tab. The written answer follows, and any claim it makes links back to a source as a small superscript footnote like `[1]` — click the number to jump to that exact article. Sources are de-duplicated and the block lists up to 12 articles per answer. Because every statement is grounded in a real article, the fastest way to verify something is to follow its footnote. ![An Ask News conversation: the search step with the query in quotes, numbered source cards with dates, and follow-up suggestions above the message box](/images/article/dashboard-ask-news-conversation.png) ## What can you do with an answer?[#](#what-can-you-do-with-an-answer) Under each answer is a small row of actions: * **Copy** — copies the answer text plus a plain-text list of its sources to your clipboard, so you can paste both into a doc or message. The button briefly reads **Copied** to confirm. * **Open in [Playground](/en/articles/getting-started/glossary#playground)** — appears when the assistant ran a news search. It opens the dashboard [Playground](/en/articles/setup-and-installation/tools/test-in-playground) pre-filled with that search’s parameters, so you can run and tweak the real API request yourself. * **Create [webhook](/en/articles/getting-started/glossary#webhook)** — also appears after a search, to turn an exploratory question into an ongoing feed for the same query. A timestamp sits at the end of the row. Under the message box you will always see the reminder: _“Answers are AI-generated from APITube News API results and may be inaccurate.”_ — so treat answers as a starting point and follow the cited links for anything important. ## How do you keep a conversation going?[#](#how-do-you-keep-a-conversation-going) After each answer, Ask News offers a few **suggested follow-up questions** as chips just above the message box — click one to ask it, or keep typing your own. Follow-ups let you drill in (“Who are the key people involved?”, “What happened last week?”) without re-explaining the topic. To start over on a new subject, click **New chat** at the top of the history rail (or press **⇧⌘O**). Each conversation is saved to your account and titled automatically from your first question, so you can leave and come back to it later. If an answer fails, an error box appears with a **Retry** button to run it again. ## How do you find and manage past chats?[#](#how-do-you-find-and-manage-past-chats) Your saved conversations live in the **history rail** on the left (on mobile, tap **History** to open it). At the top is a **Search chats** box that filters your history by chat title _and_ by the text inside the messages, so you can find a discussion by what was said in it. In the list you can: * Click the **star** on a chat to favorite it — favorites are pinned to the top of the list. * Click a chat’s title to reopen it. * Open the **⋯** menu on a chat to **Rename**, **Delete**, or share it. Sharing turns a chat into a public read-only link — see [how to share an Ask News conversation](/en/articles/account-and-dashboard/ask-news/share-ask-news) for the full walkthrough. For a broader picture of what Ask News is and how it grounds answers, see [what is Ask News](/en/articles/account-and-dashboard/ask-news/what-is-ask-news). # Common Questions[#](#common-questions) ## Do I need to know API parameters to use Ask News?[#](#do-i-need-to-know-api-parameters-to-use-ask-news) No. Ask News takes plain-language questions and builds the news search for you — you never write `title`, `sort.by`, or any other parameter. If you later want the raw request behind an answer, use **Open in Playground** on that answer to see and edit the actual API call. ## How do I send a multi-line question?[#](#how-do-i-send-a-multi-line-question) Press **Shift + Enter** inside the message box to add a line break without sending. A plain **Enter** always sends the message, so use Shift + Enter whenever you need more than one line before submitting. ## Can I stop an answer while it is being written?[#](#can-i-stop-an-answer-while-it-is-being-written) Yes. While Ask News is generating, the send button becomes a **Stop** button. Click it to end the response early — useful if you already have what you need or want to rephrase. ## Where do the follow-up suggestions come from?[#](#where-do-the-follow-up-suggestions-come-from) They are generated from your last question and its answer, and appear as chips above the message box once a response finishes. They are optional shortcuts: click one to ask it, or ignore them and type your own next question. * * * ## Related Articles * [What is Ask News?](/en/articles/account-and-dashboard/ask-news/what-is-ask-news) * [How to share an Ask News conversation](/en/articles/account-and-dashboard/ask-news/share-ask-news) * [How to test requests in the Playground](/en/articles/setup-and-installation/tools/test-in-playground) --- ## What is Ask News? URL: https://support.apitube.io/en/articles/account-and-dashboard/ask-news/what-is-ask-news Ask News is the AI chat in your APITube dashboard: ask about current events in plain language and get answers grounded in real News API articles, with cited… # What is Ask News? The AI chat in your dashboard that answers questions about current events using real News API articles — with sources ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 3, 2026 Updated July 21, 2026 # What is Ask News?[#](#what-is-ask-news) Ask News is the **AI chat built into your APITube dashboard**. You ask about current events in plain language — no query syntax — and it answers using real articles pulled live from the APITube News API, citing each source as a link. Open **Ask News** from the dashboard sidebar and type a question like _“Latest news about Tesla”_ or _“What’s happening with AI regulation?”_ to get a grounded, sourced answer in seconds. Under the hood, Ask News is an **agent**: the assistant reads your question, runs one or more News API searches to find matching articles, and writes an answer from what it found. It is a faster way to explore the same data you would otherwise query with parameters — useful for a quick read on a topic before you build the actual API request. ![The Ask News chat page in the APITube dashboard with the question box and conversation list](/images/article/dashboard-ask-news.png) ## How does Ask News work?[#](#how-does-ask-news-work) Ask News connects a large language model to the [APITube News API](/en/articles/getting-started/what-is-apitube-news-api) through the same tools the [APITube MCP server](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) exposes — a news-search tool and a `suggest` tool that resolves names to IDs. When you send a question, the assistant turns it into a live search, reads the returned articles, and grounds every statement in them. It cites sources as markdown links pointing to each article’s original `href`, so you can click straight through to the publisher. The assistant defaults to a broad **title keyword search** (the most reliable filter), and for questions about “latest” or “recent” news it sorts by publish time, newest first. It answers in the **language of your question**. If a search returns nothing, it tells you plainly and suggests rephrasing rather than inventing an answer — it is instructed to never fabricate news, sources, numbers or links. As the in-app note says, answers are AI-generated from News API results and can still be inaccurate, so treat them as a starting point and follow the cited links. ## Does Ask News cost extra or use my API quota?[#](#does-ask-news-cost-extra-or-use-my-api-quota) No. Ask News is available to every signed-in account, and it does **not** consume your API request quota. The dashboard runs the underlying News API searches with a service key on your behalf, so chatting does not draw down the request credits you use for your own API calls. To keep the feature from being abused, there is a light per-user [rate limit](/en/articles/getting-started/glossary#rate-limit); if you send messages too quickly you get a short “too many requests” pause and can continue after a moment. Ask News is a convenience layer over data you already have access to — it is not a separate paid add-on. If you want to _verify a specific claim_ rather than explore a topic, that is a different tool: see [how to fact-check a claim or article](/en/articles/use-cases/trust-and-research/fact-check-claim). ## What can you do with a conversation?[#](#what-can-you-do-with-a-conversation) Each chat is saved to your account and given an automatic title from your first question, so you can come back to it later. Conversations are **personal to you**. From a conversation you can: * **Favorite** a chat to pin it to the top of your history, **rename** it, or **delete** it. * **Share** a conversation as a public, read-only link — anyone with the link can read it, and you can disable the link at any time to revoke access. * **Open a search in the [Playground](/en/articles/getting-started/glossary#playground)** — when the assistant runs a News API search, you can jump to the dashboard Playground pre-filled with those parameters to run and tweak the real request yourself. * **Create a [webhook](/en/articles/getting-started/glossary#webhook)** from a search, to turn an exploratory question into an ongoing feed. # Common Questions[#](#common-questions) ## Is Ask News the same as calling the News API directly?[#](#is-ask-news-the-same-as-calling-the-news-api-directly) No. Ask News is a chat interface that _calls_ the News API for you and summarizes the results in natural language. Calling the API directly (or through an SDK) gives you the raw JSON — every field, full control over filters, and no AI layer in between. Use Ask News to explore a topic quickly; use the API when you need structured data for an application. A good workflow is to explore in Ask News, then use **Open in Playground** to turn the assistant’s search into a real request you can copy. ## Are the answers reliable?[#](#are-the-answers-reliable) The answers are grounded in real articles and every claim links back to its source, but they are still AI-generated summaries and may contain mistakes. Always click through to the cited article to confirm anything important. If a search finds no matching articles, Ask News will say so instead of guessing — it is explicitly instructed not to invent sources or facts. ## Can other people see my conversations?[#](#can-other-people-see-my-conversations) Only if you choose to share one. By default every conversation is private to your account. When you create a share link, that single conversation becomes readable by anyone who has the link (read-only, they cannot continue the chat). Disabling the link removes that access immediately. ## What kinds of questions work best?[#](#what-kinds-of-questions-work-best) Clear, event- or topic-focused questions work best, because they map cleanly onto a news search — for example _“Summarize today’s top business headlines”_, _“What’s the latest on SpaceX?”_, or _“Recent news about AI regulation in Europe”_. Ask News searches news, so questions that are not about current events (general trivia, opinions, or tasks unrelated to news) fall outside what it is built to answer. * * * ## Related Articles * [What is the APITube MCP server?](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) * [What is APITube News API?](/en/articles/getting-started/what-is-apitube-news-api) * [How to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title) --- ## Account & Dashboard URL: https://support.apitube.io/en/articles/account-and-dashboard Manage your APITube account from the dashboard: create and control API keys, view usage and request logs, and set your profile and preferences. ![](/images/collections/account-billing.svg) # Account & Dashboard Keys, usage logs, profile and preferences. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Brian and 2 others 3 authors 19 articles These articles cover the APITube dashboard at dashboard.apitube.io: managing API keys, reading usage charts and request logs, updating your profile, and using Ask News — the built-in assistant that answers questions about the news with live API data. The dashboard is where you rotate or revoke keys, watch your quota in real time, and debug failed requests by inspecting their log entries. If a request behaves unexpectedly, check the request logs before anything else — the status code and latency recorded there usually point straight at the cause. ## [API Keys Management](/en/articles/account-and-dashboard/keys) * * * * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to limit an API key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes) * [How to Restrict an API Key to Specific IPs](/en/articles/account-and-dashboard/keys/key-ip-restriction) * [How to Set an Expiry Date on an API Key](/en/articles/account-and-dashboard/keys/key-expiry) * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) * [What Is on the API Keys Page of the Dashboard](/en/articles/account-and-dashboard/keys/api-keys-page-tour) ## [Ask News](/en/articles/account-and-dashboard/ask-news) * * * * [How to Ask Questions with Ask News](/en/articles/account-and-dashboard/ask-news/using-ask-news) * [How to share an Ask News conversation](/en/articles/account-and-dashboard/ask-news/share-ask-news) * [What is Ask News?](/en/articles/account-and-dashboard/ask-news/what-is-ask-news) ## [Profile & Preferences](/en/articles/account-and-dashboard/profile) * * * * [How to change the dashboard language](/en/articles/account-and-dashboard/profile/change-language) * [How to change the dashboard theme](/en/articles/account-and-dashboard/profile/change-theme) * [How to Close Your APITube Account](/en/articles/account-and-dashboard/profile/close-account) * [How to manage email notification preferences](/en/articles/account-and-dashboard/profile/email-preferences) * [How to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all) * [How to update your profile and avatar](/en/articles/account-and-dashboard/profile/update-profile) ## [Usage & Logs](/en/articles/account-and-dashboard/usage-and-logs) * * * * [How to export your API logs](/en/articles/account-and-dashboard/usage-and-logs/export-logs) * [How to Manage Dashboard Notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) * [How to track your usage and quota](/en/articles/account-and-dashboard/usage-and-logs/track-usage) * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) --- ## What Is on the API Keys Page of the Dashboard URL: https://support.apitube.io/en/articles/account-and-dashboard/keys/api-keys-page-tour The API Keys page of the APITube dashboard lists every key in a table with name, masked secret, usage, status — and holds up to 20 active keys. # What Is on the API Keys Page of the Dashboard A guided tour of the keys table, the quota bar and the Create key button — test article for dashboard screenshots ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 21, 2026 # What is on the API Keys page of the dashboard[#](#what-is-on-the-api-keys-page-of-the-dashboard) The **[API Keys](/en/articles/getting-started/glossary#api-key)** page of the APITube dashboard shows every key on your account in one table — the key’s name, its masked secret with a copy control, requests used, last-used time, creation date, a 7-day activity sparkline and an Active / Revoked / Expired status. This is what the page looks like on a fresh account with a single key: ![The API Keys page of the APITube dashboard: the quota bar on top, the Develop section in the sidebar and a keys table with one active key named Production key](/images/article/dashboard-api-keys-page.png) ## What the keys table shows[#](#what-the-keys-table-shows) Each row of the table is one API key. When an article only discusses the table itself, a cropped screenshot of just that block reads better than the full window: ![Cropped view of the API keys table: one row named Production key with a masked secret, zero requests used and an Active status badge](/images/article/dashboard-api-keys-table.png) From left to right you see the **Name** (a link to the key’s detail page), the **Key** value truncated to its first characters — the full secret is copied with one click, never printed on screen — then **Requests used**, **Last used**, **Created**, the **Activity** sparkline for the last 7 days, and the **Status** badge. The counter above the table (“1 of 20 active keys”) tracks your limit: each [workspace](/en/articles/getting-started/glossary#workspace) can hold up to **20 active keys**, counted separately for Test and Live mode. The **Create key** button on the right adds a new one — the full walkthrough is in [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## What the bar above the page shows[#](#what-the-bar-above-the-page-shows) The strip at the very top of the dashboard is not specific to this page — it follows you everywhere. It shows **API requests left** for the current period, remaining **[Webhooks](/en/articles/getting-started/glossary#webhook)** and **[WebSocket](/en/articles/getting-started/glossary#websocket)** quota, your **Balance**, and a live **API status** pill that turns from “API operational” to a warning when the News API is degraded. The numbers are drawn from the same account quota that every key on the page spends from, as described in the official [rate limits reference](https://docs.apitube.io/platform/news-api/rate-limits). # Common Questions[#](#common-questions) ### Why is this article hidden from search?[#](#why-is-this-article-hidden-from-search) This page is a formatting test for embedding dashboard screenshots into the help center. It is excluded from the search index with `hideFromSearch`, so readers only reach it by direct link. ### Where was the screenshot taken?[#](#where-was-the-screenshot-taken) On a dedicated demo account (`screenshots@apitube.io`) that contains only seeded test data — one demo key and default quotas — so no real customer data ever appears in help-center images. * * * ## Related Articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) --- ## API Keys Management URL: https://support.apitube.io/en/articles/account-and-dashboard/keys Create, rename, regenerate and revoke APITube API keys, and lock them down with restrictions, endpoint scopes and expiry dates — all from the dashboard. ![](/images/collections/user-management-security.png) # API Keys Management Create, restrict and revoke API keys. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Erick 1 author 6 articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to limit an API key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes) * [How to Restrict an API Key to Specific IPs](/en/articles/account-and-dashboard/keys/key-ip-restriction) * [How to Set an Expiry Date on an API Key](/en/articles/account-and-dashboard/keys/key-expiry) * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) * [What Is on the API Keys Page of the Dashboard](/en/articles/account-and-dashboard/keys/api-keys-page-tour) --- ## How to Set an Expiry Date on an API Key URL: https://support.apitube.io/en/articles/account-and-dashboard/keys/key-expiry Set an expiration date on an APITube API key from the dashboard. Choose Never, 7, 30 or 90 days, or a custom date; expired keys are rejected with 401 ER0230. # How to Set an Expiry Date on an API Key Give a key a built-in end date so it stops working automatically ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 # How to set an expiry date on an API key[#](#how-to-set-an-expiry-date-on-an-api-key) To set an expiry date, open the **[API Keys](/en/articles/getting-started/glossary#api-key)** page in your APITube dashboard, click a key to open its detail page, and use the **Expiration** card to pick **Never**, **in 7 / 30 / 90 days**, or a **custom date**, then click **Set expiration**. Once that date passes, every request made with the key is rejected by the News API with a `401` response and the error code `ER0230`. An expiry date is useful for time-boxed access: a contractor key, a trial integration, a demo, or a temporary script that should not keep working forever. Setting one means you do not have to remember to revoke the key later — it cuts itself off on schedule. ## Where do you set a key’s expiry date?[#](#where-do-you-set-a-keys-expiry-date) Open the **API Keys** page in the dashboard, then click the key you want to change to open its detail page. The **Expiration** card has an **Expires** dropdown with these options: * **Never** — the key has no end date (this is the default for new keys). * **In 7 days**, **in 30 days**, **in 90 days** — the expiry is set relative to now. * **Custom** — a date picker appears so you can choose any future calendar date. Pick an option and click **Set expiration**. The expiry is stored on that single key only; it does not affect your other keys, your quota, or your subscription. You can come back and change it at any time. ![The Expiration card on the key detail page with the Expires dropdown set to Never and the Set expiration button](/images/article/dashboard-key-expiry-form.png) ## Can you set an expiration when creating a key?[#](#can-you-set-an-expiration-when-creating-a-key) Yes. When you click **Create key** on the API Keys page, the create dialog includes the same **Expiration** control alongside the name, restrictions, and scopes. Choose Never, 7 / 30 / 90 days, or a custom date before you confirm, and the new key is born with that end date already attached. You can read more about the rest of the create flow in [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). The expiry date must be in the **future**. If you submit a date that has already passed, the dashboard rejects it with the message _“Expiration must be in the future.”_ — a key cannot be created or saved as already dead. ## What happens when an API key expires?[#](#what-happens-when-an-api-key-expires) Once the expiry moment passes, the News API treats the key as expired on **every** request. The server checks the key right after confirming it is valid and before any IP or scope checks, so an expired key never reaches your data. The response is HTTP `401` with this body: ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 401, "code": "ER0230", "message": "API key has expired.", "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }, "timestamp": "…" } ] } ``` Expiry applies to **[Test keys](/en/articles/getting-started/glossary#test-key-and-live-key) as well as Live keys** — a `api_test_` key with a past `expires_at` is rejected with `ER0230` just like a Live one. To get a key working again, open its detail page and either move the expiry to a future date or set it back to **Never**; there is no way to revive an expired key from the request itself, because the date is enforced on each call. For the full debugging path on this and the other 401 codes, see [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors). ## How do you get warned before a key expires?[#](#how-do-you-get-warned-before-a-key-expires) The dashboard surfaces expiry in two places so a key does not silently die on you: * **Status column.** On the API Keys table, a key past its date shows a red **Expired** status. A key that is still valid but within **seven days** of expiring shows an **Active** badge with an **“Expires in Nd”** note next to it. * **Notifications.** When one or more keys are within seven days of expiry you get an **“API key expiring soon”** notification (“{count} key(s) expire within {days} days”), and once a key has expired you get an **“API key expired”** notice (“{count} key(s) have expired and no longer work”). Use these as a prompt to rotate the key or push out its expiry before downstream requests start failing. ## Who can change a key’s expiry?[#](#who-can-change-a-keys-expiry) In a shared [workspace](/en/articles/getting-started/glossary#workspace), the **owner**, **admins**, and **members** can set or change a key’s expiry. **Viewers** have read-only access and cannot. The role check runs on the server, so a viewer is blocked from changing an expiry even outside the dashboard UI. # Common Questions[#](#common-questions) * [How do I remove or extend an expiry?](#how-do-i-remove-or-extend-an-expiry) * [Does an expired key stop my whole account?](#does-an-expired-key-stop-my-whole-account) * [Do expired keys still count toward my key limit?](#do-expired-keys-still-count-toward-my-key-limit) * [Can I expire a Test key?](#can-i-expire-a-test-key) ## How do I remove or extend an expiry?[#](#how-do-i-remove-or-extend-an-expiry) Open the key’s detail page, set the **Expires** dropdown to **Never** (to remove the expiry entirely) or pick a new, later date, and click **Set expiration**. The change takes effect on the next request. Removing or extending the expiry keeps the same key secret, name, usage history, and restrictions — only the end date changes. ## Does an expired key stop my whole account?[#](#does-an-expired-key-stop-my-whole-account) No. Expiry is per key, not per account. Only requests using that specific key get the `401 ER0230` response. Your other keys keep working, and your quota, balance, and subscription are unaffected. If you have several services, give each its own key so an expiry on one never disrupts the others. ## Do expired keys still count toward my key limit?[#](#do-expired-keys-still-count-toward-my-key-limit) Yes. The active-key limit (up to 20 per workspace, counted separately for Test and Live) counts every key that has not been revoked, so an expired-but-not-revoked key still occupies a slot. If you want to free that slot, **revoke** the expired key from its row menu. Revoked keys do not count toward the limit. ## Can I expire a Test key?[#](#can-i-expire-a-test-key) Yes. The expiry setting works the same on Test and Live keys, and the API enforces it on both. A Test key whose date has passed returns the same `401 ER0230` as a Live key, so you can use a short expiry on throwaway Test keys for demos and sandboxes. * * * ## Related Articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to Fix Authentication (401) Errors](/en/articles/troubleshooting/fix-auth-errors) --- ## How to Restrict an API Key to Specific IPs URL: https://support.apitube.io/en/articles/account-and-dashboard/keys/key-ip-restriction Restrict an APITube API key to specific IP addresses or CIDR ranges from your dashboard. Requests from any other IP are rejected with 403 error code ER0601. # How to Restrict an API Key to Specific IPs Lock a key to trusted IP addresses and CIDR ranges ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=apple) # How to restrict an API key to specific IPs[#](#how-to-restrict-an-api-key-to-specific-ips) An IP allow-list ties an APITube [API key](/en/articles/getting-started/glossary#api-key) to the addresses it is allowed to call from. You add the trusted IPs in your dashboard — at key creation or later on the key’s detail page — and any request from an IP outside that list is rejected with `403` and error code `ER0601`. A key with an **empty** IP list has no restriction and works from anywhere, which is the default. This is server-side protection: if a key with an IP allow-list leaks, it is useless from any machine you did not authorize. It pairs well with endpoint scopes and an expiry date to keep a key tightly locked down. ## Where do you set a key’s allowed IP addresses?[#](#where-do-you-set-a-keys-allowed-ip-addresses) You configure IPs in the dashboard; there is no News API call to change them. Open the **API Keys** page and either create a new key or click an existing key to open its detail page. The **API Key Restrictions** card has an **Allowed IP Addresses** box — enter **one IP per line** (max 50 per list) and click **Save Restrictions**. The same field also appears in the **Create key** dialog, so you can lock a new key down before it is ever used. Leaving the box empty means the key is not IP-restricted. ![The API Key Restrictions card on the key detail page with the Allowed IP Addresses box and the Save restrictions button](/images/article/dashboard-key-restrictions-form.png) Each entry can be: * A single **IPv4** address, e.g. `203.0.113.20` * A single **IPv6** address * A **CIDR range** — IPv4 `/0`–`/32` or IPv6 `/0`–`/128`, e.g. `10.0.0.0/24` * An **octet-prefix wildcard**, e.g. `10.0.*` (matches any IP starting with `10.0.`) * `*` on its own, which matches every address (same as leaving the list empty) The dashboard validates every line against the exact rules the News API enforces, so you can only save entries the API will actually apply. An invalid entry such as `10.0.0.999` disables **Save** in the form and is rejected server-side with `422 Invalid entries: …`. ## What happens when a request comes from a blocked IP?[#](#what-happens-when-a-request-comes-from-a-blocked-ip) The IP check runs early in request handling — right after the key is confirmed valid and not expired, and before the referrer and scope checks. If the caller’s IP is not in the allow-list, the API returns `403` with `ER0601`: ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 403, "code": "ER0601", "message": "Access denied: your IP address is not allowed for this API key.", "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }, "timestamp": "…" } ] } ``` A request from an allowed IP goes through normally: ``` curl "https://api.apitube.io/v1/news/everything?title=apple" \ -H "X-API-Key: YOUR_API_KEY" ``` The same key sent from an IP outside the list returns the `ER0601` body above instead of articles. The check is identical whether you send the key as an `X-API-Key` header or an `api_key` query parameter. A `403 ER0601` means the key is recognized but the _caller’s location_ is not allowed — different from a `401`, which is an authentication failure. For a side-by-side walkthrough of `ER0601` (IP) and `ER0603` (scope), see [why is my request blocked by IP or scope](/en/articles/troubleshooting/ip-scope-blocked). ## How are IP restrictions different from scopes and expiry?[#](#how-are-ip-restrictions-different-from-scopes-and-expiry) They are independent controls you can layer on one key. An **IP allow-list** limits _where_ a key may call from (`ER0601`), [endpoint scopes](/en/articles/account-and-dashboard/keys/key-scopes) limit _which endpoints_ it may call (`ER0603`), and an [expiry date](/en/articles/account-and-dashboard/keys/key-expiry) limits _how long_ it stays valid (`ER0230`). A request must pass every restriction that is set, so a call only succeeds when its IP is allowed **and** its endpoint is in scope. Combine all three for a key that only works from your servers, only hits the endpoints it needs, and stops working on schedule. # Common Questions[#](#common-questions) ## Can I restrict a key to a whole network with CIDR?[#](#can-i-restrict-a-key-to-a-whole-network-with-cidr) Yes. Enter a CIDR range like `10.0.0.0/24` (a 256-address block) or `203.0.113.0/28` instead of listing every address. Both IPv4 (`/0`–`/32`) and IPv6 (`/0`–`/128`) prefixes are supported, and you can mix single IPs, wildcards, and CIDR ranges in the same list — up to 50 entries. A malformed CIDR never matches anything; it is skipped, not treated as an error. ## Does the API see the real client IP behind a proxy?[#](#does-the-api-see-the-real-client-ip-behind-a-proxy) The News API runs with proxy trust enabled, so the IP it checks is the original client address forwarded by the proxy, not the proxy’s own IP. IPv4-mapped IPv6 addresses (`::ffff:203.0.113.20`) are normalized back to plain IPv4 before matching, so an allow-list entry of `203.0.113.20` still matches. Allow-list the **public egress IP** your requests actually leave from — your server’s outbound IP or office gateway, not a private LAN address. ## Who can change a key’s IP restrictions?[#](#who-can-change-a-keys-ip-restrictions) [Workspace](/en/articles/getting-started/glossary#workspace) **owners, admins, and members** can edit IP restrictions. **Viewers** have read-only access and cannot — the role is checked on the server, so a viewer is blocked even outside the dashboard UI. To create and manage the keys themselves first, see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## What if I lock myself out?[#](#what-if-i-lock-myself-out) Because the list is stored on the key and enforced on every request, you cannot bypass it from the request side. If your server’s IP changes and requests start failing with `ER0601`, open the key’s detail page and add the new IP (or clear the **Allowed IP Addresses** box to remove the restriction entirely). The change applies to the next request. * * * ## Related Articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to limit an API key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes) * [Why Is My Request Blocked by IP or Scope?](/en/articles/troubleshooting/ip-scope-blocked) --- ## How to limit an API key to specific endpoints URL: https://support.apitube.io/en/articles/account-and-dashboard/keys/key-scopes Restrict an APITube API key to specific endpoints with scopes. Grant only the endpoints a key needs; calls to anything else return 403 with error code ER0603. # How to limit an API key to specific endpoints Use scopes to authorize a key for only the endpoints it needs ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn August 22, 2026 Updated July 21, 2026 # How to limit an API key to specific endpoints[#](#how-to-limit-an-api-key-to-specific-endpoints) Scopes let you authorize an APITube [API key](/en/articles/getting-started/glossary#api-key) for only the endpoints it actually needs. You pick the allowed endpoints in your dashboard — at key creation or later on the key’s detail page — and any request to an endpoint outside that list is rejected with `403` and error code `ER0603`. A key with **no** scopes set has full access to every endpoint, which is the default. Scopes follow least-privilege: a key embedded in a public-facing widget can be limited to read-only search, while a server key keeps broader access. If that public key leaks, the damage is capped to the endpoints you allowed. ## What are API key scopes?[#](#what-are-api-key-scopes) A scope is the permission for one endpoint family. Each scope id matches the request type the News API records for that endpoint, so the name you grant is the same name the API checks on every call. The available scopes are grouped in the dashboard: * **News** — `everything`, `news_raw`, `top_headlines`, `news_local`, `story`, `article`, `category`, `topic`, `industry`, `entity`, `trends`, `news_count`, `fact_check` * **Reference** — `people`, `companies`, `journalists` * **Suggest** — `suggest` * **Streaming** — `stream`, `websocket` * **[Webhooks](/en/articles/getting-started/glossary#webhook)** — `webhooks:read`, `webhooks:write` * **Account** — `balance` For example, the `everything` scope covers `/v1/news/everything`, `top_headlines` covers `/v1/news/top-headlines`, and `article` covers `/v1/news/article`. An empty scope list means the key can call all of them — selecting every scope is treated the same as selecting none (full access). ## How to set scopes on a key[#](#how-to-set-scopes-on-a-key) You manage scopes in the dashboard; there is no News API call to change them. * **At creation.** In the **Create key** dialog on the API Keys page, choose the scopes alongside the key’s name and expiry. * **On an existing key.** Open the key to reach its detail page and use the **Scopes** form. Two presets speed this up: **Full access** (every endpoint) and **Read-only** (everything except modifying webhooks). You can also toggle a whole group or tick individual scopes, then save. Saving an unknown scope is rejected with `422 Invalid scopes`, so you can only grant real endpoints. To create and manage the keys themselves first, see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ![The scopes form on the key detail page: Full access and Read-only presets above grouped endpoint checkboxes and the Save permissions button](/images/article/dashboard-key-scopes-form.png) ## What happens when a key calls a blocked endpoint?[#](#what-happens-when-a-key-calls-a-blocked-endpoint) The scope check runs early in request handling, before the endpoint does any work. If the key’s scopes do not include the endpoint, the API returns `403`: ``` { "errors": [ { "status": 403, "code": "ER0603", "message": "Access denied: this API key is not authorized for this endpoint. Required scope: article." } ] } ``` The `Required scope` field names exactly the scope you would need to add. So a key scoped to only `everything` and `top_headlines` works for search and headlines, but a call to `/v1/news/article` fails with `ER0603` until you add the `article` scope. A `403` here means the key is recognized but not allowed for this request — different from a `401`, which is an authentication failure. If you need to debug a blocked request, [why is my request blocked by IP or scope](/en/articles/troubleshooting/ip-scope-blocked) walks through `ER0603` (scope) and `ER0601` (IP) side by side. # Common Questions[#](#common-questions) ## How do webhook scopes work?[#](#how-do-webhook-scopes-work) Webhooks split by action. A `GET` request to read webhook configuration needs `webhooks:read`, while creating, updating, or deleting a webhook needs `webhooks:write`. The **Read-only** preset includes `webhooks:read` but deliberately omits `webhooks:write`, so a read-only key can inspect webhooks without being able to change them. ## What happens if a key has no scopes set?[#](#what-happens-if-a-key-has-no-scopes-set) It has full access. An empty (or absent) scope list means the key can call every endpoint — this is the default for new keys and keeps existing keys working. Add scopes only when you want to narrow a key down; remove them (or pick Full access) to open it back up. ## Who can change a key’s scopes?[#](#who-can-change-a-keys-scopes) [Workspace](/en/articles/getting-started/glossary#workspace) **owners, admins and members** can edit scopes. **Viewers** cannot — they have read-only access with no key-management permissions. Scopes are checked the same way regardless of how you send the key, whether as an `X-API-Key` header or an `api_key` query parameter. ## Are scopes the same as an expiry date or IP restriction?[#](#are-scopes-the-same-as-an-expiry-date-or-ip-restriction) No — they are independent controls you can combine on one key. Scopes limit _which endpoints_ a key may call (`ER0603`), an IP allow-list limits _where_ it may call from (`ER0601`), and an [expiry date](/en/articles/account-and-dashboard/keys/key-expiry) limits _how long_ it stays valid (`ER0230`). Layer them for tightly scoped, time-boxed access. * * * ## Related Articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to set an expiry date on an API key](/en/articles/account-and-dashboard/keys/key-expiry) * [Why Is My Request Blocked by IP or Scope?](/en/articles/troubleshooting/ip-scope-blocked) --- ## How to view usage for each API key URL: https://support.apitube.io/en/articles/account-and-dashboard/keys/key-usage See how much each APITube API key is used: lifetime usage points, last-used time, plus requests, cost and top endpoints over any date range, all in the… # How to view usage for each API key See a key's lifetime usage points, last-used time and per-period requests ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 28, 2026 Updated July 21, 2026 # How to view usage for each API key[#](#how-to-view-usage-for-each-api-key) You view usage per [API key](/en/articles/getting-started/glossary#api-key) in the dashboard, where every key carries its own usage stats. The **API Keys** list shows a **Usage points** and **Last used** column for each key at a glance, and opening a key reveals its detail page with a lifetime total plus a date-range breakdown of **Requests**, **Cost** and **Top endpoints**. Usage is tracked separately for every key, so you can see exactly which key drives your traffic. Per-key usage tells you which key powers which workload, which keys sit idle (good candidates to revoke), and where your spend goes by endpoint. It is attribution, not a limit — your quota and credits are pooled at the account level, not per key. ## Where to find per-key usage in the dashboard[#](#where-to-find-per-key-usage-in-the-dashboard) There are two views, from summary to detail: 1. **The API Keys list.** Every row shows the key’s **Name**, **Key**, **Usage points**, **Last used**, **Created** date and **Status**. This is the quick overview across all your keys. 2. **A single key’s detail page.** Click a key to open it. The top stat strip shows **Usage points (total)**, **Last used**, **Created**, **Expires** and **Status**. Below it, a usage section charts activity over a date range, and a **Request logs** section lists the individual requests made with that key. To create or revoke the keys you are inspecting, see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ![The Usage section of a key detail page: requests, billed requests and per-day charts over the selected date range](/images/article/dashboard-key-usage.png) ## What does the “Usage points” total mean?[#](#what-does-the-usage-points-total-mean) **Usage points** is the running, lifetime total of credits charged to that one key since it was created. On every billed request, the News API adds that request’s cost to the key’s `usage_points` counter and stamps its **Last used** time. Most requests cost one point, so for typical traffic the number is close to the count of requests the key has ever made. This total only ever goes up — it is a cumulative odometer for the key, not a remaining balance. Because it is stored on the key itself, it is always complete, even for activity older than your request-log history. ## How to see a key’s requests over a date range[#](#how-to-see-a-keys-requests-over-a-date-range) The usage section on the key’s detail page reads your request logs, filtered to that key, and aggregates them over a date range you choose: * **Requests** — how many calls the key made in the range. * **Cost** — the credits those calls consumed. * **Avg / day** — average requests per day across the range. * **Top endpoints** — which endpoints the key called most, so you can see whether it leans on `/v1/news/everything`, `/v1/news/top-headlines`, or something else. Each metric also shows a change versus the previous period of equal length, and a per-day chart. Switching between **Test** and **Live** mode re-scopes the view to keys of that mode. For request-by-request detail — status code, latency, endpoint and calling IP — use the **Request logs** section right below it. # Common Questions[#](#common-questions) ## Is there a separate quota or limit per key?[#](#is-there-a-separate-quota-or-limit-per-key) No. Usage is tracked per key for visibility, but your quota, credits and balance live at the **account** level and are shared across all of your keys. Spending through one key draws down the same pool as any other. To check your remaining account balance programmatically, see [how to check your balance via the API](/en/articles/retrieval/check-balance-api). If you want to cap what one key can do, restrict it by [endpoint scopes](/en/articles/account-and-dashboard/keys/key-scopes) rather than a usage limit. ## Why is the lifetime total higher than the date-range numbers?[#](#why-is-the-lifetime-total-higher-than-the-date-range-numbers) The two are measured differently. **Usage points (total)** counts every credit the key has spent since it was created. The usage section only counts requests inside the date range you picked and that appear in your request logs. Narrow the range and the Requests and Cost figures naturally fall below the lifetime total; widen it to bring them closer. ## What counts toward a key’s usage?[#](#what-counts-toward-a-keys-usage) Every billed request you make with the key. Each request adds its credit cost to the key’s total, updates its **Last used** time, and writes a log line recording the endpoint, status, latency and calling IP. Failed and empty requests are logged too, so the count reflects all traffic, not just successful searches. ## Can I tell which endpoints a key uses most?[#](#can-i-tell-which-endpoints-a-key-uses-most) Yes — the **Top endpoints** breakdown in the usage section ranks a key’s calls by endpoint over the selected range. It is the fastest way to confirm a key is only hitting the endpoints you expect, which pairs naturally with locking the key down using [endpoint scopes](/en/articles/account-and-dashboard/keys/key-scopes). * * * ## Related Articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to limit an API key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes) * [How to set an expiry date on an API key](/en/articles/account-and-dashboard/keys/key-expiry) --- ## How to Create, Rename and Revoke API Keys URL: https://support.apitube.io/en/articles/account-and-dashboard/keys/manage-keys Create, rename, regenerate and revoke APITube API keys from the dashboard. Name each key, copy it anytime, and manage up to 20 active keys per workspace. # How to Create, Rename and Revoke API Keys Create named keys, rotate secrets and cut off access — all from the API Keys page in your dashboard ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=10) # How to create, rename and revoke API keys[#](#how-to-create-rename-and-revoke-api-keys) You manage every [API key](/en/articles/getting-started/glossary#api-key) on the **API Keys** page of your APITube dashboard. Click **Create key** to add one, then use the row menu on any key to rename it, regenerate its secret, or revoke it. Each [workspace](/en/articles/getting-started/glossary#workspace) can hold up to **20 active keys**, counted separately for Test and Live mode. An API key is the secret you send with every request to authenticate it. You can pass it as the `X-API-Key` request header or as an `?api_key=` query parameter, as shown in the official [authentication reference](https://docs.apitube.io/platform/news-api/authentication). The dashboard is where you create those keys and control their lifecycle. ## Where do you manage API keys?[#](#where-do-you-manage-api-keys) Open the **API Keys** page in the dashboard. It lists every key on the account in a table with columns for **Name**, **Key**, **Usage points**, **Last used**, **Created**, a 7-day **Activity** sparkline, and **Status**. Each row shows the key value truncated, with a copy icon that copies the full secret to your clipboard. Your first key is labelled **Default**, and any key you create without a name shows as **Unnamed key**. The **Status** column flags each key as **Active**, **Revoked**, or **Expired**, and warns “Expires in Nd” when a key is within seven days of its expiry date. Test-mode keys carry a small **Test** badge so you can tell them apart at a glance. ![The API Keys page of the APITube dashboard with the keys table and the Create key button](/images/article/dashboard-api-keys-page.png) ## How to create a new API key[#](#how-to-create-a-new-api-key) 1. On the API Keys page, click **Create key**. 2. Give the key a **name** — this field is required, so pick something you will recognize later, like “Production server”. The name can be up to 255 characters. 3. Optionally expand the extra settings to add an [**expiration**](/en/articles/account-and-dashboard/keys/key-expiry) (Never, in 7 / 30 / 90 days, or a custom date), **IP and referrer restrictions**, or **endpoint scopes** that limit which endpoints the key can call. 4. Click **Create key** to confirm. ![The Create API key dialog asking for a key name and an optional expiration](/images/article/dashboard-create-key-dialog.png) The new key appears at the top of the table. Its value starts with `api_live_` for a [Live key](/en/articles/getting-started/glossary#test-key-and-live-key) or `api_test_` for a Test key — the prefix is the only thing that marks a key’s mode — followed by a long random string. Click the copy icon next to the new key to grab the full secret and paste it into your app: ``` curl -H "X-API-Key: api_live_YOUR_KEY" \ "https://api.apitube.io/v1/news/everything?per_page=10" ``` Keys are created in whichever mode (Test or Live) you currently have selected, and the table shows only the keys for that mode. ## How to rename an API key[#](#how-to-rename-an-api-key) To rename a key, open the **⋯** menu at the end of its row and choose **Rename**. Type a new name and click **Save**. Renaming only changes the label you see in the dashboard — the secret, its usage history, and any restrictions stay exactly the same, so renaming never breaks a key that is already in use. Clear, specific names (“Staging worker”, “Mobile app”) make it far easier to audit and rotate keys later. ## How to regenerate (rotate) a key[#](#how-to-regenerate-rotate-a-key) Use **Regenerate** from the row menu when a secret may have leaked. Regenerating issues a brand-new secret for the same key while keeping its name, usage history, restrictions, scopes, and expiry — only the secret string changes, and the key stays in the same mode. The **old secret stops working immediately**, so update every place that used it right away. Because the previous secret is rejected the moment you regenerate, any client still sending it will start getting `401` responses until you swap in the new value. See [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) if requests fail after a rotation. ## How to revoke an API key[#](#how-to-revoke-an-api-key) To permanently disable a key, open the row menu and choose **Revoke**, then confirm. As the confirmation says, the key **stops working immediately and cannot be restored** — there is no undo. A revoked key stays in the table marked with a **Revoked** status for your records, but it no longer authenticates requests and no longer counts toward your active-key limit, which frees a slot for a new key. Revoke a key whenever it is no longer needed or you suspect it is compromised and you do not want to keep the same key slot. If you only want to swap the secret but keep the key, its name, and its history, use **Regenerate** instead of **Revoke**. # Common Questions[#](#common-questions) * [How many API keys can I have?](#how-many-api-keys-can-i-have) * [Can I see a key’s full value again after creating it?](#can-i-see-a-keys-full-value-again-after-creating-it) * [Do separate keys split my quota?](#do-separate-keys-split-my-quota) * [Who on my team can manage API keys?](#who-on-my-team-can-manage-api-keys) ## How many API keys can I have?[#](#how-many-api-keys-can-i-have) You can hold up to **20 active keys**, and the limit is counted separately for Test and Live mode — so you get 20 Live keys and 20 Test keys. Revoked keys do not count toward the limit, so revoking an old key always frees room to create a new one. Trying to create one past the limit returns an error telling you the maximum has been reached. ## Can I see a key’s full value again after creating it?[#](#can-i-see-a-keys-full-value-again-after-creating-it) Yes. Unlike many APIs, APITube keeps the full key value available in the dashboard: the API Keys table shows each key with a copy icon that copies the complete secret at any time. There is no “you can only see it once” step. Still, treat the value as a password — store it in a secret manager and never embed a privileged key in client-side or browser code. ## Do separate keys split my quota?[#](#do-separate-keys-split-my-quota) No. Your request quota, balance, and subscription are shared at the account level, not per key. Creating several keys does not give you more requests — every key draws from the same pool. Use multiple keys to separate environments (production, staging, a partner integration) and to rotate or revoke one without disturbing the others, not to increase your limits. ## Who on my team can manage API keys?[#](#who-on-my-team-can-manage-api-keys) In a shared workspace, the **owner**, **admins**, and **members** can all create, rename, regenerate, and revoke keys. **Viewers** have read-only access and cannot change keys. Role checks are enforced on the server, so an action a role cannot perform is blocked even outside the dashboard. * * * ## Related Articles * [How to Fix Authentication (401) Errors](/en/articles/troubleshooting/fix-auth-errors) * [Why Is My Request Blocked by IP or Scope?](/en/articles/troubleshooting/ip-scope-blocked) --- ## How to change the dashboard language URL: https://support.apitube.io/en/articles/account-and-dashboard/profile/change-language Switch the APITube dashboard interface to any of 13 languages from the header flag button or Account → Preferences. The change applies instantly and is saved… # How to change the dashboard language Switch the APITube dashboard interface to any of its 13 languages, and where the choice is saved ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en) # How to change the dashboard language[#](#how-to-change-the-dashboard-language) To change the APITube dashboard language, click the **flag button** in the top bar and pick a language, or open **Account → Preferences** and use the **Language** control. The interface switches straight away — there is no save button and no manual reload — and your choice is saved in your browser. The dashboard ships in **13 languages**, and a brand-new account is shown in the language your browser asks for, falling back to English. The dashboard language changes only the **interface** — menus, labels and buttons. It does **not** change the language of the news articles you get from the API. That is a separate filter, `language.code`, on your API requests. ## Where do I change the dashboard language?[#](#where-do-i-change-the-dashboard-language) The language switch lives in **two places**, and both open the same menu: * **Header flag button (fastest).** Look at the top bar of the dashboard, near the notification bell and your avatar menu. There is a small flag button — click it and a dropdown lists every language with its flag and native name. Pick one and it applies immediately. * **Account → Preferences.** Open your **Account** page and select the **Preferences** tab. The **Language** row sits alongside **Theme** and **Timezone**, and holds the same switch. Either way, selecting a language runs instantly and refreshes the page in the new language. You do not confirm or save anything. ![The Preferences tab of the Account page with the Language row next to Theme and Timezone](/images/article/dashboard-account-preferences.png) ## Which languages can I choose?[#](#which-languages-can-i-choose) The dashboard interface is available in 13 languages, each listed by its native name: * English * Deutsch (German) * Español (Spanish) * Français (French) * Italiano (Italian) * Nederlands (Dutch) * Português (Brasil) and Português (Portugal) — two separate Brazilian and European Portuguese options * 日本語 (Japanese) * 中文 (Chinese) * ไทย (Thai) * Svenska (Swedish) * Dansk (Danish) English is the default and the fallback used when no other match is found. ## Does changing the dashboard language change my search results?[#](#does-changing-the-dashboard-language-change-my-search-results) No. The dashboard language only translates the dashboard interface. Which language the **news articles** come back in is controlled separately, by the `language.code` parameter on your API requests. For example, to get English articles you pass `language.code=en`, regardless of what language your dashboard is displayed in: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&api_key=YOUR_API_KEY" ``` So you can run the dashboard in Japanese while pulling German articles, or vice versa — the two settings are independent. See [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) for how to restrict the API results themselves. ## Where is my dashboard language saved?[#](#where-is-my-dashboard-language-saved) Your language choice is stored as a cookie in **your browser**, and it lasts for about a year. It is not saved on your account, so it does not follow you to another computer or browser — much like the [dashboard theme](/en/articles/account-and-dashboard/profile/change-theme), which is also browser-local. If you clear your browser’s cookies, the language resets. When you have no saved choice yet — a new account, a new browser, or after clearing cookies — the dashboard reads your browser’s `Accept-Language` header and picks the closest match from the 13 supported languages. If none match, it shows English. # Common Questions[#](#common-questions) * [Why was the dashboard already in my language before I changed it?](#why-was-the-dashboard-already-in-my-language-before-i-changed-it) * [Does my language choice sync across devices?](#does-my-language-choice-sync-across-devices) * [I switched the language but the news is still in English — why?](#i-switched-the-language-but-the-news-is-still-in-english--why) * [How do I switch back to English?](#how-do-i-switch-back-to-english) ## Why was the dashboard already in my language before I changed it?[#](#why-was-the-dashboard-already-in-my-language-before-i-changed-it) On your first visit, before you have picked anything, the dashboard reads your browser’s `Accept-Language` header and matches it to one of the 13 supported languages. So if your browser is set to French, the dashboard starts in French without you doing anything. When it can’t match your browser language, it falls back to English. ## Does my language choice sync across devices?[#](#does-my-language-choice-sync-across-devices) No. The language is saved as a cookie in the browser you set it in, so it does not travel to another computer, another browser, or a private/incognito window — those start from the browser-detected language again. Set the language once in each browser you use and it will stick there for about a year. ## I switched the language but the news is still in English — why?[#](#i-switched-the-language-but-the-news-is-still-in-english--why) Because the dashboard language and the article language are two different settings. Changing the dashboard language only translates the interface. The language of the articles you receive is set by the `language.code` filter on the request — for example `language.code=fr` for French news. Adjust that parameter (or the equivalent control in the [Playground](/en/articles/getting-started/glossary#playground)) to change the article language. ## How do I switch back to English?[#](#how-do-i-switch-back-to-english) Open the flag button in the top bar or the **Language** row under **Account → Preferences**, and choose **English**. It applies immediately, the same as any other language. Clearing your browser cookies also resets the dashboard to your browser-detected language, which is English if nothing else matches. * * * ## Related Articles * [How to change the dashboard theme](/en/articles/account-and-dashboard/profile/change-theme) * [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) --- ## How to change the dashboard theme URL: https://support.apitube.io/en/articles/account-and-dashboard/profile/change-theme Change the APITube dashboard theme from the avatar menu or Account → Preferences: Light, Dark, System or the 80s theme, saved in your browser. # How to change the dashboard theme Switch the APITube dashboard between Light, Dark, System and the 80s theme — and where the choice is saved ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 6, 2026 # How to change the dashboard theme[#](#how-to-change-the-dashboard-theme) To change the APITube dashboard theme, open the **avatar menu** in the top-right corner and use the theme switch at the bottom, or go to **Account → Preferences** and use the **Theme** control. Pick one of **Light**, **Dark**, **System**, or **80s**. The change applies instantly — there is no save button and no page reload — and your choice is remembered in this browser. The theme is saved in **your browser**, not on your account. It does not sync across devices or browsers, and it does not change anything about the API, your data, or your other dashboard settings. ## Where do I change the dashboard theme?[#](#where-do-i-change-the-dashboard-theme) The theme switch lives in **two places**, and both do exactly the same thing: * **Avatar menu (fastest).** Click your avatar in the top-right corner of the dashboard. The theme switch is the last item at the bottom of the dropdown — a small row of icons for Light, Dark, System and 80s. Clicking one applies it immediately without closing the menu, so you can preview each option. * **Account → Preferences.** Open your **Account** page and select the **Preferences** tab (the Account page is organized into tabs such as Profile, Security, Notifications and Preferences). The **Theme** row at the top holds the same switch. You can jump straight there with the `?tab=preferences` link on the Account page. ![The Theme switch on the Preferences tab of the Account page](/images/article/dashboard-account-preferences.png) ## What themes can I choose?[#](#what-themes-can-i-choose) The dashboard ships with four options: * **Light** — a bright, high-contrast console look, best in well-lit rooms. * **Dark** — a dark background that’s easier on the eyes at night. * **System** — follows your operating system. If your OS is set to dark mode, the dashboard is dark; when the OS switches to light, so does the dashboard. This is the **default** for a new account, so if you never touched the setting, the dashboard already matches your computer. * **80s** — a retro synthwave theme: Orbitron display headings with a neon-cyan glow and subtle CRT scanlines over the page. It’s a purely visual skin — every button, table and chart works exactly as in Light or Dark. ## Does my theme sync across devices and browsers?[#](#does-my-theme-sync-across-devices-and-browsers) No. The theme is stored locally in the browser you set it in, so it does **not** follow you to another computer, another browser, or a private/incognito window. This is different from your other dashboard preferences — the **timezone**, **date format** and **density** you pick on the same Preferences tab are saved to your account and _do_ travel with you. Only the theme is browser-local. If you want the same look everywhere, set it once in each browser you use. # Common Questions[#](#common-questions) ## Why did my theme reset to System on another computer?[#](#why-did-my-theme-reset-to-system-on-another-computer) Because the theme lives in the local browser, not your account. A different device, a different browser, or clearing your browser’s site data all start fresh — and a fresh start falls back to the **System** default, which follows that machine’s light/dark setting. Set the theme again in that browser and it will stick there. ## Does changing the theme affect the API or my results?[#](#does-changing-the-theme-affect-the-api-or-my-results) No. The theme only restyles the dashboard interface. It has no effect on API requests, response data, your [API keys](/en/articles/getting-started/glossary#api-key), quota, or billing. Switching to the 80s theme (or any other) is safe to do at any time and changes nothing about how the News API behaves. ## The theme control disappeared after I signed out — is that normal?[#](#the-theme-control-disappeared-after-i-signed-out--is-that-normal) Yes. The switch is part of the signed-in dashboard, so it’s only available while you’re logged in. Note that changing the theme is not the same as ending a session — if you want to end every active login, that’s a separate action: see [how to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all). To fine-tune what the dashboard shows you, you can also [manage dashboard notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) from the same Account area. * * * ## Related Articles * [How to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all) * [How to manage dashboard notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) --- ## How to Close Your APITube Account URL: https://support.apitube.io/en/articles/account-and-dashboard/profile/close-account Close your APITube account from Account → Security. It revokes all your API keys, changes your sign-in email and signs you out for good. # How to Close Your APITube Account Revoke every API key, change your sign-in email and sign out from Account → Security ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 21, 2026 # How to close your APITube account[#](#how-to-close-your-apitube-account) To close your APITube account, open the dashboard, go to **Account → Security**, and click **Close account** in the **Danger zone** card. A dialog asks you to type your own email to confirm; once you do, closing **revokes all your [API keys](/en/articles/getting-started/glossary#api-key)**, changes your sign-in email, and signs you out. It cannot be undone from the dashboard, so treat it as final. Closing your account is different from signing out. **Signing out everywhere** ends your login but keeps your API keys working; **closing your account** revokes every key at once, so any app that still sends one will start failing. ## What happens when you close your account?[#](#what-happens-when-you-close-your-account) Closing your account does three things in one step: it **revokes every active API key** on the account, changes your **sign-in email**, and rotates your login so you are signed out immediately. After it runs you see a short “Account closed — signing you out” message and the dashboard sends you to the sign-out page. Because the sign-in email is changed, you can no longer log in with your old email and password — that pair no longer matches an account you can reach. And because the keys are revoked, any integration that authenticates with one of those keys stops working right away. This is why it is a **Danger zone** action rather than a normal setting. ## Where is the close account button?[#](#where-is-the-close-account-button) The button lives on the **Security** tab of your **Account** page, in a red-outlined **Danger zone** card. The card is labelled _“Revoke all API keys, change your sign-in email and log out.”_ so it states exactly what the action does before you start. Click **Close account** to open the confirmation dialog titled **“Close your account?”**. The dialog repeats the warning — _“This revokes all your API keys, changes your sign-in email and logs you out. It cannot be undone from the dashboard.”_ — so there is a deliberate second step before anything happens. ![The Security tab of the Account page where the Danger zone card with the Close account button lives](/images/article/dashboard-account-security.png) ## How do I confirm closing my account?[#](#how-do-i-confirm-closing-my-account) APITube uses a type-to-confirm step so you cannot close the account with a single stray click. The dialog shows **“Type to confirm”** and the **Close account** button stays disabled until the text you enter exactly matches the email on your account. This is checked twice: the dashboard disables the button until the email matches, and the server verifies the same email again when the request arrives. If the confirmation email does not match — for example an empty or mistyped value — the request is rejected and nothing is closed, so a partial or accidental close is not possible. ## Does closing my account cancel my subscription?[#](#does-closing-my-account-cancel-my-subscription) Closing your account does **not** automatically cancel a paid subscription. The close action only revokes keys, changes your sign-in email and signs you out — it does not touch billing. If you are on a paid plan, cancel the subscription from your billing settings **before** you close the account, otherwise the subscription can keep renewing even though you can no longer sign in to manage it. The same applies to any [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance: closing the account does not refund or move a balance, so spend down or stop using it first if that matters to you. ## Close account vs. sign out everywhere: which do I need?[#](#close-account-vs-sign-out-everywhere-which-do-i-need) Pick based on what you are trying to stop: * **Sign out everywhere** — ends your dashboard **login sessions** on every device but leaves your API keys active. Use it after signing in on a shared computer or if you think someone reached your dashboard. See [how to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all). * **Revoke one key** — cuts off a single leaked or unused key while the rest keep working. See [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). * **Close account** — the most drastic option: revokes **every** key, changes your sign-in email and signs you out for good. If your real goal is just to rotate a compromised key or a leaked login, use one of the first two — closing the account is only for leaving the service entirely. # Common Questions[#](#common-questions) * [Can I undo closing my account?](#can-i-undo-closing-my-account) * [Will my API keys still work after closing?](#will-my-api-keys-still-work-after-closing) * [Does closing my account erase all my data?](#does-closing-my-account-erase-all-my-data) * [Can I close only part of my account, like one workspace?](#can-i-close-only-part-of-my-account-like-one-workspace) ## Can I undo closing my account?[#](#can-i-undo-closing-my-account) Not from the dashboard — the confirmation dialog states plainly that the action “cannot be undone from the dashboard.” Closing changes your sign-in email and rotates your login, so you cannot simply log back in with your old credentials and reverse it yourself. If you closed the account by mistake and need help, contact [support@apitube.io](mailto:support@apitube.io) rather than trying to sign in again. ## Will my API keys still work after closing?[#](#will-my-api-keys-still-work-after-closing) No. Closing your account revokes **all** of its API keys at the same time, so every request that sends one of those keys will start failing. This is the key difference from signing out of all devices, which leaves your keys running. Before you close, make sure no live application depends on those keys, or move that traffic to a different account first. ## Does closing my account erase all my data?[#](#does-closing-my-account-erase-all-my-data) Closing your account stops your access — it revokes your keys, changes your sign-in email and signs you out — but it is designed as a “close,” not a self-service data wipe, which is why it cannot be reversed from the dashboard. If you specifically need your personal data removed rather than just your access closed, contact [support@apitube.io](mailto:support@apitube.io) with that request. ## Can I close only part of my account, like one workspace?[#](#can-i-close-only-part-of-my-account-like-one-workspace) No. **Close account** applies to your whole account, not a single [workspace](/en/articles/getting-started/glossary#workspace) or a single key. To scope things down instead, revoke an individual key from your [API keys](/en/articles/account-and-dashboard/keys/manage-keys) page, or manage members and workspaces from your team settings. Reserve **Close account** for when you want to leave APITube completely. * * * ## Related Articles * [How to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## How to manage email notification preferences URL: https://support.apitube.io/en/articles/account-and-dashboard/profile/email-preferences Manage which APITube emails you get from Account → Notifications: two switches for Marketing Emails and Development updates, both on by default. # How to manage email notification preferences Choose which APITube emails reach your inbox from Account → Notifications — and how the switches affect account alerts ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 6, 2026 # How to manage email notification preferences[#](#how-to-manage-email-notification-preferences) To manage which APITube emails reach your inbox, open **Account → Notifications** in your dashboard. That tab has two switches — **Marketing Emails** and **Development updates** — and both are **on by default**. Flip either one and the choice saves right away, with a small “Saved” confirmation; there is no separate save button. Your email preferences are personal to the account you are signed in with, so changing them affects only your own inbox. ## Where do you manage email preferences?[#](#where-do-you-manage-email-preferences) Email preferences live in the **Account** page, under the **Notifications** tab. You can open it directly at `/account?tab=notifications`, or click the **Notification settings** link at the bottom of the notification bell panel. The tab shows two switches: * **Marketing Emails** — _Product digests and news._ * **Development updates** — _Product changelog and technical announcements._ Each switch saves independently the moment you toggle it, so you can turn one off and leave the other on. There is no form to submit — the change is written straight away. ![The Notifications tab of the Account page with the Marketing Emails and Development updates switches](/images/article/dashboard-account-notifications.png) ## What does each email switch control?[#](#what-does-each-email-switch-control) APITube groups its emails into two categories, and each switch controls one: * **Marketing Emails** covers product digests and general news — the promotional side of your inbox. * **Development updates** covers the product changelog and technical announcements. Both start **on**: if you have never touched these switches, you are treated as subscribed. Turning a switch off records you as unsubscribed for that category; turning it back on re-subscribes you. Because the default is “on,” you only ever need to visit this tab to _opt out_ of a category (or opt back in later). ## Do these switches affect account alerts?[#](#do-these-switches-affect-account-alerts) Yes — the **Development updates** switch also gates your operational account emails. The alerts APITube sends by email are: * **Quota warnings** at 75%, 90% and 100% of your monthly requests. * **[API key](/en/articles/getting-started/glossary#api-key) expiring soon** and **API key expired** notices. * **[Pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) spending-limit** notices at 80% and 100% of your monthly cap. All of these are delivered under the **Development updates** category, so switching it off silences these operational emails too. The **Marketing Emails** switch does not touch them. If you want product news off but account warnings on, leave **Development updates** enabled. Turning off email does **not** hide these alerts inside the app: the notification bell still surfaces quota, billing and key-expiry warnings from your live account state. See [how to manage dashboard notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) for the in-app side. One related behaviour: dismissing an alert in the bell also stops the matching email, so the two stay in sync. ## How do you unsubscribe from an email you already received?[#](#how-do-you-unsubscribe-from-an-email-you-already-received) Every APITube notification email carries an **unsubscribe link** in its footer. Opening it takes you to a public page — you do **not** need to be logged in — with a button that unsubscribes you. That footer link is a broad opt-out: it removes you from **all** email categories at once, not just the one that sent the message. For finer control, use the two switches in **Account → Notifications** instead, where you can keep one category and drop the other rather than turning everything off. # Common Questions[#](#common-questions) * [Are APITube emails on or off by default?](#are-apitube-emails-on-or-off-by-default) * [Will turning off email stop my expiring-key and quota warnings?](#will-turning-off-email-stop-my-expiring-key-and-quota-warnings) * [Do email preferences change for my whole team?](#do-email-preferences-change-for-my-whole-team) * [Can I re-subscribe after unsubscribing?](#can-i-re-subscribe-after-unsubscribing) ## Are APITube emails on or off by default?[#](#are-apitube-emails-on-or-off-by-default) On. Both **Marketing Emails** and **Development updates** are enabled unless you turn them off — if you have never opened the Notifications tab, you are counted as subscribed to both. This means the tab is where you go to _reduce_ email, and any category you have not explicitly switched off is still active. ## Will turning off email stop my expiring-key and quota warnings?[#](#will-turning-off-email-stop-my-expiring-key-and-quota-warnings) By email, yes — those operational notices ride the **Development updates** category, so switching it off stops the emails. In the dashboard, no: the notification bell recomputes those warnings from your current account state every time it loads, so an expiring key or an exhausted quota still shows up there regardless of your email settings. If key-expiry warnings matter to you, it also helps to know [how to set an expiry date on an API key](/en/articles/account-and-dashboard/keys/key-expiry) so the alert timing is under your control. ## Do email preferences change for my whole team?[#](#do-email-preferences-change-for-my-whole-team) No. These switches apply to the account you are signed in with, not to a shared [workspace](/en/articles/getting-started/glossary#workspace). Each person manages their own inbox in their own **Account → Notifications** tab. ## Can I re-subscribe after unsubscribing?[#](#can-i-re-subscribe-after-unsubscribing) Yes. Open **Account → Notifications** and switch the category back **on** — re-subscribing is immediate, the same as turning it off. This works even if you previously used the “unsubscribe from all” link in an email footer: flip the switches you want back on and those emails resume. * * * ## Related Articles * [How to manage dashboard notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) * [How to set an expiry date on an API key](/en/articles/account-and-dashboard/keys/key-expiry) * [How to change the dashboard theme](/en/articles/account-and-dashboard/profile/change-theme) --- ## Profile & Preferences URL: https://support.apitube.io/en/articles/account-and-dashboard/profile Manage your APITube profile and dashboard preferences: update your name and avatar, switch language and theme, control email notifications, and sign out of all devices. ![](/images/collections/user-management-security.png) # Profile & Preferences Name, avatar, language, theme and email. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Brian 1 author 6 articles * [How to change the dashboard language](/en/articles/account-and-dashboard/profile/change-language) * [How to change the dashboard theme](/en/articles/account-and-dashboard/profile/change-theme) * [How to Close Your APITube Account](/en/articles/account-and-dashboard/profile/close-account) * [How to manage email notification preferences](/en/articles/account-and-dashboard/profile/email-preferences) * [How to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all) * [How to update your profile and avatar](/en/articles/account-and-dashboard/profile/update-profile) --- ## How to sign out of all devices URL: https://support.apitube.io/en/articles/account-and-dashboard/profile/logout-all Sign out of APITube on every device at once from Account → Security. Signing out everywhere keeps your API keys active — only closing your account revokes them. # How to sign out of all devices End every active dashboard session at once — without touching your API keys ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 21, 2026 # How to sign out of all devices[#](#how-to-sign-out-of-all-devices) To sign out of APITube everywhere, open the dashboard, go to **Account → Security**, and click **Sign out everywhere**. Confirm in the dialog, and every device where you’re signed in — including the one you’re using right now — is signed out at the same time, so you’ll need to sign in again. Your [API keys](/en/articles/getting-started/glossary#api-key) are not affected and keep working. Signing out of all devices ends your **dashboard login sessions** only. It does not revoke, regenerate or change your **API keys**. Any app or integration that authenticates with an API key keeps running. ## Where is the sign out everywhere button?[#](#where-is-the-sign-out-everywhere-button) The button is on the **Security** tab of your **Account** page, inside the “Sign out of all devices” card. Click **Sign out everywhere**, then confirm the dialog — it warns that “This will sign you out on all devices, including this one. You’ll need to sign in again.” Once it runs, the dashboard returns you to the sign-in screen. Reach for this whenever you’ve signed in on a shared or public computer, misplaced a laptop or phone, or suspect someone else has access to your account. It is the fastest way to cut off every open session in one step. ![The Security tab of the Account page with the sign-out-everywhere card](/images/article/dashboard-account-security.png) ## Does signing out everywhere delete my API keys?[#](#does-signing-out-everywhere-delete-my-api-keys) No. Signing out of all devices ends your **login sessions**, not your keys — it does not revoke, regenerate or change any API key, and integrations that send those keys to the News API keep working. The two are separate things: your login is how you get into the dashboard, while an API key is what your code sends with each request. If your real goal is to cut off a leaked or exposed API key rather than your login, revoke or regenerate that specific key instead — see [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys). The only action that revokes every key at once is **closing your account**, which is a separate, more drastic step. ## Can I sign out of just one device?[#](#can-i-sign-out-of-just-one-device) No. The dashboard does not show a list of active sessions or individual devices, so signing out is all-or-nothing: one click on **Sign out everywhere** ends every session at the same time. There is no separate “sessions” screen for signing out a single browser or phone while leaving the others. This works the way it does because APITube recognises your login with a single session token that is shared across all your devices. Signing out everywhere refreshes that token, which instantly invalidates the old sessions on every browser and device you were using. ## Does changing my password sign me out too?[#](#does-changing-my-password-sign-me-out-too) Yes. Changing your account password — also on the **Account → Security** tab — resets the same login session, so it signs you out of every device just like **Sign out everywhere** does. After you set a new password the dashboard reloads and asks you to sign in again on this device, and any other signed-in devices are logged out as well. If you think your password has leaked, change it: that both blocks the old password and ends every existing session in one move. For keeping your API access safe (which is separate from your login), read [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security). # Common Questions[#](#common-questions) * [Where is the sign out everywhere button?](#where-is-the-sign-out-everywhere-button) * [Does signing out everywhere delete my API keys?](#does-signing-out-everywhere-delete-my-api-keys) * [Can I sign out of just one device?](#can-i-sign-out-of-just-one-device) * [Does changing my password sign me out too?](#does-changing-my-password-sign-me-out-too) ## Will I lose any data or settings when I sign out?[#](#will-i-lose-any-data-or-settings-when-i-sign-out) No. Signing out of all devices only ends your active login sessions. Your API keys, request logs, saved preferences, [workspaces](/en/articles/getting-started/glossary#workspace) and billing are all untouched — signing back in returns you to exactly the same account. The only thing you lose is the “already signed in” state on each device, which you restore by logging in again. ## Does this sign out my team members too?[#](#does-this-sign-out-my-team-members-too) No. Signing out everywhere applies only to your own account and your own devices. Other members of a shared workspace have their own separate logins, so they stay signed in. Removing someone else’s access is a different task handled from your team settings, not from the sign-out button. * * * ## Related Articles * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security) --- ## How to update your profile and avatar URL: https://support.apitube.io/en/articles/account-and-dashboard/profile/update-profile Update your APITube profile from Account → Profile: change your display name and email, upload or remove your avatar, and why a password change signs you out. # How to update your profile and avatar Change your name, email address and profile picture on the APITube dashboard — and what happens to your session when you do ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 6, 2026 # How to update your profile and avatar[#](#how-to-update-your-profile-and-avatar) To update your profile, open your **Account** page — it lands on the **Profile** tab — and edit the fields on the profile card. You can change your **display name**, your **email address**, and your **avatar** (profile picture). Each field is saved on its own, so updating your name does not touch your email, and uploading an avatar does not touch either. Changes take effect right away. ![The Profile tab of the Account page with the display name, email and avatar fields](/images/article/dashboard-account.png) Your name and email are stored on your **account**, so they follow you to every device and browser. The dashboard theme and language, by contrast, are saved only in the current browser. ## How do I change my display name?[#](#how-do-i-change-my-display-name) Edit the **name** field on the Profile tab and save it. The name is used across the dashboard — it appears in the header and as the label on your avatar — and it is trimmed and capped at **120 characters**, so anything longer is shortened when saved. The name is separate from your login: changing it does not affect how you sign in, your [API keys](/en/articles/getting-started/glossary#api-key), or your quota. If you clear the name entirely, the dashboard falls back to showing your email address instead. ## How do I change my email address?[#](#how-do-i-change-my-email-address) Edit the **email** field and save it. The address is checked for a valid format, and it must be unique — if the new email is already used by another APITube account, the save is rejected with a **422** error (“This email already exists.”) and your current email stays unchanged. When the new address is free, it is updated immediately. Your email is your account’s identity, so keep it current: it is where account and (if enabled) notification mail is sent. Toggling which emails you receive is a separate setting on the account page, not part of the profile fields. ## How do I upload or change my avatar?[#](#how-do-i-upload-or-change-my-avatar) Use the avatar control on the Profile tab to pick an image file. APITube processes every upload the same way, so you do not need to crop or resize first: * **File type** — any image format. The file is re-encoded on the server, which also rejects anything that is not a real image. * **Maximum size** — **5 MB**. Larger files are rejected before upload. * **Output** — the image is cropped to a centered square and saved as a **256×256 WebP**, and it is auto-rotated using its orientation data so sideways phone photos come out upright. Once processed, the avatar shows immediately in the header and on the Profile card. Because the stored file is a small square WebP, it loads fast anywhere the dashboard shows your picture. ## How do I remove my avatar?[#](#how-do-i-remove-my-avatar) Remove the current picture from the same avatar control. After removal, the dashboard falls back to an **initials avatar** — a colored circle showing the initials taken from your name (or your email if you have no name set). There is no “default photo” to restore; removing the avatar simply returns you to initials, and you can upload a new image at any time. ## Does changing my profile log me out?[#](#does-changing-my-profile-log-me-out) Changing your **name**, **email** or **avatar** does **not** end your session — you stay signed in. Changing your **password** is different: for security, saving a new password rotates the credential your browser uses to stay logged in, which signs you out, so you will need to log back in with the new password afterward. That is the same mechanism behind signing out everywhere — see [how to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all) if you want to force a fresh login on every browser. # Common Questions[#](#common-questions) * [Where do I edit my profile?](#how-do-i-change-my-display-name) * [Why was my new email rejected?](#why-was-my-new-email-rejected) * [What are the avatar size and format limits?](#what-are-the-avatar-size-and-format-limits) ## Why was my new email rejected?[#](#why-was-my-new-email-rejected) The most common reason is that the address is already tied to another APITube account. The dashboard checks the new email for uniqueness and returns a 422 error if it is taken, leaving your existing email in place. The other reason is format: the address must look like a real email (a name, an `@`, and a domain). Fix the address or use one that is not already registered, then save again. ## What are the avatar size and format limits?[#](#what-are-the-avatar-size-and-format-limits) The upload accepts any image format up to **5 MB**. Whatever you send is converted to a **256×256 WebP** square, cropped to center and auto-rotated, so aspect ratio and orientation are handled for you. Very large images (by pixel dimensions, not just file size) are rejected as a safety measure, but any normal photo or logo is well within the limit. ## Do profile changes affect my API usage?[#](#do-profile-changes-affect-my-api-usage) No. Your name, email and avatar are account details for the dashboard. They do not change your API keys, your request quota, your billing, or anything about how the News API responds. The only profile-area action that touches your session is a **password** change, which signs you out so you re-authenticate. To personalize the interface itself instead, [change the dashboard language](/en/articles/account-and-dashboard/profile/change-language) or theme. * * * ## Related Articles * [How to change the dashboard language](/en/articles/account-and-dashboard/profile/change-language) * [How to sign out of all devices](/en/articles/account-and-dashboard/profile/logout-all) * [How to change the dashboard theme](/en/articles/account-and-dashboard/profile/change-theme) --- ## How to export your API logs URL: https://support.apitube.io/en/articles/account-and-dashboard/usage-and-logs/export-logs Export your APITube request logs to CSV or JSON from the dashboard Logs page. The download keeps your current filters, caps at 100,000 rows, and is not masked. # How to export your API logs Download your request logs as CSV or JSON from the Logs page — what each format contains, the 100,000-row cap, and why the file is unmasked ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis June 28, 2026 Updated July 21, 2026 # How to export your API logs[#](#how-to-export-your-api-logs) Open the **Logs** page in your APITube dashboard, click the **Export** button in the toolbar, and choose **CSV** or **JSON**. The file downloads immediately and contains exactly the rows the table is currently showing — the export reuses your active filters, so a date window, a single key, or an errors-only view all carry through. Exporting reads stored data, so it never calls the News API and never spends a request or credit. Use the export when you need your request history outside the dashboard: a spreadsheet for a quick pivot, a JSON file for a script or data pipeline, or a saved record for an audit. This article covers what each format includes, how much you can pull at once, and one safety detail — the exported file is not masked. ## How do you export your logs?[#](#how-do-you-export-your-logs) Go to **Logs**, set up the view you want, then export it: 1. Apply your filters — date range, request type, status (All / Success / Errors), [API key](/en/articles/getting-started/glossary#api-key), and the search box all narrow the table. 2. Click **Export** in the toolbar (the button with the download icon). 3. Pick **CSV** or **JSON** from the dropdown. The browser downloads a file named `api-logs-.csv` or `api-logs-.json`, where the date comes from the end of your selected range. Because the export sends your current filters to the server, whatever you see is what you get. There is no separate “export everything” toggle — to export your full history, clear the filters and widen the date range first, then export. For the filtering itself, see [how to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs). ![The log table on the Logs page listing individual requests with endpoint, status, latency and cost per row](/images/article/dashboard-logs-table.png) ## What’s the difference between the CSV and JSON export?[#](#whats-the-difference-between-the-csv-and-json-export) CSV and JSON carry different amounts of detail, so pick by what you’ll do with the file: * **CSV** is a flat, six-column table built for spreadsheets: `created_at`, `request_type`, `api_key_id`, `cost`, `uri`, and `params`. The `params` column holds the request parameters as a JSON string inside the cell, and any value containing a comma, quote, or newline is properly quoted and escaped so the file opens cleanly in Excel, Google Sheets, or pandas. * **JSON** is the full record. Each entry is the complete log object, pretty-printed, and includes everything CSV has plus `status` (the HTTP code), `latency_ms`, `ip`, `country`, and `result_count` (how many articles the call returned). Choose JSON when you want the status, latency, or geo fields for analysis or a pipeline. So CSV is the compact spreadsheet view and JSON is the lossless one. If you need error rates, response times, or result counts per request, export JSON. ## Does the export include all my logs or just the filtered view?[#](#does-the-export-include-all-my-logs-or-just-the-filtered-view) The export includes the filtered view, capped at **100,000 rows**. If your filtered result is larger than that, the file contains the newest 100,000 entries and the response carries an `X-Truncated: 100000` header to signal that it was cut. To pull more, split the job into smaller date ranges and export each separately. The export is also scoped the same way the rest of the Logs page is: it only includes requests made with API keys in your **current [workspace](/en/articles/getting-started/glossary#workspace)**, and it follows the dashboard’s **Test / Live mode** toggle — in Live mode you export Live-key traffic, in Test mode you export Test-key traffic. Switch workspace or mode before exporting if you need a different set. Cost and volume in the file match what you can confirm under [track your usage and quota](/en/articles/account-and-dashboard/usage-and-logs/track-usage). ## Is my API key safe in the exported file?[#](#is-my-api-key-safe-in-the-exported-file) Treat the exported file as a secret. On screen the dashboard **masks** your API key everywhere — in the request URL and in the parameters — but the export is the raw stored record and is **not masked**. If a request was authenticated by putting the key in the URL or query parameters (`api_key=...`) rather than the `X-API-Key` header, that key appears in full inside the exported `uri` (and in `params`) column or field. Because of this, do not share an exported log file the way you might share a screenshot of the Logs page. If a file does contain a [live key](/en/articles/getting-started/glossary#test-key-and-live-key), rotate that key. Sending requests with the key in a header instead of the query string keeps it out of the logged URL in the first place. ## Who can export logs, and does it cost anything?[#](#who-can-export-logs-and-does-it-cost-anything) Anyone in the workspace can export — owners, admins, members, and viewers all have access, because exporting only reads data the dashboard already stored. It does **not** call the News API, so it spends no requests or credits from your quota and never counts against your [rate limit](/en/articles/getting-started/glossary#rate-limit). Exporting is recorded in the workspace **audit log** as a `logs.export` action, with the chosen format, the row count, whether the result was truncated, and the date range — so an owner or admin can see who pulled the data out and when. # Common Questions[#](#common-questions) * [What columns are in the CSV export?](#what-columns-are-in-the-csv-export) * [Why does my export look incomplete?](#why-does-my-export-look-incomplete) * [Does exporting logs use any of my quota?](#does-exporting-logs-use-any-of-my-quota) * [Is my API key hidden in the file?](#is-my-api-key-hidden-in-the-file) ## What columns are in the CSV export?[#](#what-columns-are-in-the-csv-export) The CSV has six columns in this order: `created_at`, `request_type`, `api_key_id`, `cost`, `uri`, and `params`. The `params` column is the request parameters serialized as JSON in a single cell. For richer fields — `status`, `latency_ms`, `ip`, `country`, `result_count` — export JSON instead, which returns the complete record for every request. ## Why does my export look incomplete?[#](#why-does-my-export-look-incomplete) Two reasons. First, the export only includes your **current filters and scope** — the active date range, type, status, key, search term, current workspace, and Test/Live mode. Widen the date range or clear the filters to get more. Second, a single export is capped at **100,000 rows**; above that you get the newest 100,000 and an `X-Truncated` header, so very large histories must be exported in smaller date slices. ## Does exporting logs use any of my quota?[#](#does-exporting-logs-use-any-of-my-quota) No. The export reads logs the dashboard has already saved and does not make a News API call, so it costs zero requests and zero credits and is not affected by rate limits. You can export as often as you need. ## Is my API key hidden in the file?[#](#is-my-api-key-hidden-in-the-file) No — unlike the on-screen view, the exported CSV or JSON is unmasked. If any request carried the key in its URL or parameters, the key appears in plain text in the file. Keep exported log files private, and rotate any key that ends up exposed in one. * * * ## Related Articles * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) * [How to track your usage and quota](/en/articles/account-and-dashboard/usage-and-logs/track-usage) * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) --- ## Usage & Logs URL: https://support.apitube.io/en/articles/account-and-dashboard/usage-and-logs Track your APITube usage and inspect every API request: search and filter the request log, read usage charts, and export your logs to CSV or JSON. ![](/images/collections/insights-dashboard.svg) # Usage & Logs Track usage and inspect every request. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Brian 1 author 4 articles * [How to export your API logs](/en/articles/account-and-dashboard/usage-and-logs/export-logs) * [How to Manage Dashboard Notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) * [How to track your usage and quota](/en/articles/account-and-dashboard/usage-and-logs/track-usage) * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) --- ## How to Manage Dashboard Notifications URL: https://support.apitube.io/en/articles/account-and-dashboard/usage-and-logs/manage-notifications Manage APITube dashboard notifications from the bell icon: read quota, billing and API-key alerts, mark them read, dismiss them, and jump to the page that… # How to Manage Dashboard Notifications Read, dismiss and act on the alerts in the notification bell — quota, billing and API-key warnings ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis June 28, 2026 Updated July 21, 2026 # How to manage dashboard notifications[#](#how-to-manage-dashboard-notifications) The **bell icon** in the top bar of your APITube dashboard collects account alerts — quota, billing and API-key warnings — and shows a count badge when any are unread. Open it to read each alert, **mark all as read**, **dismiss** ones you have handled, or click an alert to jump straight to the page that resolves it. These notifications are computed automatically from your account state, so they appear and clear themselves as conditions change. ## Where are notifications in the dashboard?[#](#where-are-notifications-in-the-dashboard) Notifications live behind the **bell icon** in the dashboard header. When you have unread alerts, a small badge shows the count (or **9+** above nine), coloured by the most serious item — red for critical, amber for a warning, brand colour for info. Click the bell to open a panel with two tabs: * **Notifications** — the actionable alerts about your account (the focus of this article). * **Activity** — a recent history of account events, such as a key being created or revoked, a payment, or a new subscription. The panel refreshes on its own while it is open, so new alerts surface without a page reload. ![The notifications panel opened from the bell icon, with Notifications and Activity tabs and the Email preferences link](/images/article/dashboard-notifications.png) ## What kinds of notifications will you see?[#](#what-kinds-of-notifications-will-you-see) APITube generates notifications from three areas of your account. Each one links to the page where you fix it: * **Quota** — warnings at **75%** and **90%** of your monthly requests, and a critical **“Quota exhausted”** alert at 100%. These point to your **Subscription** page. * **Billing** — a **low [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance** alert, **spending-limit** alerts at 80% and 100% of your monthly PAYG cap, a **subscription cancelled** notice (access continues until the end date), and a **renewal coming up** reminder. * **[API keys](/en/articles/getting-started/glossary#api-key)** — a **“Create your first API key”** prompt when you have none, plus **key expired** and **key expiring soon** alerts. The expiry alerts come from dates you set; see how to [set an expiry date on an API key](/en/articles/account-and-dashboard/keys/key-expiry). ## How do you read, dismiss and act on a notification?[#](#how-do-you-read-dismiss-and-act-on-a-notification) Each alert in the panel shows a severity icon, a title, a short body, and how long ago it appeared. An unread item carries a small dot. You have three controls: * **Click the alert** to mark it read and go to the relevant page — a quota alert opens **Subscription**, a key alert opens **API Keys**, a balance alert opens **Pay As You Go**. * **Dismiss it** with the **×** that appears when you hover an item. Dismissing removes it from the bell for good, even if the underlying condition is still true. * **Mark all as read** with the link at the top of the panel to clear the unread badge in one click (disabled when nothing is unread). At the bottom of the panel, the **Notification settings** link opens your **Account** notification preferences, where email delivery for these alerts is managed. ## Why do notifications appear and clear on their own?[#](#why-do-notifications-appear-and-clear-on-their-own) APITube does not store a fixed list of messages — it **recomputes** your notifications from current account state every time the bell loads. Only three things are saved per alert: when it first appeared, whether you read it, and whether you dismissed it. The title and severity are derived fresh each time. That means alerts resolve themselves: create a key and the “Create your first API key” prompt disappears; top up and the low-balance alert goes away; renew your plan and the quota warnings reset. You rarely need to clean them up by hand — dismissing is mainly for alerts you have acknowledged but cannot resolve yet. To see the requests driving a quota alert, open your [request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs). # Common Questions[#](#common-questions) * [What does the number on the bell mean?](#what-does-the-number-on-the-bell-mean) * [Do notifications use any of my quota?](#do-notifications-use-any-of-my-quota) * [Will I also get these notifications by email?](#will-i-also-get-these-notifications-by-email) * [Are notifications the same for everyone on my team?](#are-notifications-the-same-for-everyone-on-my-team) ## What does the number on the bell mean?[#](#what-does-the-number-on-the-bell-mean) The badge is your count of **unread** notifications. It caps the display at **9+** when you have more than nine, and it takes its colour from your most serious unread alert — red for a critical item like an exhausted quota, amber for a warning, brand colour for an informational one. Reading or dismissing items lowers the count; **Mark all as read** clears it entirely. ## Do notifications use any of my quota?[#](#do-notifications-use-any-of-my-quota) No. The bell reads data the dashboard already holds about your account; it does not call the News API. Opening the panel, reading alerts, dismissing them or marking them read never spends requests or credits from your plan. ## Will I also get these notifications by email?[#](#will-i-also-get-these-notifications-by-email) Some alerts — such as an expiring API key — can also be sent by email. Dismissing an alert in the bell also tells the system to stop emailing you about that same item, so the bell and your inbox stay in sync. Use the **Notification settings** link at the bottom of the panel (it opens **Account → Notifications**) to control which emails you receive. ## Are notifications the same for everyone on my team?[#](#are-notifications-the-same-for-everyone-on-my-team) Account-level alerts are about the **[workspace](/en/articles/getting-started/glossary#workspace) owner**: quota, balance, subscription and pay-as-you-go limits are shared across all of the owner’s workspaces, and key-expiry alerts cover the owner’s keys. So members of a shared workspace see the owner’s account alerts rather than a personal set. To manage the keys those alerts refer to, see how to [create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). * * * ## Related Articles * [How to Set an Expiry Date on an API Key](/en/articles/account-and-dashboard/keys/key-expiry) * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## How to track your usage and quota URL: https://support.apitube.io/en/articles/account-and-dashboard/usage-and-logs/track-usage Track your APITube usage and remaining quota from the dashboard overview: the requests and SSE pools, reset dates, quota alerts, and the /v1/balance check. # How to track your usage and quota Read your remaining requests, SSE pool and reset date on the dashboard overview — plus quota alerts and the /v1/balance check ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 11, 2026 Updated July 21, 2026 # How to track your usage and quota[#](#how-to-track-your-usage-and-quota) Open the dashboard **overview** (the home page) to track your usage and quota at a glance. A stat strip there shows your remaining **API Usage** requests, and your remaining **[SSE](/en/articles/getting-started/glossary#sse-stream) Usage** pool, each with the date your quota resets. The big number under **API Usage** is what you have **left**, not what you have spent — the caption reads “requests remaining”. For a per-request log and charts, use the Logs page; for a programmatic check, call `/v1/balance`. Your quota is the count of requests your plan grants for the period. Each billed call draws it down, the overview shows what is left, and the dashboard warns you before you run out — so you can top up or upgrade before requests start failing. ## Where do you see your remaining quota?[#](#where-do-you-see-your-remaining-quota) The overview stat strip is the fastest read. It has these tiles: * **API Usage** — your remaining standard requests, with a 7-day trend sparkline and a “Resets…” caption. * **SSE Usage** — your remaining real-time streaming pool, tracked separately from standard requests. Quota is shared at the **account level**, not per key — every [API key](/en/articles/getting-started/glossary#api-key) in your [workspace](/en/articles/getting-started/glossary#workspace) draws from the same pool. The strip appears in **Live** mode only: **Test** mode does not consume quota, so there is nothing to count there. If you are on a free plan the caption reads **“Resets daily”**; on a paid plan it reads **“Resets {date}”** — your monthly renewal date. ## How big is my quota, and what resets it?[#](#how-big-is-my-quota-and-what-resets-it) The size of your quota comes from your plan. The free plan includes **100** requests, **Starter** 10,000, **Basic** 50,000, **Professional** 150,000, and **Corporate** 300,000. The free plan’s quota resets **every day**; paid plans reset **once per billing cycle**, on the subscription renewal date shown in the caption. Standard streaming over Server-Sent Events draws from a **separate SSE pool**, so heavy streaming will not eat into the standard request quota and vice versa — that is why the overview reports them as two distinct tiles. ## What counts as one request against my quota?[#](#what-counts-as-one-request-against-my-quota) Most calls cost **one point**. A standard search or retrieval call — `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article`, `/v1/news/count`, and similar endpoints — deducts a single point per request. Two endpoints cost more: * **Local news** (`/v1/news/local`) costs `1` plus one point for each insight you request, so a call asking for several insights costs more than one. * **Fact-check** (`/v1/fact-check`) costs **5 points** per call. Failed and empty calls still count toward your per-key usage history (see [how to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage)). When your standard quota hits zero, those endpoints return `402` with error code `ER0176`. If you are on a paid plan and you have a [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance, eligible calls fall back to that balance instead of failing once your monthly requests are used up. ## How do you get warned before running out?[#](#how-do-you-get-warned-before-running-out) The overview shows a quota **insight banner** automatically once you have used a large share of your monthly quota. At **75%** used it appears as a warning; at **90%** or more it turns critical. The banner reads “{percent}% of monthly quota used” and links straight to your subscription so you can upgrade. You do not have to enable anything — it is computed from your remaining points against your plan’s total. ## How do you check usage over time and per key?[#](#how-do-you-check-usage-over-time-and-per-key) Two views go beyond the single “remaining” number: * **The Logs page** records every request — endpoint, status, latency, key and cost — and charts requests per day, cost per day, error rate and latency percentiles above the table. See [how to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs). * **Per-key usage** attributes spend to each key with a lifetime **usage points** total and a date-range breakdown of requests, cost and top endpoints. ![The Requests per day chart on the dashboard home page showing daily API usage over the last month](/images/article/dashboard-usage-chart.png) To read your remaining quota from code instead of the dashboard, call the `/v1/balance` endpoint, which returns your remaining `points` and never spends any itself — see [how to check your API balance and remaining quota](/en/articles/retrieval/check-balance-api). # Common Questions[#](#common-questions) * [Is quota counted per API key or per account?](#is-quota-counted-per-api-key-or-per-account) * [Why does the overview hide the quota strip in Test mode?](#why-does-the-overview-hide-the-quota-strip-in-test-mode) * [Does SSE streaming use my standard request quota?](#does-sse-streaming-use-my-standard-request-quota) * [What happens when I run out of requests?](#what-happens-when-i-run-out-of-requests) ## Is quota counted per API key or per account?[#](#is-quota-counted-per-api-key-or-per-account) Per account. Every key in your workspace draws from one shared pool, so the overview’s “API Usage” number is the same no matter which key spends it. Per-key numbers exist only for **attribution** — to see which key drives your traffic — not as separate limits. ## Why does the overview hide the quota strip in Test mode?[#](#why-does-the-overview-hide-the-quota-strip-in-test-mode) Because Test-key requests do not consume quota. The plan, API Usage and SSE Usage tiles only appear in **Live** mode, where requests are billed against your pool. Switch to Live mode to see your remaining quota and reset date. ## Does SSE streaming use my standard request quota?[#](#does-sse-streaming-use-my-standard-request-quota) No. Streaming over Server-Sent Events draws from a separate **SSE pool**, shown as its own “SSE Usage” tile on the overview. Standard search and retrieval requests draw from the **API Usage** pool. Exhausting one does not exhaust the other. ## What happens when I run out of requests?[#](#what-happens-when-i-run-out-of-requests) Standard endpoints return `402` (`ER0176`) once your points reach zero. On a paid plan with a pay-as-you-go balance, eligible calls are charged to that balance instead. Free plans reset daily and paid plans reset on the renewal date shown in the overview, so quota also returns automatically when the period rolls over. * * * ## Related Articles * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) * [How to Check Your API Balance and Remaining Quota](/en/articles/retrieval/check-balance-api) --- ## How to view and search your request logs URL: https://support.apitube.io/en/articles/account-and-dashboard/usage-and-logs/view-logs View and search every APITube API request on the dashboard Logs page. Filter by date, key, request type or status, read usage charts, and export to CSV or JSON. # How to view and search your request logs Inspect every API request on the Logs page — filter by date, key, type or status, read usage charts, and export to CSV or JSON ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis June 28, 2026 Updated July 21, 2026 # How to view and search your request logs[#](#how-to-view-and-search-your-request-logs) Open the **Logs** page in your APITube dashboard to see every API request your account has made. The page shows a searchable, filterable table — one row per request with its time, endpoint, request type, status code, latency, key and cost — plus usage charts above it. You can narrow the list by date range, [API key](/en/articles/getting-started/glossary#api-key), request type, status, or a full-text search, and export the filtered view to CSV or JSON. The Logs page is the fastest way to answer “what did my integration actually call, and what came back?” — useful for debugging a failing request, confirming a key is live, or auditing which key spent what. ## Where do you find your request logs?[#](#where-do-you-find-your-request-logs) Go to **Logs** in the dashboard. Every request is recorded with its timestamp, the endpoint it hit, the HTTP status it returned, its latency, the key that made it, and the cost it spent. Two scopes apply automatically: * **[Workspace](/en/articles/getting-started/glossary#workspace).** You only see requests made with keys that belong to your current workspace, so switching workspaces switches the log you are looking at. * **Test vs Live mode.** The table follows the dashboard’s mode toggle: in Test mode you see Test-key traffic, in Live mode you see Live-key traffic. Switch the mode to see the other set. Each key’s own per-key view of this data — lifetime usage, last-used time and a usage chart — lives on the key’s detail page; see [how to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) for that angle. ![The API logs page of the dashboard: filters and Export in the toolbar, request and error-rate stats, and per-day charts above the log table](/images/article/dashboard-logs.png) ## What does each log row show?[#](#what-does-each-log-row-show) The table has a column for each part of a request: * **Time** — when the request arrived. * **Type** — the request type, the same endpoint-family name used by [endpoint scopes](/en/articles/account-and-dashboard/keys/key-scopes) (`everything`, `top_headlines`, `article`, and so on). * **Status** — the HTTP status code, shown green for success and red for `400`\+ errors. * **Latency** — how long the request took, in milliseconds. * **Key** — which API key made the call. * **Cost** — what the request spent. * **Endpoint** — the request path. Click any row to open a detail panel with more: the result count, the caller’s IP and country, the full request URL and its parameters, a **Copy as cURL** button, and an **Open in [Playground](/en/articles/getting-started/glossary#playground)** link when the endpoint is reproducible there. Your API key is **masked** everywhere in this panel — in the URL and in the parameters — so sharing a screenshot never leaks the secret. Some rows may have no status if the request was not fully logged. ## How do you filter and search the logs?[#](#how-do-you-filter-and-search-the-logs) The toolbar above the table holds the filters, and they combine — apply several at once to zero in on a request: * **Search box** — full-text match against the request; press `/` anywhere on the page to jump into it. * **Type** — pick one request type; the dropdown shows each type with how many requests match. * **Status** — All, Success, or Error. * **Key** — limit to one API key (each option shows its request count). * **Date range** — pick the period with the date picker. Filters are reflected in the page URL (`from`, `to`, `type`, `status`, `key`, `q`), so a filtered view is a shareable, bookmarkable link — for example `/logs?key=12&status=error` jumps straight to failed requests from key 12. You can also save a filter combination as a **saved view** to reuse it later. ## How do you read the usage charts above the table?[#](#how-do-you-read-the-usage-charts-above-the-table) Above the table the page summarizes the filtered requests so you do not have to scan rows by hand. A stat strip shows total **requests**, total **cost**, **average per day**, **error rate**, and **average latency**, with `p50` / `p95` / `p99` latency percentiles beside it. Charts then break the same data down: requests per day, cost per day, a split by request type, top countries, a status breakdown (`2xx` / `4xx` / `5xx`), and your top error endpoints. Every chart respects the active filters, so filtering to one key or one day reshapes the charts too. ## How do you export your logs?[#](#how-do-you-export-your-logs) Use the **Export** button in the toolbar and choose **CSV** or **JSON**. The export uses your current filters, so whatever the table is showing — a single key, a date window, only errors — is exactly what downloads. CSV suits a spreadsheet; JSON suits a script or a data pipeline. # Common Questions[#](#common-questions) * [Are my API keys exposed in the logs?](#are-my-api-keys-exposed-in-the-logs) * [Do Test and Live requests show up together?](#do-test-and-live-requests-show-up-together) * [Who on my team can see the request logs?](#who-on-my-team-can-see-the-request-logs) * [Does viewing my logs use any quota?](#does-viewing-my-logs-use-any-quota) ## Are my API keys exposed in the logs?[#](#are-my-api-keys-exposed-in-the-logs) No. Wherever a request URL or its parameters appear — in the table and in the row detail panel — the API key value is masked. You can read which key made a call by its name, copy the request as cURL, or screenshot the panel without revealing the secret itself. ## Do Test and Live requests show up together?[#](#do-test-and-live-requests-show-up-together) No. The log follows the dashboard’s Test / Live mode toggle: in Test mode you see only Test-key requests, and in Live mode only Live-key requests. Flip the toggle to look at the other set. The log is also scoped to your current workspace, so only keys in that workspace appear. ## Who on my team can see the request logs?[#](#who-on-my-team-can-see-the-request-logs) Everyone in the workspace can view the logs — owners, admins, members, and viewers all have read access. Viewers cannot create or change keys (see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys)), but they can still inspect what has been called. ## Does viewing my logs use any quota?[#](#does-viewing-my-logs-use-any-quota) No. The Logs page reads data the dashboard already stored; it does not call the News API, so browsing, filtering, charting, and exporting your logs never spend requests or credits from your quota. * * * ## Related Articles * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [Understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes) --- ## How do requests and credits work? URL: https://support.apitube.io/en/articles/billing/credits/how-credits-work How APITube requests and credits work: one call spends one credit from your plan quota, paid plans fall back to a pay-as-you-go balance at $0.01, and streaming… # How do requests and credits work? How APITube counts a request, the four quota pools it draws from, and when your balance takes over ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 2, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=electric+vehicles) # How do requests and credits work?[#](#how-do-requests-and-credits-work) Every billed API call spends **one credit** from your plan’s quota, and most search and retrieval endpoints cost exactly that — one credit per call. When your plan quota runs out, a paid plan keeps working by charging the same call to your [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance at **$0.01 per request** instead of failing. APITube also keeps your standard requests, [SSE](/en/articles/getting-started/glossary#sse-stream) stream and [WebSocket](/en/articles/getting-started/glossary#websocket) stream in three **separate** quota pools, so heavy streaming never eats your search allowance. Credits are the same thing the API calls _points_: they are your plan’s request allowance for the period. Each billed call draws one point from the pool, the dashboard counts it, and when a pool reaches zero the API stops serving that kind of call until you have quota again or top up. ## What is a credit and where is it stored?[#](#what-is-a-credit-and-where-is-it-stored) A credit (a _point_) is one unit of request allowance held on your **account**, not on an individual key. Your account carries four separate balances: a standard-request pool, an SSE-streaming pool, a WebSocket pool, and a pay-as-you-go cash balance. Every key you create shares the same account pools, so revoking or adding keys does not change how much quota you have — it only changes which key the spend is attributed to. Each billed call also bumps that key’s lifetime usage total, which is how the dashboard shows spend per key. ## How much does one request cost?[#](#how-much-does-one-request-cost) The default is one credit per call, and the price is **per call, not per article**. A page that returns a single article and a page that returns the full 250-article maximum both cost exactly one credit — raising `per_page` and paginating is the cheapest way to pull large result sets. The ceiling is 250 on Professional and up — Basic is capped at 200, Starter at 50 and Free at 10 articles per request. A few endpoints differ: `/v1/fact-check` costs **5 credits** because it runs a retrieval-and-reasoning pass, adding the natural-language `prompt` parameter costs **2 extra credits** on a first-time wording (Basic and up only), and the real-time streams bill **per article delivered** rather than per connection. The full per-endpoint breakdown lives in [what counts as one request](/en/articles/billing/credits/what-counts-as-request). ``` curl "https://api.apitube.io/v1/news/everything?title=electric%20vehicles&api_key=YOUR_API_KEY" ``` That single call deducts one credit from your standard pool — but only if it returns at least one article. A search that matches nothing comes back empty and is **not** charged, so you can tighten filters and retry a zero-result query for free. ## Which pool does a request draw from?[#](#which-pool-does-a-request-draw-from) Each kind of traffic has its own pool, and each is gated on its own balance: * **Standard requests** — search, retrieval, counts and directory lookups draw from your main request pool. * **SSE streaming** (`/v1/news/stream`) draws from a dedicated streaming pool and bills one credit per article it pushes. See [how streaming quota is counted](/en/articles/billing/credits/sse-quota). * **WebSocket streaming** (`/v1/news/ws`) draws from its own WebSocket pool, again one credit per article delivered. * **Pay-as-you-go balance** is real money, charged only when a plan pool is empty. Because the pools are separate, running your SSE stream to zero does not block a normal `/v1/news/everything` search, and vice versa. ![The dashboard header quota bar showing API requests left, webhook and WebSocket pools, and the pay-as-you-go balance](/images/article/dashboard-quota-bar.png) ## When does my balance get charged instead of my quota?[#](#when-does-my-balance-get-charged-instead-of-my-quota) Your plan quota is always spent first. On a **paid** plan, once the standard pool hits zero and you still have a pay-as-you-go balance, the next request is charged to that balance at one cent — **$0.01 per request** — so the call succeeds instead of returning an error. This fallback is why a request always counts as one charge; only the pool it comes from changes. Pools never go negative. When your standard quota is exhausted **and** your balance is zero, the API stops serving paid endpoints and returns `402 ER0176`. If you have a balance but have hit your monthly pay-as-you-go spending cap, you get `402 ER0177` instead. See [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests). # Common Questions[#](#common-questions) * [Do credits and points mean the same thing?](#do-credits-and-points-mean-the-same-thing) * [Do test keys spend credits?](#do-test-keys-spend-credits) * [Does a bigger page of results cost more?](#does-a-bigger-page-of-results-cost-more) * [Why is my streaming pool separate from my search quota?](#why-is-my-streaming-pool-separate-from-my-search-quota) ## Do credits and points mean the same thing?[#](#do-credits-and-points-mean-the-same-thing) Yes. “Credits” in the dashboard and “points” in the API refer to the same request allowance on your account. One billed call spends one point, except for the fact-check endpoint (5) and the per-article streams. ## Do test keys spend credits?[#](#do-test-keys-spend-credits) No. Calls made with a **test** key hit the live API but never draw down any pool, so you can preview request shapes and responses without touching your quota or balance. Only [live keys](/en/articles/getting-started/glossary#test-key-and-live-key) are billed. ## Does a bigger page of results cost more?[#](#does-a-bigger-page-of-results-cost-more) No. On the search endpoints the price is one credit per call whether the page holds one article or the full 250-article maximum. Fewer, larger calls therefore cost fewer credits than many small ones. ## Why is my streaming pool separate from my search quota?[#](#why-is-my-streaming-pool-separate-from-my-search-quota) Streaming bills one credit per article delivered and can run continuously, so APITube keeps its SSE and WebSocket allowances in dedicated pools. That isolation means a long-running stream cannot silently drain the quota you need for ordinary searches. * * * ## Related Articles * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) * [How streaming (SSE) quota is counted](/en/articles/billing/credits/sse-quota) --- ## Credits & Quota URL: https://support.apitube.io/en/articles/billing/credits How APITube requests and credits work: what counts as one request, what each endpoint costs, when your quota resets, and what happens when you run out. ![](/images/collections/reports.png) # Credits & Quota How requests, credits and resets work. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Brian 1 author 5 articles * [How do requests and credits work?](/en/articles/billing/credits/how-credits-work) * [How streaming (SSE) quota is counted](/en/articles/billing/credits/sse-quota) * [Understanding APITube Rate Limits](/en/articles/billing/credits/rate-limits) * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) --- ## What happens when you run out of requests? URL: https://support.apitube.io/en/articles/billing/credits/out-of-requests When you run out of APITube requests the API returns 402 ER0176. Learn what the error means, how pay-as-you-go billing takes over, and when your quota resets. # What happens when you run out of requests? Why you get a 402 ER0176 'no points' error, how pay-as-you-go billing takes over, and when your quota resets ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis June 28, 2026 Updated July 21, 2026 # What happens when you run out of requests?[#](#what-happens-when-you-run-out-of-requests) When your request quota hits zero, the News API stops serving paid endpoints and returns an HTTP **402** with error code **ER0176** and the message _“You have no points on your account.”_ The one exception: if your key has a [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance, a paid plan keeps working by charging each request to that balance instead of failing. So “running out” only blocks you when you have **no quota and no balance** left. ## What error do you get when you run out of requests?[#](#what-error-do-you-get-when-you-run-out-of-requests) Once your remaining quota (called **points** in the API) drops below one and you have no pay-as-you-go balance, the next call to any billed endpoint — `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article` and the rest — is rejected before it runs. The response is a `402` with this body: ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 402, "code": "ER0176", "message": "You have no points on your account.", "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }, "timestamp": "2026-06-28T12:00:00.000Z" } ] } ``` Because the request is turned away before any work happens, **no quota is charged** for a `402` — you are not billed for being out of credit. Treat `ER0176` as the signal to top up, upgrade, or wait for your reset rather than to keep retrying. ## What happens to requests after your quota hits zero?[#](#what-happens-to-requests-after-your-quota-hits-zero) Your monthly plan quota is always drawn down first: every successful call deducts one point from your plan allowance. Once that allowance reaches zero, what happens next depends on whether you carry a pay-as-you-go balance: * **Paid plan with a balance** — requests do not fail. Each call falls back to your pay-as-you-go balance and is billed at **$0.01 per request** (one cent), so traffic keeps flowing past your plan limit. * **No balance left** — the next call returns `402 ER0176` until your quota resets or you add funds. A request is only charged when it actually returns at least one article, so an empty search does not draw down your quota. For the full per-endpoint breakdown of what costs what, see [what counts as one request](/en/articles/billing/credits/what-counts-as-request). ## When does your quota reset?[#](#when-does-your-quota-reset) Your quota refills automatically, and the cadence depends on your plan: * **Free plan** — the allowance is **100 requests per day** and resets **daily**. When you hit the daily cap you get `ER0176` until the next day’s reset. * **Paid plans** — the allowance resets **monthly**, on your subscription’s renewal date. The dashboard overview shows the exact reset date so you know when a fresh allowance lands. You never have to do anything for the reset to happen — it follows your billing cycle. If you need requests _before_ the reset, the two options below get you unblocked immediately. ## How to keep making requests after you run out[#](#how-to-keep-making-requests-after-you-run-out) You have three ways to recover, depending on how much headroom you need: 1. **Add a pay-as-you-go balance.** Topping up moves the key onto overflow billing at $0.01 per request. The minimum top-up is **$1**, which buys 100 requests; once a balance is present, a paid key keeps serving past its plan quota instead of returning `ER0176`. 2. **Upgrade your plan.** A higher plan grants a larger monthly allowance, which is the better fix if you consistently exhaust your quota every cycle. 3. **Wait for the reset.** If the overage is occasional, simply waiting for the daily (free) or monthly (paid) refill restores your full allowance at no extra cost. Before you run out, you can watch how close you are: every API response includes an `x-points-remaining` header (and `x-balance-remaining` for your pay-as-you-go funds), and you can poll [the `/v1/balance` endpoint](/en/articles/retrieval/check-balance-api) at any time without spending a request. The dashboard header shows the same numbers at a glance: ![The dashboard header strip with the remaining API requests counter and the account balance](/images/article/dashboard-quota-bar.png) ## How is this different from a rate-limit (429) error?[#](#how-is-this-different-from-a-rate-limit-429-error) A `402 ER0176` means you are **out of quota** for the period — you have spent your allowance. A `429` is a **[rate-limit](/en/articles/getting-started/glossary#rate-limit)** error: you are sending requests too fast, even though you may still have plenty of quota left. They are unrelated walls and need different fixes — a `402` is solved by topping up, upgrading, or waiting for the reset, while a `429` is solved by slowing your request rate. For the rate-limit case, see [how to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). # Common Questions[#](#common-questions) ## Am I charged for a request that returns 402?[#](#am-i-charged-for-a-request-that-returns-402) No. When the API rejects a call with `402 ER0176`, the request is turned away before it does any work, so no quota or balance is deducted. You are never billed for being out of credit; only successful, article-returning calls cost anything. ## Do test keys ever run out of requests?[#](#do-test-keys-ever-run-out-of-requests) No. [Test keys](/en/articles/getting-started/glossary#test-key-and-live-key) hit the live API but do not consume quota, so they never trigger the `ER0176` wall. They are meant for previewing request and response shapes; switch to a live key for billed, production traffic. ## I have a balance but still get a 402 — why?[#](#i-have-a-balance-but-still-get-a-402--why) If you have set a monthly pay-as-you-go spending limit and reached it, overflow billing stops and the API returns `402 ER0177` (“Monthly pay-as-you-go spending limit reached”) instead of `ER0176`. That cap resets at the start of each calendar month, or you can raise it in the dashboard to resume pay-as-you-go requests right away. ## How do I know how many requests I have left?[#](#how-do-i-know-how-many-requests-i-have-left) Read the `x-points-remaining` header on any API response, or call `/v1/balance`, which returns your remaining points without consuming any. See [how to check your balance via the API](/en/articles/retrieval/check-balance-api) for the exact call. * * * ## Related Articles * [How to check your balance via the API](/en/articles/retrieval/check-balance-api) * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [How to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors) --- ## Understanding APITube Rate Limits URL: https://support.apitube.io/en/articles/billing/credits/rate-limits APITube rate limits cap requests per minute — 50 on paid plans, 200 on Corporate, 10 on free, 15 on test keys — counted per account, not per key. # Understanding APITube Rate Limits What the per-minute limits are, how they differ from your credit quota, and why a 429 never costs a credit ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 23, 2026 Updated July 6, 2026 # Understanding APITube rate limits[#](#understanding-apitube-rate-limits) APITube enforces two separate ceilings on your account: a **[rate limit](/en/articles/getting-started/glossary#rate-limit)** that caps how _fast_ you can call the API, and a **credit quota** that caps how _many_ requests you can make in total. The rate limit on a paid-plan [API key](/en/articles/getting-started/glossary#api-key) is **50 requests per minute** (**200** on Corporate; the free plan is limited to **10 per minute**) and resets every minute. It is independent of your plan’s quota, and a request blocked by the rate limit never deducts a credit. Keeping these two limits straight matters for billing: hitting the rate limit slows you down for a few seconds, while exhausting your quota stops you until the quota resets or you top up. ## What is a rate limit, and how is it different from my quota?[#](#what-is-a-rate-limit-and-how-is-it-different-from-my-quota) A rate limit is a **speed cap**. It counts requests in a one-minute window and rejects anything over the cap so that a single key cannot flood the service. A quota is a **volume cap** — the total number of requests included in your plan, drawn down one credit at a time as you make calls. The two limits behave differently: * The **rate limit** resets every minute. Going over it returns `429` and costs nothing — the check runs before the request is processed, so no credit is spent. * The **credit quota** is your plan’s overall allowance. When it runs out you get a different error: `402` with code `ER0176` (“You have no points on your account.”), not a `429`. See [what counts as one request](/en/articles/billing/credits/what-counts-as-request) and [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests). So a `429` means “you’re calling too quickly, wait a moment”, while a `402 ER0176` means “you’ve used up your plan’s requests”. ## What are APITube’s per-minute rate limits?[#](#what-are-apitubes-per-minute-rate-limits) The limits are counted in a one-minute window, per API key, and differ by key type: * **Paid-plan keys** — 50 requests per minute (**Corporate: 200**); **free-plan keys** — 10 per minute. * **[Test keys](/en/articles/getting-started/glossary#test-key-and-live-key)** — 15 requests per minute. Test data does not draw down your quota, so the rate limit is the only safeguard on test keys and is set lower. * **Fact-check** (`/v1/fact-check`) — 10 requests per minute, on its own counter separate from the 50-per-minute pool, because each call runs a language model. The counter is keyed on the **account**, not on the individual key: every live key you own draws on one shared budget, so issuing more keys does not buy more throughput. Test keys are counted separately (they have their own 15/min ceiling), and your IP address is used only as a fallback when no key is present. Between paid plans the cap barely moves — Starter, Basic and Professional share the same 50/min ceiling and only Corporate rises to 200/min, while the free plan sits at 10/min. Paid plans mainly raise your credit _quota_, not the per-minute speed. ## How do I know how close I am to the limit?[#](#how-do-i-know-how-close-i-am-to-the-limit) Every response carries rate-limit headers you can read to pace your traffic: * `x-ratelimit-limit` — your per-minute ceiling (for example, `50`). * `x-ratelimit-remaining` — calls left in the current window. * `x-ratelimit-reset` — seconds until the window resets. When a request is rejected, the response adds a `retry-after` header with the number of seconds to wait. A blocked response looks like this: ``` HTTP/1.1 429 Too Many Requests retry-after: 27 x-ratelimit-limit: 50 x-ratelimit-remaining: 0 x-ratelimit-reset: 27 ``` Watch `x-ratelimit-remaining` and slow down before it reaches `0`, instead of waiting for the `429`. ## What happens when I exceed the rate limit?[#](#what-happens-when-i-exceed-the-rate-limit) Going over the cap returns HTTP `429` with code `ER0203` and a message that states your ceiling and how long to wait — for example, _“Rate limit exceeded. You can make 50 requests per minute. Try again in 1 minute.”_ If you keep sending requests after that — 30 over-limit responses — the key is temporarily banned and returns `429` with code `ER0204` instead. The ban is temporary and clears after the interval named in the message. The fix for both is the same: stop, read the wait time, and back off before retrying. For backoff patterns and a full breakdown of `ER0203` versus `ER0204`, see [how to fix rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). The official parameter reference lives at [docs.apitube.io](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Do rate limits use up my credits?](#do-rate-limits-use-up-my-credits) * [Are rate limits higher on paid plans?](#are-rate-limits-higher-on-paid-plans) * [Do test keys and live keys share the same limit?](#do-test-keys-and-live-keys-share-the-same-limit) * [Is the rate limit separate from running out of requests?](#is-the-rate-limit-separate-from-running-out-of-requests) ## Do rate limits use up my credits?[#](#do-rate-limits-use-up-my-credits) No. The rate-limit check runs before a request is processed, so a `429` (either `ER0203` or `ER0204`) does not deduct a credit from your quota. Only requests that are actually processed and returned count against your plan. ## Are rate limits higher on paid plans?[#](#are-rate-limits-higher-on-paid-plans) No. The per-minute rate limit is **50 requests per minute** on the paid plans (the free plan is limited to 10/min); it does not rise with a more expensive plan. Upgrading raises your overall credit quota — the total number of requests you can make — not the per-minute speed. If you need more throughput at once, spread work across multiple API keys, since the limit is counted per key. ## Do test keys and live keys share the same limit?[#](#do-test-keys-and-live-keys-share-the-same-limit) No. A paid-plan key gets 50 requests per minute, a free-plan key gets 10, a test key gets 15 per minute, and `/v1/fact-check` has its own 10-per-minute counter. Each is tracked separately, so a test key hitting its limit never affects a live key, and fact-check calls never block your other News API requests. ## Is the rate limit separate from running out of requests?[#](#is-the-rate-limit-separate-from-running-out-of-requests) Yes. They are two different ceilings with two different errors. The rate limit returns `429` (`ER0203`/`ER0204`) and resets every minute. Running out of your plan’s requests returns `402 ER0176` and stays until your quota resets or you top up. A `429` is a short pause; a `402 ER0176` means your quota is empty. * * * ## Related Articles * [How to fix rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors) * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) --- ## How streaming (SSE) quota is counted URL: https://support.apitube.io/en/articles/billing/credits/sse-quota APITube SSE streaming bills one credit per delivered article from a separate streaming pool — never per connection or heartbeat. Here is how the quota is… # How streaming (SSE) quota is counted Why the SSE stream bills one credit per delivered article from a separate streaming pool — not per connection ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 22, 2026 Updated July 21, 2026 # How streaming (SSE) quota is counted[#](#how-streaming-sse-quota-is-counted) The [SSE](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream` bills **one credit per article it actually delivers to you** — never for the open connection, and never for heartbeats. Those credits come from a **separate streaming pool** on your account (the API tracks it as `sse_points`), distinct from the request quota that your normal searches draw down. So an open stream that matches nothing costs nothing, and your regular search quota is untouched by streaming. This is the key difference from a normal call. A search like `/v1/news/everything` costs one credit per call regardless of how many articles come back. Streaming flips that: there is no per-call charge, only a per-article charge, counted as each article is written to your connection. ## What exactly gets billed on an SSE stream?[#](#what-exactly-gets-billed-on-an-sse-stream) Only a successfully delivered article is billed, and the charge is **one credit drawn from your streaming pool** for each one. Concretely: * **Each delivered article = 1 streaming credit.** The stream checks for new matching articles about every 30 seconds and pushes up to 50 per cycle; every article written to your socket deducts one streaming credit and is logged as a `stream` request. * **The open connection is free.** Holding `/v1/news/stream` open costs nothing on its own — you are not charged for connection time. * **Heartbeats are free.** About every 30 seconds the server sends a `: heartbeat` comment to keep the connection alive. These are not events and are never billed. * **The last, undelivered frame is free.** If your client drops mid-write and the final article never flushes, that article is not charged — the credit is only taken once the article is confirmed written. Because billing is per article, the way to control streaming spend is to filter tightly. Every search filter works on the stream, so narrowing by `language.code`, `category.id`, `source.domain` or `sentiment` means fewer matching articles, which means fewer credits. See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for the filtering syntax. ## Does the streaming pool share my search quota?[#](#does-the-streaming-pool-share-my-search-quota) No. Streaming has its own pool. Your account carries three separate allowances that do not borrow from each other: * **Request pool** — drawn down by normal REST calls like `/v1/news/everything` (one credit per call). * **Streaming (SSE) pool** — drawn down only by `/v1/news/stream`, one credit per delivered article. * **[WebSocket](/en/articles/getting-started/glossary#websocket) pool** — drawn down only by the `/v1/news/ws` stream, also one credit per delivered article. Spending your monthly search quota does not stop you from streaming, and a busy stream does not eat into the budget for your searches. Each pool is counted independently. (For how the request pool is charged on regular calls, see [what counts as one request](/en/articles/billing/credits/what-counts-as-request).) The dashboard header shows all the pools side by side: ![The dashboard header quota bar with separate counters for API requests, webhook and WebSocket streaming pools](/images/article/dashboard-quota-bar.png) ## What happens when the streaming pool runs out?[#](#what-happens-when-the-streaming-pool-runs-out) It depends on whether you have a [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance: * **No streaming credits and no balance, at connect time** — the server refuses the connection with HTTP `402` and code `ER0176` (“You have no SSE points on your account.”). Top up or wait for your renewal, then reconnect. * **Streaming pool empties mid-stream, no balance** — you receive an `error` event with code `ER0301` (“Balance exhausted”) and the connection closes. Reconnect once your pool refills or after you add funds. * **Paid plan with a pay-as-you-go balance** — when the streaming pool reaches zero, delivery does not stop. Each further article falls back to your balance at **$0.01 per article** (one cent), the same pay-as-you-go rate as regular requests. Streaming keeps flowing past the pool until the balance runs out. If you have set a monthly pay-as-you-go spending limit and reach it while streaming on balance, the stream stops with `402 ER0177` (“Monthly pay-as-you-go spending limit reached”) instead — that cap resets at the start of each calendar month. For the general overflow behaviour, see [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests). ## How do connection limits affect what I spend?[#](#how-do-connection-limits-affect-what-i-spend) The Free plan allows **1** concurrent SSE connection — but its feed is **delayed by 12 hours**, so a Free stream carries yesterday’s articles rather than live ones; paid plans stream without delay and cap concurrency at **2** on Starter, **2** on Basic, **10** on Professional, and **50** on Corporate. Opening one more than your plan allows returns HTTP `429` with code `ER0360`. These limits cap concurrency, not cost — every connection still bills per delivered article from the same shared streaming pool, so two open streams that both match the same articles will each be billed for the articles they receive. Close streams you no longer need so an idle connection does not hold a slot. A single connection also has a **6-hour lifetime**; after that the server sends error `ER0362` and asks you to reconnect. Reconnecting with the `Last-Event-Id` header resumes from your last article without gaps and without re-billing articles you already received. # Common Questions[#](#common-questions) ## Why did my streaming pool drop while I made no searches?[#](#why-did-my-streaming-pool-drop-while-i-made-no-searches) Because streaming and searching are billed from different pools. Every article the SSE stream pushed to you deducted one streaming credit, even though you ran no `/v1/news/everything` calls. Each delivery is recorded as a `stream` request in your logs, so open your request logs to see exactly which articles were billed and when. ## Do test keys consume streaming quota?[#](#do-test-keys-consume-streaming-quota) No. A [test key](/en/articles/getting-started/glossary#test-key-and-live-key) streams live events but its article content is masked for preview, and deliveries do **not** draw down any pool — streaming or otherwise. Use a test key to confirm your client connects, parses the `article` event and handles reconnection, then switch to a live key for full content and real billing. ## Can I check my streaming pool with /v1/balance?[#](#can-i-check-my-streaming-pool-with-v1balance) Not directly — the `/v1/balance` endpoint returns your **request** points and plan, not the streaming pool. To see streaming spend, look at your request logs (each delivered article appears as a `stream` request) or the usage view in your dashboard, where streaming deliveries are counted alongside your other traffic. ## Is the open connection or heartbeat ever billed?[#](#is-the-open-connection-or-heartbeat-ever-billed) No. You are billed strictly per article delivered. The persistent connection itself, the periodic `: heartbeat` keep-alives, and any final article that fails to flush before a disconnect are all free. If your filters match nothing for an hour, that hour of streaming costs zero credits. * * * ## Related Articles * [How to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) --- ## What counts as one request? URL: https://support.apitube.io/en/articles/billing/credits/what-counts-as-request What counts as one APITube request: most calls cost one credit, what each endpoint charges, why empty searches are free, and which calls cost nothing at all. # What counts as one request? How APITube credits are charged per call — and what doesn't cost anything ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 23, 2026 # What counts as one request?[#](#what-counts-as-one-request) One request is one billed API call, and most calls cost **one credit** drawn from your account quota. A standard search or retrieval call — `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article`, `/v1/news/count` and similar endpoints — deducts a single credit. A few endpoints cost more, and a few cost nothing, so it pays to know which is which before you build. Credits (the API also calls them _points_) are your plan’s request allowance for the period. Each billed call draws one credit from the pool, the dashboard counts it, and when the pool hits zero the API stops serving paid endpoints until your quota resets or you top up. ## How many credits does each endpoint cost?[#](#how-many-credits-does-each-endpoint-cost) Pricing is per call, not per article returned. The defaults: * **Standard search and retrieval — 1 credit.** `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article`, `/v1/news/story/:id`, `/v1/news/count`, the category/topic/industry/[entity](/en/articles/getting-started/glossary#entity) feeds, `/v1/news/trends`, `/v1/news/raw`, and people/company directory lookups each cost one credit. * **Local news — 1 credit plus 1 per insight.** `/v1/news/local` charges one credit for the listing and one more for each insight block you ask it to compute, so a request that bundles several insights costs more than one. Each block also costs _time_: one adds roughly 8–15 seconds, and asking for all twelve at once runs past the 30-second gateway timeout and fails with `502` — request only the blocks you use, and narrow the search with a filter first. * **Fact-check — 5 credits.** `/v1/fact-check` is the most expensive single call, charging five credits because it runs a retrieval-and-reasoning pass over the matching coverage. * **Streaming and [webhooks](/en/articles/getting-started/glossary#webhook) — 1 credit per article delivered.** The [SSE](/en/articles/getting-started/glossary#sse-stream) stream (`/v1/news/stream`), the [WebSocket](/en/articles/getting-started/glossary#websocket) stream (`/v1/news/ws`) and webhook deliveries all bill per article pushed to you, not per connection — and each draws from its own pool (`sse_points`, `ws_points`, `webhook_points`) rather than your standard request quota. Idle connections, heartbeats and empty polls cost nothing. * **Free calls — 0 credits.** `/v1/balance`, the `/v1/suggest/*` autocomplete endpoints and `/v1/news/event-types` are never billed, so a filter UI can call them as often as it needs. They still count toward your per-minute [rate limit](/en/articles/getting-started/glossary#rate-limit). * **Natural-language `prompt` — 2 extra credits.** Adding [`prompt`](/en/articles/searching-and-filtering/keyword-search/natural-language-search) to a request adds two credits on top of the endpoint’s own cost, and only the first time that wording is used — interpretations are cached for 24 hours, so repeats are free. The parameter requires Basic or above; on Free and Starter it returns `403 ER0706` and costs nothing. A single response can return up to 250 articles — 200 on Basic, 50 on Starter, 10 on Free — (the `per_page` maximum), and that whole page still costs one credit on the search endpoints — page size does not change the price. ## Does an empty search still cost a credit?[#](#does-an-empty-search-still-cost-a-credit) No. The article-returning search endpoints only charge when they actually return at least one article. If `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article` or the category/topic feeds match nothing, the call returns an empty result set and **no credit is deducted**. This means a tightly filtered query that comes back empty is free to retry after you loosen the filters. The one exception is `/v1/news/count`, which always returns a number and therefore always costs one credit, even when that number is zero. So if you only need to know _how many_ articles match, expect to pay for the count call regardless of the result. ## Which calls cost nothing?[#](#which-calls-cost-nothing) Two things never draw down your quota: * **Checking your balance.** `/v1/balance` returns your remaining credits and plan without charging anything, so you can poll it freely. See [how to check your balance via the API](/en/articles/retrieval/check-balance-api). * **Test-key requests.** Calls made with a **test** key (or in the dashboard’s Test mode) hit the live API but do not consume quota — they are for previewing shapes and responses, not billed traffic. Requests that are **rejected before they run** are also not billed: an invalid key (`401`), an exhausted quota (`402 ER0176`), or a rate-limit block (`429`) is turned away before any credit is charged. ## How are credits drawn — quota or balance?[#](#how-are-credits-drawn--quota-or-balance) Your plan **quota** is spent first; only once your monthly quota is used up does an eligible call fall back to your [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) **balance** instead of failing — so a request still counts as one charge, just against a different pool. Every billed call also writes a log line and bumps the calling key’s lifetime usage total, which is how the dashboard attributes spend per key. # Common Questions[#](#common-questions) ## Does returning more articles cost more credits?[#](#does-returning-more-articles-cost-more-credits) No. On the search endpoints the price is one credit per call, whether the page holds one article or the full 250-article maximum. To pull large result sets economically, raise `per_page` and paginate rather than making many small calls — fewer calls means fewer credits. ## Is `/v1/news/count` really billed even when it returns zero?[#](#is-v1newscount-really-billed-even-when-it-returns-zero) Yes. Unlike the article-returning endpoints, `/v1/news/count` charges one credit on every call because it always produces a result — the count itself. Use it when you specifically need a total; if you just want to check whether _any_ articles exist, a normal search that returns nothing is free. ## Why did my usage go up without a successful search?[#](#why-did-my-usage-go-up-without-a-successful-search) Most likely a `/v1/news/count` call or a streamed article. Count requests bill regardless of the number returned, and the SSE stream bills one credit for each article it delivers. To see exactly what was charged and when, open your request logs or [track your usage and quota](/en/articles/account-and-dashboard/usage-and-logs/track-usage) in the dashboard. ## How do I see what I’ve spent per key?[#](#how-do-i-see-what-ive-spent-per-key) Open a key’s detail page in the dashboard for a lifetime usage-points total plus a date-range breakdown of requests, cost and top endpoints. See [how to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) — useful for spotting which key drives the most spend. * * * ## Related Articles * [How to track your usage and quota](/en/articles/account-and-dashboard/usage-and-logs/track-usage) * [How to view usage for each API key](/en/articles/account-and-dashboard/keys/key-usage) * [How to check your balance via the API](/en/articles/retrieval/check-balance-api) --- ## Plans, Billing & Credits URL: https://support.apitube.io/en/articles/billing Understand APITube plans, credits and quota: what counts as a request, how rate limits and resets work, pay-as-you-go top-ups, and managing your subscription. ![](/images/collections/account-billing.svg) # Plans, Billing & Credits Plans, credits, quota and payments. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) By Brian and 1 other 2 authors 15 articles Plans, credits, quota and payments in one place: what counts as a billable request, how monthly quota and rate limits work per plan, pay-as-you-go top-ups when you need burst capacity, upgrading or downgrading a subscription, and how content licensing applies to the data you receive. Two articles answer most billing questions: [free plan limits](/en/articles/billing/plans/free-plan-limits) for what you get without paying, and [rate limits](/en/articles/billing/credits/rate-limits) for how request throughput differs between plans. ## [Credits & Quota](/en/articles/billing/credits) * * * * [How do requests and credits work?](/en/articles/billing/credits/how-credits-work) * [How streaming (SSE) quota is counted](/en/articles/billing/credits/sse-quota) * [Understanding APITube Rate Limits](/en/articles/billing/credits/rate-limits) * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) ## [Licensing](/en/articles/billing/licensing) * * * * [Can I Use APITube Content on My Website or Product?](/en/articles/billing/licensing/content-usage-rights) ## [Pay As You Go](/en/articles/billing/pay-as-you-go) * * * * [How to set a monthly spending limit](/en/articles/billing/pay-as-you-go/set-spending-limit) * [How to top up your balance](/en/articles/billing/pay-as-you-go/top-up-balance) * [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) ## [Plans](/en/articles/billing/plans) * * * * [Compare APITube Plans: Pricing and Limits by Tier](/en/articles/billing/plans/compare-plans) * [What's Included in the Free Plan?](/en/articles/billing/plans/free-plan-limits) * [Why Is Article Content Truncated on My Plan?](/en/articles/billing/plans/why-content-truncated) ## [Subscription](/en/articles/billing/subscription) * * * * [How to Cancel Your Subscription](/en/articles/billing/subscription/cancel-subscription) * [How to Upgrade or Downgrade Your APITube Plan](/en/articles/billing/subscription/upgrade-downgrade) * [Where to Find Your Invoices and Billing History](/en/articles/billing/subscription/billing-history) --- ## Can I Use APITube Content on My Website or Product? URL: https://support.apitube.io/en/articles/billing/licensing/content-usage-rights APITube grants a license to use its API data, not ownership: you can build on the metadata, but not republish copyrighted article content or build a competing… # Can I Use APITube Content on My Website or Product? What the APITube Terms of Service let you do with API data — your use license, third-party content, attribution, and where the free plan applies ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 4, 2026 # Can I use APITube content on my website or product?[#](#can-i-use-apitube-content-on-my-website-or-product) Yes — you can build websites and products on APITube API data, because the Terms of Service grant you a license to use the materials **for as long as your use case requires**. But it is a license to _use_, not a transfer of ownership, and it comes with clear limits: you may not reproduce or republish copyrighted article content, remove attribution or copyright notices, or build a competing news database. This article is a plain-language summary of what the APITube Terms of Service allow. The Terms of Service are the authoritative document — the sections below point to the rules that matter most when you put API data into a product. ## What does the APITube use license let you do?[#](#what-does-the-apitube-use-license-let-you-do) The Terms of Service grant permission to download and use the materials from APITube for as long as your use case requires. It is explicitly **a grant of a license, not a transfer of title** — APITube and the original publishers keep ownership, and you get the right to use the data within the rules. The data itself is aggregated from **publicly available web pages** using APITube’s own technology, and it does **not** contain personally identifiable information about end users. That enrichment layer — the classifications, [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment) scores, and source metadata APITube generates — is what you build products on. For how that data is gathered in the first place, see [how APITube collects and processes news](/en/articles/getting-started/how-apitube-collects-news). ## What are you not allowed to do with API data?[#](#what-are-you-not-allowed-to-do-with-api-data) The use license lists specific prohibitions. You may not: * **reproduce or republish copyrighted material** through the service; * **build a competing news database**; * reverse-engineer any software, or remove copyright or other proprietary notations; * register more than one [API key](/en/articles/getting-started/glossary#api-key) at a time (unless authorised), or circumvent the limits placed on your key or account; * use the service in any manner that violates the law. There are also rules specific to the data you receive: you must not misrepresent its ownership or source, obscure or change any copyright or trademark notices, or falsify or delete author attributions. And unless APITube expressly authorises it, you may not publicly release or disclose usage statistics or other information about the data. ## Can I republish the full article text and images?[#](#can-i-republish-the-full-article-text-and-images) Be careful here. The data returned by the API can contain **third-party content — text, images, and videos —** that remains the responsibility of whoever published it, and that content may be protected by intellectual-property rights. Under the Terms, you may not use that content unless you are licensed to do so or are otherwise permitted by law. In practice, the safe thing to build on is the **metadata and enrichment** APITube generates about each article; reproducing or republishing the original copyrighted article body or images is not something your APITube subscription grants. You remain responsible for copyright compliance and for obtaining any permissions or licenses you need for the underlying content. ## Can I use the free plan in production?[#](#can-i-use-the-free-plan-in-production) No. APITube’s no-charge tier — the Terms of Service call it the **Developer plan** — is for **development and testing in a development environment only**. It may not be used in a staging or production environment, including internally. If you integrate the free plan outside a development environment, the free license is revoked and a paid subscription is required to keep using the service. So for any live product or internal production workload, move to a paid plan. See [what’s included in the free plan](/en/articles/billing/plans/free-plan-limits) for its exact limits, and [compare APITube plans](/en/articles/billing/plans/compare-plans) for the paid tiers. This page is a plain-language summary, not legal advice. The APITube [Terms of Service](https://apitube.io/terms/terms-of-service) are the authoritative document — read them (especially the _Use license_ and _Data license_ sections) before you ship, and note that they are governed by the laws of the United Kingdom. # Common Questions[#](#common-questions) * [Do I own the data returned by the API?](#do-i-own-the-data-returned-by-the-api) * [Can I build a commercial product on APITube?](#can-i-build-a-commercial-product-on-apitube) * [What happens if my license is terminated?](#what-happens-if-my-license-is-terminated) * [Someone’s copyrighted work appears in my results — what do I do?](#someones-copyrighted-work-appears-in-my-results--what-do-i-do) ## Do I own the data returned by the API?[#](#do-i-own-the-data-returned-by-the-api) No. The Terms of Service grant you a **license to use** the data, not ownership of it — it is a grant of a license, not a transfer of title. APITube keeps its rights to the aggregated data, and the original publishers keep their rights to the underlying article content. You are free to use the data within the license terms, but you do not acquire the copyright to it. ## Can I build a commercial product on APITube?[#](#can-i-build-a-commercial-product-on-apitube) Yes, subject to the rules. You can use the API data in a product for as long as your use case requires, and the enrichment APITube generates (classifications, entities, sentiment, source metadata) is designed to be built on. What you may **not** do is build a competing news database, or republish copyrighted article content you are not separately licensed to use. If your product runs in production, it needs a paid plan — the free Developer plan is limited to development and testing. ## What happens if my license is terminated?[#](#what-happens-if-my-license-is-terminated) APITube may terminate the license at any time, with or without cause and with or without notice, effective immediately. If that happens, any remaining paid period is refunded **pro-rata**. Certain provisions — such as ownership, warranty disclaimers, and limitations of liability — survive termination by their nature. ## Someone’s copyrighted work appears in my results — what do I do?[#](#someones-copyrighted-work-appears-in-my-results--what-do-i-do) Users are responsible for ensuring their use of materials accessed through APITube complies with copyright law, and for obtaining any necessary permissions or licenses. If you believe your own copyrighted work is accessible through the Service in violation of your copyright, notify APITube through the contact form — see [how to contact APITube support](/en/articles/trust-and-support/contact-support). * * * ## Related Articles * [What's Included in the Free Plan?](/en/articles/billing/plans/free-plan-limits) * [How does APITube collect and process news?](/en/articles/getting-started/how-apitube-collects-news) * [How to Contact APITube Support](/en/articles/trust-and-support/contact-support) --- ## Licensing URL: https://support.apitube.io/en/articles/billing/licensing What the APITube Terms of Service allow you to do with API data: your use license, third-party article content rules, attribution, and the Developer plan's scope. ![](/images/collections/account-billing.svg) # Licensing What you can do with the data. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) By Beatrice 1 author 1 article * [Can I Use APITube Content on My Website or Product?](/en/articles/billing/licensing/content-usage-rights) --- ## Pay As You Go URL: https://support.apitube.io/en/articles/billing/pay-as-you-go How APITube pay-as-you-go works: top up a balance, pay $0.01 per request past your plan quota, set a monthly spending limit, and track your balance. ![](/images/collections/account-billing.svg) # Pay As You Go Top up and pay per request over quota. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Brian 1 author 3 articles * [How to set a monthly spending limit](/en/articles/billing/pay-as-you-go/set-spending-limit) * [How to top up your balance](/en/articles/billing/pay-as-you-go/top-up-balance) * [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) --- ## How to set a monthly spending limit URL: https://support.apitube.io/en/articles/billing/pay-as-you-go/set-spending-limit Set a monthly pay-as-you-go spending limit in the APITube dashboard so overflow billing stops at a ceiling you choose. Owners pick any value from $1 to… # How to set a monthly spending limit Cap pay-as-you-go overflow at a dollar ceiling so a traffic spike can't drain your balance ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 22, 2026 Updated July 21, 2026 # How to set a monthly spending limit[#](#how-to-set-a-monthly-spending-limit) Set a monthly [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) spending limit on the **Pay As You Go** page in your dashboard: enter a dollar amount (anything from **$1 to $100,000**) and save. Once your pay-as-you-go spend in the current calendar month reaches that ceiling, billed requests stop with `402 ER0177` instead of draining your balance — so a runaway loop or a traffic spike can never cost more than the number you chose. ## Where do you set the pay-as-you-go spending limit?[#](#where-do-you-set-the-pay-as-you-go-spending-limit) The limit lives on the **Pay As You Go** page of the dashboard, in the **Monthly spending limit** card. Type the cap in US dollars and press **Save limit**. The card shows where you stand for the month — for example, “$12.40 of $50.00 used this month (25%)” — so you can see how much headroom is left before billing stops. Only the **[workspace](/en/articles/getting-started/glossary#workspace) owner** can change this limit. A pay-as-you-go balance is shared across every workspace the owner runs, so the ceiling is set once on the owner’s account and applies everywhere that account’s keys are used — admins, members and viewers do not see the control. The accepted range is **$1 to $100,000**. Anything outside that is rejected, and an empty or zero value means “no limit” — billing falls back to the default behaviour where overflow runs until your balance hits zero. ![The Monthly spending limit card on the Pay As You Go page with the dollar cap field and Save button](/images/article/dashboard-payg-limit-form.png) ## What happens when the spending limit is reached?[#](#what-happens-when-the-spending-limit-is-reached) When your pay-as-you-go spend for the current month reaches the limit, the next request that would be billed to your balance is refused with HTTP `402` and the error code `ER0177`: ``` { "status": "not_ok", "errors": [ { "status": 402, "code": "ER0177", "message": "Monthly pay-as-you-go spending limit reached." } ] } ``` No balance is touched on that call — the request simply does no work and returns the error, so hitting the limit never costs you anything extra. The same `ER0177` reaches real-time clients too: the [SSE](/en/articles/getting-started/glossary#sse-stream) stream emits it as an `event: error`, and the [WebSocket](/en/articles/getting-started/glossary#websocket) stream sends an `error` frame and closes with code `4006`. Note that `ER0177` is different from `ER0176` (“You have no points on your account”). `ER0176` means your plan quota **and** your balance are both empty; `ER0177` means you still have money in your balance but have chosen to stop spending it this month. See [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests) for the difference. ## Does the spending limit affect my plan quota?[#](#does-the-spending-limit-affect-my-plan-quota) No. The limit only governs **pay-as-you-go** spend — the overflow billed at $0.01 per request once your monthly plan quota is used up. Your included plan quota is always spent first and is never blocked by this ceiling. The cap only comes into play after the quota is exhausted and a request would otherwise draw a cent from your balance. Read [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) for how the quota-then-balance order works. ## When does the spending counter reset?[#](#when-does-the-spending-counter-reset) The counter tracks spend per **calendar month in UTC**, and it resets lazily at the start of each new month. The first billed request after the 1st (UTC) starts a fresh period at zero, so spending automatically resumes on the new month with the same limit still in place. If you need to keep going before the reset, raise the limit (or remove it) in the dashboard and billing continues immediately. ## How do you watch your spend and get warned early?[#](#how-do-you-watch-your-spend-and-get-warned-early) You get alerts before you hit the wall, and you can also read the remaining budget straight from the API: * **80% warning** — when you’ve used 80% of the monthly limit, the dashboard raises an “Approaching spending limit” notification (the bell) and sends an email. * **100% block** — at 100%, you get a “Spending limit reached” notification and email letting you know new requests are blocked until next month or you raise the limit. * **`x-budget-remaining` header** — every API response includes this header (cents left before the limit) **whenever a limit is set**, so your client can see the wall approaching in real time. You can turn email alerts on or off in [dashboard notification settings](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications). # Common Questions[#](#common-questions) ## How do I remove the spending limit?[#](#how-do-i-remove-the-spending-limit) On the **Pay As You Go** page, use the **Remove limit** action under the Monthly spending limit card. That clears the ceiling, and overflow billing returns to the default behaviour — pay-as-you-go runs until your balance is empty. You can set a new limit again at any time. ## Why can’t I change the spending limit?[#](#why-cant-i-change-the-spending-limit) Only the **workspace owner** can set or change the pay-as-you-go limit, because the balance and billing are shared across all of the owner’s workspaces. If you’re an admin, member or viewer, the control is hidden and the owner needs to make the change. ## Does the limit cap how much I can top up?[#](#does-the-limit-cap-how-much-i-can-top-up) No. The spending limit only caps how much of your balance pay-as-you-go can **spend** in a calendar month. Your balance itself, and top-ups, are not limited by it — you can hold any balance and still set a low monthly spend ceiling. The minimum limit you can set is $1 and the maximum is $100,000. ## What’s the difference between hitting the limit and running out of balance?[#](#whats-the-difference-between-hitting-the-limit-and-running-out-of-balance) Hitting the monthly limit returns `402 ER0177` while you still have money in your balance — it’s a self-imposed stop that lifts next month or when you raise the limit. Running out of balance (and plan quota) returns `402 ER0176` instead, which means there are no funds left to spend at all. In both cases the blocked request does no work and isn’t charged. * * * ## Related Articles * [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) * [How to manage dashboard notifications](/en/articles/account-and-dashboard/usage-and-logs/manage-notifications) --- ## How to top up your balance URL: https://support.apitube.io/en/articles/billing/pay-as-you-go/top-up-balance Top up your APITube Pay As You Go balance from the dashboard: pick a preset from $10 to $500 or any custom amount from $1 to $10,000, then check out securely. # How to top up your balance Add funds to your Pay As You Go balance from the dashboard in a few clicks ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis June 28, 2026 Updated July 21, 2026 # How to top up your balance[#](#how-to-top-up-your-balance) To top up your [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance, open the **Pay As You Go** page in your APITube dashboard, choose a preset amount (from $10 to $500) or type any custom amount between **$1 and $10,000**, then complete the secure checkout. Your balance is credited as soon as payment clears, and every dollar buys **100 requests** because one request costs $0.01. Only the [workspace](/en/articles/getting-started/glossary#workspace) owner can top up, since the balance is shared across the whole workspace. ## Where do you top up your balance?[#](#where-do-you-top-up-your-balance) Top-ups happen on the **Pay As You Go** page of the dashboard — the same page that shows your current balance and your monthly spending limit. The page gives you two ways to pick an amount: * **Preset buttons** — $10, $25, $50, $100, $250 and $500, with **$50 selected by default**. Each button shows how many requests that amount buys. * **Custom amount** — a dollar field where you can enter any whole-dollar value from **$1 to $10,000**. Amounts outside that range are rejected before checkout. ![The Pay As You Go page showing the current balance and the top-up amount selector](/images/article/dashboard-payg.png) Because one request costs one cent, the request count scales directly with the dollars you add: Top-up Requests $1 (minimum) 100 $10 1,000 $50 5,000 $100 10,000 $500 50,000 $10,000 (maximum) 1,000,000 For how that balance is spent once you start calling the API, see [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg). ## How does the top-up checkout work?[#](#how-does-the-top-up-checkout-work) When you confirm an amount, the dashboard hands you off to a **secure hosted checkout** — APITube never collects card details itself. The amount you picked is carried to the payment flow as a dollar value (for example, the dashboard opens `…/topup/create?amount_dollars=50`), which creates a checkout for exactly that price and sends you to the payment page. Once payment clears, you are returned to the **Pay As You Go** page and your balance reflects the new funds. There is nothing else to switch on after a top-up. The balance simply waits in your account, and the very next request that exceeds your monthly plan quota draws from it automatically — at the same $0.01 per request. ## Who can top up the balance?[#](#who-can-top-up-the-balance) Only the **workspace owner** can add funds. A Pay As You Go balance is shared across every workspace the owner runs, and billing is tied to the owner’s account, so the top-up form only appears for the owner. Admins, members and viewers instead see a note that the balance is managed by the owner and cannot start a top-up. If you need more balance and you are not the owner, ask the workspace owner to top up. ## How much does each request cost from the balance?[#](#how-much-does-each-request-cost-from-the-balance) Each billed request deducts **$0.01 (one cent)** from your balance, and your plan quota is always spent first — the balance only covers overflow once your monthly quota is used up. That makes the balance easy to read as a request count: $5.00 left means 500 requests left. When both your quota and your balance reach zero, the next call returns `402 ER0176` (“You have no points on your account”) instead of doing work. To stop overflow before it drains the whole balance, set a [monthly spending limit](/en/articles/billing/pay-as-you-go/set-spending-limit). ## How do you check your balance after topping up?[#](#how-do-you-check-your-balance-after-topping-up) Every API response returns your remaining balance in the **`x-balance-remaining`** header, expressed in cents — so a value of `500` means $5.00, or 500 requests left. You can also poll the `/v1/balance` endpoint at any time to read your balance and plan **without spending a request**. See [how to check your balance via the API](/en/articles/retrieval/check-balance-api) for the exact call. # Common Questions[#](#common-questions) ## What are the minimum and maximum top-up amounts?[#](#what-are-the-minimum-and-maximum-top-up-amounts) The minimum top-up is **$1** (100 requests) and the maximum is **$10,000** (1,000,000 requests) in a single transaction. The custom field enforces this range, and any amount outside it is rejected before you reach checkout. ## Does my balance expire after I top up?[#](#does-my-balance-expire-after-i-top-up) No. Your Pay As You Go balance never expires — it stays in your account until you spend it on API requests, whether that takes days or months. Topping up does not start a subscription or a renewal clock; the funds simply wait until a request needs them. ## Can I get a refund for an unused balance?[#](#can-i-get-a-refund-for-an-unused-balance) Your balance is non-refundable, but it never expires, so any unused funds stay available for future requests. If you mostly need a predictable monthly allowance rather than overflow, compare a subscription plan instead. ## Do I need a subscription to top up?[#](#do-i-need-a-subscription-to-top-up) No. You can hold a Pay As You Go balance without a paid monthly plan, and eligible requests are billed to it at $0.01 each. On a monthly plan, the balance acts purely as overflow: your included quota is spent first, and top-ups only cover requests beyond it. * * * ## Related Articles * [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) * [How to set a monthly spending limit](/en/articles/billing/pay-as-you-go/set-spending-limit) * [How to check your balance via the API](/en/articles/retrieval/check-balance-api) * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) --- ## What is Pay As You Go? URL: https://support.apitube.io/en/articles/billing/pay-as-you-go/what-is-payg Pay As You Go lets you top up an APITube balance and pay $0.01 per request once your plan quota runs out, so traffic keeps flowing instead of failing with 402. # What is Pay As You Go? Top up a balance and pay only for the requests you make past your plan quota ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis June 28, 2026 Updated July 21, 2026 # What is Pay As You Go?[#](#what-is-pay-as-you-go) [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) (PAYG) is an overflow balance you top up in advance: once your monthly plan quota is used up, each extra request is billed to that balance at **$0.01 per request** instead of failing. So a busy day no longer stops your traffic — calls that exceed your plan keep working as long as the balance has money in it. Without a balance, the same call would be rejected with `402 ER0176`. ## How does pay-as-you-go billing work?[#](#how-does-pay-as-you-go-billing-work) Your plan quota is always spent first. Every successful call deducts one request from your monthly allowance, and only when that allowance hits zero does pay-as-you-go take over — each further call then draws **one cent** from your balance instead of being turned away. The balance is a single fund attached to your account, so you do not configure it per key or per endpoint. That balance covers overflow on every billed channel at the same one-cent rate: * **Standard requests** — `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article` and the other search and retrieval endpoints each cost one cent past your plan quota. * **Real-time streaming** — the [SSE](/en/articles/getting-started/glossary#sse-stream) stream (`/v1/news/stream`) and [WebSocket](/en/articles/getting-started/glossary#websocket) feed bill one cent **per article delivered** once your streaming allowance is spent. Because one request equals one cent, you can read your balance directly as a request count: a $1 balance is 100 requests, a $50 balance is 5,000. When the balance reaches zero and your plan quota is also empty, the next call returns `402 ER0176` (“You have no points on your account”) — the signal to top up rather than keep retrying. See [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests) for the full out-of-quota behaviour. ## How much does pay-as-you-go cost?[#](#how-much-does-pay-as-you-go-cost) Pay-as-you-go is a flat **$0.01 per request** with no subscription attached. There is no monthly fee and no commitment — you only pay for calls you actually make past your plan quota. The minimum top-up is **$1**, which buys **100 requests**, and your balance does not expire: it stays in your account until you spend it. ## How do you add a pay-as-you-go balance?[#](#how-do-you-add-a-pay-as-you-go-balance) You top up from the **Pay As You Go** page in your dashboard. Pick a preset amount — $10, $25, $50, $100, $250 or $500 — or enter your own (the $1 minimum applies), then complete checkout. Billing runs through the existing payment flow, so the dashboard hands you off to a secure checkout page and credits your balance once payment clears. The balance then sits ready, and the very next request that exceeds your plan quota draws from it automatically — there is nothing else to switch on. ## How do you cap your pay-as-you-go spending?[#](#how-do-you-cap-your-pay-as-you-go-spending) You can set a **monthly spending limit** so overflow billing stops at a ceiling you choose. The limit is set on the Pay As You Go page ([workspace](/en/articles/getting-started/glossary#workspace) owners only, since the balance is shared across a workspace) and accepts any value from **$1 to $100,000**. Once your pay-as-you-go spend in the current calendar month reaches the limit, billed calls stop with a different error: ``` { "status": "not_ok", "errors": [ { "status": 402, "code": "ER0177", "message": "Monthly pay-as-you-go spending limit reached." } ] } ``` The counter resets at the start of each calendar month (UTC), so spending automatically resumes on the 1st — or you can raise the limit in the dashboard to keep going right away. The limit applies only to pay-as-you-go spend; it never touches your plan quota. ## How do you track your remaining balance?[#](#how-do-you-track-your-remaining-balance) Every API response carries your balance in a header, so you can watch it without a separate call: * `x-balance-remaining` — your pay-as-you-go balance in **cents** (so `500` means $5.00, or 500 requests left). * `x-points-remaining` — your plan quota still available before pay-as-you-go kicks in. * `x-budget-remaining` — cents left before your monthly limit, sent only when you have a spending limit set. You can also poll the `/v1/balance` endpoint at any time; it returns your remaining quota and plan **without consuming a request**. See [how to check your balance via the API](/en/articles/retrieval/check-balance-api) for the exact call. ![The Pay as you go page of the dashboard with the balance, top-up amounts and the monthly spending limit card](/images/article/dashboard-payg.png) # Common Questions[#](#common-questions) ## Does my pay-as-you-go balance expire?[#](#does-my-pay-as-you-go-balance-expire) No. Your pay-as-you-go balance has no expiry — it stays in your account until you spend it, whether that takes days or months. Topping up does not start a subscription or a renewal clock; the funds simply wait until a request needs them. ## Do I need a subscription to use pay-as-you-go?[#](#do-i-need-a-subscription-to-use-pay-as-you-go) You do not need a paid monthly plan to add a balance. As soon as your account holds a pay-as-you-go balance, eligible requests are billed to it at $0.01 each. On a monthly plan, pay-as-you-go acts purely as overflow: your included quota is spent first, and the balance only covers requests beyond it. ## Does pay-as-you-go cover real-time streaming?[#](#does-pay-as-you-go-cover-real-time-streaming) Yes. The same balance backs overflow on the SSE (`/v1/news/stream`) and WebSocket feeds, which bill **one cent per article delivered** once your streaming allowance is exhausted — exactly the rate standard requests pay. A single balance therefore covers both your regular calls and your streaming usage. ## What happens when my balance and quota both run out?[#](#what-happens-when-my-balance-and-quota-both-run-out) The next billed call returns `402 ER0176` (“You have no points on your account”) and does no work, so you are never charged for being out of credit. To get unblocked, top up your balance, upgrade your plan for a larger monthly quota, or wait for your plan quota to reset. For the difference between running out of quota and hitting a [rate limit](/en/articles/getting-started/glossary#rate-limit), see [what counts as one request](/en/articles/billing/credits/what-counts-as-request). * * * ## Related Articles * [What happens when you run out of requests?](/en/articles/billing/credits/out-of-requests) * [How to check your balance via the API](/en/articles/retrieval/check-balance-api) * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) --- ## Compare APITube Plans: Pricing and Limits by Tier URL: https://support.apitube.io/en/articles/billing/plans/compare-plans Compare APITube plans side by side: Free ($0), Starter ($29), Basic ($99), Professional ($199) and Corporate ($599) — quotas, streaming, webhooks and rate… # Compare APITube Plans: Pricing and Limits by Tier Side-by-side pricing, request quotas, streaming allowance, webhooks and rate limits for every APITube tier ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 22, 2026 Updated August 14, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=electric+vehicles&per_page=250) # Compare APITube plans: Free, Starter, Basic, Professional and Corporate[#](#compare-apitube-plans-free-starter-basic-professional-and-corporate) APITube has five plans: **Free ($0)**, **Starter ($29/month)**, **Basic ($99/month)**, **Professional ($199/month)** and **Corporate ($599/month)**. They all reach the same search and retrieval endpoints — what changes between them is how many requests you get, how much of each article you can read, how many real-time streams and [webhooks](/en/articles/getting-started/glossary#webhook) you can run, and how fast you may call the API. This page lays out every tier side by side so you can match a plan to your workload. ## What do the five APITube plans cost and include?[#](#what-do-the-five-apitube-plans-cost-and-include) Each plan gives you a monthly pool of requests (the API calls these _points_), a separate streaming allowance, and its own connection, webhook and [rate limits](/en/articles/getting-started/glossary#rate-limit). Here is the full comparison: Free Starter Basic Professional Corporate Price (monthly) $0 $29 $99 $199 $599 Price (annual) — $279 $959 $1,919 $4,999 Requests per cycle 100 / day 10,000 50,000 150,000 300,000 Renewal cycle 1 day 31 days 31 days 31 days 31 days Rate limit ([live key](/en/articles/getting-started/glossary#test-key-and-live-key)) 10 / min 50 / min 50 / min 50 / min 50 / min Streaming ([SSE](/en/articles/getting-started/glossary#sse-stream)) credits 1,000 3,000 5,000 15,000 40,000 Concurrent SSE streams 1 2 2 10 50 Saved webhooks 1 5 5 20 100 Article content Preview Full Full Full Full Articles per request (`per_page`) 10 50 250 250 250 [Pagination](/en/articles/getting-started/glossary#pagination) First 5 pages Unlimited Unlimited Unlimited Unlimited [Pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) fallback No Yes Yes Yes Yes Fact-check endpoint No Yes Yes Yes Yes Natural-language `prompt` No No Yes Yes Yes Streaming and connection figures shown are for the monthly plans. The `per_page` page-size cap is **250** results on Basic and up — **Starter** is capped at **50** and **Free** at **10** — asking for more returns `400 ER0171`, and the default page size drops to the plan ceiling, so a Free request that omits `per_page` gets 10 instead of the usual 100. On Free that compounds with the 5-page cap: 5 × 10 = **50 articles** is the whole reach of one query. If you are still weighing which tier fits, see [which plan is right for me](/en/articles/getting-started/which-plan-is-right). ## What is the difference between the Free and paid plans?[#](#what-is-the-difference-between-the-free-and-paid-plans) The **Free plan** is built for evaluation. It costs **$0**, gives you **100 requests** on a fast **1-day** renewal cycle, and reaches every search and retrieval endpoint against the real live index — it is not a separate sandbox. Its trade-offs are the limits people hit first: the article `body` and `body_html` come back as a **preview** trimmed to a marker (`...[Upgrade subscription plan]`) — everything else, including the link, image, description and all enrichment, is full — you can only page through the **first 5 pages** of a result set (a sixth page returns `HTTP 400` with error `ER0173`), everything a Free key sees is **delayed by 12 hours** (search, streams and webhooks alike), streaming is capped at **one** concurrent connection, export formats other than JSON, `/v1/news/trends` and the MCP server return `403 ER0706`, and the rate limit is **10 requests per minute**. For the full breakdown, read [what’s included in the free plan](/en/articles/billing/plans/free-plan-limits). Every **paid plan** (Starter and up) removes the content preview when you use a live key, lifts the 5-page cap, raises the rate limit to **50 requests per minute**, lifts streaming to more concurrent connections and larger pools, and unlocks the `/v1/fact-check` endpoint and the pay-as-you-go fallback. Beyond that the tiers mostly scale the same numbers, with one feature difference: the natural-language [`prompt`](/en/articles/searching-and-filtering/keyword-search/natural-language-search) parameter starts at **Basic**, so Free and Starter keys get `403 ER0706` when they use it. ``` curl "https://api.apitube.io/v1/news/everything?title=electric%20vehicles&per_page=250&api_key=YOUR_API_KEY" ``` That single call returns up to 250 articles for one request on Professional and Corporate — Basic is capped at 200, Starter at 50 and Free at 10 — larger pages, not more calls, is the cheapest way to pull data. See [how requests and credits work](/en/articles/billing/credits/how-credits-work). ## Which paid plan should you pick — Starter, Basic, Professional or Corporate?[#](#which-paid-plan-should-you-pick--starter-basic-professional-or-corporate) The four paid tiers scale the same set of numbers, so pick by the biggest constraint in your workload: * **Starter — $29/month.** 10,000 requests per 31-day cycle, 3,000 streaming credits, up to 2 concurrent SSE streams, 5 saved webhooks, and up to 50 articles per request. The cheapest tier with full article content, the 50/min rate limit and fact-check. The natural-language `prompt` parameter is not included. Sized for a first production integration. * **Basic — $99/month.** 50,000 requests per 31-day cycle, 5,000 streaming credits, up to 2 concurrent SSE streams, and 5 saved webhooks. Same connection and webhook limits as Starter — what you gain is the larger request and streaming pools, the full 250 articles per request, and the natural-language `prompt` parameter. * **Professional — $199/month.** 150,000 requests, 15,000 streaming credits, up to 10 concurrent SSE streams, and 20 saved webhooks. The step up when one Basic pool or two streams are not enough. * **Corporate — $599/month.** 300,000 requests, 40,000 streaming credits, up to 50 concurrent SSE streams, and 100 saved webhooks. Built for high-volume pipelines and many parallel feeds. Each tier is also available billed **annually** — Starter at **$279/year**, Basic at **$959/year**, Professional at **$1,919/year** and Corporate at **$4,999/year** — which is lower than paying the monthly price twelve times. ## What happens when a plan runs out of requests?[#](#what-happens-when-a-plan-runs-out-of-requests) When your request pool reaches zero, the next billed call returns **`402` with error `ER0176`** (`You have no points on your account`). What happens next depends on your plan. On a **paid** plan, if you have a pay-as-you-go balance, the request is instead charged to that balance at **$0.01 per request** so the call succeeds — the minimum top-up is **$1**, which buys **100 requests**. The **Free** plan has no pay-as-you-go fallback, so requests simply resume when the 1-day cycle renews, or immediately if you upgrade. Rate limits are per plan, not flat: a Free live key is capped at **10 requests per minute**, while a paid live key gets **50 per minute**. Test keys are held to 15/min on any plan, and the `/v1/fact-check` endpoint has its own 10/min cap. Exceeding a limit returns `429 ER0203`; repeat abuse (30 violations) triggers a temporary ban with `429 ER0204`. # Common Questions[#](#common-questions) * [Does the Free plan expire or require a card?](#does-the-free-plan-expire-or-require-a-card) * [Do all plans share the same rate limit?](#do-all-plans-share-the-same-rate-limit) * [Can I use fact-check on any plan?](#can-i-use-fact-check-on-any-plan) * [Which plans include the natural-language prompt parameter?](#which-plans-include-the-natural-language-prompt-parameter) * [Is there an annual discount?](#is-there-an-annual-discount) ## Does the Free plan expire or require a card?[#](#does-the-free-plan-expire-or-require-a-card) No card is needed to use the Free plan. Its 100-request allowance renews on a **1-day** cycle rather than the 31-day cycle of the paid plans, so it is a small, frequently-refreshing pool for testing rather than a monthly quota. You only pay when you upgrade or add a pay-as-you-go balance. ## Do all plans share the same rate limit?[#](#do-all-plans-share-the-same-rate-limit) No. Rate limits vary by plan and key type: a **Free** live key is limited to **10 requests per minute**, a **Starter**, **Basic** or **Professional** live key gets **50 per minute**, **Corporate** gets **200 per minute**, and **test** keys on any plan get 15 per minute. These are the standard production values; the ban after 30 violations (`ER0204`) is the same across plans. ## Can I use fact-check on any plan?[#](#can-i-use-fact-check-on-any-plan) No. The `/v1/fact-check` endpoint is disabled on the Free plan — calling it there returns `403` with error `ER0706` (`Fact-check is not available on the free plan`). It works on Starter, Basic, Professional and Corporate. Note that fact-check costs 5 requests per call rather than 1, because it runs a retrieval-and-reasoning pass. ## Which plans include the natural-language prompt parameter?[#](#which-plans-include-the-natural-language-prompt-parameter) Basic, Professional and Corporate. The `prompt` parameter — the one that turns “Tesla news in English for the last 10 days” into real filters — returns `403 ER0706` on Free and Starter, and nothing is charged for the refused request. It sits one tier higher than fact-check, which starts at Starter. The filters it produces are not gated at all: `title`, `organization.name`, `published_at.start` and the rest work on every plan if you write them yourself, and a translation costs 2 points on top of the request on the plans that have it. ## Is there an annual discount?[#](#is-there-an-annual-discount) Yes. Starter, Basic, Professional and Corporate can be billed annually at $279, $959, $1,919 and $4,999 per year, each lower than twelve monthly payments. The request and connection limits stay the same as the monthly plan; annual plans include a larger streaming allowance — annual Starter, for example, carries 10,000 streaming credits instead of 3,000. * * * ## Related Articles * [Which Plan Is Right for Me?](/en/articles/getting-started/which-plan-is-right) * [What's Included in the Free Plan?](/en/articles/billing/plans/free-plan-limits) * [How do requests and credits work?](/en/articles/billing/credits/how-credits-work) --- ## What's Included in the Free Plan? URL: https://support.apitube.io/en/articles/billing/plans/free-plan-limits The APITube free plan is $0 for 100 requests a day, 10 articles per request and the first 5 pages; only the article body is trimmed, everything else is full. # What's Included in the Free Plan? The quota, streaming, webhook and pagination limits of the APITube free plan, and why the article body comes back as a preview ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 23, 2026 Updated August 14, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=Apple) # What’s included in the free plan?[#](#whats-included-in-the-free-plan) The APITube free plan costs **$0** and gives you **100 requests** per day and **one** [webhook](/en/articles/getting-started/glossary#webhook). Streaming ([SSE](/en/articles/getting-started/glossary#sse-stream)/[WebSocket](/en/articles/getting-started/glossary#websocket)) is available with **one** concurrent connection each, funded by **1,000** SSE and **1,000** WebSocket deliveries per day; paid plans raise both. Everything the free plan delivers is **delayed by 12 hours** — articles published in the last 12 hours are visible only on a paid plan. It reaches every search and retrieval endpoint and returns complete articles — link, image, description, source and all NLP enrichment — with one exception: the article **body** comes back as a 200-character preview. You can also page through only the **first 5 pages** of any result set. It is built for evaluating the API and wiring up an integration; a paid plan removes the body preview and raises every limit. ``` curl "https://api.apitube.io/v1/news/everything?title=Apple&api_key=YOUR_FREE_KEY" ``` That call runs against the full live index and returns real, matching articles — the free plan is not a separate sandbox. What differs from a paid plan is how much you can pull and how much of each article’s text you see. ## What do you get on the free plan?[#](#what-do-you-get-on-the-free-plan) The free plan unlocks the whole API surface at no cost, with these allowances: * **100 requests per day** — your standard request pool (the API calls these _points_). Each billed call spends one, exactly like a paid plan. * **Streaming (one connection)** — the free plan can hold **one** concurrent SSE and **one** WebSocket connection, funded by **1,000** SSE and **1,000** WebSocket deliveries per day; paid plans raise both. * **One live SSE stream** — the free plan can open **one** live `/v1/news/stream` connection at a time; a second returns `ER0360`. Paid plans allow more concurrent streams. * **1 webhook** — you can save one webhook subscription. * **12-hour delay** — a free key sees an article only after it has been published for 12 hours. The delay applies to search, aggregates, SSE/WebSocket streams and webhook deliveries alike, so a stream is not a way around it. Paid plans get articles as soon as they are indexed. * **Search & retrieval endpoints** — search, top headlines, single-article lookup, [story clusters](/en/articles/getting-started/glossary#story), counts and the directories work on the free plan. Four extras do not: `/v1/news/trends`, `/v1/fact-check`, the [MCP server](/en/articles/setup-and-installation/ai-and-mcp/use-in-ai-assistants) and the natural-language [`prompt`](/en/articles/searching-and-filtering/keyword-search/natural-language-search) parameter (Basic and up). All return `403 ER0706` on a free key, and none is charged when refused. * **JSON only** — `export=csv`, `xlsx`, `xml`, `rss`, `tsv`, `parquet` and `jsonl` are paid-plan formats; on a free key they return `403 ER0706`. `export=json` and plain requests work as usual. * **`per_page` up to 10** — the free plan returns at most **10 articles per request** (Starter 50, Basic 200, Professional and Corporate 250). Asking for more returns `ER0171`, and a free request that omits `per_page` gets 10 rather than the usual default of 100. The 100-request pool runs on a short **1-day cycle** (`validity_days: 1`), where paid monthly plans use a 31-day cycle. So the free plan is a small, fast-renewing allowance rather than a large monthly one. For how the request pools work in detail, see [how requests and credits work](/en/articles/billing/credits/how-credits-work). ## Why is article content truncated on the free plan?[#](#why-is-article-content-truncated-on-the-free-plan) On the free plan the API returns the article **body as a preview**, not in full. `body` and `body_html` are cut to the first **200 characters** and tagged with `...[Upgrade subscription plan]`. Nothing else is trimmed: `href`, `image`, `description`, the source domain and every URL come back complete, so free-plan articles are readable and clickable. This is expected behaviour, not an error — the `HTTP` status is still `200` and the articles are real. Everything else is **not** trimmed. The `title`, `description`, `href`, `image`, source details, `entities`, `categories`, `topics`, `sentiment` scores, `readability`, `published_at` and language all come back complete, so you can build and ship a working prototype on the free plan and only miss the full body text. ``` { "title": "Apple reports record quarterly revenue", "href": "https://example.com/apple-record-quarter", "description": "Apple posted its strongest December quarter to date, driven by iPhone and services revenue.", "body": "Apple Inc. said on Thursday that revenue rose across every product...(+1962 chars hidden)...[Upgrade subscription plan]" } ``` The same preview also applies to [test keys](/en/articles/getting-started/glossary#test-key-and-live-key). For the full field-by-field breakdown of what gets masked, see [why are my results masked or placeholder text](/en/articles/troubleshooting/masked-results). ## How many results can you retrieve on the free plan?[#](#how-many-results-can-you-retrieve-on-the-free-plan) The free plan is capped at the **first 5 pages** of any query, and each page holds at most **10 articles**. Asking for page 6 or higher returns `HTTP 400` with error `ER0173` (`Free plan is limited to the first 5 pages. Upgrade your subscription plan to paginate further.`), and asking for `per_page` above 10 returns `ER0171`. The two limits multiply: 5 pages × 10 articles means a free key can reach at most **50 articles** per query. ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&per_page=10&page=5&api_key=YOUR_FREE_KEY" ``` Page 5 with `per_page=10` is the deepest a free-plan request can go — articles 41 to 50 of the result set. To reach more of a large result set, upgrade to a paid plan: that lifts both the page cap and the 10-article page size. The 50-article reach (5 pages × 10 per page) and the content preview are the two limits people hit first on the free plan. Both are plan-based, not filter-based: your search is matching correctly — a paid plan simply returns more of it. The free plan's rate limit of \*\*10 requests per minute\*\* applies on top (Starter, Basic and Professional get 50, Corporate 200); see [understanding rate limits](/en/articles/billing/credits/rate-limits). ## What happens when the free requests run out?[#](#what-happens-when-the-free-requests-run-out) When your 100-request pool reaches zero, the next billed call returns `402` with error `ER0176`. The free plan has **no [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) fallback** — that cash-balance overflow is a paid-plan feature — so requests resume when your quota renews on the next cycle, or immediately if you upgrade. A search that matches nothing is **not** charged, so retrying a zero-result query to refine filters is free. See [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests). Test keys (prefix `api_test_`) are a useful companion here: they hit the live API but never draw down your 100-request pool, so you can keep prototyping request shapes without spending free quota. The trade-off is that test keys also preview content, just like the free plan. ## How to unlock full content and more quota[#](#how-to-unlock-full-content-and-more-quota) To remove the preview and the page cap, move to a paid plan and use a **live key** (prefix `api_live_`). On a paid plan the `body`, `body_html`, `description` and URLs come back in full, the 5-page limit is lifted, `per_page` rises to 50 (Starter) or 250 (Basic and up), the request and streaming pools are much larger, and you can hold more concurrent SSE connections and save more webhooks. To pick the right tier, see [which plan is right for me](/en/articles/getting-started/which-plan-is-right). # Common Questions[#](#common-questions) * [Does the free plan cost anything?](#does-the-free-plan-cost-anything) * [Can I see full article text on the free plan?](#can-i-see-full-article-text-on-the-free-plan) * [Why do I get an error asking for page 6?](#why-do-i-get-an-error-asking-for-page-6) * [How often does the free quota renew?](#how-often-does-the-free-quota-renew) ## Does the free plan cost anything?[#](#does-the-free-plan-cost-anything) No. The free plan is **$0** — there is no charge and no card required to make requests within its 100-request daily allowance. You only pay when you upgrade to a paid plan or add a pay-as-you-go balance, and pay-as-you-go itself is a paid-plan feature. ## Can I see full article text on the free plan?[#](#can-i-see-full-article-text-on-the-free-plan) No. On the free plan only `body` and `body_html` are trimmed to a 200-character preview ending in `...[Upgrade subscription plan]`. The `description` comes back in full, as do the headline, link, image, source, entities, sentiment and every other structured field — the full article text is the one thing a paid plan adds. ## Why do I get an error asking for page 6?[#](#why-do-i-get-an-error-asking-for-page-6) Because the free plan is limited to the first 5 pages of results. Requesting `page=6` or higher returns `HTTP 400` with `ER0173`. The filter still matched — you have simply reached the free-plan pagination cap. The free page size is already at its ceiling of 10, so those five pages hold 50 articles at most — narrow the query with filters, or upgrade to page deeper and pull larger pages. ## How often does the free quota renew?[#](#how-often-does-the-free-quota-renew) The free plan’s 100-request allowance runs on a 1-day cycle (`validity_days: 1`), unlike the 31-day cycle of the monthly paid plans. So it is a small, frequently-renewing pool rather than a large monthly one — good for light, ongoing testing, not for pulling large datasets in one go. * * * ## Related Articles * [Why Are My Results Masked or Placeholder Text?](/en/articles/troubleshooting/masked-results) * [How do requests and credits work?](/en/articles/billing/credits/how-credits-work) * [Which Plan Is Right for Me?](/en/articles/getting-started/which-plan-is-right) --- ## Plans URL: https://support.apitube.io/en/articles/billing/plans Compare APITube plans, see what the free plan includes and its limits, and understand why article content is truncated on some plans. ![](/images/collections/account-billing.svg) # Plans Compare plans and free-plan limits. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Brian 1 author 3 articles * [Compare APITube Plans: Pricing and Limits by Tier](/en/articles/billing/plans/compare-plans) * [What's Included in the Free Plan?](/en/articles/billing/plans/free-plan-limits) * [Why Is Article Content Truncated on My Plan?](/en/articles/billing/plans/why-content-truncated) --- ## Why Is Article Content Truncated on My Plan? URL: https://support.apitube.io/en/articles/billing/plans/why-content-truncated APITube trims only the article body to the first 200 characters, and only on the free plan or a test key. Any paid plan on a live key returns the full text. # Why Is Article Content Truncated on My Plan? Why the article body comes back as a short preview, which plans it affects, and how to get the full text ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=electric+vehicles) # Why is article content truncated on my plan?[#](#why-is-article-content-truncated-on-my-plan) Article content is truncated because you are on the **free plan** or using a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** — those are the only two cases where APITube trims the text. On the free plan (or any test key), the `body` and `body_html` fields are cut to the **first 200 characters** and end with a marker like `...(+4813 chars hidden)...[Upgrade subscription plan]`. On any **paid plan** (Starter, Basic, Professional or Corporate) with a live key, the full article body comes back. Nothing else about the request changes: the `HTTP` status is `200`, the article count is real, and the rest of the article — title, description, link, image, source and all enrichment — is complete. Only the body text is shortened. ``` { "title": "Ford raises its EV production target for 2027", "href": "https://example.com/ford-ev-target-2027", "description": "The automaker said it will lift output as demand for electric pickups recovers.", "body": "Ford said on Tuesday it plans to increase electric-vehicle production... ...(+4813 chars hidden)...[Upgrade subscription plan]", "language": "en" } ``` ## Which plans truncate article content?[#](#which-plans-truncate-article-content) Only the **free plan** truncates content, and only the body of the article. APITube decides whether to trim from a single rule: the body is trimmed when the key’s plan is `free` **or** the key is a test key. Every paid tier — **Starter, Basic, Professional and Corporate** — returns the full `body` and `body_html` when you call it with a live key (prefix `api_live_`). If you want to know which tier fits your workload, see [Compare APITube plans](/en/articles/billing/plans/compare-plans). Test keys are the exception to the plan rule: a test key (prefix `api_test_`) always returns trimmed content, **even if your account is on a paid plan**, because a test key is meant for wiring up an integration without spending quota. On a test key the marker text reads `...[Test mode — use a live key for full content]` instead of the upgrade marker, but the trimming is the same. ## What exactly gets truncated, and what stays full?[#](#what-exactly-gets-truncated-and-what-stays-full) On the free plan (or a test key) APITube trims the article text and leaves everything else intact: * **Truncated:** `body` and `body_html` are cut to the first **200 characters**, then padded with `...(+N chars hidden)` and the upgrade marker. * **Full and unchanged:** `title`, `description`, `href`, `image`, `links[].url`, `media[].url`, the source `domain`, `home_page_url` and `favicon`, the English `translations`, and every enrichment field — [entities](/en/articles/getting-started/glossary#entity) (people, companies, locations), [sentiment](/en/articles/getting-started/glossary#sentiment) scores, categories, topics, industries, readability and word/sentence counts. So a free-plan response is a usable article: real headline, working link, real summary, real entities and sentiment, and the real number of matches — the preview hides only the article body itself. ## How do I get the full article body?[#](#how-do-i-get-the-full-article-body) There are two ways to remove the truncation, depending on why it is happening: 1. **On the free plan → upgrade to a paid plan.** Any paid tier returns the full body on a live key. See [Which plan is right for me?](/en/articles/getting-started/which-plan-is-right) to pick one. 2. **Using a test key → switch to a live key.** If your account is already on a paid plan but content is still trimmed, you are calling the API with a test key. Swap the `api_test_` key for your `api_live_` key. The request itself does not change — only the key does: ``` curl "https://api.apitube.io/v1/news/everything?title=electric%20vehicles&api_key=YOUR_LIVE_KEY" ``` You can also send the key as a header (`X-API-Key: YOUR_LIVE_KEY`) instead of the `api_key` query parameter. With a live key on a paid plan, the `body` and `body_html` in the response contain the complete text with no marker. ## I upgraded but content is still truncated — why?[#](#i-upgraded-but-content-is-still-truncated--why) The most common cause is the **key type**, not the plan. Content trimming looks at two things: the plan and whether the key is a test key. Upgrading your plan fixes the first, but if you are still calling the API with an `api_test_` key, the response stays trimmed regardless of the plan. Check the key prefix in your request: `api_test_` always previews, `api_live_` returns full content. This is also covered from the troubleshooting angle in [Why are my results masked or placeholder text?](/en/articles/troubleshooting/masked-results). # Common Questions[#](#common-questions) * [Does truncation mean my request failed?](#does-truncation-mean-my-request-failed) * [Are entities and sentiment also truncated on the free plan?](#are-entities-and-sentiment-also-truncated-on-the-free-plan) * [How long is the preview exactly?](#how-long-is-the-preview-exactly) * [Do exports and streams truncate content too?](#do-exports-and-streams-truncate-content-too) ## Does truncation mean my request failed?[#](#does-truncation-mean-my-request-failed) No. Truncation is expected behaviour on the free plan and on test keys — it is not an error. The `HTTP` status is `200`, the article count and all metadata are real, and the API matched genuine articles. Only `body` and `body_html` are shortened to a preview. ## Are entities and sentiment also truncated on the free plan?[#](#are-entities-and-sentiment-also-truncated-on-the-free-plan) No. Entities, sentiment scores, categories, topics and the word/sentence counts are returned in full on every plan, including free — as are the description and every URL. The trimming applies to the article body alone. You can evaluate the full enrichment on a free plan before deciding to upgrade. ## How long is the preview exactly?[#](#how-long-is-the-preview-exactly) The `body` and `body_html` are cut to the **first 200 characters**. After the cut, APITube appends `...(+N chars hidden)` — where `N` is the number of characters it removed — followed by the marker `...[Upgrade subscription plan]` (or the test-mode marker on a test key). ## Do exports and streams truncate content too?[#](#do-exports-and-streams-truncate-content-too) Yes. The same rule applies everywhere: search endpoints, retrieval endpoints, exports (CSV, RSS and so on) and real-time [SSE](/en/articles/getting-started/glossary#sse-stream) streams all return the trimmed preview when the key is on the free plan or is a test key. Switching to a live key on a paid plan returns full content across all of them. * * * ## Related Articles * [What's Included in the Free Plan?](/en/articles/billing/plans/free-plan-limits) * [Compare APITube Plans: Pricing and Limits by Tier](/en/articles/billing/plans/compare-plans) * [Why Are My Results Masked or Placeholder Text?](/en/articles/troubleshooting/masked-results) --- ## Where to Find Your Invoices and Billing History URL: https://support.apitube.io/en/articles/billing/subscription/billing-history Find your APITube billing history on the Subscription page in the dashboard, and download invoices and receipts from the Manage billing button. # Where to Find Your Invoices and Billing History See your past APITube orders in the dashboard and download invoices from the LemonSqueezy customer portal ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 4, 2026 # Where to find your invoices and billing history[#](#where-to-find-your-invoices-and-billing-history) Your APITube **billing history** lives on the **Subscription** page in your dashboard — a table of your recent orders showing the **date**, **description**, **amount** and **status** of each payment. To download an actual **invoice or receipt**, or to update your payment method, use the **Manage billing** button on that same page: it opens the **LemonSqueezy customer portal**, since LemonSqueezy is the payment provider that processes APITube subscriptions and top-ups. Billing is tied to the [workspace](/en/articles/getting-started/glossary#workspace) owner, so only the owner sees these details. ## Where is my billing history in the dashboard?[#](#where-is-my-billing-history-in-the-dashboard) Open the **Subscription** page in your APITube dashboard. Below the **Current plan** card you will find a **Billing history** table with four columns: * **Date** — when the order was created. * **Description** — what the order was for (the product name, such as your plan or a [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) top-up). * **Amount** — the charge, shown in US dollars (for example, `$99`). * **Status** — the state of the payment, shown as a coloured badge. The table lists your **25 most recent orders, newest first**, and covers both subscription payments and [pay-as-you-go top-ups](/en/articles/billing/pay-as-you-go/top-up-balance) — each top-up is an order and appears as its own row. If you have never paid — for example on the Free plan — the table shows **“No billing history yet”** instead. ## Where do I download invoices and receipts?[#](#where-do-i-download-invoices-and-receipts) The dashboard table is a summary of your orders; the downloadable **invoices, receipts and payment-method settings** live in the **LemonSqueezy customer portal**. On the **Subscription** page, click **Manage billing**. APITube looks up your subscription and redirects you to LemonSqueezy’s customer portal for that subscription, where you can download past invoices and receipts and update the card on file. **Manage billing** only works when you have an **active paid subscription**. On the Free plan — or before any subscription exists — there is no portal to open, so the button is not shown. To start a subscription and unlock invoices, pick a paid plan (see [which APITube plan is right for me](/en/articles/getting-started/which-plan-is-right)). ## What do the billing statuses mean?[#](#what-do-the-billing-statuses-mean) Each row in **Billing history** carries a status badge that tells you where the payment stands: * **Completed** / **Paid** (green) — the payment went through successfully; this is what you see for a normal, settled order. * **Pending** (amber) — the payment is still being processed and has not settled yet. * **Cancelled** / **Failed** (red) — the order did not complete, either because it was cancelled or the charge failed. A green badge is the one to look for on a paid plan or a top-up. If a charge sits on **Pending** for a long time or shows **Failed**, open **Manage billing** to check the card on file in the LemonSqueezy portal. ## Why can’t I see billing history or invoices?[#](#why-cant-i-see-billing-history-or-invoices) Two things gate access to billing: * **You are not the workspace owner.** In a shared workspace, quota, subscription and billing all belong to the **owner**. If you are a member, admin or viewer, the Subscription page shows **“Billing is managed by the workspace owner”** and hides the history and buttons. Ask the owner for a copy of an invoice, or switch to your own personal workspace to see your own billing. * **You have no paid orders yet.** On the Free plan there are no orders, so the history is empty and there is no customer portal. Both the history rows and the **Manage billing** button appear only once you have subscribed or topped up. The APITube dashboard reads your plan and orders from the account database, but every billing _action_ — checkout, top-up, cancellation and invoice download — happens in LemonSqueezy. So the dashboard is where you **see** your billing, and the LemonSqueezy customer portal (reached via **Manage billing**) is where you **manage** it. # Common Questions[#](#common-questions) * [How many orders does billing history show?](#how-many-orders-does-billing-history-show) * [Can I get a PDF invoice?](#can-i-get-a-pdf-invoice) * [Why is the Manage billing button missing?](#why-is-the-manage-billing-button-missing) * [Do pay-as-you-go top-ups show up in billing history?](#do-pay-as-you-go-top-ups-show-up-in-billing-history) ## How many orders does billing history show?[#](#how-many-orders-does-billing-history-show) The Billing history table on the Subscription page shows your **25 most recent orders**, with the newest at the top. Each row is a single order — a plan payment or a pay-as-you-go top-up — with its date, description, amount and status. ## Can I get a PDF invoice?[#](#can-i-get-a-pdf-invoice) Yes. The dashboard shows the summary; the downloadable invoice or receipt is in the **LemonSqueezy customer portal**. Click **Manage billing** on the Subscription page to open the portal for your subscription, then download the invoice or receipt for the order you need. This requires an active paid subscription. ## Why is the Manage billing button missing?[#](#why-is-the-manage-billing-button-missing) Because it appears only when you have an **active paid subscription** _and_ you are the **workspace owner**. On the Free plan there is no subscription to manage, so no portal exists. As a non-owner member, billing is handled by the owner, and the Subscription page tells you so instead of showing the button. ## Do pay-as-you-go top-ups show up in billing history?[#](#do-pay-as-you-go-top-ups-show-up-in-billing-history) Yes. A [pay-as-you-go](/en/articles/billing/pay-as-you-go/what-is-payg) top-up is recorded as an order, so it appears in the Billing history table as its own row alongside your subscription payments, with its own amount and status. * * * ## Related Articles * [Which APITube plan is right for me?](/en/articles/getting-started/which-plan-is-right) * [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) * [How to top up your balance](/en/articles/billing/pay-as-you-go/top-up-balance) --- ## How to Cancel Your Subscription URL: https://support.apitube.io/en/articles/billing/subscription/cancel-subscription Cancel your APITube subscription from the Subscription page in the dashboard. Only the workspace owner can cancel; your account and API key return to the Free… # How to Cancel Your Subscription Cancel from the Subscription page in your dashboard — only the workspace owner can, and your account returns to the Free plan ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 4, 2026 # How to cancel your subscription[#](#how-to-cancel-your-subscription) Cancel your APITube subscription from the **Subscription** page in your dashboard: open it, and on the **Current plan** card select **Cancel**. Cancellation is processed through **LemonSqueezy** (the payment provider) and takes effect right away — your account and your [API key](/en/articles/getting-started/glossary#api-key) return to the **Free plan**, so no further charges are made. Only the **[workspace](/en/articles/getting-started/glossary#workspace) owner** can cancel; members see a note that billing is handled by the owner. The **Cancel** button appears only when you have an **active paid subscription** and you are the owner. On the Free plan there is nothing to cancel, so the button is not shown. ## Where is the cancel button?[#](#where-is-the-cancel-button) Open the **Subscription** page in your dashboard. At the top is the **Current plan** card, showing your plan badge and, for an active subscription, when it **renews**. When you are the workspace owner with an active paid plan, that card shows two buttons: * **Manage billing** — opens the LemonSqueezy customer portal for your subscription (update your card, download invoices and receipts). See [where to find your invoices and billing history](/en/articles/billing/subscription/billing-history). * **Cancel** — ends your paid subscription. Selecting **Cancel** sends the request to APITube’s billing service, which cancels the subscription in LemonSqueezy and returns you to the Subscription page with a confirmation. There is no separate API call to cancel — cancellation is a dashboard action, not a News API endpoint. ## What happens after you cancel?[#](#what-happens-after-you-cancel) Cancelling does several things at once, all handled for you: * Your subscription is marked **cancelled** and the cancellation time is recorded. * Your **account plan** and your **API key** are moved to the **Free plan**, so free-plan limits and the content preview now apply. See [what’s included in the free plan](/en/articles/billing/plans/free-plan-limits) for exactly what changes — smaller request pool, a 5-page cap, and truncated article bodies. * Your **email notification** subscriptions are turned off. * No further subscription charges are made through LemonSqueezy. Because your key drops to the Free plan, article `body`, `body_html` and `description` come back as a preview tagged `...[Upgrade subscription plan]` rather than in full. Your key keeps working — it just returns free-plan responses from that point on. ## Who is allowed to cancel?[#](#who-is-allowed-to-cancel) Only the **workspace owner** can cancel, because the subscription, quota and billing all belong to the owner. If you are a member, admin or viewer of a shared workspace, the Subscription page shows **“Billing is managed by the workspace owner”** and hides the Cancel and Manage billing buttons. To cancel a workspace’s plan, the owner has to do it from their own account. Your personal workspace has its own owner (you), so you can always cancel a subscription you started there. ## How do you resubscribe after cancelling?[#](#how-do-you-resubscribe-after-cancelling) Resubscribing is self-service. After you cancel, the Subscription page still shows the full plan list below the Current plan card. Pick a plan there to start a new checkout through LemonSqueezy, and your account and API key move back onto that paid plan once payment completes. There is no waiting period — you can subscribe again immediately, and you can also switch plans this way at any time. # Common Questions[#](#common-questions) * [Does cancelling delete my account or API key?](#does-cancelling-delete-my-account-or-api-key) * [Do I keep paid access until the end of the billing period?](#do-i-keep-paid-access-until-the-end-of-the-billing-period) * [Can I cancel through the API?](#can-i-cancel-through-the-api) * [Why don’t I see a Cancel button?](#why-dont-i-see-a-cancel-button) ## Does cancelling delete my account or API key?[#](#does-cancelling-delete-my-account-or-api-key) No. Cancelling only ends the **paid subscription**. Your account stays, and your API key keeps working — it is simply downgraded to the Free plan, so it returns free-plan responses (a smaller request pool and preview-length article content). To remove the key itself you would revoke it separately in **API Keys**; cancelling the subscription does not delete it. ## Do I keep paid access until the end of the billing period?[#](#do-i-keep-paid-access-until-the-end-of-the-billing-period) When you cancel, APITube moves your account and API key to the **Free plan** as part of the cancellation, so your key starts returning free-plan responses. Cancellation also stops future charges through LemonSqueezy. If you need full article content again, resubscribe from the plan list on the Subscription page. ## Can I cancel through the API?[#](#can-i-cancel-through-the-api) No. There is no News API endpoint to cancel a subscription — cancellation is a **billing action** in the dashboard, handled through LemonSqueezy, not part of the News API. Use the **Cancel** button on the Subscription page (or the LemonSqueezy customer portal reached via **Manage billing**). ## Why don’t I see a Cancel button?[#](#why-dont-i-see-a-cancel-button) The Cancel button shows only when two things are true: you have an **active paid subscription**, and you are the **workspace owner**. On the Free plan there is no subscription to cancel, so nothing is shown. As a non-owner in a shared workspace, billing is handled by the owner, and the page tells you so instead of showing the button. * * * ## Related Articles * [Where to Find Your Invoices and Billing History](/en/articles/billing/subscription/billing-history) * [What's Included in the Free Plan?](/en/articles/billing/plans/free-plan-limits) * [Which APITube plan is right for me?](/en/articles/getting-started/which-plan-is-right) --- ## Subscription URL: https://support.apitube.io/en/articles/billing/subscription Manage your APITube subscription: change or cancel your plan through LemonSqueezy, and find your billing history, invoices and receipts. ![](/images/collections/account-billing.svg) # Subscription Change or cancel your plan; find invoices. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Brian 1 author 3 articles * [How to Cancel Your Subscription](/en/articles/billing/subscription/cancel-subscription) * [How to Upgrade or Downgrade Your APITube Plan](/en/articles/billing/subscription/upgrade-downgrade) * [Where to Find Your Invoices and Billing History](/en/articles/billing/subscription/billing-history) --- ## How to Upgrade or Downgrade Your APITube Plan URL: https://support.apitube.io/en/articles/billing/subscription/upgrade-downgrade Change your APITube plan on the Subscription page: pick Starter, Basic, Professional or Corporate, monthly or yearly, and check out in LemonSqueezy. # How to Upgrade or Downgrade Your APITube Plan Change between the Free, Starter, Basic, Professional and Corporate tiers from the Subscription page in your dashboard ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 11, 2026 Updated August 9, 2026 # How to upgrade or downgrade your APITube plan[#](#how-to-upgrade-or-downgrade-your-apitube-plan) To change your APITube plan, open the **Subscription** page in your dashboard, pick the tier you want on one of the pricing cards, and click its button. A higher tier shows **Upgrade to {plan}**, a lower one shows **Downgrade to {plan}**, and your current tier is shown as a disabled **Current plan** button. Clicking a plan sends you to the **LemonSqueezy** checkout to complete the change. Only the **[workspace](/en/articles/getting-started/glossary#workspace) owner** can switch plans. APITube has five tiers — **Free** ($0), **Starter** ($29), **Basic** ($99), **Professional** ($199) and **Corporate** ($599) per month — and each one sets your request quota, streaming credits, concurrent stream limit and [webhook](/en/articles/getting-started/glossary#webhook) limit. Moving between them is how you get more (or fewer) of those allowances. ## How do I change my plan in the dashboard?[#](#how-do-i-change-my-plan-in-the-dashboard) The plan change lives entirely on the **Subscription** page: 1. Open the **Subscription** page from the dashboard sidebar. The **Current plan** card at the top shows your active tier. 2. Scroll to the pricing cards. Four paid tiers are shown as cards — **Starter**, **Basic**, **Professional** and **Corporate** — each with its price and a button. 3. Click the button on the tier you want. Your current tier’s button is disabled and labelled **Current plan**, so you can only pick a different one. 4. You are taken to the **LemonSqueezy** checkout to enter or confirm payment. LemonSqueezy is the payment provider that processes APITube subscriptions, so every checkout and cancellation happens there, not inside the dashboard. ![The Subscription page with the current plan banner and the paid pricing cards](/images/article/dashboard-subscription.png) Once the payment is processed, your plan updates and the **Current plan** card reflects the new tier. When a paid subscription is active, the card also shows a **Renews {date}** line so you know when the next billing cycle starts. ## What is the difference between upgrade and downgrade?[#](#what-is-the-difference-between-upgrade-and-downgrade) The button label depends on where the tier you pick sits relative to your current one. APITube orders tiers **Free → Starter → Basic → Professional → Corporate**. Picking a tier **above** your current one shows **Upgrade to {plan}** (for example, `Upgrade to Professional`); picking one **below** shows **Downgrade to {plan}** (for example, `Downgrade to Starter`). If you are on Free, every paid tier counts as an upgrade. Both directions go through the same LemonSqueezy checkout — the label just tells you whether you are moving up or down the ladder. Use an upgrade when you are hitting your request or streaming limits and a downgrade when a smaller tier covers your usage. To see exactly what each tier includes before you decide, read [compare APITube plans](/en/articles/billing/plans/compare-plans) or [which APITube plan is right for me](/en/articles/getting-started/which-plan-is-right). ## Should I pick monthly or yearly billing?[#](#should-i-pick-monthly-or-yearly-billing) Above the pricing cards is a **Monthly / Yearly** toggle. Switch it before you click a plan to choose the billing cycle: * **Monthly** — you are billed each month at the monthly price ($29 Starter, $99 Basic, $199 Professional, $599 Corporate). * **Yearly** — you are billed once a year, and the annual price works out lower than paying month by month ($279 Starter, $959 Basic, $1,919 Professional, $4,999 Corporate per year). The toggle changes which product the plan button points at, so make sure it is set the way you want before checkout. A yearly plan is the cheaper choice if you know you will use APITube for the whole year. ## What changes when I switch plans?[#](#what-changes-when-i-switch-plans) Your plan sets four allowances, so switching tiers moves all of them at once: * **Request quota** — the number of API requests per cycle (100 per day on Free, 10,000 on Starter, 50,000 on Basic, 150,000 on Professional, 300,000 on Corporate). * **Streaming credits** — a separate allowance for the [SSE](/en/articles/getting-started/glossary#sse-stream) stream. * **Concurrent streams** — how many live streams you can hold open at the same time. * **Webhook limit** — how many webhooks you can create (1 on Free, up to 100 on Corporate). The new tier’s allowances are the ones listed for it, so an upgrade raises every limit and a downgrade lowers them. The dashboard reads your current plan and orders from your account, so the **Subscription** page always shows your live tier and renewal date after a change settles. ## Who can upgrade or downgrade the plan?[#](#who-can-upgrade-or-downgrade-the-plan) Only the **workspace owner** can change the plan. In APITube, quota, subscription and billing all belong to the workspace owner and are shared across that owner’s workspaces, so the pricing cards and billing buttons appear only for the owner. If you are a member, admin or viewer, the Subscription page shows **“Billing is managed by the workspace owner”** instead of the plan options. Ask the owner to make the change, or switch to your own personal workspace where you are the owner. ## How do I move to a lower plan or cancel?[#](#how-do-i-move-to-a-lower-plan-or-cancel) To move to a smaller **paid** tier, just pick that lower card — it shows **Downgrade to {plan}** and goes through checkout like any other change. Dropping all the way to **Free** is different: Free is not something you buy, so there is no Free card to click. Instead, when you have an active paid subscription the Subscription page shows a **Cancel** button (next to **Manage billing**); cancelling ends the paid subscription and returns you to the free tier. Both buttons hand off to LemonSqueezy, where the actual cancellation and payment-method changes happen. The dashboard is where you **see** and start a plan change; the LemonSqueezy customer portal (reached via **Manage billing**) is where you download invoices and manage the card on file. See [where to find your invoices and billing history](/en/articles/billing/subscription/billing-history) for that side of billing. # Common Questions[#](#common-questions) * [Can a team member change the workspace plan?](#who-can-upgrade-or-downgrade-the-plan) * [Where does checkout actually happen?](#how-do-i-change-my-plan-in-the-dashboard) * [Is yearly billing cheaper than monthly?](#should-i-pick-monthly-or-yearly-billing) * [How do I go back to the free plan?](#how-do-i-move-to-a-lower-plan-or-cancel) ## Can a team member change the workspace plan?[#](#can-a-team-member-change-the-workspace-plan) No. Changing the plan is limited to the **workspace owner**, because subscription and billing belong to the owner and are shared across their workspaces. A member, admin or viewer sees “Billing is managed by the workspace owner” on the Subscription page and cannot open the pricing cards. The owner has to perform the upgrade or downgrade. ## Where does checkout actually happen?[#](#where-does-checkout-actually-happen) Inside **LemonSqueezy**, the payment provider for APITube. The dashboard shows your current plan and the pricing cards, but clicking a plan hands you off to the LemonSqueezy checkout to complete payment. Cancellations and payment-method updates happen there too — the dashboard is where you view billing and start actions, LemonSqueezy is where they are processed. ## Is yearly billing cheaper than monthly?[#](#is-yearly-billing-cheaper-than-monthly) Yes. A yearly plan is billed once a year for less than twelve monthly payments would total — for example Starter is $29/month or $279/year, and Basic is $99/month or $959/year. Set the **Monthly / Yearly** toggle to **Yearly** before you click a plan to choose the annual price. ## How do I go back to the free plan?[#](#how-do-i-go-back-to-the-free-plan) There is no Free card to buy, so returning to Free means **cancelling** your paid subscription. With an active subscription, use the **Cancel** button on the Subscription page (shown next to **Manage billing**); it takes you to LemonSqueezy to cancel. After cancellation your account returns to the free tier and its limits. * * * ## Related Articles * [Compare APITube Plans: Pricing and Limits by Tier](/en/articles/billing/plans/compare-plans) * [Which APITube plan is right for me?](/en/articles/getting-started/which-plan-is-right) * [Where to find your invoices and billing history](/en/articles/billing/subscription/billing-history) --- ## How to Export News to CSV or Excel URL: https://support.apitube.io/en/articles/delivery-and-export/export/export-csv-excel Add export=csv or export=xlsx to any APITube News API search to download results as a spreadsheet — the same filtered articles, one row each, 29 columns,… # How to Export News to CSV or Excel Add export=csv or export=xlsx to any /v1/news/everything search to download a spreadsheet ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=tesla&export=csv) # How to export news to CSV or Excel[#](#how-to-export-news-to-csv-or-excel) To export APITube News API results to CSV or Excel, add `export=csv` or `export=xlsx` to your request to `/v1/news/everything`. Instead of the usual JSON, the API returns a spreadsheet file built from the **same articles your filters select** — one row per article and 29 fixed columns — so you can open it directly in Excel, Google Sheets or Numbers. ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&export=csv&api_key=YOUR_API_KEY" -o results.csv ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter. The `-o results.csv` flag saves the download to a file, because the response is served as an attachment. ## How to export search results to CSV[#](#how-to-export-search-results-to-csv) Add `export=csv` to any `/v1/news/everything` search. The API responds with `Content-Type: text/csv; charset=utf-8` and `Content-Disposition: attachment; filename="results.csv"`, so a browser downloads it as a file rather than displaying it. The first row holds the column headers; every matching article becomes one comma-separated row below it. Because the export runs **after** your normal search, the file contains exactly the articles your query returns — every filter still applies. Combine keywords, language and date filters, then add `export=csv` at the end: ``` curl "https://api.apitube.io/v1/news/everything?title=electric vehicle&language.code=en&export=csv&api_key=YOUR_API_KEY" -o ev_news.csv ``` This produces a CSV of English-language headlines about electric vehicles, ready to open in any spreadsheet tool. ## How to export to Excel (XLSX)[#](#how-to-export-to-excel-xlsx) To get a native Excel workbook instead of plain text, use `export=xlsx`. The API returns a real `.xlsx` file (`Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`, `filename="results.xlsx"`) with a single worksheet named **Articles**. This is the format to use when you want formatting, filtering and pivot tables in Excel without an import step: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&export=xlsx&api_key=YOUR_API_KEY" -o financial_news.xlsx ``` A tab-separated variant is also available with `export=tsv` (`Content-Type: text/tab-separated-values`, `filename="results.tsv"`), which is handy when your article fields already contain commas. ## What columns are in the exported file?[#](#what-columns-are-in-the-exported-file) CSV, XLSX and TSV all share the same 29 columns, in this order: `ID`, `Href`, `PublishedAT`, `Title`, `Description`, `Body`, `Language`, `Author`, `Image`, `Categories`, `Topics`, `Industries`, `Entities`, `Source`, `Sentiment`, `Summary`, `Keywords`, `Links`, `Media`, `Story`, `IsDuplicate`, `IsAccessibleForFree`, `IsBreaking`, `ReadTime`, `SentencesCount`, `ParagraphsCount`, `WordsCount`, `CharactersCount` and `Translations` (the English machine translation of the title and description). Simple values (title, language, read time) appear as plain text or numbers. Nested fields that are objects or lists in JSON — `Categories`, `Topics`, `Industries`, `Entities`, `Sentiment`, `Media`, `Links` and `Keywords` — are serialized as JSON strings inside a single cell, so no data is lost when the article is flattened into a row. ## Which endpoints support CSV and Excel export?[#](#which-endpoints-support-csv-and-excel-export) The `export` parameter works on the article-returning news endpoints, not just `everything`. You can add `export=csv` or `export=xlsx` to `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/local`, `/v1/news/story/:id`, `/v1/news/article`, `/v1/news/entity`, `/v1/news/category`, `/v1/news/topic` and `/v1/news/industry`. The same filters and the same 29-column layout apply on each one. ## How to control how many rows you get[#](#how-to-control-how-many-rows-you-get) Each request exports the current page of results, so use `page` and `per_page` to control the file size. One request returns up to **250** rows — **50** on the Starter plan (`per_page` max 250, or 200 on Basic, 50 on Starter and 10 on Free); asking for more returns HTTP 400 with error `ER0171` (“Limit is out of range. Your plan allows up to N results per page.”). The default is 100 rows per page. To pull a larger dataset, raise `per_page` toward the limit and page through the results: ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&per_page=250&page=2&export=csv&api_key=YOUR_API_KEY" -o results_page2.csv ``` For the full rules on `page` and `per_page`, see [How to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). The canonical parameter list is in the [official News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is CSV or XLSX export available on every plan?](#is-csv-or-xlsx-export-available-on-every-plan) * [How does export interact with field selection (fl)?](#how-does-export-interact-with-field-selection-fl) * [What other export formats are available?](#what-other-export-formats-are-available) * [What happens if I pass an unknown export value?](#what-happens-if-i-pass-an-unknown-export-value) ## Is CSV or XLSX export available on every plan?[#](#is-csv-or-xlsx-export-available-on-every-plan) Yes. Export is a formatting step applied to whatever your search already returns — it is not a separate paid feature. The export request counts as one normal request against your quota, exactly like the JSON version of the same search. ## How does export interact with field selection (fl)?[#](#how-does-export-interact-with-field-selection-fl) Field selection runs before the export step. If you also pass an `fl` parameter to narrow the fields returned, the spreadsheet still has all 29 columns, but the columns you excluded come through empty. To get a fully populated file, run the export without `fl`. ## What other export formats are available?[#](#what-other-export-formats-are-available) Alongside `csv`, `xlsx` and `tsv`, the `export` parameter accepts `rss`, `xml`, `jsonl` (with the alias `ndjson`) and `parquet`. To turn a search into a subscribable feed instead of a download, see [How to turn a news search into an RSS feed](/en/articles/delivery-and-export/export/export-rss). Omit `export`, or set `export=json`, to get the default JSON response. ## What happens if I pass an unknown export value?[#](#what-happens-if-i-pass-an-unknown-export-value) An unrecognized `export` value is ignored and the API falls back to the standard JSON response. Only the documented formats (`csv`, `tsv`, `xml`, `rss`, `xlsx`, `jsonl`/`ndjson`, `parquet`) change the output; anything else returns JSON. * * * ## Related Articles * [How to Turn a News Search into an RSS Feed](/en/articles/delivery-and-export/export/export-rss) * [How to Paginate Through Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## How to Export News for Data Pipelines (JSONL, Parquet) URL: https://support.apitube.io/en/articles/delivery-and-export/export/export-data-pipelines Use export=jsonl or export=parquet on any APITube News API search to pull results into a data pipeline — line-delimited JSON or a typed columnar Parquet file. # How to Export News for Data Pipelines (JSONL, Parquet) Use export=jsonl or export=parquet to load APITube News API results into a data pipeline ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington August 23, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=tesla&export=jsonl) # How to export news for data pipelines (JSONL, Parquet)[#](#how-to-export-news-for-data-pipelines-jsonl-parquet) To load APITube News API results into a data pipeline, add `export=jsonl` for line-delimited JSON or `export=parquet` for a typed columnar Parquet file. Both run on top of any `/v1/news/everything` search, so the file contains exactly the articles your filters select — ready to stream into a warehouse, lake, or dataframe instead of parsing a paginated JSON response. ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&export=jsonl&api_key=YOUR_API_KEY" -o results.jsonl ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter. The `-o` flag saves the download to a file, because both formats are served as attachments. ## How do I export to JSONL (JSON Lines)?[#](#how-do-i-export-to-jsonl-json-lines) Add `export=jsonl` to your search. The API responds with `Content-Type: application/x-ndjson` and the filename `results.jsonl`, and writes **one full article object per line**, separated by newlines. Each line is the same complete, nested article you get inside the `results` array of a normal JSON response — nothing is flattened or dropped — so JSONL is the format to use when you want the full structure, not a spreadsheet-style table. ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&export=jsonl&api_key=YOUR_API_KEY" -o news.jsonl ``` The alias `export=ndjson` produces the exact same output. Line-delimited JSON streams cleanly into tools like `jq`, and loads directly into BigQuery, Snowflake, and most log/ETL systems that expect one JSON record per line. ## How do I export to Parquet?[#](#how-do-i-export-to-parquet) Use `export=parquet` to get a compact, columnar binary file. The API responds with `Content-Type: application/octet-stream` and the filename `results.parquet`. Unlike JSONL, Parquet uses a **fixed, typed schema** of 29 columns: text fields are stored as strings, the flags `is_duplicate`, `is_free`, and `is_breaking` as booleans, and `read_time`, `sentences_count`, `paragraphs_count`, `words_count`, and `characters_count` as `int64`. Two columns surprise people: `id` and `published_at` are **strings**, not an integer and a timestamp — cast them yourself after loading if your query engine needs the native types. Column names are snake\_case here (`published_at`, `is_free`), unlike the CSV/XLSX headers, which are capitalised (`PublishedAT`, `IsAccessibleForFree`). ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&export=parquet&api_key=YOUR_API_KEY" -o financial_news.parquet ``` Nested fields — `categories`, `topics`, `industries`, `entities`, `sentiment`, `media`, `links`, and `keywords` — are stored as JSON strings inside their column, so the structure survives the conversion. Parquet loads natively into pandas, DuckDB, Apache Spark, and lakehouse engines like Athena, where the typed columns and column pruning make analytical queries fast. ## JSONL vs Parquet: which should I use?[#](#jsonl-vs-parquet-which-should-i-use) Pick JSONL when you want the **full nested article** record per line and a format that streams and appends easily — log pipelines, BigQuery/Snowflake line-delimited loads, or quick `jq` filtering. Pick Parquet when you want a **typed, columnar** file for analytics and storage — smaller on disk, fast to scan one column at a time, and a first-class citizen in data-lake and dataframe tooling. Both reflect the same filtered search; only the shape on disk differs. For a flat spreadsheet instead, see [how to export news to CSV or Excel](/en/articles/delivery-and-export/export/export-csv-excel). ## How many articles does one export return?[#](#how-many-articles-does-one-export-return) Each request exports the **current page** of results, because the export runs after your normal search and [pagination](/en/articles/getting-started/glossary#pagination). Use `page` and `per_page` to control the file size. One request returns up to **250** records — **50** on the Starter plan (`per_page` max 250, or 200 on Basic, 50 on Starter and 10 on Free); asking for more returns HTTP 400 with error `ER0171`. The default page size is 100. ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&per_page=250&page=2&export=jsonl&api_key=YOUR_API_KEY" -o news_page2.jsonl ``` To build a larger dataset, page through the results (`page=1`, `page=2`, …) and append each export to your pipeline. For the full rules on `page` and `per_page`, see [how to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). Each request — exported or not — counts as a single request against your plan. # Common Questions[#](#common-questions) * [Which endpoints support JSONL and Parquet export?](#which-endpoints-support-jsonl-and-parquet-export) * [What is the difference between jsonl and ndjson?](#what-is-the-difference-between-jsonl-and-ndjson) * [Does the export keep nested fields like entities and sentiment?](#does-the-export-keep-nested-fields-like-entities-and-sentiment) * [What other export formats are available?](#what-other-export-formats-are-available) ## Which endpoints support JSONL and Parquet export?[#](#which-endpoints-support-jsonl-and-parquet-export) The `export` parameter works on the article-returning news endpoints: `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/local`, `/v1/news/story`, `/v1/news/article`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry`, and `/v1/news/entity`. The aggregate endpoints `/v1/news/count` and `/v1/news/trends` return JSON only. The same filters apply on each. The canonical list is in the [official News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## What is the difference between jsonl and ndjson?[#](#what-is-the-difference-between-jsonl-and-ndjson) There is no difference in output. `export=jsonl` and `export=ndjson` are aliases that produce the identical line-delimited JSON file (`Content-Type: application/x-ndjson`). Use whichever name your tooling expects. ## Does the export keep nested fields like entities and sentiment?[#](#does-the-export-keep-nested-fields-like-entities-and-sentiment) Yes, but differently per format. JSONL keeps every field as a real nested JSON object on each line. Parquet keeps the same fields, but nested ones (`entities`, `categories`, `sentiment`, `media`, and similar) are stored as JSON strings inside their column, so you parse that string after loading. ## What other export formats are available?[#](#what-other-export-formats-are-available) Alongside `jsonl` (alias `ndjson`) and `parquet`, the `export` parameter accepts `csv`, `xlsx`, `tsv`, `xml`, and `rss`. Omit `export`, or set `export=json`, to get the default JSON response. * * * ## Related Articles * [How to Export News to CSV or Excel](/en/articles/delivery-and-export/export/export-csv-excel) * [How to Paginate Through Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## How to Export a Dataset of Articles from the Dashboard URL: https://support.apitube.io/en/articles/delivery-and-export/export/export-dataset-dashboard Datasets in the APITube dashboard export up to 1,000,000 articles to JSONL, CSV or Parquet for a flat 1,000 requests. Basic plan and above, file kept 7 days. # How to Export a Dataset of Articles from the Dashboard Bulk-export up to 1,000,000 articles to JSONL, CSV or Parquet for a flat 1,000 requests — without writing a single API call ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn September 3, 2026 # How to export a dataset of articles from the dashboard[#](#how-to-export-a-dataset-of-articles-from-the-dashboard) Open **Datasets** in the dashboard sidebar, pick a date range and filters, check the article count, and click **Create dataset** — a background worker collects every matching article into one gzip-compressed JSONL, CSV or Parquet file that you download from the same page. One dataset costs a flat **1,000 requests** regardless of size (up to 1,000,000 articles), is available on the **Basic plan and above**, and the finished file stays downloadable for **7 days**. Datasets are included from the **Basic** plan. On Free and Starter the Datasets page is visible, but the export cannot be queued — the page shows an upgrade notice instead of the form. ![The Datasets page of the APITube dashboard: the Datasets entry in the Develop section of the sidebar, a note that files are kept for 7 days and one dataset costs 1,000 requests, and a table of finished exports with format, status, article count and expiry date](/images/article/dashboard-datasets-page.png) ## What is a dataset export?[#](#what-is-a-dataset-export) A dataset export is the bulk version of the `export` parameter described in [What export formats are available?](/en/articles/delivery-and-export/export/export-formats-overview). A single API request returns at most one page of results, so collecting a whole month of articles means paging through the archive yourself and stitching the files together. The Datasets page does that for you: it walks the archive in `published_at` order, writes every article once, and hands you one file. The rows are the same article objects the `/v1/news/everything` endpoint returns — every field, including [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment), categories and translations. ## How do I create a dataset?[#](#how-do-i-create-a-dataset) 1. Open **Datasets** in the **Develop** section of the sidebar and click **Create dataset**. 2. Give the export a **name** (optional — the date range is used when you leave it empty) and choose a **format**: JSONL, CSV or Parquet. 3. Pick the **date range**. It applies to the article’s published date in UTC and can span up to **366 days**. 4. Add **filters** if you need a subset — the builder offers the same filters as `/v1/news/everything`: title keywords, language, category, country, source domain, sentiment and the advanced ones. Leave everything empty to export the whole range. 5. Watch the **Price & estimate** card on the right. The article count recalculates on its own a moment after every change, and the card tells you how the flat price will be paid. 6. Optionally click **Preview first 5 rows** to see the first articles of the future file. 7. Click **Create dataset**. The export is queued, the page switches to its detail view, and the price is charged at that moment. ![The New dataset form: a date range of March 1–6, 2026, the filter builder with title, language, category, country, source domain and sentiment fields, and the Price & estimate card showing a flat price of 1,000 requests, 4,010 matching articles and the note that the price is covered by the plan quota](/images/article/dashboard-datasets-new.png) ## How much does a dataset cost?[#](#how-much-does-a-dataset-cost) Every dataset costs **1,000 requests**, whether it holds 50 articles or 1,000,000. The charge is taken once, when you queue the export: * **From your plan quota** when at least 1,000 requests are left — the estimate card says “Covered by your quota” and shows the remaining amount. * **From your [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance** ($10.00) when the quota is short, provided the balance switch on the Pay as you go page is on and the amount fits your monthly spending limit. * If neither is possible the card says “Not enough credits” and the **Create dataset** button stays disabled until you top up or the quota resets. The pages the worker fetches while building the file are **not** billed to your account, and neither the estimate nor the preview uses your quota. If an export fails for a technical reason — the News API stops responding, the file cannot be written — the 1,000 requests are refunded automatically and the detail page shows “refunded” next to the price. Cancelling an export yourself does not refund it. ## What does the preview show?[#](#what-does-the-preview-show) **Preview first 5 rows** fetches the first five articles of the export in date order and shows their ID, published time, title, source domain and language. Under the table the page tells you how many fields a full row carries (33 at the time of writing), so you can check that the filters match what you expect before spending 1,000 requests. Change a filter and the button turns into **Refresh preview**. ![The Preview card under the form: a five-row table with article ID, published time, title, source domain and language, and the note that each row has 33 fields](/images/article/dashboard-datasets-preview.png) ## How do I follow progress and download the file?[#](#how-do-i-follow-progress-and-download-the-file) The detail page of a dataset shows its status (Queued, Running, Finalizing, Ready, Failed, Canceled or Expired), the articles collected so far against the estimate, the price paid, and a progress bar that updates while the worker runs. Exports of a few thousand articles finish within minutes; the largest ones take hours because the worker keeps a conservative request rate. When the status turns **Ready**, the **Download** button appears with the file size, a notification lands in the bell (and in your inbox), and the file stays available for 7 days — the exact expiry date is shown in the header strip. ![The detail page of a finished dataset: status Ready, format JSONL, 248 articles, price 1,000 requests from quota, a complete progress bar and the Edit & re-run, Download (1.4 MB) and Delete buttons](/images/article/dashboard-dataset-detail.png) Only **one export runs at a time per account**; while one is active the **Create dataset** button is disabled and the list page shows the active export with its progress. A running export can be cancelled from the detail page or from the actions menu of the list. A finished export can be **deleted** — that removes the file and the row. ## Which file formats are available and how are they packed?[#](#which-file-formats-are-available-and-how-are-they-packed) * **JSONL** — one JSON object per line, gzip-compressed (`.jsonl.gz`). The full article object, easiest to stream into a pipeline. * **CSV** — a flat table, gzip-compressed (`.csv.gz`), with the same columns as the API’s own CSV export: nested fields such as `source`, `entities` or `translations` are stored as JSON strings inside the cell. * **Parquet** — a columnar file (`.parquet`, compressed internally) for pandas, DuckDB and Spark, with nested fields as JSON strings. Rows are written in ascending `published_at` order, and every article appears exactly once. ## Can I edit or re-run an export?[#](#can-i-edit-or-re-run-an-export) A finished, failed or cancelled export has an **Edit & re-run** button that opens the form pre-filled with the same name, format, date range and filters, so you can adjust one thing and queue a new export. Re-running is a new order and costs another 1,000 requests. # Common Questions[#](#common-questions) * [Why is the Create dataset button disabled?](#why-is-the-create-dataset-button-disabled) * [Do title searches still have the 31-day limit?](#do-title-searches-still-have-the-31-day-limit) * [Who in my workspace can create and download datasets?](#who-in-my-workspace-can-create-and-download-datasets) * [Is the export written to the audit log?](#is-the-export-written-to-the-audit-log) ## Why is the Create dataset button disabled?[#](#why-is-the-create-dataset-button-disabled) The button unlocks only when the estimate is fresh and the order can be paid. It stays disabled while the article count is recalculating after a change, when the count exceeds the 1,000,000-article limit (narrow the range or filters), when another export of your account is still running, when your plan is below Basic, or when neither the quota nor the pay-as-you-go balance can cover 1,000 requests. ## Do title searches still have the 31-day limit?[#](#do-title-searches-still-have-the-31-day-limit) The News API limits a title or `query` search to a 31-day `published_at` window per request. A dataset can still span up to 366 days with such filters: the export splits the range into 31-day chunks automatically, and the estimate does the same. Filters that do not search the title — language, category, source domain, entities — have no such window. ## Who in my workspace can create and download datasets?[#](#who-in-my-workspace-can-create-and-download-datasets) Owners, admins and members can create exports; viewers can open the Datasets page and download finished files but cannot queue new ones. A member can cancel or delete only the exports they created; admins and the owner manage every export. The 1,000 requests are always charged to the [workspace](/en/articles/getting-started/glossary#workspace) owner’s quota or balance, exactly like regular API requests made with the workspace’s keys. ## Is the export written to the audit log?[#](#is-the-export-written-to-the-audit-log) Yes. Creating, cancelling, downloading and deleting a dataset each produce an entry in the workspace **Audit log** with the actor, the dataset name and details such as the format and the estimated article count. * * * ## Related Articles * [What Export Formats Are Available?](/en/articles/delivery-and-export/export/export-formats-overview) * [How to Export News for Data Pipelines (JSONL, Parquet)](/en/articles/delivery-and-export/export/export-data-pipelines) --- ## What Export Formats Are Available? URL: https://support.apitube.io/en/articles/delivery-and-export/export/export-formats-overview APITube News API exports results as JSON, CSV, TSV, XLSX, XML, RSS, JSONL/NDJSON or Parquet. Add the export parameter to any search to download the format you… # What Export Formats Are Available? Use the export parameter to get APITube News API results as JSON, CSV, XLSX, TSV, RSS, XML, JSONL or Parquet ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington August 23, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=tesla&export=csv) # What export formats are available?[#](#what-export-formats-are-available) The APITube News API can return your search results in **eight formats besides JSON**: CSV, TSV, XLSX, XML, RSS, JSONL, NDJSON and Parquet. You pick one by adding the `export` parameter to any article-returning request — the filters stay the same, only the output changes. Leave `export` off, or set `export=json`, and you get the default JSON response. [Export formats](/en/articles/getting-started/glossary#export-format) are a **paid-plan feature**: on a free key every format except `json` returns `403 ER0706` (`Export formats are not available on the free plan.`). `export=json` and requests without `export` behave the same on every plan. ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&export=csv&api_key=YOUR_API_KEY" -o results.csv ``` ## Which export formats does APITube support?[#](#which-export-formats-does-apitube-support) Every format below is selected with the same `export` parameter. The API sets the matching `Content-Type` and, for downloadable files, a `Content-Disposition: attachment` header so a browser saves the file instead of displaying it. `export` value Output Content-Type `json` _(default)_ Standard paginated JSON response `application/json` `csv` Comma-separated spreadsheet, `results.csv` `text/csv` `tsv` Tab-separated spreadsheet, `results.tsv` `text/tab-separated-values` `xlsx` Native Excel workbook, sheet named **Articles** `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` `xml` Nested XML document (served inline, without a `Content-Disposition` filename) `application/xml` `rss` RSS 2.0 feed you can open in a reader `application/xml` `jsonl` One JSON object per line, `results.jsonl` `application/x-ndjson` `ndjson` Alias for `jsonl` — identical output, and the download is named `results.jsonl` too `application/x-ndjson` `parquet` Typed columnar file, `results.parquet` `application/octet-stream` ## How do I change the export format?[#](#how-do-i-change-the-export-format) Add `export=` anywhere in your query string. The export step runs **after** your normal search, so the file holds exactly the articles your filters return — keywords, language, date range and any other filter still apply. Build the search you want first, then append the format: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&export=xlsx&api_key=YOUR_API_KEY" -o financial_news.xlsx ``` If you pass a value the API doesn’t recognise, it ignores it and falls back to the normal JSON response rather than erroring out. You can send the key as the `api_key` query parameter (shown above) or as an `X-API-Key` header. ## Which formats are flat, and which keep the full structure?[#](#which-formats-are-flat-and-which-keep-the-full-structure) This is the main difference to know when you choose a format: * **Flat tabular formats — `csv`, `tsv`, `xlsx`, `parquet`.** Each article becomes one row with the same **29 fixed columns** (ID, Href, PublishedAT, Title, Description, Body, Language, Author, Image, Categories, Topics, Industries, [Entities](/en/articles/getting-started/glossary#entity), Source, [Sentiment](/en/articles/getting-started/glossary#sentiment), Summary, Keywords, Links, Media, Story, IsDuplicate, IsAccessibleForFree, IsBreaking, ReadTime, SentencesCount, ParagraphsCount, WordsCount, CharactersCount, Translations). Nested objects like `source` or `entities` are written as JSON text inside their cell. Parquet additionally keeps typed columns — booleans, integers and strings — which is why it loads cleanly into data tools. * **Structured formats — `xml`, `jsonl`, `ndjson`.** These keep the full nested article shape. `jsonl`/`ndjson` write one complete JSON object per line, so you can stream the file line by line; `xml` mirrors the same nesting as the JSON response. So if you need a spreadsheet, pick `csv`, `tsv` or `xlsx`. If you need the complete enrichment (entities, per-field sentiment, links, media), pick `jsonl` or `xml`. For analytics pipelines, `parquet` keeps the data typed — see [how to export for data pipelines](/en/articles/delivery-and-export/export/export-data-pipelines). ## Which endpoints support export?[#](#which-endpoints-support-export) The `export` parameter works on the article-returning news endpoints — not only `everything`. You can add it to `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/local`, `/v1/news/story/:id`, `/v1/news/article`, `/v1/news/entity`, `/v1/news/category`, `/v1/news/topic` and `/v1/news/industry`. The same format list and column layout apply on each one. The full parameter reference lives in the [News API parameters documentation](https://docs.apitube.io/platform/news-api/everything). * * * # Common Questions[#](#common-questions) * [How many articles does one export return?](#how-many-articles-does-one-export-return) * [Does exporting cost extra requests?](#does-exporting-cost-extra-requests) * [What’s the difference between JSONL and NDJSON?](#whats-the-difference-between-jsonl-and-ndjson) * [Which format should I choose?](#which-format-should-i-choose) ## How many articles does one export return?[#](#how-many-articles-does-one-export-return) An export returns one page of results, just like a JSON search. Page size is controlled by `per_page`, which defaults to **100** and has a maximum of **250** — **200** on Basic, **50** on Starter, **10** on Free; asking for more returns a `400` error (`ER0171`, “Limit is out of range”). To export a larger result set, page through it with `page` and `per_page` and combine the files yourself: ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&per_page=250&page=2&export=csv&api_key=YOUR_API_KEY" -o results_page2.csv ``` ## Does exporting cost extra requests?[#](#does-exporting-cost-extra-requests) No. An export is the same endpoint call with one extra parameter, so it counts as a single API request — the same as the JSON search would. The format you choose does not change the cost. ## What’s the difference between JSONL and NDJSON?[#](#whats-the-difference-between-jsonl-and-ndjson) There is none. `export=ndjson` is an alias for `export=jsonl`: both produce the same line-delimited JSON output with a `Content-Type: application/x-ndjson` header. Use whichever name your tooling expects. ## Which format should I choose?[#](#which-format-should-i-choose) * **JSON** — default, best for direct API consumption in code. * **CSV / XLSX** — open in Excel, Google Sheets or Numbers without an import step. * **TSV** — same as CSV but tab-separated, useful when article fields already contain commas. * **RSS** — subscribe to a search in a feed reader; see [how to turn a search into an RSS feed](/en/articles/delivery-and-export/export/export-rss). * **XML** — nested output for systems that consume XML. * **JSONL / NDJSON / Parquet** — load into data pipelines and analytics tools. * * * ## Related Articles * [How to Export News to CSV or Excel](/en/articles/delivery-and-export/export/export-csv-excel) * [How to Export News for Data Pipelines (JSONL, Parquet)](/en/articles/delivery-and-export/export/export-data-pipelines) * [How to Turn a News Search into an RSS Feed](/en/articles/delivery-and-export/export/export-rss) --- ## How to Turn a News Search into an RSS Feed URL: https://support.apitube.io/en/articles/delivery-and-export/export/export-rss Add export=rss to any APITube News API search to get an RSS 2.0 feed you can open in a feed reader — the same filters, returned as XML instead of JSON. # How to Turn a News Search into an RSS Feed Add export=rss to any /v1/news/everything request to get a subscribable RSS 2.0 feed ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=bitcoin&export=rss) # How to turn a news search into an RSS feed[#](#how-to-turn-a-news-search-into-an-rss-feed) To turn any APITube News API search into an RSS feed, add `export=rss` to your request to `/v1/news/everything`. Instead of the usual JSON, the API returns a standard **RSS 2.0** document built from the same articles your filters select, so you can paste the URL straight into a feed reader. The feed is served with the content type `application/xml; charset=utf-8`. ``` curl "https://api.apitube.io/v1/news/everything?title=bitcoin&export=rss&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter. The request above returns Bitcoin headlines as an RSS feed rather than JSON. ## What does export=rss return?[#](#what-does-exportrss-return) `export=rss` returns an RSS 2.0 feed. The `` carries a fixed title, “APITube News Feed”, and the description “Latest news articles from APITube News API”. Each article becomes one `` with: * `` — the article headline * `<link>` and `<guid>` — the article URL * `<description>` — the article description * `<pubDate>` — the article’s publish date The response also sets `Content-Disposition: inline; filename="rss.xml"`, so a browser opens it inline and a feed reader treats it as a feed file. Because the export runs **after** your normal search, the feed contains exactly the articles your query returns — every filter still applies. ## How to build the feed from a filtered search[#](#how-to-build-the-feed-from-a-filtered-search) Any filter you can use on `/v1/news/everything` shapes the feed. Combine keywords, language, source and date filters, then add `export=rss` at the end. This produces a feed of English-language headlines about electric vehicles, excluding one keyword: ``` curl "https://api.apitube.io/v1/news/everything?title=electric vehicle&language.code=en&ignore.title=opinion&export=rss&api_key=YOUR_API_KEY" ``` You can also drive the feed with the advanced Boolean language — see [How to use AND, OR and NOT in news search](/en/articles/searching-and-filtering/keyword-search/boolean-search) — by adding a `query` parameter alongside `export=rss`. The export step does not change your filters; it only changes the output format. ## How to control how many items appear in the feed[#](#how-to-control-how-many-items-appear-in-the-feed) The feed contains the articles from the current page of results, so use `page` and `per_page` to control its size. One request returns up to **250** items — **50** on the Starter plan (`per_page` max 250, or 200 on Basic, 50 on Starter and 10 on Free); asking for more returns HTTP 400 with error `ER0171`. To pull a larger feed, raise `per_page` toward the limit or page through results and request additional pages: ``` curl "https://api.apitube.io/v1/news/everything?title=bitcoin&per_page=100&export=rss&api_key=YOUR_API_KEY" ``` For the full rules on `page` and `per_page`, see [How to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). ## How to subscribe to the feed[#](#how-to-subscribe-to-the-feed) To save the feed to a file, redirect the output: ``` curl "https://api.apitube.io/v1/news/everything?title=bitcoin&export=rss&api_key=YOUR_API_KEY" -o bitcoin.xml ``` To subscribe in a feed reader, give it the full request URL including your `api_key` and `export=rss`. The reader will poll that URL and show new matching articles as they appear. Because the key travels in the URL, treat that feed URL as a secret — anyone who has it can read your feed using your key. RSS is one of several non-JSON outputs: the same `export` parameter also accepts `csv`, `tsv`, `xml`, `xlsx`, `jsonl` (alias `ndjson`) and `parquet`. The canonical parameter list is in the [official News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Which RSS version does the feed use?](#which-rss-version-does-the-feed-use) * [Can I change the feed title or description?](#can-i-change-the-feed-title-or-description) * [Do my search filters still work with export=rss?](#do-my-search-filters-still-work-with-exportrss) * [What other export formats are available?](#what-other-export-formats-are-available) ## Which RSS version does the feed use?[#](#which-rss-version-does-the-feed-use) The feed is **RSS 2.0**, served as `application/xml; charset=utf-8` with the filename `rss.xml`. Standard feed readers and RSS libraries parse it without any special handling. ## Can I change the feed title or description?[#](#can-i-change-the-feed-title-or-description) No. The channel title (“APITube News Feed”) and description (“Latest news articles from APITube News API”) are fixed for every feed. What changes between feeds is the list of `<item>` entries, which is driven entirely by your search filters. ## Do my search filters still work with export=rss?[#](#do-my-search-filters-still-work-with-exportrss) Yes. `export=rss` only changes the output format. The search runs first with all of your filters — `title`, `language.code`, `source.*`, date ranges, `query` and the rest — and the matching articles are then rendered as RSS items, so the feed always reflects your query. ## What other export formats are available?[#](#what-other-export-formats-are-available) Alongside `rss`, the `export` parameter accepts `csv`, `tsv`, `xml`, `xlsx`, `jsonl` (with the alias `ndjson`) and `parquet`. Omit `export`, or set `export=json`, to get the default JSON response. * * * ## Related Articles * [How to Paginate Through Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) --- ## Export Formats URL: https://support.apitube.io/en/articles/delivery-and-export/export Export APITube News API results in non-JSON formats — turn any search into CSV, Excel, RSS, XML, TSV, JSONL or Parquet with the export parameter. # Export Formats Export APITube News API results in non-JSON formats — turn any search into CSV, Excel, RSS, XML, TSV, JSONL or Parquet with the export parameter. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Jacob and 1 other 2 authors 5 articles * [How to Export a Dataset of Articles from the Dashboard](/en/articles/delivery-and-export/export/export-dataset-dashboard) * [How to Export News for Data Pipelines (JSONL, Parquet)](/en/articles/delivery-and-export/export/export-data-pipelines) * [How to Export News to CSV or Excel](/en/articles/delivery-and-export/export/export-csv-excel) * [How to Turn a News Search into an RSS Feed](/en/articles/delivery-and-export/export/export-rss) * [What Export Formats Are Available?](/en/articles/delivery-and-export/export/export-formats-overview) --- ## Real-time Delivery & Export URL: https://support.apitube.io/en/articles/delivery-and-export Receive APITube news in real time and export your data — SSE and WebSocket streaming, webhooks, and CSV, RSS, JSONL and Parquet export formats. ![](/images/collections/consolidate-benchmark.png) # Real-time Delivery & Export Real-time streaming, webhooks and export formats. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Erick and 1 other 2 authors 14 articles Beyond request/response: this collection explains how to have news pushed to you or taken away in bulk. It covers real-time streaming over SSE, webhooks that deliver matching articles to your endpoint as they are indexed, and export formats for offline analysis. Streaming and webhooks suit different jobs — a stream keeps one connection open and is billed per delivered article, while webhooks fire at your server and retry on failure. Start with the streaming articles if you consume news in your own process, and the webhook ones if you want APITube to call you. ## [Export Formats](/en/articles/delivery-and-export/export) * * * * [How to Export a Dataset of Articles from the Dashboard](/en/articles/delivery-and-export/export/export-dataset-dashboard) * [How to Export News for Data Pipelines (JSONL, Parquet)](/en/articles/delivery-and-export/export/export-data-pipelines) * [How to Export News to CSV or Excel](/en/articles/delivery-and-export/export/export-csv-excel) * [How to Turn a News Search into an RSS Feed](/en/articles/delivery-and-export/export/export-rss) * [What Export Formats Are Available?](/en/articles/delivery-and-export/export/export-formats-overview) ## [Real-time Streaming](/en/articles/delivery-and-export/streaming) * * * * [How to Receive Instant Breaking-News Alerts](/en/articles/delivery-and-export/streaming/breaking-news-alerts) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Stream News over WebSocket](/en/articles/delivery-and-export/streaming/stream-with-websocket) * [Polling vs Streaming: How to Keep News Data Fresh](/en/articles/delivery-and-export/streaming/polling-vs-streaming) * [SSE vs WebSocket vs Webhooks: Which to Choose](/en/articles/delivery-and-export/streaming/choose-realtime-method) ## [Webhooks](/en/articles/delivery-and-export/webhooks) * * * * [How to Set Up a Webhook for a Saved Search](/en/articles/delivery-and-export/webhooks/set-up-webhook) * [How to Verify Webhook Signatures (HMAC)](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) * [Understanding Webhook Retries and Delivery History](/en/articles/delivery-and-export/webhooks/webhook-retries-history) * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) --- ## How to Receive Instant Breaking-News Alerts URL: https://support.apitube.io/en/articles/delivery-and-export/streaming/breaking-news-alerts Get instant breaking-news alerts from APITube: open an SSE connection to /v1/news/stream with is_breaking=1 and each breaking article is pushed live as it… # How to Receive Instant Breaking-News Alerts Open one SSE connection with is\_breaking=1 and get each breaking story pushed the moment it is published ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 # How to receive instant breaking-news alerts[#](#how-to-receive-instant-breaking-news-alerts) To get breaking news the instant it is published, open one [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) connection to `GET /v1/news/stream` and add `is_breaking=1`. APITube holds the connection open and pushes only articles flagged as breaking — you never poll a search endpoint. A single cURL command is enough to start: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?is_breaking=1" ``` The `-N` flag disables cURL buffering so each alert prints the moment it arrives. The `is_breaking=1` filter runs through the same filter chain as a normal search, so the live feed carries only breaking stories. You can pass your key as the `X-API-Key` header or as an `?api_key=` query parameter. ## What does an instant breaking-news alert look like?[#](#what-does-an-instant-breaking-news-alert-look-like) Each breaking article is pushed as a named `article` event with a unique `id:` and the full article JSON on `data:` lines — the same object you get from a search: ``` event: article id: 123456 data: {"id":123456,"title":"...","is_breaking":true,"source":{"domain":"reuters.com"},...} ``` The stream checks for new matching articles about every **30 seconds** and sends up to **50** per cycle. Between alerts, APITube writes a heartbeat comment (a line starting with `:`) about every **30 seconds** to hold the connection open — heartbeats are free and are not real events. A single connection can stay open for up to **6 hours**, after which the server sends error code `ER0362` and asks you to reconnect. The stream delivers **new** breaking articles only, not a backlog. On connect, APITube anchors to the latest matching article and then pushes everything published after that moment, so you receive each story as it breaks rather than a history dump. ## How do I scope alerts to a topic, language or place?[#](#how-do-i-scope-alerts-to-a-topic-language-or-place) Because `is_breaking` lives in the shared filter chain, it stacks with every other search filter using AND logic — append them to the same query string. This narrows the live feed to English breaking news from one source and trims each message to a few fields: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?is_breaking=1&language.code=en&source.domain=reuters.com&fl=id,title,published_at" ``` To watch breaking events around a single place, layer a geographic radius on top — here, within 100 km of central London: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?is_breaking=1&location.lat=51.5074&location.lng=-0.1278&location.radius=100" ``` `is_breaking` accepts only `0` or `1`: a non-numeric value is rejected with `400` and code `ER0185`, and any other number returns `400` with `ER0186`. For the full breaking filter and how it behaves on search, see [how to monitor breaking news and real-time events](/en/articles/searching-and-filtering/events/monitor-breaking-news). ## How do I reconnect without missing an alert?[#](#how-do-i-reconnect-without-missing-an-alert) SSE has built-in resume. Every `article` event carries an `id:`; if the connection drops, reconnect and send the last id you saw in the `Last-Event-Id` request header: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ -H "Last-Event-Id: 123456" \ "https://api.apitube.io/v1/news/stream?is_breaking=1" ``` APITube delivers any matching article published after id `123456`, then keeps streaming, so a brief network blip costs you no alerts. In the browser, the native `EventSource` API replays the last id for you automatically. For the full SSE mechanics, see [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## What does a breaking-news stream cost?[#](#what-does-a-breaking-news-stream-cost) You are billed **one credit per breaking article actually delivered** — never for the open connection and never for heartbeats. If nothing breaks that matches your filters, nothing is spent. Streaming draws from a **separate streaming-credit pool** on your account; when that pool is empty, a positive [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance is used instead. If you connect with no streaming credits and no paid balance, the server rejects the connection with `402` and code `ER0176`. If the balance runs out mid-stream, you get an `error` event with code `ER0301` and the connection closes — top up or wait for your plan credits to renew, then reconnect. # Common Questions[#](#common-questions) * [How many breaking-news streams can I run at once?](#how-many-breaking-news-streams-can-i-run-at-once) * [Does is\_breaking=1 mean the story is only minutes old?](#does-is_breaking1-mean-the-story-is-only-minutes-old) * [Can I test breaking alerts without spending credits?](#can-i-test-breaking-alerts-without-spending-credits) * [Should I use a stream or a webhook for alerts?](#should-i-use-a-stream-or-a-webhook-for-alerts) ## How many breaking-news streams can I run at once?[#](#how-many-breaking-news-streams-can-i-run-at-once) The number of simultaneous SSE connections depends on your plan. The Free plan allows **1** simultaneous connection; paid plans allow **2** on Starter, **2** on Basic, **10** on Professional, and **50** on Corporate. Opening one more than your plan allows returns `429` with code `ER0360`. Closing a stream frees its slot, so close connections you no longer need rather than leaving them idle. ## Does is\_breaking=1 mean the story is only minutes old?[#](#does-is_breaking1-mean-the-story-is-only-minutes-old) No. `is_breaking=1` filters by the breaking flag the pipeline assigns to an article, not by a time window. The stream itself only ever delivers articles published after you connect, so on the live feed every alert is genuinely new — but the flag alone is not a freshness guarantee on a normal search. ## Can I test breaking alerts without spending credits?[#](#can-i-test-breaking-alerts-without-spending-credits) Yes. A [test key](/en/articles/getting-started/glossary#test-key-and-live-key) streams live `article` events but the article content is **masked** for preview, and deliveries do **not** consume your quota. Use a test key to confirm your client connects, parses the `article` event format and handles reconnection, then switch to a live key for full content and real billing. ## Should I use a stream or a webhook for alerts?[#](#should-i-use-a-stream-or-a-webhook-for-alerts) Use the SSE stream when your client is long-lived and holds the connection open — a live dashboard or an alerting process that runs continuously. Use a [webhook](/en/articles/getting-started/glossary#webhook) when you want APITube to push alerts to your endpoint without keeping a socket open. Both deliver the same article objects and both bill per delivered article; for a side-by-side guide, see [SSE vs WebSocket vs webhooks: which to choose](/en/articles/delivery-and-export/streaming/choose-realtime-method). * * * ## Related Articles * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Monitor Breaking News and Real-Time Events](/en/articles/searching-and-filtering/events/monitor-breaking-news) * [SSE vs WebSocket vs Webhooks: Which to Choose](/en/articles/delivery-and-export/streaming/choose-realtime-method) --- ## SSE vs WebSocket vs Webhooks: Which to Choose URL: https://support.apitube.io/en/articles/delivery-and-export/streaming/choose-realtime-method Compare APITube's three real-time delivery methods — webhooks, SSE and WebSocket — by transport, reconnection and billing, and pick the right one for your app. # SSE vs WebSocket vs Webhooks: Which to Choose Pick the right real-time delivery method for new APITube articles ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 # SSE vs WebSocket vs webhooks: which to choose[#](#sse-vs-websocket-vs-webhooks-which-to-choose) Use a **[webhook](/en/articles/getting-started/glossary#webhook)** when you want APITube to push new articles to your server and you do not want to hold a connection open. Use **[SSE](/en/articles/getting-started/glossary#sse-stream)** when a long-lived client should receive a one-way stream that reconnects itself. Use **[WebSocket](/en/articles/getting-started/glossary#websocket)** when you need a two-way socket. All three deliver the same article objects in near real time and bill **one credit per article actually delivered** — the open connection, heartbeats and pings are free. The decision comes down to who holds the connection, how reconnection is handled, and which credit pool pays. The rest of this article maps each method to the job it fits, with the exact numbers from the API. ## How do the three real-time methods compare?[#](#how-do-the-three-real-time-methods-compare) Method Who holds the connection Reconnection Credit pool Webhook APITube `POST`s to your URL — no socket on your side Automatic retries; 3 consecutive failures disable it Separate webhook pool SSE Your client holds `GET /v1/news/stream` open Automatic, via the `Last-Event-Id` header Separate streaming pool WebSocket Your client holds `wss://…/v1/news/ws` open Manual — reconnect with new query params Separate WebSocket pool All three accept the **same filters** as a normal news search (language, category, source, [sentiment](/en/articles/getting-started/glossary#sentiment), [entities](/en/articles/getting-started/glossary#entity), sorting, field selection), and all three deliver **new** articles only — they anchor to the latest matching article and stream what comes after, never a history dump. For backfilling old articles you still run a normal search against `/v1/news/everything`. ## When should I use a webhook?[#](#when-should-i-use-a-webhook) Choose a webhook for server-to-server alerting where you do not want to babysit a socket. A background worker checks your active webhooks about every **10 seconds**, takes up to **100 articles** per delivery, and `POST`s them as signed JSON to your URL — so your endpoint only does work when there is something new. Each request carries an `X-Webhook-Signature: sha256=…` header you verify with your secret. Failed deliveries are retried about every **60 seconds**, and after **3 consecutive failures** APITube disables the webhook until you re-enable it. Webhooks are **created in the dashboard**, not over the API; the API only exposes `GET`, `PATCH` and `DELETE /v1/webhooks/:id` for managing ones that already exist. See [what are webhooks and how do they work](/en/articles/delivery-and-export/webhooks/what-are-webhooks) for the full delivery contract. ## When should I use SSE?[#](#when-should-i-use-sse) Choose Server-Sent Events for a long-running client that wants the simplest reconnection. Open one connection to `GET /v1/news/stream`; the server checks for matches about every **30 seconds**, sends up to **50 articles** per cycle, and keeps the line alive with a heartbeat roughly every **30 seconds**. A connection lasts up to **6 hours** before you reconnect. SSE is one-way and resumes itself: every article event carries an `id:`, and reconnecting with that value in the `Last-Event-Id` header replays anything you missed. In the browser the native `EventSource` API does this for you with no extra code, which makes SSE the easiest method to start with. Details and client snippets are in [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## When should I use WebSocket?[#](#when-should-i-use-websocket) Choose WebSocket when you need a **two-way** socket — for example to send a `ping` and get a `pong` back, or because your stack already speaks `wss`. Connect to `wss://api.apitube.io/v1/news/ws`; the 50-article batch, 30-second heartbeat and 6-hour maximum match SSE, and WebSocket polls for matches about every **10 seconds**. The difference is the transport, not the data. WebSocket has **no** `Last-Event-Id` resume: if the socket drops, you reconnect with your query parameters and resume from the latest article. A missing or invalid key closes the socket immediately with close code `1008`. The message format and keep-alive flow are covered in [how to stream news over WebSocket](/en/articles/delivery-and-export/streaming/stream-with-websocket). ## How does billing differ between them?[#](#how-does-billing-differ-between-them) Every method bills **per article actually delivered**, never per connection — but they draw from different pools, so you can run more than one at once without them competing: * **Webhooks** spend a **separate webhook credit pool**; when it is empty, a positive [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance is used instead. * **SSE** spends a **separate streaming credit pool**; when it is empty, a positive pay-as-you-go balance is used instead. With no streaming credits and no balance, the connection is rejected with HTTP `402` and code `ER0176`. * **WebSocket** spends its **own WebSocket credit pool**, again falling back to pay-as-you-go balance, and returns code `ER0404` when both are empty. Concurrent connection limits are the same for SSE and WebSocket. The Free plan allows **1** concurrent connection; paid plans allow **2** on Starter, **2** on Basic, **10** on Professional, and **50** on Corporate. Webhooks hold no socket on your side, so they have no connection limit of this kind. ## What if I only need occasional or historical articles?[#](#what-if-i-only-need-occasional-or-historical-articles) If you are not delivering in real time, skip all three and just call `/v1/news/everything` on demand. A search bills **1 credit only when it returns results** — an empty result set costs nothing — and one call returns up to 250 articles (10 on Free, 50 on Starter, 200 on Basic). Polling on a timer suits one-off lookups and backfilling history; switch to push delivery (webhook, SSE or WebSocket) only once you need new articles the moment they publish. The official [endpoints reference on docs.apitube.io](https://docs.apitube.io/platform/news-api/endpoints) lists every delivery route. # Common Questions[#](#common-questions) * [Which method is easiest to start with?](#which-method-is-easiest-to-start-with) * [Can I use more than one method at the same time?](#can-i-use-more-than-one-method-at-the-same-time) * [Do all three support the same filters?](#do-all-three-support-the-same-filters) * [Do test keys work with every method?](#do-test-keys-work-with-every-method) ## Which method is easiest to start with?[#](#which-method-is-easiest-to-start-with) SSE, because the browser `EventSource` API handles the connection and reconnection for you, and a single cURL command with `-N` shows live events in your terminal. Webhooks need a public HTTPS endpoint that returns `2xx`, and WebSocket needs a `wss` client, so both take a little more setup than SSE. ## Can I use more than one method at the same time?[#](#can-i-use-more-than-one-method-at-the-same-time) Yes. Webhooks bill from a separate webhook pool, SSE from the streaming pool, and WebSocket from the WebSocket pool — three independent pools — so a webhook and a live stream do not draw down the same balance. This lets you, for example, run dashboards over SSE while a webhook alerts a back-end service in parallel. ## Do all three support the same filters?[#](#do-all-three-support-the-same-filters) Yes. Every filter that works on a normal news search works on a webhook, an SSE stream and a WebSocket: append it to the query string (or save it on the webhook). That includes language, category, source, sentiment, entities, sorting and the `fl` field selector, so you only receive — and only pay for — the articles you actually want. ## Do test keys work with every method?[#](#do-test-keys-work-with-every-method) Yes. A test key delivers live events over all three methods, but the article content is **masked** for preview and deliveries do **not** consume your quota. Use a test key to confirm your client connects, parses the article format and handles reconnection, then switch to a live key for full content and real billing. * * * ## Related Articles * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Stream News over WebSocket](/en/articles/delivery-and-export/streaming/stream-with-websocket) --- ## Real-time Streaming URL: https://support.apitube.io/en/articles/delivery-and-export/streaming Stream APITube news as it is published — Server-Sent Events (SSE) and WebSocket connections that push new matching articles to you in real time, with reconnection support. # Real-time Streaming Stream APITube news as it is published — Server-Sent Events (SSE) and WebSocket connections that push new matching articles to you in real time, with reconnection support. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Erick 1 author 5 articles * [How to Receive Instant Breaking-News Alerts](/en/articles/delivery-and-export/streaming/breaking-news-alerts) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Stream News over WebSocket](/en/articles/delivery-and-export/streaming/stream-with-websocket) * [Polling vs Streaming: How to Keep News Data Fresh](/en/articles/delivery-and-export/streaming/polling-vs-streaming) * [SSE vs WebSocket vs Webhooks: Which to Choose](/en/articles/delivery-and-export/streaming/choose-realtime-method) --- ## Polling vs Streaming: How to Keep News Data Fresh URL: https://support.apitube.io/en/articles/delivery-and-export/streaming/polling-vs-streaming Poll the APITube News API on a schedule when minutes of delay are fine, and switch to SSE, WebSocket or webhooks when seconds matter. Both work on every plan. # Polling vs Streaming: How to Keep News Data Fresh Decide between pulling /v1/news/everything on a schedule and having new articles pushed to you — with the real costs of each ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Tesla&language_code=en&published_at_start=NOW-1HOUR&per_page=250) # Polling vs streaming: how to keep news data fresh[#](#polling-vs-streaming-how-to-keep-news-data-fresh) Poll `/v1/news/everything` on a schedule when a few minutes of delay are acceptable — it is simpler, works on every plan including Free, and an empty poll costs nothing. Switch to push delivery ([SSE](/en/articles/getting-started/glossary#sse-stream), [WebSocket](/en/articles/getting-started/glossary#websocket) or a [webhook](/en/articles/getting-started/glossary#webhook)) when seconds matter: breaking-news alerts, live dashboards, trading signals. The two models bill differently and fail differently, so the right choice is a property of your use case, not a preference. ## How do I poll for new articles correctly?[#](#how-do-i-poll-for-new-articles-correctly) A polling loop is one repeated search with a sliding time window. Ask for articles published since the last run, newest first (the default sort), and de-duplicate by article `id` on your side: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&language.code=en&published_at.start=NOW-1HOUR&per_page=250&api_key=YOUR_API_KEY" ``` Three details make the loop reliable: * **Overlap the window.** Poll every 30 minutes but ask for the last hour (`published_at.start=NOW-1HOUR`). Articles are indexed with some delay after publication, so a window equal to your interval can miss pieces that entered the index late; the overlap catches them, and your `id` set drops the repeats. * **Keep seen ids.** Store the `id` of every article you processed (the last few thousand is plenty) and skip repeats. This makes the overlap free and the loop idempotent. * **Page when needed.** `per_page` goes up to 250 (10 on Free, 50 on Starter, 200 on Basic); if a busy window returns a full page, follow the response’s `next_page` URL until `has_next_pages` is `false` — the mechanics are in [how to paginate results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). The relative date syntax (`NOW-1HOUR`, `NOW-24HOURS`, `NOW-7DAYS`) is covered in [how to filter by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## When is polling the right choice?[#](#when-is-polling-the-right-choice) Polling wins whenever the consumer is itself periodic. A daily digest, an hourly [sentiment](/en/articles/getting-started/glossary#sentiment) aggregate, a nightly data-warehouse load — pushing articles one by one into a job that runs on a schedule adds moving parts and saves nothing. Polling is also the pragmatic choice when: * **You are on the Free plan.** Free can open **one** SSE or WebSocket connection, but everything it receives is **delayed by 12 hours** — the delay applies to streams and webhooks exactly as it does to search, so pushing does not make Free any fresher. Until you upgrade, a polling loop is the simpler shape: at 10 requests per minute it covers many topics from one key, and the article `body` arrives as the same preview either way. * **Cost control matters more than latency.** A search request is charged only when it returns at least one article; a poll that finds nothing is free. Quiet topics cost you nothing between stories. * **Your infrastructure is simple.** A cron job and an HTTP call, no long-lived connections to babysit, no public endpoint to secure. ## When should I switch to push delivery?[#](#when-should-i-switch-to-push-delivery) Push earns its complexity when the value of an article decays in seconds — alerting, live tickers, automated reactions. New matching articles reach an SSE or WebSocket stream within roughly half a minute of entering the index, and a webhook’s delivery worker picks them up within seconds. All three push methods bill one credit per **delivered** article (the open connection, heartbeats and empty periods are free) and draw from their own credit pools, separate from search requests. Push also changes your failure model: you now own reconnection (streams) or a highly-available public endpoint (webhooks). Which of the three push methods fits your architecture — who holds the connection, how reconnection works — is the subject of [SSE vs WebSocket vs webhooks](/en/articles/delivery-and-export/streaming/choose-realtime-method); the parameters shared by all delivery methods are in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Can I combine both?[#](#can-i-combine-both) The strongest setups usually do. Run one narrow stream for the events that cannot wait — `is_breaking=1`, or negative mentions of your own brand — and a scheduled poll for the broad sweep that feeds analytics and archives. The stream stays cheap because its filters are tight; the poll stays cheap because empty runs are free. One caution: the same article delivered by your stream _and_ fetched by your poll is billed in both places, so keep the two filter sets disjoint. # Common Questions[#](#common-questions) * [Can polling miss articles entirely?](#can-polling-miss-articles-entirely) * [How often can I poll?](#how-often-can-i-poll) * [Is polling cheaper than streaming?](#is-polling-cheaper-than-streaming) ## Can polling miss articles entirely?[#](#can-polling-miss-articles-entirely) Only if your window has gaps. An article is searchable from the moment it is indexed, which can lag its `published_at` by a bit — that is exactly what the overlap window absorbs. With `published_at.start` overlapping the previous run and id-based de-duplication, a polling loop is lossless for any topic whose volume fits your page budget. ## How often can I poll?[#](#how-often-can-i-poll) Up to your [rate limit](/en/articles/getting-started/glossary#rate-limit): 10 requests per minute on Free, 50 per minute on paid plans (15 for [test keys](/en/articles/getting-started/glossary#test-key-and-live-key)). In practice a poll every 1–5 minutes is indistinguishable from streaming for most workloads — at that point, choose by architecture rather than by latency. Exceeding the limit returns `429` (`ER0203`); see [how to fix rate-limit errors](/en/articles/troubleshooting/rate-limit-errors). ## Is polling cheaper than streaming?[#](#is-polling-cheaper-than-streaming) For quiet or bursty topics, usually: empty polls are free, and a non-empty poll is one charged request for up to 250 articles (200 on Basic, 50 on Starter, 10 on Free). Streaming bills per delivered article, which is economical precisely when almost every delivery matters to you. High-volume, always-on topics tilt toward streaming; low-volume monitoring tilts toward polling. * * * ## Related Articles * [SSE vs WebSocket vs Webhooks: Which to Choose](/en/articles/delivery-and-export/streaming/choose-realtime-method) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Stream News in Real Time with SSE URL: https://support.apitube.io/en/articles/delivery-and-export/streaming/stream-with-sse Stream APITube news in real time with Server-Sent Events: open one connection to /v1/news/stream, get new matching articles pushed as they publish, and resume… # How to Stream News in Real Time with SSE Open one persistent connection to /v1/news/stream and receive matching articles the moment they are published ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 # How to stream news in real time with SSE[#](#how-to-stream-news-in-real-time-with-sse) To stream news in real time, open a single persistent connection to `GET /v1/news/stream`. APITube keeps it open and pushes each new article that matches your filters as a [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) (SSE) message — you never poll. The fastest way to try it is one cURL command: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?language.code=en" ``` The `-N` flag turns off cURL buffering so events print the instant they arrive. The connection stays open and new English-language articles appear as they are published. Pass your key either in the `X-API-Key` header or as an `?api_key=` query parameter. ## How does the SSE stream work?[#](#how-does-the-sse-stream-work) The stream checks for new matching articles roughly every **30 seconds** and sends up to **50 articles** per cycle. Between articles, APITube sends a heartbeat comment about every **30 seconds** to keep the connection alive — these heartbeats are free and not real events. A single connection can stay open for up to **6 hours**, after which the server asks you to reconnect (it sends error code `ER0362`). Crucially, the stream is for **new** articles, not a history dump. When you connect without a resume header, APITube anchors to the latest matching article and then streams everything published after that moment. To pull older articles, run a normal search against the `/everything` endpoint instead. ## What does an SSE message look like?[#](#what-does-an-sse-message-look-like) Each delivered article arrives as a named `article` event with a unique `id:` and the full article JSON on `data:` lines: ``` event: article id: 123456 data: {"id":123456,"title":"...","source":{"domain":"reuters.com"},...} ``` The `data:` payload is the **same article object** you get from a news search, so any code that already parses `/everything` results works unchanged. The `id:` is the article ID — keep the latest one you received, because it is your resume point. Error conditions arrive as an `error` event, for example `event: error` with `data: {"code":"ER0301","message":"Balance exhausted"}`, after which the server closes the connection. ## How do I filter what the stream sends?[#](#how-do-i-filter-what-the-stream-sends) Every filter that works on a normal news search works here — append it to the query string. Language, category, source, [sentiment](/en/articles/getting-started/glossary#sentiment), [entities](/en/articles/getting-started/glossary#entity), sorting, and field selection all apply: ``` # English sport news from one source, only the fields you need curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?language.code=en&category.id=medtop:15000000&source.domain=reuters.com&fl=id,title,source.domain" ``` Use the `fl` parameter to trim each message to just the fields you use — see [how to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) — and start narrow with a filter like [language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) so you only pay for articles you actually want. The official [SSE Stream reference on docs.apitube.io](https://docs.apitube.io/platform/news-api/sse-stream) lists every supported language and client snippet. ## How do I reconnect without losing articles?[#](#how-do-i-reconnect-without-losing-articles) SSE has built-in resume. Every `article` event carries an `id:`; if the connection drops, reconnect and send the last ID you saw in the `Last-Event-Id` request header: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ -H "Last-Event-Id: 123456" \ "https://api.apitube.io/v1/news/stream?language.code=en" ``` APITube immediately delivers any matching article published after ID `123456`, then continues streaming new ones — so a brief network blip costs you nothing. In the browser, the native `EventSource` API does this for you: it reconnects automatically and replays the last event ID with no extra code. ## What does streaming cost?[#](#what-does-streaming-cost) You are billed **1 credit per article actually delivered** — never for the open connection and never for heartbeats. Credits are deducted as each article is written to you, so if nothing matches your filters, nothing is spent. Streaming draws from a **separate streaming-credit pool** on your account, distinct from your regular request credits; when that pool is empty, a positive [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance is used instead. If you connect with no streaming credits and no paid balance, the server rejects the connection with HTTP `402` and code `ER0176`. If the balance runs out mid-stream, you get an `error` event with code `ER0301` and the connection closes — reconnect after topping up or when your plan credits renew. # Common Questions[#](#common-questions) * [How is SSE different from webhooks?](#how-is-sse-different-from-webhooks) * [How many streams can I run at once?](#how-many-streams-can-i-run-at-once) * [Can I open the stream from a browser?](#can-i-open-the-stream-from-a-browser) * [Do test keys work with the stream?](#do-test-keys-work-with-the-stream) ## How is SSE different from webhooks?[#](#how-is-sse-different-from-webhooks) SSE keeps a connection **you** hold open and pushes articles down it in real time, which suits live dashboards and a process that runs continuously. A [webhook](/en/articles/getting-started/glossary#webhook) instead has APITube `POST` new articles to a URL you registered, which suits server-to-server alerting where you do not want to babysit a socket. Both deliver the same article objects and both bill per delivered article; pick SSE when your client is long-lived, and a [webhook](/en/articles/delivery-and-export/webhooks/what-are-webhooks) when you want delivery to your endpoint without an always-on connection. ## How many streams can I run at once?[#](#how-many-streams-can-i-run-at-once) The number of simultaneous SSE connections depends on your plan. The Free plan allows **1** simultaneous connection; paid plans allow **2** on Starter, **2** on Basic, **10** on Professional, and **50** on Corporate. Opening one more than your plan allows returns HTTP `429` with code `ER0360`. Closing a stream frees its slot, so close connections you no longer need rather than leaving them idle. ## Can I open the stream from a browser?[#](#can-i-open-the-stream-from-a-browser) Yes, with the standard `EventSource` API. Because browsers cannot set custom headers on an `EventSource`, pass your key as a query parameter: `new EventSource('https://api.apitube.io/v1/news/stream?api_key=YOUR_API_KEY&language.code=en')`. Listen for the `article` event and parse `event.data`. Keep in mind the key is then visible in the page, so use a restricted key for browser-side code rather than a privileged one. ## Do test keys work with the stream?[#](#do-test-keys-work-with-the-stream) Yes. A [test key](/en/articles/getting-started/glossary#test-key-and-live-key) streams live events but the article content is **masked** for preview, and deliveries do **not** consume your quota. Use a test key to confirm your client connects, parses the `article` event format and handles reconnection, then switch to a live key to receive full article content and real-time delivery. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Select Specific Response Fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) --- ## How to Stream News over WebSocket URL: https://support.apitube.io/en/articles/delivery-and-export/streaming/stream-with-websocket Stream APITube news over WebSocket: connect to wss://api.apitube.io/v1/news/ws, get new matching articles pushed live, send ping keep-alives, and handle the… # How to Stream News over WebSocket Open a wss connection to /v1/news/ws and receive matching articles the moment they are published ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn August 22, 2026 # How to stream news over WebSocket[#](#how-to-stream-news-over-websocket) To stream news over [WebSocket](/en/articles/getting-started/glossary#websocket), open one connection to `wss://api.apitube.io/v1/news/ws` and pass your filters in the query string. APITube holds the socket open and pushes each new article that matches as a JSON message — no polling on your side. The quickest way to try it is the `wscat` client: ``` # npm install -g wscat wscat -c "wss://api.apitube.io/v1/news/ws?api_key=YOUR_API_KEY&language.code=en" ``` Authenticate with your key in the `X-API-Key` header or, for browser and most WebSocket clients that cannot set custom headers, as the `?api_key=` query parameter. A missing or invalid key closes the socket immediately with close code `1008` (`Unauthorized`). ## How does the WebSocket stream work?[#](#how-does-the-websocket-stream-work) The server checks for new matching articles about every **10 seconds** and sends up to **50 articles** per cycle. It also emits a heartbeat message roughly every **30 seconds** so idle connections stay alive. A single connection lasts up to **6 hours**; at that point the server sends error code `ER0362` and closes with code `4005`, asking you to reconnect. The stream delivers **new** articles, not a history dump. On connect, APITube anchors to the single most recent article that matches your filters and then streams everything published after it. To pull older articles, run a normal search against `/v1/news/everything` instead — the WebSocket is purely for what arrives next. ## What messages does the WebSocket send?[#](#what-messages-does-the-websocket-send) Every message is a JSON object with a `type` field, so you tell them apart by `type`: * **Articles** — `type: "article"`; the article itself is in the `data` field (the same object a news search returns — `id`, `title`, `source`, and so on, read as `msg.data.id`, `msg.data.title`, …). * **Control messages** — `connected` (sent once on connect, with a `session_id`), `subscribed` (echoes your active `filters`), `heartbeat` (with a `timestamp`), `pong` (reply to your ping), and `error` (with a `code` and `message`). A browser client that branches on `type` handles them cleanly: ``` const ws = new WebSocket('wss://api.apitube.io/v1/news/ws?api_key=YOUR_API_KEY&language.code=en'); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === 'error') { console.error(msg.code, msg.message); return; } if (msg.type !== 'article') return; // connected / subscribed / heartbeat / pong — ignore const article = msg.data; // the article object lives under data console.log('new article', article.id, article.title); }; ``` ## How do I filter the stream and keep it alive?[#](#how-do-i-filter-the-stream-and-keep-it-alive) Every filter that works on a normal news search works here — append it to the query string. Language, category, source, [sentiment](/en/articles/getting-started/glossary#sentiment), [entities](/en/articles/getting-started/glossary#entity), sorting, and field selection all apply: ``` wscat -c "wss://api.apitube.io/v1/news/ws?api_key=YOUR_API_KEY&language.code=en&category.id=medtop:15000000&source.domain=reuters.com&fl=id,title,source.domain" ``` Use `fl` to trim each message to the fields you actually use — see [how to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields). To keep a quiet connection healthy behind proxies, send a ping and the server replies with a pong: ``` {"action":"ping"} ``` The server answers `{"type":"pong","timestamp":...}`. Any other client message is ignored, so you cannot change filters on a live socket — reconnect with new query parameters instead. The official [endpoints reference on docs.apitube.io](https://docs.apitube.io/platform/news-api/endpoints) lists `/v1/news/ws` alongside the rest of the API. ## What does WebSocket streaming cost?[#](#what-does-websocket-streaming-cost) You are billed **1 credit per article actually delivered** — never for the open connection, heartbeats, or pongs. A credit is deducted only after the article is successfully written to an open socket, so if nothing matches your filters, nothing is spent. WebSocket deliveries draw from a **separate WebSocket credit pool** on your account, distinct from your regular request credits; when that pool is empty, a positive [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance is used instead. If you connect with no WebSocket credits and no paid balance, the server sends error code `ER0404` and closes with code `4002`. If the balance runs out mid-stream, you get an `error` message with code `ER0402` and the socket closes — reconnect after topping up or when your plan credits renew. A separate case is the monthly [pay-as-you-go spending limit](/en/articles/billing/pay-as-you-go/set-spending-limit): once the socket would start billing your balance and that limit is already reached, the server sends `ER0177` and closes with code `4006` — raise or clear the limit in the dashboard to resume. # Common Questions[#](#common-questions) * [How is WebSocket different from SSE?](#how-is-websocket-different-from-sse) * [How many WebSocket connections can I open at once?](#how-many-websocket-connections-can-i-open-at-once) * [Do test keys work over WebSocket?](#do-test-keys-work-over-websocket) * [What happens when my key is revoked?](#what-happens-when-my-key-is-revoked) ## How is WebSocket different from SSE?[#](#how-is-websocket-different-from-sse) Both push the same article objects in real time and both bill per delivered article. The difference is the transport: WebSocket is a two-way socket, so your client can send a `ping` and the server can reply, while [Server-Sent Events](/en/articles/delivery-and-export/streaming/stream-with-sse) are one-way and resume automatically with a `Last-Event-Id` header. Choose WebSocket when you already speak `wss` or want client-to-server pings; choose [SSE](/en/articles/getting-started/glossary#sse-stream) when you want built-in reconnection and the simplicity of the browser `EventSource` API. For server-to-server delivery without holding any socket open, use a [webhook](/en/articles/delivery-and-export/webhooks/what-are-webhooks) instead. ## How many WebSocket connections can I open at once?[#](#how-many-websocket-connections-can-i-open-at-once) The number of simultaneous WebSocket connections depends on your plan. The Free plan allows **1** simultaneous connection; paid plans allow **2** on Starter, **2** on Basic, **10** on Professional, and **50** on Corporate. Opening one more than your plan allows sends error code `ER0403` and closes that attempt with code `4003`. Closing a socket frees its slot, so close connections you no longer need rather than leaving them idle. ## Do test keys work over WebSocket?[#](#do-test-keys-work-over-websocket) Yes. A [test key](/en/articles/getting-started/glossary#test-key-and-live-key) streams live events, but the article content is **masked** for preview and deliveries do **not** consume your quota. Use a test key to confirm your client connects, parses the article and control messages, and handles reconnection, then switch to a live key on a paid plan for full content and real billing (a free live key can stream one connection, but content stays preview). ## What happens when my key is revoked?[#](#what-happens-when-my-key-is-revoked) A WebSocket connection can stay open for hours, so APITube re-checks your key on every poll cycle. If you revoke the key while a stream is running, the server sends error code `ER0361` and closes the socket with code `4004` within the next cycle. Reconnect with a valid key to resume. The same re-check keeps your credit balance in sync across multiple connections, so concurrent sockets cannot bill past zero. * * * ## Related Articles * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) * [How to Select Specific Response Fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) --- ## Webhooks URL: https://support.apitube.io/en/articles/delivery-and-export/webhooks Push delivery of new APITube articles to your endpoint — how webhooks work, HMAC signature verification, retries and delivery history. # Webhooks Push delivery of new APITube articles to your endpoint — how webhooks work, HMAC signature verification, retries and delivery history. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Erick 1 author 4 articles * [How to Set Up a Webhook for a Saved Search](/en/articles/delivery-and-export/webhooks/set-up-webhook) * [How to Verify Webhook Signatures (HMAC)](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) * [Understanding Webhook Retries and Delivery History](/en/articles/delivery-and-export/webhooks/webhook-retries-history) * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) --- ## How to Set Up a Webhook for a Saved Search URL: https://support.apitube.io/en/articles/delivery-and-export/webhooks/set-up-webhook Set up an APITube webhook in the dashboard: pick an endpoint URL, an API key and saved-search filters, then copy the signing secret shown once. # How to Set Up a Webhook for a Saved Search Create a webhook in the APITube dashboard so new matching articles are pushed to your endpoint ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 # How to set up a webhook for a saved search[#](#how-to-set-up-a-webhook-for-a-saved-search) You set up an APITube [webhook](/en/articles/getting-started/glossary#webhook) in the **dashboard**, not over the API. Open the dashboard, go to **Webhooks → Create webhook**, enter the endpoint URL that should receive deliveries, choose the [API key](/en/articles/getting-started/glossary#api-key) the webhook bills against, build the saved-search filters that decide which articles qualify, and create it. APITube then watches for new matching articles and `POST`s them to your URL. There is no `POST /v1/webhooks` endpoint — creation lives in the dashboard on purpose, because that is where the per-plan webhook limit is enforced. ## Where do you create a webhook?[#](#where-do-you-create-a-webhook) Webhooks are created on the **Create webhook** page in the dashboard (`/webhooks/new`), reachable from the **Webhooks** list. The API itself only exposes endpoints for webhooks that already exist — listing, reading, updating and deleting — so there is no way to create one with a `curl` call. If you are looking for the concept first, read [what webhooks are and how they work](/en/articles/delivery-and-export/webhooks/what-are-webhooks); this article is the step-by-step setup. To create a webhook you need a role that can manage them: an **owner**, **admin** or **member** can create webhooks, but a **viewer** cannot. You also need at least one active API key in the current [workspace](/en/articles/getting-started/glossary#workspace), since every webhook is tied to a key. ## What do you enter when creating a webhook?[#](#what-do-you-enter-when-creating-a-webhook) The Create webhook form has three inputs: * **Endpoint URL** — the address APITube delivers to. It must be a valid `http://` or `https://` URL. Plain `http://` is accepted but the form warns against it, because the request body carries article data and a signature header; use HTTPS in production. URLs that resolve to loopback or private network addresses are rejected. * **API key** — the key the webhook delivers under. Pick a **live** key for real content or a **test** key to try the flow first. The key must belong to the current workspace and must not be revoked. * **Filters** — the [saved search](/en/articles/getting-started/glossary#saved-search). The builder offers the same dot-notation filters as the `/v1/news/everything` search, so a webhook delivers exactly the articles that search would return. ![The Create webhook page: endpoint URL and API key fields, the filter builder, and an example payload preview on the right](/images/article/dashboard-webhook-builder.png) ## How do you choose the filters for a saved search?[#](#how-do-you-choose-the-filters-for-a-saved-search) A webhook’s filters are a subset of the regular News API search filters — the same parameters you would use on `/v1/news/everything`, minus the request-time options that make no sense for a push subscription (sorting, [pagination](/en/articles/getting-started/glossary#pagination), field selection, facets, highlighting). So you can scope a webhook by title keywords, language, country, source domain, category, [entities](/en/articles/getting-started/glossary#entity), sentiment and the other search filters. For example, a saved search for English-language coverage of a company from a specific source is expressed with the same parameter names you already know: ``` title=acme language.code=en source.domain=reuters.com ``` Build the filters narrowly. The webhook only fires for articles that match, so a tight saved search means fewer, more relevant deliveries. The full list of filter parameters lives in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything), and you can read how individual filters behave in articles like [how to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category). ## Where is the signing secret?[#](#where-is-the-signing-secret) When the webhook is created, the dashboard shows a **signing secret** that starts with `whsec_`. Use it to verify that incoming deliveries really came from APITube by checking the `X-Webhook-Signature` header. The signing secret is shown **once**, right after you create the webhook. Copy it immediately and store it somewhere safe — the dashboard never displays it again, and there is no endpoint that returns it. If you lose it, you will need to recreate the webhook. The signature is an HMAC-SHA256 over the timestamp and the request body, keyed with this secret. The full verification recipe — header format, what to hash, and how to compare safely — is in [how to verify webhook signatures](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures). ## How to test the webhook before going live[#](#how-to-test-the-webhook-before-going-live) After creating a webhook you can send a **test event** from its detail page. This delivers a signed sample payload to your endpoint immediately, bypassing the normal delivery worker. The test works regardless of the webhook’s status (active, paused or disabled), does **not** touch your billing, and records the result in the delivery history so you can inspect the response status and body. Use it to confirm your endpoint receives the request, validates the signature and replies with an HTTP `2xx` before you rely on real deliveries. ## How to manage a webhook after creating it[#](#how-to-manage-a-webhook-after-creating-it) Once a webhook exists, you can manage it over the API as well as in the dashboard. The API exposes read and management endpoints — but never creation: ``` # List your webhooks curl "https://api.apitube.io/v1/webhooks" -H "X-API-Key: YOUR_API_KEY" # Pause one (status accepts active or paused) curl -X PATCH "https://api.apitube.io/v1/webhooks/7" \ -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"status":"paused"}' # Delete one curl -X DELETE "https://api.apitube.io/v1/webhooks/7" -H "X-API-Key: YOUR_API_KEY" ``` `PATCH /v1/webhooks/:id` can change the URL, the filters or the status. A status of `paused` stops deliveries without deleting the webhook; switching it back to `active` resumes them — and also reactivates a webhook that APITube auto-disabled after repeated failures (covered in [webhook retries and delivery history](/en/articles/delivery-and-export/webhooks/webhook-retries-history)). # Common Questions[#](#common-questions) * [How many webhooks can I create?](#how-many-webhooks-can-i-create) * [Can I create a webhook through the API?](#can-i-create-a-webhook-through-the-api) * [Who on my team can create a webhook?](#who-on-my-team-can-create-a-webhook) * [Can I pause a webhook instead of deleting it?](#can-i-pause-a-webhook-instead-of-deleting-it) ## How many webhooks can I create?[#](#how-many-webhooks-can-i-create) The number of webhooks is capped by your plan: **Free 1, Starter 5, Basic 5, Professional 20, and Corporate 100**. The limit is counted per account owner across all workspaces, and test-key and live-key webhooks are counted separately — so a Free account can have one live webhook and one test webhook. If you hit the cap, the dashboard prompts you to upgrade before you can add another. ## Can I create a webhook through the API?[#](#can-i-create-a-webhook-through-the-api) No. There is no `POST /v1/webhooks` endpoint — webhook creation is deliberately dashboard-only, so the per-plan limit is always enforced. Over the API you can only list (`GET /v1/webhooks`), read (`GET /v1/webhooks/:id`), update (`PATCH /v1/webhooks/:id`) and delete (`DELETE /v1/webhooks/:id`) webhooks that already exist. ## Who on my team can create a webhook?[#](#who-on-my-team-can-create-a-webhook) In a workspace, the **owner**, **admins** and **members** can create and manage webhooks. **Viewers** have read-only access and cannot create one. Each webhook is tied to an API key in the workspace, and deliveries bill against that key’s account. ## Can I pause a webhook instead of deleting it?[#](#can-i-pause-a-webhook-instead-of-deleting-it) Yes. Set the webhook’s status to `paused` — in the dashboard or with `PATCH /v1/webhooks/:id` — to stop deliveries while keeping the configuration and signing secret. Set it back to `active` to resume. Deleting a webhook is permanent and also removes its delivery history, so pause it if you only need a temporary stop. * * * ## Related Articles * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) * [How to Verify Webhook Signatures (HMAC)](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) * [Understanding Webhook Retries and Delivery History](/en/articles/delivery-and-export/webhooks/webhook-retries-history) --- ## How to Verify Webhook Signatures (HMAC) URL: https://support.apitube.io/en/articles/delivery-and-export/webhooks/verify-webhook-signatures Verify APITube webhook signatures: recompute HMAC-SHA256 over the timestamp and raw body with your whsec_ secret and compare it to the X-Webhook-Signature… # How to Verify Webhook Signatures (HMAC) Validate the X-Webhook-Signature header with HMAC-SHA256 so you can trust a webhook really came from APITube ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 26, 2026 Updated July 21, 2026 # How to verify webhook signatures (HMAC)[#](#how-to-verify-webhook-signatures-hmac) Every APITube [webhook](/en/articles/getting-started/glossary#webhook) delivery is signed so you can confirm it really came from APITube and was not tampered with. To verify it, recompute an HMAC-SHA256 hash over the string `timestamp + "." + rawBody` using your webhook’s signing secret, prefix it with `sha256=`, and compare the result to the `X-Webhook-Signature` header. If they match, the request is authentic; if they do not, reject it with a `401`. ``` POST https://your-app.example.com/webhook Content-Type: application/json X-Webhook-Signature: sha256=abc123def456... X-Webhook-Id: 7 X-Webhook-Delivery-Id: 42 X-Webhook-Timestamp: 1709000000 ``` The signature lives in `X-Webhook-Signature`, the exact unix-second timestamp that was signed is in `X-Webhook-Timestamp`, and the body is the JSON APITube POSTed. You need all three plus your secret to verify. ## What signature does APITube send?[#](#what-signature-does-apitube-send) APITube computes the signature as `HMAC-SHA256(secret, timestamp + "." + rawBody)` and sends it hex-encoded in the `X-Webhook-Signature` header, prefixed with the algorithm: `sha256=<hex>`. The `timestamp` is the value from the `X-Webhook-Timestamp` header (unix seconds), and `rawBody` is the exact bytes of the request body. Each delivery also carries `X-Webhook-Id` (the webhook subscription ID, which matches `webhook_id` in the body) and `X-Webhook-Delivery-Id` (a per-delivery ID that stays stable across retries, useful for deduplication). The request body is JSON shaped like this, with the same [article fields you would get from a news search](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields): ``` { "event": "articles.new", "webhook_id": 7, "delivered_at": "2026-06-26T12:00:00.000Z", "articles": [ { "id": 123, "title": "...", "source": { "domain": "reuters.com" } } ] } ``` ## Where do I get the signing secret?[#](#where-do-i-get-the-signing-secret) The signing secret is created together with the webhook and starts with the prefix `whsec_`. You create webhooks in the [dashboard](https://dashboard.apitube.io) — there is no public `POST` endpoint to create one over the API — and the secret is shown only once, in the response when the webhook is created. Copy it then and store it like a password (an environment variable, not in client-side code). If you lose it, recreate the webhook to get a new secret. The same secret signs every delivery for that webhook, so your endpoint can verify all of them with one stored value. ## How to verify the signature in Node.js[#](#how-to-verify-the-signature-in-nodejs) Recompute the HMAC over `timestamp + "." + rawBody` and compare it to the header in constant time. Verify against the **raw** request body — the exact bytes you received — not a re-serialized object, because re-running `JSON.stringify` on a parsed body can produce different bytes and the signature will not match. ``` import crypto from 'node:crypto'; const MAX_SKEW_SECONDS = 300; // reject deliveries older than 5 minutes (replay protection) function verifyWebhook(secret, signature, timestamp, rawBody) { const age = Math.floor(Date.now() / 1000) - Number(timestamp); if (!Number.isFinite(age) || Math.abs(age) > MAX_SKEW_SECONDS) return false; const expected = `sha256=${crypto.createHmac('sha256', secret).update(timestamp + '.' + rawBody).digest('hex')}`; const received = String(signature || ''); if (received.length !== expected.length) return false; return crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected)); } app.post('/webhook', (req, res) => { const signature = req.headers['x-webhook-signature']; const timestamp = req.headers['x-webhook-timestamp']; const rawBody = req.rawBody; // use express.raw / the unparsed body, not JSON.stringify(req.body) if (!verifyWebhook(SECRET, signature, timestamp, rawBody)) { return res.status(401).send('Invalid signature'); } const { articles } = JSON.parse(rawBody); res.status(200).send('OK'); }); ``` ## How to verify the signature in Python[#](#how-to-verify-the-signature-in-python) The Python version follows the same two steps — check the timestamp freshness, then compare an HMAC-SHA256 digest in constant time with `hmac.compare_digest`. ``` import hmac import hashlib import time MAX_SKEW_SECONDS = 300 # replay protection def verify_webhook(secret, signature, timestamp, raw_body): try: age = int(time.time()) - int(timestamp) except (TypeError, ValueError): return False if abs(age) > MAX_SKEW_SECONDS: return False expected = 'sha256=' + hmac.new( secret.encode(), (timestamp + '.' + raw_body).encode(), hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature or '', expected) ``` # Common Questions[#](#common-questions) ## Why doesn’t my computed signature match?[#](#why-doesnt-my-computed-signature-match) The most common cause is signing the wrong bytes. The signature covers `timestamp + "." + rawBody`, where `rawBody` is the unmodified request body. If your framework parses JSON and you call `JSON.stringify` again, key order or whitespace can change and the hash will differ. Capture the raw body before parsing (for example `express.raw({ type: 'application/json' })`), and make sure you concatenate the `X-Webhook-Timestamp` value with a literal `.` before the body — not the body alone. When you debug a mismatch, compare against the exact payload APITube sent: the webhook’s **Delivery log** in the dashboard stores each delivery’s raw request body, so you can hash precisely those bytes. ![The webhook Delivery log in the dashboard exposing the raw request payload of a delivery for signature debugging](/images/article/dashboard-webhook-deliveries.png) ## Should I reject old webhooks?[#](#should-i-reject-old-webhooks) Yes. Comparing the `X-Webhook-Timestamp` against the current time and rejecting anything outside a window — 5 minutes (`300` seconds) is a reasonable default — stops a captured request from being replayed later. APITube includes the signed timestamp in every delivery precisely so your endpoint can enforce this. Pair the freshness check with the `X-Webhook-Delivery-Id` header to deduplicate retries of the same delivery. ## Do I need to compare signatures in constant time?[#](#do-i-need-to-compare-signatures-in-constant-time) Use a constant-time comparison such as `crypto.timingSafeEqual` (Node.js) or `hmac.compare_digest` (Python) rather than `==`. A plain string comparison can leak, through timing differences, how much of the signature matched, which weakens the check. Both functions need equal-length inputs, so the Node.js example bails out early when the lengths differ. Because the same `whsec_` secret signs every delivery, this verification is the single gate that proves a webhook came from APITube before you act on the `articles` it carries. * * * ## Related Articles * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) * [How to Set Up a Webhook for a Saved Search](/en/articles/delivery-and-export/webhooks/set-up-webhook) * [Understanding Webhook Retries and Delivery History](/en/articles/delivery-and-export/webhooks/webhook-retries-history) --- ## Understanding Webhook Retries and Delivery History URL: https://support.apitube.io/en/articles/delivery-and-export/webhooks/webhook-retries-history APITube retries a failed webhook delivery up to 5 times with growing gaps, auto-disables it after 3 consecutive failures, and logs every attempt in your… # Understanding Webhook Retries and Delivery History How APITube retries failed webhook deliveries, when a webhook is auto-disabled, and where to inspect every delivery ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 26, 2026 Updated July 21, 2026 # Understanding webhook retries and delivery history[#](#understanding-webhook-retries-and-delivery-history) When a [webhook](/en/articles/getting-started/glossary#webhook) delivery fails, APITube retries it automatically up to 5 times in total with growing gaps between attempts, and disables the webhook after 3 consecutive failed deliveries. Every attempt — successful or not — is recorded in the webhook’s delivery history in your dashboard, including the HTTP status code your endpoint returned and the exact request and response bodies. A delivery counts as **successful only when your endpoint replies with an HTTP `2xx` status**. Any other response — a `4xx`, a `5xx`, a `3xx` redirect (APITube does not follow redirects), a connection error, or a timeout after 30 seconds — is treated as a failure and queued for retry. ## How many times does APITube retry a failed delivery?[#](#how-many-times-does-apitube-retry-a-failed-delivery) APITube attempts each delivery up to **5 times total**: the initial send plus 4 retries. The gaps grow after each failure so a briefly-down endpoint gets time to recover without being hammered: * 1st retry — about **1 minute** after the first failure * 2nd retry — about **5 minutes** later * 3rd retry — about **30 minutes** later * 4th retry — about **2 hours** later A background worker checks for due retries once a minute, so these times are “at least this long,” not exact-to-the-second. After the 5th failed attempt the delivery is marked `failed` permanently and is not retried again. Each retry resends the **same articles** from the original batch (a delivery carries up to 100 articles). The `X-Webhook-Delivery-Id` header stays the same across every retry of one delivery, so your endpoint can deduplicate: if you already processed a delivery ID, ignore the repeat and still return `2xx`. ## When does APITube disable a webhook?[#](#when-does-apitube-disable-a-webhook) A webhook is automatically **disabled after 3 consecutive failed deliveries**. APITube looks at the most recent deliveries for that webhook; a run of failures with no success in between trips the limit and flips the webhook’s status to `disabled`. A disabled webhook stops receiving new deliveries until you re-enable it from the dashboard. This is why a single bad deploy can knock a webhook offline: if your endpoint returns errors for a few deliveries in a row, the webhook is disabled even after retries are exhausted. After fixing your endpoint, set the webhook back to `active` in the dashboard so polling resumes. ## Where do I see the delivery history?[#](#where-do-i-see-the-delivery-history) Open the webhook on its detail page in your [dashboard](https://dashboard.apitube.io) — webhooks are created and managed there, since the API only exposes `GET`, `PATCH`, and `DELETE` for existing webhooks, not a create endpoint. The delivery log lists every attempt with a status badge (`success`, `pending`, or `failed`) and the last HTTP code returned. ![The Delivery log of a webhook: a failed test delivery selected, with attempts, HTTP status, response body and the exact request payload](/images/article/dashboard-webhook-deliveries.png) Selecting a delivery shows: * **Attempts** — how many tries this delivery has used out of the maximum (e.g. `3/5`); the counter rises each time the delivery fails * **Articles** — how many articles were in the batch * **Created / Completed** — when the delivery was queued and when it reached a final state * **Response** — the HTTP status code and the raw response body your endpoint returned (stored up to 16 KB) * **Request** — the exact JSON payload APITube POSTed (stored up to 64 KB) * **Last error** — the failure reason for a failed delivery (for example a timeout or a blocked URL) The payload your endpoint receives is shaped like this, with the same [article fields you get from a news search](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields): ``` { "event": "articles.new", "webhook_id": 7, "delivered_at": "2026-06-26T12:00:00.000Z", "articles": [ { "id": 123, "title": "...", "source": { "domain": "reuters.com" } } ] } ``` ## How to test and re-send a delivery[#](#how-to-test-and-re-send-a-delivery) Two dashboard actions help you debug without waiting for live articles: * **Send test event** posts a signed sample payload to your endpoint immediately, bypassing the worker, and records the result (status code, request and response bodies) as a new row in the history. Use it to confirm your endpoint is reachable and your [signature verification](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) works. * **Resend** re-queues an existing delivery: its status resets to `pending`, the attempt counter resets, and the worker picks it up on its next pass. Resend only takes effect while the webhook is `active` — re-enable a disabled or paused webhook first. # Common Questions[#](#common-questions) ## Am I charged for failed webhook deliveries?[#](#am-i-charged-for-failed-webhook-deliveries) No. Billing happens **only for deliveries that actually succeed** (your endpoint returned `2xx`). Failed attempts do not deduct from your quota. If a delivery fails on the first try and then succeeds on a retry, it is charged once, at the point it succeeds — never per attempt. ## Why does a delivery show “failed” with no status code?[#](#why-does-a-delivery-show-failed-with-no-status-code) A delivery with no HTTP status code means the request never got a response: a connection error, a DNS failure, a 30-second timeout, or a URL blocked by APITube’s safety checks (private or loopback addresses are rejected before sending). The reason appears in the delivery’s **last error** field. A delivery that returned a code but a non-`2xx` one (like `500` or `404`) will show that code instead. ## What happens if the articles are gone by the time a retry runs?[#](#what-happens-if-the-articles-are-gone-by-the-time-a-retry-runs) Retries resend the same article IDs from the original batch. If those articles are no longer available when a much-later retry runs, that retry is marked failed with the reason “Articles no longer available for retry.” This is rare in practice, but it is why an endpoint that stays down for hours can end up with permanently failed deliveries even though it eventually came back online — handle deliveries promptly and return `2xx` quickly. ## How do I stop a webhook from being auto-disabled?[#](#how-do-i-stop-a-webhook-from-being-auto-disabled) Keep your endpoint returning `2xx` quickly. Acknowledge the delivery as soon as you have stored the payload, then do slow work asynchronously — if your handler takes longer than 30 seconds, APITube counts it as a failure, and three failures in a row disable the webhook. A fast `2xx` acknowledgement is the single best way to keep deliveries flowing. * * * ## Related Articles * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) * [How to Set Up a Webhook for a Saved Search](/en/articles/delivery-and-export/webhooks/set-up-webhook) * [How to Verify Webhook Signatures (HMAC)](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) --- ## What Are Webhooks and How Do They Work? URL: https://support.apitube.io/en/articles/delivery-and-export/webhooks/what-are-webhooks Webhooks let APITube push new articles that match your saved search to your URL by signed HTTP POST — no polling. Learn how delivery, signing, billing and… # What Are Webhooks and How Do They Work? How APITube pushes new articles matching your saved search to your endpoint by HTTP POST ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 # What are webhooks and how do they work?[#](#what-are-webhooks-and-how-do-they-work) A [webhook](/en/articles/getting-started/glossary#webhook) is a [saved search](/en/articles/getting-started/glossary#saved-search) that **pushes** results to you: instead of repeatedly calling the News API to ask “anything new?”, you register a URL once, and APITube sends an HTTP `POST` to that URL whenever new articles match your filters. Each webhook stores a set of search filters, a destination URL and a signing secret; a background worker watches for new matching articles and delivers them to you in near real time. This flips the usual model. Polling means _you_ pull on a timer and mostly get empty responses; a webhook means APITube pushes only when there is something new, so your endpoint does less work and sees new coverage sooner. ## How does APITube deliver a webhook?[#](#how-does-apitube-deliver-a-webhook) Delivery runs in a separate worker from the API itself. About every **10 seconds** it goes through your active webhooks and, for each one, looks for articles newer than the last one it sent — APITube keeps a high-water mark per webhook, so every article is delivered **once** and you never get repeats. It applies that webhook’s saved filters to the new articles, takes up to **100 articles** per delivery, and `POST`s them as JSON to your URL. Your endpoint signals success by replying with an HTTP **`2xx`** status. APITube does not follow redirects, blocks delivery to private or loopback addresses, and gives your endpoint **30 seconds** to respond before treating the attempt as failed. A fast `2xx` acknowledgement is all that is required — do slow processing afterwards. ## What does a webhook request look like?[#](#what-does-a-webhook-request-look-like) Every delivery is a `POST` with a JSON body and a set of `X-Webhook-*` headers: ``` POST https://your-app.example.com/webhook Content-Type: application/json X-Webhook-Signature: sha256=... X-Webhook-Id: 7 X-Webhook-Delivery-Id: 42 X-Webhook-Timestamp: 1709000000 ``` ``` { "event": "articles.new", "webhook_id": 7, "delivered_at": "2026-06-27T12:00:00.000Z", "articles": [ { "id": 123, "title": "...", "source": { "domain": "reuters.com" } } ] } ``` The `articles` array carries the same article objects you get from a news search. `X-Webhook-Id` identifies the webhook (it matches `webhook_id` in the body), and `X-Webhook-Delivery-Id` identifies the individual delivery and stays stable across retries, so you can deduplicate. The `X-Webhook-Signature` header lets you prove the request really came from APITube — see [how to verify webhook signatures](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures). ## What happens when a delivery fails?[#](#what-happens-when-a-delivery-fails) If your endpoint returns a non-`2xx` status, times out, or cannot be reached, the delivery is marked failed and queued for retry by a separate retry pass. After **3 consecutive failed deliveries**, APITube automatically **disables** the webhook until you re-enable it — so a deploy that breaks your endpoint can knock the webhook offline. The full retry schedule and where to inspect every attempt are covered in [understanding webhook retries and delivery history](/en/articles/delivery-and-export/webhooks/webhook-retries-history). Billing is tied to success: you are charged **per article that is actually delivered**, and only when your endpoint returns `2xx`. Failed attempts cost nothing; if a delivery fails and later succeeds on a retry, it is billed once, at success. ## How do I create and manage a webhook?[#](#how-do-i-create-and-manage-a-webhook) Webhooks are **created in the dashboard**, where you set the URL and the saved-search filters and receive the signing secret (it starts with `whsec_`). There is no public `POST /v1/webhooks` endpoint — creation lives in the dashboard on purpose. ![The Webhooks page of the dashboard listing a configured webhook with its endpoint URL and status](/images/article/dashboard-webhooks.png) Over the API you can only list and manage webhooks that already exist: ``` # List your webhooks curl "https://api.apitube.io/v1/webhooks" -H "X-API-Key: YOUR_API_KEY" # Inspect one curl "https://api.apitube.io/v1/webhooks/7" -H "X-API-Key: YOUR_API_KEY" # Delete one curl -X DELETE "https://api.apitube.io/v1/webhooks/7" -H "X-API-Key: YOUR_API_KEY" ``` `GET /v1/webhooks` and `GET /v1/webhooks/:id` read your webhooks, `PATCH /v1/webhooks/:id` updates an existing one (for example to change its URL or pause it), and `DELETE /v1/webhooks/:id` removes it. # Common Questions[#](#common-questions) * [How is a webhook different from polling the API?](#how-is-a-webhook-different-from-polling-the-api) * [Will I receive the same article twice?](#will-i-receive-the-same-article-twice) * [How many articles arrive in one delivery?](#how-many-articles-arrive-in-one-delivery) * [Do test keys deliver webhooks?](#do-test-keys-deliver-webhooks) ## How is a webhook different from polling the API?[#](#how-is-a-webhook-different-from-polling-the-api) Polling means your code calls a search endpoint on a schedule and filters out what it has already seen, spending requests even when nothing changed. A webhook inverts that: APITube tracks what is new for you and only contacts your endpoint when matching articles appear, usually within seconds. Webhooks suit “tell me when X happens” alerting; a direct search call still suits one-off lookups and backfilling history. ## Will I receive the same article twice?[#](#will-i-receive-the-same-article-twice) Not under normal operation. APITube records a high-water mark per webhook and only sends articles newer than the last delivered one, so each article goes out once. The exception is a **retry** of a failed delivery, which resends the same batch — use the `X-Webhook-Delivery-Id` header to recognise and ignore a repeat while still returning `2xx`. ## How many articles arrive in one delivery?[#](#how-many-articles-arrive-in-one-delivery) Up to **100 articles** per delivery. If more than 100 new articles match between checks, they are split across consecutive deliveries, each carrying its own `X-Webhook-Delivery-Id`. Your endpoint should loop over the `articles` array rather than assuming a single item. ## Do test keys deliver webhooks?[#](#do-test-keys-deliver-webhooks) Yes, but with a preview. A webhook tied to a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) (one whose key starts with `api_test_`) still fires, but the article content is masked and the delivery does **not** consume your quota. Use a test key to confirm your endpoint receives, verifies and acknowledges deliveries before switching the webhook to a live key for real content. * * * ## Related Articles * [How to Verify Webhook Signatures (HMAC)](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) * [Understanding Webhook Retries and Delivery History](/en/articles/delivery-and-export/webhooks/webhook-retries-history) --- ## Glossary of News API terms URL: https://support.apitube.io/en/articles/getting-started/glossary Plain-language definitions of APITube News API terms: API key, points, rate limit, scope, workspace, SSE stream, webhook, story, entity, OPR and more. # Glossary of News API terms Short definitions of every term you meet in the APITube dashboard, docs and API responses — with links to the full guides ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 6, 2026 # Glossary of News API terms[#](#glossary-of-news-api-terms) This glossary defines the terms you will meet across the APITube dashboard, the API response and the documentation — each in one or two sentences, with a link to the article that covers it in depth. If you are new, read [key concepts](/en/articles/getting-started/key-concepts) first for how the data model fits together; use this page when a single word needs a quick answer. ## API key[#](#api-key) The secret token that authenticates every request, sent as an `X-API-Key` header or an `api_key` query parameter. Keys come in two modes — see [test vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) — and are managed per workspace in the dashboard. Never expose a live key in client-side code; [API key security](/en/articles/setup-and-installation/account-and-keys/api-key-security) explains safer patterns. ## Test key and live key[#](#test-key-and-live-key) A **test key** returns real responses with truncated article bodies and never spends your quota — for development. A **live key** returns full content and counts against your plan. The response header `x-apitube-mode` tells you which mode served the call. ## Request (point)[#](#request-point) The unit your plan quota counts. On `/v1/news/everything` a request is only charged when at least one article comes back; failed calls and empty result sets are free. What exactly is charged per endpoint is broken down in [what counts as a request](/en/articles/billing/credits/what-counts-as-request). ## Balance and pay-as-you-go (PAYG)[#](#balance-and-pay-as-you-go-payg) Money-based credit that covers usage beyond your plan’s included requests: you top up a dollar balance and overage is drawn from it. A monthly spending cap can stop PAYG from growing unbounded — see [what pay-as-you-go is](/en/articles/billing/pay-as-you-go/what-is-payg) and [how to set a spending limit](/en/articles/billing/pay-as-you-go/set-spending-limit). ## Rate limit[#](#rate-limit) The per-minute ceiling on how many calls a key may make, separate from your monthly quota. Exceeding it returns HTTP `429` with error code `ER0203`; repeated violations trigger a temporary ban (`ER0204`). Numbers per plan and fixes are in [how to fix rate-limit errors](/en/articles/troubleshooting/rate-limit-errors). ## Scope[#](#scope) A per-endpoint permission attached to an API key. A key scoped to search endpoints cannot call, say, streaming — the API answers `403` with `ER0603`. Scopes are set when creating or editing a key; see [API key scopes](/en/articles/account-and-dashboard/keys/key-scopes). ## Workspace[#](#workspace) The container your keys, members and billing live in. Teams share one workspace so everyone uses the same quota and key list, with roles controlling who may manage what — covered under [teams and workspaces](/en/articles/teams-and-workspaces). ## Endpoint[#](#endpoint) One addressable API function, such as `/v1/news/everything` (search), `/v1/news/top-headlines` or `/v1/fact-check`. All endpoints share the same authentication and error envelope, so code written for one transfers to the rest. ## SSE stream[#](#sse-stream) Server-Sent Events — a long-lived HTTP connection on which new matching articles are pushed to you as they are indexed, instead of you polling. Streaming draws from its own credit pool, separate from REST requests; start with [how to stream with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## WebSocket[#](#websocket) The bidirectional alternative to SSE for real-time delivery, useful when your platform already speaks WebSocket. Same filters, same billing model as streaming — see [how to stream with WebSocket](/en/articles/delivery-and-export/streaming/stream-with-websocket) and [choosing a real-time method](/en/articles/delivery-and-export/streaming/choose-realtime-method). ## Webhook[#](#webhook) Push delivery in reverse: you register a URL plus a saved search, and APITube `POST`s each new matching article to that URL, signed with an HMAC header so you can verify the sender. Deliveries retry with backoff and are billed per delivered article. ## Export format[#](#export-format) Every search can be re-run as a downloadable file: the response’s `export` block carries ready URLs for CSV, XLSX, RSS, XML, TSV, Parquet, JSONL and JSON. See the [export formats overview](/en/articles/delivery-and-export/export/export-formats-overview). ## Pagination[#](#pagination) How you read beyond the first page of results: pass `page=2, 3, …` or follow the response’s prebuilt `next_page` URL until `has_next_pages` is `false`. Default page size is 100 articles, maximum 250 (10 on Free, 50 on Starter, 200 on Basic). ## Request ID[#](#request-id) The unique identifier (`request_id` in the body, `X-Request-ID` header) attached to every call. Quote it when contacting support — it lets the exact request be traced in the logs. ## Entity[#](#entity) A person, company, place or other named thing the NLP layer detected in an article, with its type, position and its own per-entity sentiment. Entities power queries like “news mentioning this company” — see [finding news by entity](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## Sentiment[#](#sentiment) The tone score of a text, from negative to positive, available for the whole article and per entity. [Filter by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) explains the polarity values and score ranges. ## Story[#](#story) The cluster of articles from different sources covering the same underlying event. Fetching a story gives you every angle on one event in a single call — see [what a story is](/en/articles/news-data/what-is-a-story). ## Duplicate[#](#duplicate) A reprint or near-copy of an article already in the index, flagged so you can exclude repeated content from results — see [excluding paywalled and duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates). ## Category, topic and industry[#](#category-topic-and-industry) Three parallel taxonomies attached to each article: **categories** follow the IPTC Media Topics scheme (ids like `medtop:15000000`), **topics** are finer subject slugs, and **industries** map coverage to business sectors. Each has its own filter — start with [filter by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category). ## OPR (Open PageRank)[#](#opr-open-pagerank) The authority score of a source’s domain, based on how widely the site is referenced on the web. Higher OPR means a more established publisher; use it to keep results to serious outlets — explained in [what OPR is](/en/articles/trust-and-support/what-is-opr). ## Error code (ERxxxx)[#](#error-code-erxxxx) The machine-readable cause inside every error response, read together with its HTTP status — `ER0202` is an invalid key, `ER0203` a rate limit, and so on. The full envelope and the common codes are in [understanding API error codes](/en/articles/troubleshooting/error-codes). ## Stream slot[#](#stream-slot) One of the simultaneous streaming connections your plan allows (1 on Free, 2 on Starter, 2 on Basic, 10 on Professional, 50 on Corporate). Opening one connection more than the limit returns `ER0360`; a stuck slot after a crashed client can be freed with the session endpoints — see [fixing SSE stream problems](/en/articles/troubleshooting/sse-stream-issues). ## Saved search[#](#saved-search) The set of search filters attached to a webhook: the same dot-notation parameters as `/v1/news/everything`, stored with the webhook so APITube knows which new articles to deliver. Building one is part of [setting up a webhook](/en/articles/delivery-and-export/webhooks/set-up-webhook). ## Playground[#](#playground) The interactive sandbox in the dashboard that runs real News API requests against your own keys, with every parameter as a form field and generated code snippets. Handy for testing a filter before writing code — see [how to test requests in the API Playground](/en/articles/setup-and-installation/tools/test-in-playground). ## Fact check[#](#fact-check) The `/v1/fact-check` endpoint: give it a claim and it returns a verdict with supporting articles from the news index. It is priced differently from search and unavailable on the Free plan — walkthrough in [how to fact-check a claim](/en/articles/use-cases/trust-and-research/fact-check-claim). # Common Questions[#](#common-questions) * [Is this the same as the official docs glossary?](#is-this-the-same-as-the-official-docs-glossary) * [What should I read after the glossary?](#what-should-i-read-after-the-glossary) ## Is this the same as the official docs glossary?[#](#is-this-the-same-as-the-official-docs-glossary) No — the official [documentation glossary](https://docs.apitube.io/platform/news-api/glossary) leans toward response-field definitions for developers reading the API reference. This page covers the same vocabulary in plainer language and adds the account-side terms (workspace, scope, PAYG, test key) you meet in the dashboard, linking each one to its how-to article in this help centre. ## What should I read after the glossary?[#](#what-should-i-read-after-the-glossary) If you have not called the API yet, go to [how to run your first news search](/en/articles/getting-started/your-first-search) — it walks through one request end to end. If you are deciding whether APITube fits your project, [key concepts](/en/articles/getting-started/key-concepts) explains the data model these terms come from. * * * ## Related Articles * [Key concepts: articles, sources, entities, sentiment, stories](/en/articles/getting-started/key-concepts) * [How credits work](/en/articles/billing/credits/how-credits-work) * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) --- ## How does APITube collect and process news? URL: https://support.apitube.io/en/articles/getting-started/how-apitube-collects-news APITube discovers news from RSS feeds, Google News and sitemaps, fetches and parses each article, enriches it with language, sentiment and entities, then… # How does APITube collect and process news? From publisher feeds to enriched JSON — how raw articles become queryable data ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 # How does APITube collect and process news?[#](#how-does-apitube-collect-and-process-news) APITube continuously discovers news from publishers across the web — through their RSS feeds, Google News and XML sitemaps — then fetches each article, extracts the clean text, enriches it with NLP (language, [sentiment](/en/articles/getting-started/glossary#sentiment), named [entities](/en/articles/getting-started/glossary#entity) and category, topic and industry labels), and indexes the result so you can pull it with a single REST call, a live stream or a [webhook](/en/articles/getting-started/glossary#webhook). You never scrape a page or parse a feed yourself: by the time news reaches you it is already structured, labelled JSON. In short, the pipeline has four stages — **discover, fetch, enrich, serve** — and the rest of this article walks through each. For what the finished article object looks like, see [what’s inside a news article](/en/articles/getting-started/understanding-article-data). ## Where does APITube get its news from?[#](#where-does-apitube-get-its-news-from) APITube finds articles by monitoring the places publishers announce them, not by guessing URLs. Three discovery sources feed the pipeline: * **RSS feeds** — the feeds publishers maintain for their own sites. * **Google News** — used as a broad discovery channel across many outlets. * **XML sitemaps** — the sitemap files sites publish to list their pages. These sources are polled continuously, so newly published URLs are picked up as they appear rather than on a fixed daily batch. Each discovered URL is queued for the next stage; the result is a steady stream of fresh links from a wide range of outlets. ## How is a raw web page turned into structured data?[#](#how-is-a-raw-web-page-turned-into-structured-data) Once a URL is discovered, APITube fetches the page and turns its HTML into a clean article. The processing stages run one after another: 1. **Fetch** — APITube downloads the article’s HTML from the publisher. 2. **Parse and extract** — the main article text is pulled out of the page and separated from navigation, ads and other boilerplate, leaving the readable body. 3. **Enrich** — natural-language processing runs over that text to add the metadata you query on (covered in the next section). 4. **Index** — the finished article is stored and indexed so it can be searched, retrieved and streamed quickly. The output of this pipeline is the structured JSON object the API returns — a headline, body, URL, publish date and source, plus the enrichment APITube computed. You query the indexed result, never the live web page. ## What does APITube add to each article?[#](#what-does-apitube-add-to-each-article) The enrichment stage is what makes APITube more than a list of links: it attaches machine-readable metadata to every article so you can filter and analyse without reading the text yourself. Each processed article carries: * **Language** — the detected language code of the article text. * **Sentiment** — an overall positive, neutral or negative reading, plus sentiment toward individual entities. * **Entities** — the people, organizations, locations, products and other names mentioned, with their positions in the text. * **Classification** — category, topic and industry labels. * **Source and media metadata** — the publisher, and the images and media attached to the article. These fields are computed for you on every article, so a single request returns news already tagged by language, sentiment, who is mentioned and what it is about. For the vocabulary behind these — articles, sources, entities, stories — see [key concepts](/en/articles/getting-started/key-concepts). ## How do you get the processed news?[#](#how-do-you-get-the-processed-news) The indexed, enriched articles are served from a single base URL, `https://api.apitube.io`, in three ways, all using the same [API key](/en/articles/getting-started/glossary#api-key): * **REST (pull)** — search and retrieval endpoints such as `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/article` return data on demand, as JSON or an [export format](/en/articles/getting-started/glossary#export-format). * **Real-time streaming** — the [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream (`/v1/news/stream`) and the WebSocket feed push matching articles to you as they are indexed. * **Webhooks** — APITube posts new matching articles to a URL you control, so your system reacts without polling. Choose pull for periodic jobs and streaming or webhooks when you need news the moment it is processed. To make a first call, follow [how to run your first news search](/en/articles/getting-started/your-first-search); the full parameter list is on the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Do I have to scrape or parse HTML myself?](#do-i-have-to-scrape-or-parse-html-myself) * [Can I get the original article body and HTML?](#can-i-get-the-original-article-body-and-html) * [How soon do new articles become available?](#how-soon-do-new-articles-become-available) * [What enrichment is applied to each article?](#what-enrichment-is-applied-to-each-article) ## Do I have to scrape or parse HTML myself?[#](#do-i-have-to-scrape-or-parse-html-myself) No. Fetching the page, stripping boilerplate and extracting the readable body all happen inside APITube’s pipeline before the article reaches you. The API returns clean, structured JSON — a title, body, source, date and enrichment fields — so there is no HTML parsing, feed handling or scraping on your side. ## Can I get the original article body and HTML?[#](#can-i-get-the-original-article-body-and-html) Yes. The `/v1/news/raw` endpoint returns the article’s raw text in two fields: `body` (plain text) and `body_html` (the HTML version). Use it when you need the unprocessed content rather than the cleaned, enriched object the search endpoints return. See [how to get the raw article body and HTML](/en/articles/retrieval/get-raw-body) for the call. ## How soon do new articles become available?[#](#how-soon-do-new-articles-become-available) Discovery runs continuously rather than as a once-a-day batch, so articles are processed and indexed shortly after a publisher lists them, then become searchable. If you need news the instant it is indexed rather than polling on a schedule, subscribe to the Server-Sent Events stream or a webhook, which deliver matching articles as they are processed. ## What enrichment is applied to each article?[#](#what-enrichment-is-applied-to-each-article) Every article is enriched with its detected language, an overall sentiment reading plus sentiment toward named entities, the entities themselves (people, organizations, locations and products with their text positions), and classification into category, topic and industry. This is the metadata you filter and sort on across the API, and it is attached automatically — you do not request enrichment separately. * * * ## Related Articles * [What is APITube News API?](/en/articles/getting-started/what-is-apitube-news-api) * [What's inside a news article?](/en/articles/getting-started/understanding-article-data) * [Key concepts: articles, sources, entities, sentiment, stories](/en/articles/getting-started/key-concepts) --- ## How far back does the news archive go? URL: https://support.apitube.io/en/articles/getting-started/how-far-back-archive-goes How far back the APITube news archive goes: no fixed number — depth varies by source, language and topic. Sort ascending and read the oldest article to measure… # How far back does the news archive go? There is no single fixed cut-off — how to measure the exact archive depth for your own query ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 4, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&sort_by=published_at&sort_order=asc&per_page=1) # How far back does the news archive go?[#](#how-far-back-does-the-news-archive-go) APITube does **not** publish a single fixed “N years back” cut-off, because archive depth varies by source, language and topic — a large English wire agency reaches back much further than a niche local site added last month. The reliable way to know how deep the archive is **for your query** is to sort your results oldest-first and read the earliest article’s date. No API parameter reports a headline depth figure, so you measure it directly instead of trusting a number. There is no separate “archive” endpoint either: historical and fresh articles come from the same `/v1/news/everything` search. That means the same trick — sort ascending, take the first result — works on any filtered slice you care about. ## Is there a fixed cut-off date for the archive?[#](#is-there-a-fixed-cut-off-date-for-the-archive) No. The News API exposes no field or parameter that returns a global “earliest date” or a total-years number, and the coverage figures on the marketing site are not a per-query guarantee. What actually determines how far back a result set reaches is your **filters**: the language, source, country or [entity](/en/articles/getting-started/glossary#entity) you asked for. A query restricted to one small publisher will bottom out at that publisher’s oldest ingested article; a broad query across many sources reaches back to the oldest article among all of them. Because depth is query-dependent, the honest answer is a method, not a constant: ask the archive for the oldest article that matches your filters and read its timestamp. ## How do I find the earliest article for my query?[#](#how-do-i-find-the-earliest-article-for-my-query) Sort by publication date **ascending** and request a single article. By default results come back newest-first (`sort.by` defaults to `published_at`, `sort.order` to `desc`), so flip the order to `asc` and set `per_page=1`: ``` curl "https://api.apitube.io/v1/news/everything?sort.by=published_at&sort.order=asc&per_page=1&api_key=YOUR_API_KEY" ``` The `published_at` of that one article is the earliest date the archive currently holds for an unfiltered query. To measure the depth of a **specific** slice, add your filters before running it — for example, the oldest German-language article, or the oldest article from one domain: ``` curl "https://api.apitube.io/v1/news/everything?language.code=de&sort.by=published_at&sort.order=asc&per_page=1&api_key=YOUR_API_KEY" ``` Pass your key as the `api_key` query parameter or the `X-API-Key` header. This probe costs the same as any small search and answers the depth question precisely for the exact query you plan to run. ## How much history exists in a given period?[#](#how-much-history-exists-in-a-given-period) To gauge _volume_ rather than the earliest date, use `/v1/news/count` with a date range. On a **live** key, passing a real filter (such as `published_at.start` / `published_at.end`) returns the true number of matching articles for that window without downloading them: ``` curl "https://api.apitube.io/v1/news/count?published_at.start=2023-01-01&published_at.end=2023-12-31&api_key=YOUR_API_KEY" ``` Two caveats worth knowing: a **count with no filters at all** returns a large rounded showcase figure rather than a literal database size, and a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** always returns a showcase number instead of the real volume. So to profile how much history exists in a period, use a live key and always include the date range. Stepping the window month by month is a quick way to see how article volume grows over time — see [how to count news articles](/en/articles/retrieval/count-articles) for the endpoint’s details. ## Can I read the whole archive at once?[#](#can-i-read-the-whole-archive-at-once) No — a single response is capped at `per_page=250`, or 200 on Basic, 50 on Starter and 10 on Free (a larger value returns `ER0171`), so any deep window is retrieved across multiple pages. Fix a date range, sort ascending, and increment `page` until the results run out, then move the window and repeat. The querying mechanics — accepted date formats, [pagination](/en/articles/getting-started/glossary#pagination), and the plan-based page limits — are covered in full in [can I access historical news archives?](/en/articles/news-data/historical-archives) and the parameter itself in [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). The complete date syntax also lives in the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). **Depth is not the same as freshness.** This page is about how far _back_ the archive reaches. For how quickly a brand-new article shows up, see [how fresh is the data and what is the latency?](/en/articles/getting-started/how-fresh-is-the-data) # Common Questions[#](#common-questions) * [Does APITube have a separate archive endpoint?](#does-apitube-have-a-separate-archive-endpoint) * [Why isn’t there a single “N years” number?](#why-isnt-there-a-single-n-years-number) * [Can I reach older articles on the Free plan?](#can-i-reach-older-articles-on-the-free-plan) ## Does APITube have a separate archive endpoint?[#](#does-apitube-have-a-separate-archive-endpoint) No. Historical articles and fresh articles are served by the **same** `/v1/news/everything` endpoint — what makes a request “historical” is the date filter you add (`published_at.start` / `published_at.end`), not a different URL. Every other filter (language, source, entity, country) combines with the date range in the same request, so you narrow the archive exactly like you narrow recent news. ## Why isn’t there a single “N years” number?[#](#why-isnt-there-a-single-n-years-number) Because coverage depth is not uniform. Different sources were added at different times, and per language and topic the earliest available article differs. A global constant would be misleading for most queries, so instead of publishing one figure APITube lets you **measure** the earliest date for your specific filters (sort ascending, `per_page=1`). That number is the one that actually applies to your use case. ## Can I reach older articles on the Free plan?[#](#can-i-reach-older-articles-on-the-free-plan) The date filter itself is not restricted on the Free plan — you can query any past range. What is limited is how deep you can paginate: Free stops after the first **5 pages** (`ER0173`) and caps `per_page` at 10, which puts a single Free query at up to 50 articles. To page further into a historical window, upgrade to a paid plan. The earliest-article probe above still works on Free, since it only needs the first page. * * * ## Related Articles * [Can I access historical news archives?](/en/articles/news-data/historical-archives) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) --- ## How Fresh Is the Data and What Is the Latency? URL: https://support.apitube.io/en/articles/getting-started/how-fresh-is-the-data APITube returns newest-first by default and pushes new matches over SSE every 30 seconds; each article carries the publisher's own published_at time. # How Fresh Is the Data and What Is the Latency? How the published\_at timestamp works, how to get the newest articles first, and how to receive matches in near real time ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 4, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=Tesla) # How fresh is the data and what is the latency?[#](#how-fresh-is-the-data-and-what-is-the-latency) By default the APITube News API returns the **newest articles first**, and its real-time [SSE](/en/articles/getting-started/glossary#sse-stream) stream re-checks the index and pushes any new matches **every 30 seconds**. Each article carries the **publisher’s own `published_at` timestamp**, so an article’s availability depends on how quickly APITube discovers, fetches and parses it — there is no single fixed latency number, but a fresh search always surfaces the latest matching items at the top. ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&api_key=YOUR_API_KEY" ``` That request already sorts by publish time, newest first — you do not have to add a sort parameter to get the freshest results. ## What does the published\_at timestamp mean?[#](#what-does-the-published_at-timestamp-mean) The `published_at` field is the **time the source published the article**, not the time APITube ingested it. Between those two moments sits the collection pipeline: an article has to be discovered (via RSS, sitemaps and other feeds), fetched, then parsed and enriched before it becomes searchable. So the gap between when a story goes live on a publisher’s site and when it appears in your query is the length of that discovery-fetch-parse path — it varies by source and is not a guaranteed interval. This matters when you measure “age”: `now − published_at` includes that pipeline lag, so a just-indexed article can still show a `published_at` a little in the past. The timestamp is honest about the publisher’s clock, which is what you want for filtering and sorting by real publish time. ## How do I get the newest articles first?[#](#how-do-i-get-the-newest-articles-first) You already get newest-first without asking: the default sort is `published_at` in descending order. To be explicit — or to flip it — set `sort.by` and `sort.order`: ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` * `sort.by=published_at` — order by publish time (the default). * `sort.order=desc` — newest first (the default); use `asc` for oldest first. If you want the most recent items by any other axis, `sort.by` also accepts modes like `relevance`, `engagement` and `quality`. See [how to sort by relevance, date, engagement or quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) for the full list. ## How do I limit results to the last hour or day?[#](#how-do-i-limit-results-to-the-last-hour-or-day) Add a lower bound with `published_at.start`. It accepts absolute dates (`2026-07-01`, or a full `2026-07-01T09:00:00Z`) **and** relative Solr-style expressions built from `NOW`: ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&published_at.start=NOW-1HOUR&api_key=YOUR_API_KEY" ``` * `NOW-1HOUR` — only articles published in the last hour. * `NOW-1DAY` / `NOW-7DAY` — the last day or week. * `NOW/DAY` — since the start of today (UTC). Pair it with `published_at.end` to bound the top of the window. Both filter on the publisher’s `published_at`, so they follow real publish time, not ingestion order. For the full date syntax, see [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## How do I receive new articles in near real time?[#](#how-do-i-receive-new-articles-in-near-real-time) Instead of polling the search endpoint yourself, open the Server-Sent Events stream at `/v1/news/stream` with the same filters. The server re-checks the index every **30 seconds** and pushes any new matching articles down the open connection, so you get near real-time delivery without writing a poll loop: ``` curl -N "https://api.apitube.io/v1/news/stream?title=Tesla&api_key=YOUR_API_KEY" ``` The stream reads new articles by a stable indexing cursor so nothing is skipped or delivered twice, and it sorts each 30-second batch by `published_at` before sending, so items arrive in publish-time order. For setup, resuming and event format, see [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## How do I drop stale backfill from the stream?[#](#how-do-i-drop-stale-backfill-from-the-stream) Newly discovered articles sometimes carry an older `published_at` (a source that was just crawled but published hours ago). To keep only genuinely recent items, add `stream.max_age`, a rolling freshness window measured in **minutes**: ``` curl -N "https://api.apitube.io/v1/news/stream?title=Tesla&stream.max_age=60&api_key=YOUR_API_KEY" ``` `stream.max_age=60` delivers only articles published within the last 60 minutes and re-applies that window on every 30-second poll, dropping older backfill **before** it is delivered. The value must be a positive whole number of minutes; an invalid value returns `HTTP 400` with error `ER0363` rather than being silently ignored. # Common Questions[#](#common-questions) * [Is there a guaranteed maximum latency?](#is-there-a-guaranteed-maximum-latency) * [Why does an article’s published\_at look slightly in the past?](#why-does-an-articles-published_at-look-slightly-in-the-past) * [How often does the SSE stream check for new articles?](#how-often-does-the-sse-stream-check-for-new-articles) * [Do I need a sort parameter to get the latest news?](#do-i-need-a-sort-parameter-to-get-the-latest-news) ## Is there a guaranteed maximum latency?[#](#is-there-a-guaranteed-maximum-latency) There is no fixed end-to-end latency figure. How soon an article appears depends on the collection pipeline — discovery, fetch, then parse — which varies by source and feed. What is fixed is the delivery cadence once an article is indexed: the SSE stream pushes new matches every 30 seconds, and a default search always returns the newest matching items first. ## Why does an article’s published\_at look slightly in the past?[#](#why-does-an-articles-published_at-look-slightly-in-the-past) Because `published_at` reflects the **publisher’s** publish time, not when APITube indexed it. The article only becomes searchable after it is discovered, fetched and parsed, so `now − published_at` includes that pipeline lag. The timestamp is accurate to the source, which is exactly what date filters and publish-time sorting rely on. ## How often does the SSE stream check for new articles?[#](#how-often-does-the-sse-stream-check-for-new-articles) Every 30 seconds. The `/v1/news/stream` endpoint polls the index on a 30-second interval and forwards any new matching articles, with a heartbeat on the same cadence to keep the connection alive. That is the freshest delivery method; regular search endpoints return whatever is indexed at request time. ## Do I need a sort parameter to get the latest news?[#](#do-i-need-a-sort-parameter-to-get-the-latest-news) No. The default sort is already `published_at` descending, so the newest articles come back first on `/v1/news/everything` without any sort parameter. Add `sort.by` and `sort.order` only when you want a different order, or use `published_at.start=NOW-1HOUR` to also restrict the window to recent items. * * * ## Related Articles * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Sort by Relevance, Date, Engagement or Quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) --- ## How many news sources does APITube cover? URL: https://support.apitube.io/en/articles/getting-started/how-many-sources APITube aggregates news from more than 300,000 sources. There is no list-all endpoint — verify coverage with the source.domain filter and facets on source.id. # How many news sources does APITube cover? The size of the source pool, and how to verify coverage for the publishers you actually care about ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 7, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_domain=bloomberg.com&per_page=1) # How many news sources does APITube cover?[#](#how-many-news-sources-does-apitube-cover) APITube aggregates news from **more than 300,000 sources** — the news websites and publishers it crawls worldwide. That is the headline number, but for most projects the useful question is narrower: _are the specific publishers I care about covered?_ Because APITube deliberately does not expose a single “download every source” endpoint, you confirm coverage by probing for the sources you need rather than pulling one giant list. This page gives you the coverage figure, explains what counts as a source, and shows the three practical ways to check whether a given publisher — or a whole set of them — is in the pool. ## How big is the source pool?[#](#how-big-is-the-source-pool) The pool is **300,000+ news websites**. A “source” in APITube is one publisher domain that the pipeline discovers and crawls — a site like `reuters.com` or `bbc.co.uk`, not an individual article. Each source carries its own metadata: a `name`, a `domain`, a `type`, a political `bias` label, and an [OPR authority rank](/en/articles/trust-and-support/what-is-opr). Those sources publish across many languages and countries — for the language and country breakdown, see [which languages and countries are supported](/en/articles/getting-started/supported-languages-and-countries). ## Is there an endpoint that lists every source?[#](#is-there-an-endpoint-that-lists-every-source) No. There is no directory endpoint that dumps the full source list — a plain `/v1/sources` route is intentionally not available. With half a million publishers, a list-all call would be unusable anyway. Instead, you filter your search to a specific domain, or aggregate the sources inside a result set with facets. The two sections below cover each approach. ## How do I check whether a specific source is covered?[#](#how-do-i-check-whether-a-specific-source-is-covered) Filter any search by the exact publisher domain with `source.domain`. A tracked domain returns that publisher’s articles; a domain APITube does not track fails fast with `400` and error `ER0214` (`source domain name '…' not found`) — so the response itself is a definitive coverage check: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=bloomberg.com&per_page=1&api_key=YOUR_API_KEY" ``` You supply the domain yourself (the publisher’s website address); there is no name-based lookup endpoint. Every article that comes back carries a `source` object with the publisher’s stable numeric `id`, `domain`, `type`, `home_page_url` and [OPR](/en/articles/getting-started/glossary#opr-open-pagerank) rank — read the `id` there to switch to `source.id` filtering, which survives a publisher changing its domain. ## How do I restrict a search to specific sources?[#](#how-do-i-restrict-a-search-to-specific-sources) To read several publishers at once, filter with `source.domain` and pass up to **three** domains as a comma-separated list: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=bbc.co.uk,reuters.com&api_key=YOUR_API_KEY" ``` If any domain you pass is not in the pool, the request fails fast with `400` and error `ER0214` (`source domain name '…' not found`), so one unknown domain blocks the whole call. To go the other direction and _exclude_ sources, use `ignore.source.domain`. The full filter is documented in [how to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source). ## How do I see which sources appear in my results?[#](#how-do-i-see-which-sources-appear-in-my-results) To measure the source diversity of a query — how many different publishers cover a topic and which ones dominate — add a **facet** on `source.id`. Set `facet=true` and name the field with `facet.field`: ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&facet=true&facet.field=source.id&facet.limit=20&api_key=YOUR_API_KEY" ``` The response includes a `facets` block that counts articles per source for that query. `facet.limit` defaults to 10 and caps at 100, and `facet.field` is required when `facet=true` (otherwise `ER0310`). This turns “how many sources cover this?” into a number you can read straight off a single request. # Common Questions[#](#common-questions) * [Can I download the full list of sources?](#can-i-download-the-full-list-of-sources) * [What counts as one source?](#what-counts-as-one-source) * [What if the source I need is not covered?](#what-if-the-source-i-need-is-not-covered) * [How current is the 300,000+ figure?](#how-current-is-the-300000-figure) ## Can I download the full list of sources?[#](#can-i-download-the-full-list-of-sources) No. APITube does not offer a list-all sources endpoint, so there is no single call that returns all 300,000+ publishers. The supported pattern is to check the publishers you need with the `source.domain` filter — a tracked domain returns articles, an unknown one returns `ER0214` — and filter searches to them. If you want to profile the sources behind a topic instead of a fixed list, facet a search on `source.id` and read the per-source counts. ## What counts as one source?[#](#what-counts-as-one-source) One source is one publisher domain that APITube crawls — a website such as `reuters.com`, counted once regardless of how many articles it publishes. Each source has a stable `id`, a `domain`, a resource `type`, and an OPR authority rank, which you can read from the `source` object on any returned article or use as search filters (`source.id`, `source.domain`). ## What if the source I need is not covered?[#](#what-if-the-source-i-need-is-not-covered) If `source.domain` rejects the domain with `ER0214`, the publisher is not yet in the pool — but you can ask for it to be added. See [how to request a new news source](/en/articles/trust-and-support/request-news-source). New sources are added over time, so a domain that is missing today may be covered later. ## How current is the 300,000+ figure?[#](#how-current-is-the-300000-figure) 300,000+ is the coverage figure APITube publishes, and the pool grows as new publishers are discovered, so treat it as a floor rather than a fixed cap. Because coverage changes, the reliable check for any single project is always to probe the exact publishers you need with the `source.domain` filter rather than rely on a headline count. * * * ## Related Articles * [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to request a new news source](/en/articles/trust-and-support/request-news-source) * [What is the OPR (Open Page Rank) score?](/en/articles/trust-and-support/what-is-opr) --- ## Getting Started URL: https://support.apitube.io/en/articles/getting-started Learn what the APITube News API does, how news data is structured, and how to run your first search in under a minute. ![](/images/collections/get-started.svg) # Getting Started What the API does and your first search. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Kent and 2 others 3 authors 12 articles New to the APITube News API? Start here. These articles explain what the API does, where the news comes from, how fresh the data is, and how far back the archive goes — everything you need to judge whether APITube fits your project before you write a line of code. If you want to skip straight to practice, read [key concepts](/en/articles/getting-started/key-concepts) first, then pick a plan with [which plan is right for you](/en/articles/getting-started/which-plan-is-right). Most readers run their first successful request within a few minutes of getting an API key. * [Glossary of News API terms](/en/articles/getting-started/glossary) * [How does APITube collect and process news?](/en/articles/getting-started/how-apitube-collects-news) * [How far back does the news archive go?](/en/articles/getting-started/how-far-back-archive-goes) * [How Fresh Is the Data and What Is the Latency?](/en/articles/getting-started/how-fresh-is-the-data) * [How many news sources does APITube cover?](/en/articles/getting-started/how-many-sources) * [How to run your first news search](/en/articles/getting-started/your-first-search) * [Key concepts: articles, sources, entities, sentiment, stories](/en/articles/getting-started/key-concepts) * [What Can You Build with the News API?](/en/articles/getting-started/what-can-i-build) * [What is APITube News API?](/en/articles/getting-started/what-is-apitube-news-api) * [What's inside a news article?](/en/articles/getting-started/understanding-article-data) * [Which APITube plan is right for me?](/en/articles/getting-started/which-plan-is-right) * [Which Languages and Countries Does the News API Support?](/en/articles/getting-started/supported-languages-and-countries) --- ## Key concepts: articles, sources, entities, sentiment, stories URL: https://support.apitube.io/en/articles/getting-started/key-concepts The core APITube concepts: article = one news item, source = its publisher, entities = people and companies mentioned, sentiment = tone, story = grouped… # Key concepts: articles, sources, entities, sentiment, stories The five building blocks of the APITube News API data model — what each one means and how they fit together ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 Updated July 6, 2026 # Key concepts: articles, sources, entities, sentiment, stories[#](#key-concepts-articles-sources-entities-sentiment-stories) Five concepts make up the APITube News API data model. An **article** is one news item; a **source** is the website that published it; **[entities](/en/articles/getting-started/glossary#entity)** are the people, companies and places the article mentions; **[sentiment](/en/articles/getting-started/glossary#sentiment)** is the tone of the text; and a **story** is the group of articles that cover the same event across different sources. Every search you run returns articles, and each article carries its source, entities and sentiment inside it — so understanding these five terms is enough to read any response. If you have not made a call yet, start with [how to run your first news search](/en/articles/getting-started/your-first-search); this article explains what the fields in that response actually mean. ## What is an article?[#](#what-is-an-article) An **article** is the central object — one published news item, returned as one element of the `results` array. Each article object carries the content (`title`, `description`, `body`), where and when it ran (`href`, `published_at`, `language`), and a block of NLP enrichment computed by APITube: `entities`, `sentiment`, `keywords`, `summary`, `categories`, `topics` and `industries`. It also includes practical flags such as `is_duplicate`, `is_breaking` and `read_time`, plus a `media` list for images and video. The `id` field is the article’s unique identifier — you reuse it to fetch the full article or its related story. ## What is a source?[#](#what-is-a-source) A **source** is the publisher an article came from. Every article has a `source` object describing that publisher: its `domain` (for example `reuters.com`), `home_page_url`, `type`, political `bias` (such as `left`, `center` or `right`), a `location` with the publisher’s country, and a `rankings.opr` value. **[OPR](/en/articles/getting-started/glossary#opr-open-pagerank)** (Open Page Rank) is APITube’s authority score for the site — a higher OPR means a more established, widely-referenced publisher. Sources are how you separate a wire service from a personal blog: you can filter or sort by source domain, bias and OPR to keep results to outlets you trust. ## What is an entity?[#](#what-is-an-entity) An **entity** is a real-world thing APITube detected in the article text — a person, company, place, product and more. Each entry in an article’s `entities` array has a `name`, a `type`, a `frequency` (how often it appears), its own `sentiment`, and `links` to its Wikipedia and Wikidata pages so you can disambiguate “Apple the company” from “apple the fruit.” APITube recognizes nine entity types: * `person`, `location`, `organization`, `brand`, `product` * `natural-disaster`, `disease`, `event`, `sport` Entities are what let you ask “show me every article that mentions this company” instead of guessing keywords — see [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## What is sentiment?[#](#what-is-sentiment) **Sentiment** is the emotional tone of the text, scored by APITube’s NLP. Each article has a `sentiment` object with three angles — `overall`, `title` and `body` — and each one carries a `polarity` (positive, negative or neutral) plus a numeric `score`. Sentiment is also computed **per entity**, so an article can be broadly positive overall while being negative toward one company it names. That entity-level sentiment lives inside each entity’s own `sentiment` block, with a count of positive, neutral and negative mentions. Use the article-level value to gauge a headline’s mood, and the entity-level value to track how one brand or person is being portrayed. ## What is a story?[#](#what-is-a-story) A **story** is a group of articles that cover the same real-world event from different outlets. The same news — a product launch, an election result, a disaster — gets written up by dozens of sources, and the story concept ties that coverage together. Each article carries a `story` reference, and you fetch the rest of the coverage with the `/v1/news/story/:id` endpoint, which finds other articles whose headlines share the source article’s keywords and ranks them by overlap. Stories are how you go from one article to the full picture of an event — see [how to get all articles covering the same story](/en/articles/retrieval/get-story-cluster). The related `is_duplicate` flag marks near-identical re-posts so you can collapse them. # Common Questions[#](#common-questions) * [What is the difference between an article and a story?](#what-is-the-difference-between-an-article-and-a-story) * [What types of entities does APITube detect?](#what-types-of-entities-does-apitube-detect) * [Is sentiment scored for the whole article or per entity?](#is-sentiment-scored-for-the-whole-article-or-per-entity) * [What is the difference between categories, topics and industries?](#what-is-the-difference-between-categories-topics-and-industries) ## What is the difference between an article and a story?[#](#what-is-the-difference-between-an-article-and-a-story) An **article** is a single news item from one source — one row in your `results`. A **story** is the set of articles, usually from many sources, that report the same event. One story contains many articles; one article belongs to one story. Use an article when you want a specific piece of coverage, and a story when you want every outlet’s take on the same event. ## What types of entities does APITube detect?[#](#what-types-of-entities-does-apitube-detect) APITube classifies each detected entity as one of nine types: `person`, `location`, `organization`, `brand`, `product`, `natural-disaster`, `disease`, `event` and `sport`. The `type` field on each entity tells you which one it is, so you can, for example, pull only the organizations mentioned in an article or only the locations. ## Is sentiment scored for the whole article or per entity?[#](#is-sentiment-scored-for-the-whole-article-or-per-entity) Both. Every article has an overall `sentiment` (with separate `title` and `body` readings), and APITube also scores sentiment toward each individual entity it detects. So a single article can read as neutral overall yet carry clearly negative sentiment toward one company it names — the per-entity score captures that, which the article-level score alone would miss. ## What is the difference between categories, topics and industries?[#](#what-is-the-difference-between-categories-topics-and-industries) They are three separate classification layers attached to every article. **Categories** are the standardized IPTC news taxonomy (such as politics or health), **topics** are finer-grained subject tags, and **industries** map an article to a business sector. Each is its own array on the article and its own filter, so you can narrow a search by any of the three independently. * * * ## Related Articles * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) --- ## Which Languages and Countries Does the News API Support? URL: https://support.apitube.io/en/articles/getting-started/supported-languages-and-countries APITube News API supports 59 languages and 177 countries. Filter by an article's language with language.code and by the publisher's country with… # Which Languages and Countries Does the News API Support? Filter articles across 59 languages and 177 countries with language.code and source.country.code ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 4, 2026 Updated July 7, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en) # Which languages and countries does the News API support?[#](#which-languages-and-countries-does-the-news-api-support) The APITube News API lets you filter articles across **59 languages** and **177 countries**. You narrow results by an article’s detected language with the `language.code` parameter (for example `en`), and by the publisher’s country with `source.country.code` (for example `us`). The full, authoritative code lists are published in the API reference — the [list of languages](https://docs.apitube.io/platform/news-api/list-of-languages) and the [list of countries](https://docs.apitube.io/platform/news-api/list-of-countries). Language codes follow the two-letter ISO 639-1 style (`en`, `fr`, `de`), and country codes follow the two-letter ISO 3166 style (`us`, `gb`, `jp`). Each filter accepts up to **three** codes at once, separated by commas, and returns articles matching **any** of them. ## Which languages can you filter by?[#](#which-languages-can-you-filter-by) APITube recognizes **59 languages** you can pass to `language.code`, plus an `un` value that stands for undetected or unknown content. The language APITube detects on each article at processing time is what you filter against. To fetch only English articles: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&api_key=YOUR_API_KEY" ``` Pass several codes to widen the net — up to three, comma-separated, matched with OR: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en,fr,de&api_key=YOUR_API_KEY" ``` A few rules to know. A code must be one or two characters, or the request returns `400 ER0061`. An unrecognized code returns `400 ER0237` (“language with code not found”), so check spelling against the [list of languages](https://docs.apitube.io/platform/news-api/list-of-languages). One quirk: `language.code=us` is treated as `en`. For the full mechanics, see [how to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). ## Which countries can you filter by?[#](#which-countries-can-you-filter-by) `source.country.code` covers **177 countries** (plus an `un` value for unknown-origin sources) and filters by the country of the news **source** — where the publisher is based — using a two-letter code. To get articles from United States sources: ``` curl "https://api.apitube.io/v1/news/everything?source.country.code=us&api_key=YOUR_API_KEY" ``` Like language, it accepts up to three codes, comma-separated and OR-matched, for example `source.country.code=us,gb,ca`. Each code must be exactly two characters (else `400 ER0246`), and an unknown code returns `400 ER0212`. Because this parameter is about the publisher, not the story’s subject, it answers “which country’s outlets ran this?” rather than “where did this happen?”. To target where an event took place, use the location filters covered in [how to filter news by country and location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location). ## How do you combine language and country?[#](#how-do-you-combine-language-and-country) The two filters stack, so you can pin both the language and the source country in one request. This returns English-language articles from United States and United Kingdom sources: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&source.country.code=us,gb&api_key=YOUR_API_KEY" ``` Within a single filter the codes are OR-matched (any of the listed languages, any of the listed countries); across the two filters they are combined with AND (the language **and** the country must both match). You can layer any other filter on top — a `title` search, a date range, or a category — because language and country are part of the shared filter chain. You can send the key as the `api_key` query parameter or as an `X-API-Key` header. ## How do you exclude a language or country?[#](#how-do-you-exclude-a-language-or-country) To remove specific languages or countries instead of selecting them, use the `ignore.` variants. `ignore.language.code` drops articles in the listed languages, and `ignore.source.country.code` drops articles from the listed source countries — each accepting up to three comma-separated codes: ``` curl "https://api.apitube.io/v1/news/everything?ignore.language.code=fr&ignore.source.country.code=gb&api_key=YOUR_API_KEY" ``` # Common Questions[#](#common-questions) * [How many languages and countries are supported?](#how-many-languages-and-countries-are-supported) * [What does language.code=us do?](#what-does-languagecodeus-do) * [Does source.country.code mean where the news happened?](#does-sourcecountrycode-mean-where-the-news-happened) * [Are all languages and countries covered equally?](#are-all-languages-and-countries-covered-equally) ## How many languages and countries are supported?[#](#how-many-languages-and-countries-are-supported) The `language.code` filter supports **59 languages** (plus an `un` value for undetected content), and `source.country.code` supports **177 countries** (plus an `un` value). These come straight from the API reference lists, which are the authoritative source: the [list of languages](https://docs.apitube.io/platform/news-api/list-of-languages) and the [list of countries](https://docs.apitube.io/platform/news-api/list-of-countries). If a code is not on those lists, the API rejects it. ## What does language.code=us do?[#](#what-does-languagecodeus-do) `us` is not a language, but the API maps `language.code=us` to `en` (English) as a convenience. If you meant to filter by United States **sources**, use `source.country.code=us` instead — that is the country filter, while `language.code` is only about the article’s language. ## Does source.country.code mean where the news happened?[#](#does-sourcecountrycode-mean-where-the-news-happened) No. `source.country.code` filters by the country of the **publisher** that ran the article, not the location the story is about. A US outlet reporting on an event in Japan is a `source.country.code=us` article. To filter by the geographic location of the story, use the location filters described in [how to filter news by country and location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location). ## Are all languages and countries covered equally?[#](#are-all-languages-and-countries-covered-equally) The code lists tell you what you can filter by, not how many articles exist for each value. Article volume varies by language and country — high-output languages and countries return far more results than niche ones. If a specific `language.code` or `source.country.code` returns few articles, the code is valid but coverage for that value is simply thinner. Learn how the pipeline gathers articles in [how APITube collects and processes news](/en/articles/getting-started/how-apitube-collects-news). * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Country and Location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location) * [How does APITube collect and process news?](/en/articles/getting-started/how-apitube-collects-news) --- ## What's inside a news article? URL: https://support.apitube.io/en/articles/getting-started/understanding-article-data What's inside an APITube news article object: the content, classification, entity, sentiment, source and quality fields returned for every article, with a real… # What's inside a news article? The fields APITube returns for every article — content, classification, entities, sentiment, source and quality signals ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 Updated July 31, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fcategory%2F%7Btaxonomy%7D%2F%7Bcategory_id%7D&pp_taxonomy=iptc_mediatopics&pp_category_id=medtop%3A15000000) # What’s inside a news article?[#](#whats-inside-a-news-article) Every article APITube returns is a single JSON object with the **same fixed shape**, whether it comes from a search, a stream, or a single-article lookup. Alongside the obvious content fields — `title`, `description`, `body`, `href`, `image`, `published_at` — each object carries machine-readable enrichment: `categories`, `topics`, `industries`, `entities`, three levels of `sentiment`, a `source` profile, `readability` scores, social `shares`, and status flags. That enrichment is what turns a raw headline into something you can filter, score, and act on. If you are new to the vocabulary here (article vs source vs [entity](/en/articles/getting-started/glossary#entity) vs story), start with [key concepts](/en/articles/getting-started/key-concepts), then come back for the field-by-field breakdown. ## What does a news article object look like?[#](#what-does-a-news-article-object-look-like) Here is a trimmed example showing the overall structure (most arrays and nested fields are abbreviated): ``` { "id": 1234567, "href": "https://www.example-news.com/markets/...", "published_at": "2026-06-28T09:15:00.000Z", "title": "Central bank holds rates steady", "description": "The decision was widely expected by markets...", "language": "en", "translations": { "en": { "title": null, "description": null } }, "author": { "id": 88, "name": "Jane Doe" }, "categories": [ { "id": 5012, "name": "Sport", "score": 0.92, "taxonomy": "iptc_mediatopics", "links": { "self": "https://api.apitube.io/v1/news/category/iptc_mediatopics/medtop:15000000" } } ], "entities": [ { "id": 4521, "name": "Federal Reserve", "type": "organization", "frequency": 3, "sentiment": { "score": 0.1, "polarity": "neutral", "mentions": { "positive": 1, "neutral": 2, "negative": 0 } } } ], "sentiment": { "overall": { "score": 0.2, "polarity": "positive" }, "title": {}, "body": {} }, "source": { "id": 77, "domain": "example-news.com", "type": "news", "bias": "center", "rankings": { "opr": 8 }, "location": { "country_name": "United States", "country_code": "US" } }, "readability": { "flesch_reading_ease": 55.3, "automated_readability_index": 9.4, "reading_age": 14 }, "shares": { "total": 120, "facebook": 80, "twitter": 30, "reddit": 10 }, "read_time": 4, "words_count": 812, "is_breaking": false, "is_duplicate": false, "story": { "id": 1234567, "uri": "https://api.apitube.io/v1/news/story/1234567" } } ``` ## What are the core content fields?[#](#what-are-the-core-content-fields) These are the human-readable parts of the article: * **`id`** — the numeric article identifier, stable across endpoints. * **`title`** — the headline. * **`description`** — a short summary, stripped of HTML. * **`body`** — the full article text as plain text, while **`body_html`** keeps the original HTML markup. They hold the same content in two forms; for retrieving the raw body and HTML directly, see [how to get the raw article body and HTML](/en/articles/retrieval/get-raw-body). * **`href`** — the canonical URL of the original article, and **`image`** — its lead image URL. * **`published_at`** — the publish time in ISO 8601 (UTC), and **`language`** — the detected language code, such as `en`. * **`translations`** — the English machine translation of a non-English article’s headline and description, under `translations.en` as `title` and `description` (the body is not translated). The block ships with every article; for an English article, like the one above, both are `null`. See [how APITube handles languages and translation](/en/articles/news-data/languages-and-translation). * **`author`** — an `{ id, name }` object when a byline was detected. ## How are categories, topics and entities structured?[#](#how-are-categories-topics-and-entities-structured) Classification fields are arrays of objects, not bare strings, so each tag carries context: * **`categories`** — IPTC Media Topics, each with an `id`, `name`, a relevance `score`, the `taxonomy`, and a `self` link to that category’s feed. * **`topics`** and **`industries`** — additional thematic tags, each with an `id`, `name` and `self` link (topics also carry a `score`). * **`keywords`** — a flat array of salient terms. * **`entities`** — the people, organizations, places and things mentioned. Each entity has an `id`, `name`, a `type` (one of `person`, `location`, `organization`, `brand`, `product`, `natural-disaster`, `disease`, `event`, `sport`), a `frequency` count, `links` to Wikipedia and Wikidata where known, and its own `sentiment` block. The `title.pos` and `body.pos` arrays mark where the entity appears. * **`locations_mentioned`** — a convenience array distilled from location entities, each with a `name`, `country` code, and `lat`/`lng` when available. ## What sentiment, source and quality data is included?[#](#what-sentiment-source-and-quality-data-is-included) Beyond classification, every article is scored and attributed: * **`sentiment`** — three views of tone: `overall`, `title` and `body`, each with a numeric `score` and a `polarity` label. Entities additionally carry [sentiment](/en/articles/getting-started/glossary#sentiment) _toward that entity_, so you can tell whether a company was mentioned favourably even in a neutral article. * **`source`** — a profile of the publisher: `domain`, `home_page_url`, `type`, political `bias`, `rankings.opr` (the source’s [OPR](/en/articles/getting-started/glossary#opr-open-pagerank) authority score), `location` (country name and code), and a `favicon`. * **`readability`** — reading-difficulty metrics including `flesch_reading_ease`, `flesch_kincaid_grade`, `automated_readability_index`, a `difficulty_level`, `target_audience`, and an estimated `reading_age`. * **Length counters** — `words_count`, `sentences_count`, `paragraphs_count`, `characters_count`, and `read_time` (an estimated reading time). ## Which fields tell you about engagement and status?[#](#which-fields-tell-you-about-engagement-and-status) A few fields describe an article’s reach and state: * **`shares`** — social-share counts (`total`, `facebook`, `twitter`, `reddit`). For very fresh articles these ramp up over roughly the first two hours after publication, so counts on a brand-new article are partial by design. * **`media`** and **`links`** — arrays of `{ url, type }` for attached media and outbound links; **`summary`** is an array of key sentences, each with its own sentiment. * **`story`** — the cluster this article belongs to, with an `id` and a `uri` to fetch every article covering the same event. * **Flags** — `is_breaking` marks high-importance news, `is_duplicate` marks near-identical reprints, and `is_free` reports whether the **original** article is freely readable at its source (the opposite of paywalled). Note `is_free` is about the source article, not your subscription. # Common Questions[#](#common-questions) ## Why are some fields shortened with a marker?[#](#why-are-some-fields-shortened-with-a-marker) The article body (`body`, `body_html`) is truncated when the response is a preview rather than full content; the description, `href`, `image` and source URLs are not. On the **Free plan** the cut-off value is tagged `...[Upgrade subscription plan]`; with a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** the same preview is tagged `...[Test mode — use a live key for full content]` instead. Either way the schema is identical to a paid response — the field names and structure do not change, only the values are shortened. Use a paid plan with a live key to receive full content. ## How do I get only the fields I need?[#](#how-do-i-get-only-the-fields-i-need) Use the `fl` parameter to request a subset of fields, which shrinks the response and speeds up parsing — for example `fl=id,title,source.domain,sentiment.overall`. See [how to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields). The field names you pass are exactly the ones described on this page. ## What’s the difference between body and body\_html?[#](#whats-the-difference-between-body-and-body_html) `body` is the article text as **plain text** with HTML stripped out, which is what you want for NLP, search indexing, or display in a plain context. `body_html` preserves the original **HTML markup** (paragraphs, links, formatting), which is useful when you want to render the article as it appeared. Both contain the same article content. ## What does locations\_mentioned contain?[#](#what-does-locations_mentioned-contain) `locations_mentioned` is built from the location entities in the article that have a known country. Each item gives a place `name`, a `country` code, and `lat`/`lng` coordinates when available — a quick way to map where an article is about without walking the full `entities` array yourself. * * * ## Related Articles * [Key concepts: articles, sources, entities, sentiment, stories](/en/articles/getting-started/key-concepts) * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) --- ## What Can You Build with the News API? URL: https://support.apitube.io/en/articles/getting-started/what-can-i-build What you can build with the APITube News API: live news feeds, brand and breaking-news monitoring, market intelligence, AI and RAG apps, and research datasets. # What Can You Build with the News API? From live news feeds and brand monitoring to market intelligence and AI apps — all from one set of filters ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington June 28, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en&title=climate&export=rss) # What can you build with the News API?[#](#what-can-you-build-with-the-news-api) You can build live news feeds, brand and competitor monitoring, breaking-news alerting, market and media intelligence, AI assistants, and research datasets — all on top of the same search endpoint, `/v1/news/everything`, and the same filter parameters. You learn the filters once and reuse them across every scenario below; the only thing that changes is which filters you combine and how you receive the result (pull, stream, or export). Each section names the real parameters and endpoints that power that use case, so you can go from idea to a working request immediately. If you have not made a call yet, start with [how to run your first news search](/en/articles/getting-started/your-first-search) and come back. ## Build a news feed or aggregator[#](#build-a-news-feed-or-aggregator) Pull articles that match a topic, language, or publisher and render them as your own feed. `/v1/news/everything` is the core query; narrow it with `language.code`, `source.domain`, `published_at.start` / `published_at.end`, and the `title` filter for keyword matching (wrap a phrase in quotes for an exact match). The same query can be returned as a ready-made RSS feed by adding `export=rss`, so an RSS reader or a CMS can consume it with no JSON parsing on your side: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&title=climate&export=rss" \ -H "X-API-Key: YOUR_API_KEY" ``` Drop `export=rss` and you get the same articles as JSON for a custom front end. Export also covers `csv`, `tsv`, `xml`, `xlsx`, `parquet`, and `jsonl`. ## Monitor a brand, company or person[#](#monitor-a-brand-company-or-person) Track every mention of a company, brand, or individual and how the coverage leans. Filter the same search with `organization.name`, `brand.name`, or `person.name`, then layer `entity.sentiment.polarity` (`positive`, `negative`, or `neutral`) to surface only coverage that is negative _about that [entity](/en/articles/getting-started/glossary#entity)_ — the signal a PR or comms team watches: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` For an ongoing watch rather than a one-off query, see [how to monitor news about a company or brand](/en/articles/searching-and-filtering/entities/monitor-company-news). You can also have new matches pushed to you instead of polling — over the [SSE](/en/articles/getting-started/glossary#sse-stream) stream, [WebSocket](/en/articles/getting-started/glossary#websocket), or a [webhook](/en/articles/getting-started/glossary#webhook). ## Track breaking news and real-time events[#](#track-breaking-news-and-real-time-events) Catch developing stories the moment they are indexed. The `is_breaking=1` filter narrows any search to articles flagged as breaking, and `/v1/news/stream` (Server-Sent Events) or `/v1/news/ws` (WebSocket) delivers matching articles as a live push feed instead of a poll. Combine the two and you have a real-time breaking-news alerter: ``` curl -N "https://api.apitube.io/v1/news/stream?is_breaking=1&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream accepts the same filters as the search endpoint, so you can scope it to a topic, country, or company. See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for handling the connection. ## Run market and media intelligence[#](#run-market-and-media-intelligence) Turn coverage into signals. `/v1/news/trends` surfaces trending topics and entities over time; `/v1/news/count` returns how many articles match a query without downloading them, which is ideal for share-of-voice and volume charts. Add `entity.sentiment.polarity` to read tone toward a specific company, `source.bias` (`left`, `center`, `right`) to compare how outlets across the spectrum cover a story, and the `/v1/companies`, `/v1/people`, and `/v1/journalists` directories to enrich names with profiles. Together these power market intelligence, media analysis, and financial [sentiment](/en/articles/getting-started/glossary#sentiment) dashboards. ## Power an AI app or agent[#](#power-an-ai-app-or-agent) Feed clean article text to a model. `/v1/news/raw` returns the raw body and HTML of an article, which is the building block for retrieval-augmented generation (RAG) and summarization. `/v1/fact-check` checks a claim against the news index. For assistants, APITube ships an **MCP server** that exposes the News API as tools — `search_news` and `suggest` — plus ready-made prompts like `monitor_company`, `topic_sentiment`, and `breaking_news`, so an AI client (such as Claude or Cursor) can query the news directly without you writing HTTP code. ## Export datasets for research and pipelines[#](#export-datasets-for-research-and-pipelines) Build datasets for analysis or machine learning. Any search becomes a file by adding `export=jsonl` or `export=parquet` — both stream cleanly into data pipelines and notebooks — while `csv` and `xlsx` suit spreadsheets. Pair this with `/v1/news/count` to size a dataset before pulling it, and with `published_at.start` / `published_at.end` to slice it by date range. # Common Questions[#](#common-questions) * [Do different use cases use different endpoints?](#do-different-use-cases-use-different-endpoints) * [Can news be pushed to me instead of polling?](#can-news-be-pushed-to-me-instead-of-polling) * [Can I build with AI tools without writing API code?](#can-i-build-with-ai-tools-without-writing-api-code) ## Do different use cases use different endpoints?[#](#do-different-use-cases-use-different-endpoints) Mostly no. `/v1/news/everything` plus its filters powers feeds, monitoring, intelligence, and dataset exports — you change the filters, not the endpoint. A few jobs have their own endpoint because they return a different shape: `/v1/news/trends` for trending topics, `/v1/news/count` for match counts, `/v1/news/raw` for full article text, and `/v1/fact-check` for claim checking. The full parameter list lives in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## Can news be pushed to me instead of polling?[#](#can-news-be-pushed-to-me-instead-of-polling) Yes. Alongside pull-based REST requests, APITube offers a Server-Sent Events stream (`/v1/news/stream`) and a WebSocket feed (`/v1/news/ws`) that push matching articles as they are indexed, plus webhooks that deliver new matches to a URL you control. Use pull for periodic jobs and streaming or webhooks when you need news the instant it arrives. ## Can I build with AI tools without writing API code?[#](#can-i-build-with-ai-tools-without-writing-api-code) Yes. The APITube MCP server wraps the News API as tools (`search_news`, `suggest`) that an MCP-compatible assistant — such as Claude or Cursor — can call directly. The assistant runs the search for you, so you can prototype a news-aware agent without hand-coding HTTP requests against the endpoints. * * * ## Related Articles * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to monitor news about a company or brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## What is APITube News API? URL: https://support.apitube.io/en/articles/getting-started/what-is-apitube-news-api APITube News API is a REST API that returns news articles as JSON — enriched with language, sentiment and entities — through search, real-time streams and… # What is APITube News API? A REST API that returns global news articles as structured JSON, enriched with language, sentiment and entities ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # What is APITube News API?[#](#what-is-apitube-news-api) APITube News API is a REST API that returns news articles as structured JSON over HTTPS. You send an HTTP request with your [API key](/en/articles/getting-started/glossary#api-key), optionally narrow it with filters, and get back ready-to-use article objects — each enriched with the language, [sentiment](/en/articles/getting-started/glossary#sentiment), named [entities](/en/articles/getting-started/glossary#entity) and topic labels that APITube adds automatically. There is no scraping, no HTML parsing and no feed wrangling on your side: the data arrives clean and machine-readable. In one sentence: it turns the world’s news into a queryable, filterable dataset you reach with a single HTTP call. The rest of this article covers what the data contains, what you can do with it, and how you get it out. ## What does the APITube News API do?[#](#what-does-the-apitube-news-api-do) The APITube News API collects articles from across the web, processes each one, and serves the result through a single HTTP base URL, `https://api.apitube.io`. Every endpoint speaks JSON and authenticates with an API key, so any language or tool that can make an HTTP request can use it — `curl`, a browser, a backend service, a spreadsheet, or an AI assistant. A request to the main search endpoint returns a JSON envelope: a `status`, a `results` array of article objects, paging fields (`page`, `has_next_pages`, `next_page`), a `request_id`, and an `export` block of links that re-run the same query in other formats. You read the `results` array and you have the news. To see this end to end, follow [how to run your first news search](/en/articles/getting-started/your-first-search). ## What data does each article include?[#](#what-data-does-each-article-include) Each article is a rich object, not just a headline and a link. Alongside the title, body, URL, publish date and source, APITube attaches the enrichment it computes for every article: * **Language** — the detected language code of the text. * **Sentiment** — an overall positive/neutral/negative reading, and sentiment toward individual entities. * **Entities** — the people, organizations, locations, products and other names mentioned, with their positions in the text. * **Classification** — category, topic and industry labels. * **Source and media metadata** — the publisher, plus images and other media attached to the article. For a field-by-field tour of an article object, see [what’s inside a news article](/en/articles/getting-started/understanding-article-data); for the vocabulary used across the API — articles, sources, entities, stories — see [key concepts](/en/articles/getting-started/key-concepts). ## What can you do with the API?[#](#what-can-you-do-with-the-api) The API is a family of endpoints, all under the same base URL and key. The main groups are: * **Search** — `/v1/news/everything` queries the whole index with filters for keyword, language, country, date, source, sentiment, entities and more. * **Headlines and local** — `/v1/news/top-headlines` for the day’s leading stories and `/v1/news/local` for geo-targeted news. * **Single items** — `/v1/news/article` for one article, `/v1/news/story/:id` for every article covering the same story, and `/v1/news/raw` for the raw body and HTML. * **Counting and trends** — `/v1/news/count` returns how many articles match without downloading them, and `/v1/news/trends` surfaces trending topics and entities over time. * **Directories and lookups** — `/v1/people`, `/v1/companies` and `/v1/journalists` profiles, plus `/v1/suggest/*` autocomplete for entities, sources, categories, topics and industries. * **Fact-checking** — `/v1/fact-check` checks a claim against the news index. Because every news query accepts the same filter parameters, you learn the filters once and reuse them across endpoints. ## How do you get the data out?[#](#how-do-you-get-the-data-out) APITube delivers news three ways, so you can pull, stream or be pushed to: * **Pull (REST + exports).** Request data on demand. Beyond JSON, a search can be returned as CSV, TSV, XML, RSS, XLSX, Parquet or JSONL — useful for spreadsheets, RSS readers and data pipelines alike. * **Real-time streaming.** Subscribe to a live feed over [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) (`/v1/news/stream`) or [WebSocket](/en/articles/getting-started/glossary#websocket) and receive matching articles as they are indexed. * **[Webhooks](/en/articles/getting-started/glossary#webhook).** Have APITube push new matching articles to your own URL, so your system reacts without polling. You authenticate the same way on all of them: send your key as an `Authorization: Bearer` token, an `X-API-Key` header, or an `api_key` query parameter. ## How do you start using it?[#](#how-do-you-start-using-it) Three steps: create an account, copy your API key from the dashboard, and send a request. A first call needs nothing but the endpoint and your key: ``` curl "https://api.apitube.io/v1/news/everything" \ -H "X-API-Key: YOUR_API_KEY" ``` That returns the latest news, newest first. From there you add filters to narrow it. The complete list of parameters lives in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is APITube News API a REST API?](#is-apitube-news-api-a-rest-api) * [What formats can I receive news in?](#what-formats-can-i-receive-news-in) * [Do I need an API key to use it?](#do-i-need-an-api-key-to-use-it) * [Is the data real-time?](#is-the-data-real-time) ## Is APITube News API a REST API?[#](#is-apitube-news-api-a-rest-api) Yes. It is an HTTP REST API served from `https://api.apitube.io`. You make standard `GET` or `POST` requests, pass your filters as query-string parameters or a JSON body, and receive a JSON response. No SDK is required — any HTTP client works — though official client libraries exist to make it more convenient. ## What formats can I receive news in?[#](#what-formats-can-i-receive-news-in) JSON is the default. The same search can also be returned as CSV, TSV, XML, RSS, XLSX (Excel), Parquet or JSONL by changing the export format, so the API fits spreadsheets, RSS readers and data pipelines without extra conversion on your side. ## Do I need an API key to use it?[#](#do-i-need-an-api-key-to-use-it) Yes. Almost every endpoint requires a valid API key, sent as an `Authorization: Bearer` token, an `X-API-Key` header, or an `api_key` query parameter. You create a key in your APITube dashboard. A request with no key — or an invalid one — is rejected with a `401` before any work is done. ## Is the data real-time?[#](#is-the-data-real-time) It can be. As well as on-demand REST requests, APITube offers a live Server-Sent Events stream and a WebSocket feed that push matching articles as they are indexed, plus webhooks that deliver new articles to a URL you control. Choose pull for periodic jobs and streaming or webhooks when you need news the moment it arrives. * * * ## Related Articles * [How to run your first news search](/en/articles/getting-started/your-first-search) * [Key concepts: articles, sources, entities, sentiment, stories](/en/articles/getting-started/key-concepts) * [What's inside a news article?](/en/articles/getting-started/understanding-article-data) --- ## Which APITube plan is right for me? URL: https://support.apitube.io/en/articles/getting-started/which-plan-is-right Compare APITube's Free, Starter, Basic, Professional and Corporate plans by monthly requests, streaming credits, concurrent streams and webhooks — and pick one. # Which APITube plan is right for me? Match Free, Starter, Basic, Professional or Corporate to your request volume, streaming and webhooks ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 22, 2026 Updated August 14, 2026 # Which APITube plan is right for me?[#](#which-apitube-plan-is-right-for-me) Pick your plan by how many requests you make and whether you need real-time delivery. **Free** (100 requests/day) is for evaluating the API. **Starter** ($29/mo, 10,000 requests) is the cheapest tier with full article content. **Basic** ($99/mo, 50,000 requests) suits a small production app. **Professional** ($199/mo, 150,000 requests) handles serious traffic and heavier streaming. **Corporate** ($599/mo, 300,000 requests) is for high-volume and multi-team use. If you only sometimes exceed your quota, stay on a smaller plan and let [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) cover the overflow. The plans differ on four numbers — how many **requests** you get, your **streaming** allowance, how many **concurrent streams** you can open, and how many **[webhooks](/en/articles/getting-started/glossary#webhook)** you can run — plus two things that only change at the edges: the **[rate limit](/en/articles/getting-started/glossary#rate-limit)** (10 requests per minute on Free, 50 on Starter, Basic and Professional, 200 on Corporate) and a short list of **paid-only features** noted below. Everything else, including which endpoints you can call, is identical across plans. ## How do the APITube plans compare?[#](#how-do-the-apitube-plans-compare) Plan Price Requests included Articles per request Streaming credits Concurrent streams Webhooks Free $0 100 / day 10 1,000 1 1 Starter $29 / mo 10,000 50 3,000 2 5 Basic $99 / mo 50,000 200 5,000 2 5 Professional $199 / mo 150,000 250 15,000 10 20 Corporate $599 / mo 300,000 250 40,000 50 100 “Requests included” is your allowance per billing cycle (one request = one credit, and most search and retrieval calls cost a single credit — see [what counts as one request](/en/articles/billing/credits/what-counts-as-request)). “Streaming credits” is the [SSE](/en/articles/getting-started/glossary#sse-stream) pool (`sse_points`), which bills per article delivered. The [WebSocket](/en/articles/getting-started/glossary#websocket) feed and webhook deliveries draw on **their own pools** (`ws_points`, `webhook_points`) that never borrow from it or from your request quota: on Free, Starter and Basic all three match the SSE number, while Professional gets 25,000 WebSocket and 25,000 webhook credits and Corporate gets 100,000 of each. “Concurrent streams” is how many live SSE/WebSocket connections you can hold open at once, and “Webhooks” is how many push subscriptions you can run. “Articles per request” is the `per_page` ceiling: Professional and Corporate pull 250 articles in one call, Basic 200, Starter 50 and Free 10. Paid plans renew on a **31-day** cycle. The Free plan has a short **1-day** validity, so its 100-request daily allowance is sized for testing, not production. ![The Subscription page of the dashboard comparing the paid plans with a full condition table below](/images/article/dashboard-subscription.png) ## Which plan should you choose?[#](#which-plan-should-you-choose) * **Free** — choose it to try the API, prototype, or run a tiny side project. You get 100 requests per day, one webhook, and **one** stream (1 SSE + 1 WebSocket connection, 1,000 deliveries each per day) — but everything arrives with a **12-hour delay**, so Free is not a real-time tier. Articles come back complete except for the body text (see below); fact-check, trends, the MCP server and every [export format](/en/articles/getting-started/glossary#export-format) except JSON are off. * **Starter** — choose it for the first paid step: 10,000 requests per cycle, 50 articles per request, 3,000 streaming credits, two concurrent streams and up to five webhooks. It carries the same connection and webhook limits as Basic and full article content, so it is the cheapest way off the Free plan’s truncation. The `prompt` parameter is not part of it. * **Basic** — choose it for a small but real production workload: roughly 50,000 requests per cycle, 200 articles per request, two concurrent streams and up to five webhooks. It is also the first tier with the natural-language `prompt` parameter. Good for a single app or dashboard. * **Professional** — choose it when traffic grows past Basic or you lean on real-time: 150,000 requests, a much larger 15,000 streaming pool, ten concurrent streams and twenty webhooks. * **Corporate** — choose it for high-volume pipelines, agencies or multiple teams: 300,000 requests, 40,000 streaming credits, fifty concurrent streams and a hundred webhooks. A simple rule: size the plan to the request volume you expect in a cycle, then check the streaming and webhook columns cover your real-time needs. If requests are your only concern and you rarely stream, the request count alone decides it. ## What is the same on every plan?[#](#what-is-the-same-on-every-plan) Upgrading raises your rate limit only at the top. It is **50 requests per minute** on Starter, Basic and Professional, **200/min** on Corporate — the Free plan is capped at **10/min** and test keys at **15/min** — and exceeding it repeatedly triggers a temporary ban. So a higher plan gives you a larger monthly allowance and more streams/webhooks — not a faster burst rate. For the details, see [understanding rate limits](/en/articles/billing/credits/rate-limits). Every plan can call the same endpoints — search, headlines, local, single article, story clusters, count, trends, directories and exports are all routable on every tier. What a plan gates is a short list of **features**, and they sit at two different heights: * **Fact-check** (`/v1/fact-check`), **[Trends](/en/articles/retrieval/discover-trends)** (`/v1/news/trends`), the **MCP server** and every **export format** except JSON need **Starter or higher**. On Free each returns `403 ER0706`. * **Real-time delivery** needs **Starter or higher**: Free is served with a 12-hour delay everywhere, including SSE, WebSocket and webhooks. * The natural-language [`prompt`](/en/articles/searching-and-filtering/keyword-search/natural-language-search) parameter needs **Basic or higher**. On Free and Starter it returns `403 ER0706` too, before anything is charged. The filters a prompt writes for you are available on every plan if you send them yourself. ## Why is article content cut off on the Free plan?[#](#why-is-article-content-cut-off-on-the-free-plan) On the Free plan, article bodies are truncated and replaced with an `[Upgrade subscription plan]` marker instead of the full text. This is intentional: Free is a preview tier, so you can see the structure of every article object — title, source, language, sentiment, entities, dates — but not the complete body. The same truncation applies to test keys. To get full, untruncated article content, move to any paid plan (Starter, Basic, Professional or Corporate) and use a live key. The behaviour is the same idea as [test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys). ## What about annual billing and overflow?[#](#what-about-annual-billing-and-overflow) Starter, Basic, Professional and Corporate are also available **annually**, billed once a year for less than twelve monthly payments — Starter is **$279/year**, Basic **$959/year**, Professional **$1,919/year** and Corporate **$4,999/year** — with the same request allowance and a larger streaming pool. Annual plans renew every 366 days instead of every 31. For requests beyond your plan, you do not have to jump to a bigger tier: **Pay As You Go** tops up an overflow balance at **$0.01 per request** ($1 = 100 requests). Your plan quota is always spent first, and only overflow draws from the balance — see [what is Pay As You Go](/en/articles/billing/pay-as-you-go/what-is-payg). This lets a smaller plan absorb the occasional busy day without an upgrade. # Common Questions[#](#common-questions) * [Does a bigger plan give me a higher rate limit?](#does-a-bigger-plan-give-me-a-higher-rate-limit) * [What happens when I run out of requests?](#what-happens-when-i-run-out-of-requests) * [Can I start on Free and upgrade later?](#can-i-start-on-free-and-upgrade-later) * [Do I have to upgrade to handle a traffic spike?](#do-i-have-to-upgrade-to-handle-a-traffic-spike) ## Does a bigger plan give me a higher rate limit?[#](#does-a-bigger-plan-give-me-a-higher-rate-limit) No. The rate limit is **50 requests per minute** on the paid plans (Starter, Basic, Professional and Corporate); the **Free plan is capped at 10 per minute**. A higher plan increases your total monthly request allowance, streaming credits, concurrent streams and webhook count, but not the per-minute burst rate. If you hit `429` errors, the fix is spacing out requests, not upgrading. ## What happens when I run out of requests?[#](#what-happens-when-i-run-out-of-requests) Once your plan allowance for the cycle is spent, the next billed call returns `402 ER0176` unless you have a Pay As You Go balance to cover it. With a balance, overflow requests bill at $0.01 each and keep working. For the full out-of-quota behaviour, see [what happens when you run out of requests](/en/articles/billing/credits/out-of-requests). ## Can I start on Free and upgrade later?[#](#can-i-start-on-free-and-upgrade-later) Yes. Free is designed for evaluation, so a normal path is to build and test on Free (with truncated content), then move to a paid plan when you need full article bodies, more requests, fact-check, or more streams and webhooks. Your API keys stay the same; only the plan attached to your account changes. ## Do I have to upgrade to handle a traffic spike?[#](#do-i-have-to-upgrade-to-handle-a-traffic-spike) Not necessarily. If you are usually within your plan but occasionally exceed it, Pay As You Go covers the overflow at $0.01 per request, so a one-off busy period does not force a permanent upgrade. Upgrade when your _baseline_ usage consistently sits above your plan’s included requests, not for rare peaks. * * * ## Related Articles * [What counts as one request?](/en/articles/billing/credits/what-counts-as-request) * [What is Pay As You Go?](/en/articles/billing/pay-as-you-go/what-is-payg) * [Test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) --- ## How to run your first news search URL: https://support.apitube.io/en/articles/getting-started/your-first-search Run your first APITube news search: send a request to /v1/news/everything with your API key, get the latest news as a JSON results array, then narrow it with… # How to run your first news search Send one request to /v1/news/everything, authenticate with your API key, and read the JSON response ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to run your first news search[#](#how-to-run-your-first-news-search) To run your first news search, send a request to `https://api.apitube.io/v1/news/everything` with your [API key](/en/articles/getting-started/glossary#api-key). With no filters it returns the latest news from across APITube’s index, newest first. The reply is a JSON object whose `results` field is the array of articles. You can pass the key as an `api_key` query parameter or as an `X-API-Key` header — both work. ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "api_key=YOUR_API_KEY" ``` ``` const res = await fetch("https://api.apitube.io/v1/news/everything", { headers: { "X-API-Key": "YOUR_API_KEY" } }); const data = await res.json(); console.log(data.results.map(a => a.title)); ``` ``` import requests resp = requests.get( "https://api.apitube.io/v1/news/everything", headers={"X-API-Key": "YOUR_API_KEY"}, ) for article in resp.json()["results"]: print(article["title"]) ``` That single call is enough to get news back. Everything else — keywords, language, date range, sorting — is an optional filter you add on top of this same endpoint. If you prefer not to type the request at all, the **Quickstart** block on your dashboard home page shows this exact call with your key already filled in: ![The dashboard home page with the Quickstart block: a ready-to-run first request with your API key filled in](/images/article/dashboard-home.png) ## What is the endpoint and how do you authenticate?[#](#what-is-the-endpoint-and-how-do-you-authenticate) The main search endpoint is `/v1/news/everything`. Every request must carry your API key, and there are two ways to send it: the `X-API-Key` request header or the `api_key` query parameter. The endpoint accepts both `GET` (parameters in the query string) and `POST` (parameters in a JSON body), and APITube merges the two, so you can mix them. ``` curl "https://api.apitube.io/v1/news/everything" \ -H "X-API-Key: YOUR_API_KEY" ``` If the key is missing you get HTTP `401` with error code `ER0201`; if it is not a valid key you get `401` with `ER0202`. A working key returns HTTP `200` and the JSON envelope described below. ## How do you read the response?[#](#how-do-you-read-the-response) A successful search returns a JSON object — an envelope around your articles, not a bare array. The fields you will use first are: * `status` — `"ok"` on success. * `results` — the array of article objects (the news itself). * `page` and `limit` — the current page number and how many articles are on it. * `has_next_pages` and `next_page` — whether more results exist and a ready-made URL for the next page. * `request_id` — a unique ID for this call; quote it if you contact support. * `export` — ready-to-use URLs that re-run the same search as CSV, XLSX, RSS, XML, TSV, Parquet, JSONL or JSON. ``` { "status": "ok", "page": 1, "limit": 100, "has_next_pages": true, "next_page": "https://api.apitube.io/v1/news/everything?page=2", "results": [ "… article objects …" ], "request_id": "…" } ``` Each item in `results` is a full article — headline, source, publish date, link, language, and NLP enrichment such as [sentiment](/en/articles/getting-started/glossary#sentiment) and detected [entities](/en/articles/getting-started/glossary#entity). ## How do you narrow your first search?[#](#how-do-you-narrow-your-first-search) Add filters as extra parameters on the same `/v1/news/everything` call. They combine with **AND**, so each one you add makes the result set smaller and more specific. Common first filters are `title` (keywords in the headline), `language.code` (a two-letter language such as `en`), `published_at.start` / `published_at.end` (a date window) and `source.domain` (one publisher). This request asks for recent English articles mentioning electric vehicles, ten per page: ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=electric vehicles" \ --data-urlencode "language.code=en" \ --data-urlencode "per_page=10" \ --data-urlencode "api_key=YOUR_API_KEY" ``` The `title` filter matches the headline only; for how multi-word matching, synonyms and exact phrases behave, see [how to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title). The full parameter list is in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## How many articles come back, and how do you get more?[#](#how-many-articles-come-back-and-how-do-you-get-more) Without `per_page`, a search returns up to **100** articles per page; the maximum you can request is **250** on Basic and up, **50** on Starter and **10** on Free — and the default drops with the ceiling, so a Free key returns 10 per page. To read beyond the first page, either increment the `page` parameter (`page=2`, `page=3`, …) or follow the `next_page` URL the response already built for you. The `has_next_pages` flag tells you when there is nothing left to fetch. To get top headlines instead of a full search, use the [top headlines endpoint](/en/articles/retrieval/get-top-headlines). # Common Questions[#](#common-questions) * [Where do I get an API key?](#where-do-i-get-an-api-key) * [Why is the article text shortened or showing placeholder text?](#why-is-the-article-text-shortened-or-showing-placeholder-text) * [Does a search that finds nothing use up a request?](#does-a-search-that-finds-nothing-use-up-a-request) * [GET or POST — which should I use?](#get-or-post--which-should-i-use) ## Where do I get an API key?[#](#where-do-i-get-an-api-key) Your API key lives in your APITube dashboard. Create an account, open the API keys section, and copy the key into the `X-API-Key` header or the `api_key` parameter shown above. You can keep an eye on what each request spends from your quota — see [how to check your API balance and remaining quota](/en/articles/retrieval/check-balance-api). ## Why is the article text shortened or showing placeholder text?[#](#why-is-the-article-text-shortened-or-showing-placeholder-text) On a free plan, and with any [test key](/en/articles/getting-started/glossary#test-key-and-live-key), the long article body is truncated for preview. That is expected: switch to a live key on a paid plan to receive full content. If you see masked or placeholder strings where the body should be, that is the same preview behavior — see [why your results are masked or placeholder text](/en/articles/troubleshooting/masked-results). ## Does a search that finds nothing use up a request?[#](#does-a-search-that-finds-nothing-use-up-a-request) No. On `/v1/news/everything`, a request is only counted against your quota when at least one article is returned. A search that matches zero articles — and any request that fails with a `4xx` error — does not spend a request. Test keys never spend quota at all. ## GET or POST — which should I use?[#](#get-or-post--which-should-i-use) Either. `GET` puts parameters in the query string, which is the quickest way to test from a browser or `curl`. `POST` puts them in a JSON body, which is cleaner for long or complex queries. The endpoint accepts both and merges query and body, so the same filters behave identically whichever you choose. * * * ## Related Articles * [How to Search News by Title](/en/articles/searching-and-filtering/keyword-search/search-by-title) * [How to get top headlines](/en/articles/retrieval/get-top-headlines) * [How to Check Your API Balance and Remaining Quota](/en/articles/retrieval/check-balance-api) --- ## All Collections URL: https://support.apitube.io/en/articles Browse every help category for the APITube News API. # All Collections Browse every help category. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Tasha and 5 others 6 authors 203 articles ## [Getting Started](/en/articles/getting-started) * * * * [Glossary of News API terms](/en/articles/getting-started/glossary) * [How does APITube collect and process news?](/en/articles/getting-started/how-apitube-collects-news) * [How far back does the news archive go?](/en/articles/getting-started/how-far-back-archive-goes) * [How Fresh Is the Data and What Is the Latency?](/en/articles/getting-started/how-fresh-is-the-data) * [How many news sources does APITube cover?](/en/articles/getting-started/how-many-sources) * [How to run your first news search](/en/articles/getting-started/your-first-search) * [Key concepts: articles, sources, entities, sentiment, stories](/en/articles/getting-started/key-concepts) * [What Can You Build with the News API?](/en/articles/getting-started/what-can-i-build) * [What is APITube News API?](/en/articles/getting-started/what-is-apitube-news-api) * [What's inside a news article?](/en/articles/getting-started/understanding-article-data) * [Which APITube plan is right for me?](/en/articles/getting-started/which-plan-is-right) * [Which Languages and Countries Does the News API Support?](/en/articles/getting-started/supported-languages-and-countries) ## [Setup & Installation](/en/articles/setup-and-installation) * * * * [Account & API Keys 6 articles](/en/articles/setup-and-installation/account-and-keys) * [AI Assistants & MCP 3 articles](/en/articles/setup-and-installation/ai-and-mcp) * [Built-in Tools 3 articles](/en/articles/setup-and-installation/tools) * [No-code & Automation 3 articles](/en/articles/setup-and-installation/no-code) * [SDKs & Client Libraries 4 articles](/en/articles/setup-and-installation/sdks) ## [Searching & Filtering News](/en/articles/searching-and-filtering) * * * * [Keyword & Title Search 6 articles](/en/articles/searching-and-filtering/keyword-search) * [Content & Quality 8 articles](/en/articles/searching-and-filtering/content-quality) * [Entities, People & Companies 7 articles](/en/articles/searching-and-filtering/entities) * [Events & Breaking News 3 articles](/en/articles/searching-and-filtering/events) * [Filter by Attributes 9 articles](/en/articles/searching-and-filtering/by-attribute) * [Sentiment 2 articles](/en/articles/searching-and-filtering/sentiment) * [Sorting, Pagination & Shaping 8 articles](/en/articles/searching-and-filtering/sorting-and-shaping) ## [News Endpoints & Retrieval](/en/articles/retrieval) * * * * [How to Autocomplete Filter Values with the Suggest API](/en/articles/retrieval/autocomplete-filter-values) * [How to Check Your API Balance and Remaining Quota](/en/articles/retrieval/check-balance-api) * [How to Compare News Trends Between Two Periods](/en/articles/retrieval/compare-trends) * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Get a Single Article by ID from the News API](/en/articles/retrieval/get-article-by-id) * [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) * [How to Get Local and Geo-Targeted News](/en/articles/retrieval/get-local-news) * [How to Get the Raw Article Body and HTML](/en/articles/retrieval/get-raw-body) * [How to Get Top Headlines from the News API](/en/articles/retrieval/get-top-headlines) ## [News Data & Content](/en/articles/news-data) * * * * [Can I access historical news archives?](/en/articles/news-data/historical-archives) * [Categories, Topics and Industries: What Is the Difference](/en/articles/news-data/categories-topics-industries) * [How accurate is the sentiment analysis?](/en/articles/news-data/sentiment-accuracy) * [How APITube handles languages and translation](/en/articles/news-data/languages-and-translation) * [How does APITube ensure data quality?](/en/articles/news-data/data-quality) * [How Does Sentiment Analysis Work?](/en/articles/news-data/how-sentiment-works) * [How story clustering and duplicate detection work](/en/articles/news-data/story-and-dedup) * [Understanding Entities: People, Companies, Locations](/en/articles/news-data/understanding-entities) * [What data is included with each article?](/en/articles/news-data/what-data-in-article) * [What Is a Story Cluster (Story vs Article)?](/en/articles/news-data/what-is-a-story) * [What NLP enrichment is applied to each article?](/en/articles/news-data/nlp-enrichment) ## [Real-time Delivery & Export](/en/articles/delivery-and-export) * * * * [Export Formats 5 articles](/en/articles/delivery-and-export/export) * [Real-time Streaming 5 articles](/en/articles/delivery-and-export/streaming) * [Webhooks 4 articles](/en/articles/delivery-and-export/webhooks) ## [Use Cases & Solutions](/en/articles/use-cases) * * * * [Brand, PR & Marketing 9 articles](/en/articles/use-cases/brand-and-marketing) * [Finance & Market Intelligence 6 articles](/en/articles/use-cases/finance) * [Risk, Security & Safety 6 articles](/en/articles/use-cases/risk-and-safety) * [Society, Health & Trends 5 articles](/en/articles/use-cases/society-health) * [Trust, Misinformation & Research 4 articles](/en/articles/use-cases/trust-and-research) ## [Account & Dashboard](/en/articles/account-and-dashboard) * * * * [API Keys Management 6 articles](/en/articles/account-and-dashboard/keys) * [Ask News 3 articles](/en/articles/account-and-dashboard/ask-news) * [Profile & Preferences 6 articles](/en/articles/account-and-dashboard/profile) * [Usage & Logs 4 articles](/en/articles/account-and-dashboard/usage-and-logs) ## [Plans, Billing & Credits](/en/articles/billing) * * * * [Credits & Quota 5 articles](/en/articles/billing/credits) * [Licensing 1 article](/en/articles/billing/licensing) * [Pay As You Go 3 articles](/en/articles/billing/pay-as-you-go) * [Plans 3 articles](/en/articles/billing/plans) * [Subscription 3 articles](/en/articles/billing/subscription) ## [Teams & Workspaces](/en/articles/teams-and-workspaces) * * * * [How Billing and Usage Are Shared in a Workspace](/en/articles/teams-and-workspaces/shared-billing) * [How to Change a Member's Role or Remove Them](/en/articles/teams-and-workspaces/manage-members) * [How to Create and Switch Workspaces](/en/articles/teams-and-workspaces/create-switch-workspaces) * [How to Invite Team Members to a Workspace](/en/articles/teams-and-workspaces/invite-members) * [How to Rename or Delete a Workspace](/en/articles/teams-and-workspaces/rename-or-delete-workspace) * [How to review the workspace audit log](/en/articles/teams-and-workspaces/audit-log) * [What Are Workspaces and When to Use Them](/en/articles/teams-and-workspaces/what-are-workspaces) * [Workspace Roles: Owner, Admin, Member, Viewer](/en/articles/teams-and-workspaces/workspace-roles) ## [Referrals & Rewards](/en/articles/referrals) * * * * [How the Referral Program Works](/en/articles/referrals/how-referrals-work) * [How to Invite Friends and Earn Credit](/en/articles/referrals/invite-and-earn) * [How to Track Your Referrals and Rewards](/en/articles/referrals/track-referrals) * [Why Hasn't My Referral Reward Been Credited?](/en/articles/referrals/referral-not-credited) ## [Troubleshooting & Errors](/en/articles/troubleshooting) * * * * [How to Debug Your API Requests](/en/articles/troubleshooting/debug-requests) * [How to Fix 400 Bad Request Errors](/en/articles/troubleshooting/fix-400-errors) * [How to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) * [How to Fix Rate-Limit (429) Errors](/en/articles/troubleshooting/rate-limit-errors) * [How to Fix SSE Stream Problems (ER0360, Disconnects)](/en/articles/troubleshooting/sse-stream-issues) * [News API Frequently Asked Questions](/en/articles/troubleshooting/general-faqs) * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [Why Are My Results Masked or Placeholder Text?](/en/articles/troubleshooting/masked-results) * [Why is my request blocked by IP or scope?](/en/articles/troubleshooting/ip-scope-blocked) * [Why Is My Search Returning No Results?](/en/articles/troubleshooting/no-results) * [Why Is My Webhook Not Receiving Events?](/en/articles/troubleshooting/webhook-not-receiving-events) ## [Trust, Coverage & Support](/en/articles/trust-and-support) * * * * [How many websites does APITube aggregate?](/en/articles/trust-and-support/source-coverage) * [How to Contact APITube Support](/en/articles/trust-and-support/contact-support) * [How to Report a Bug or Request a Feature](/en/articles/trust-and-support/report-bug-request-feature) * [How to Request a New News Source](/en/articles/trust-and-support/request-news-source) * [What is the OPR (Open PageRank) score?](/en/articles/trust-and-support/what-is-opr) * [Where to Check APITube API Status and Uptime](/en/articles/trust-and-support/api-status) * [Where to Find APITube Product Updates and Changelog](/en/articles/trust-and-support/changelog) --- ## Categories, Topics and Industries: What Is the Difference URL: https://support.apitube.io/en/articles/news-data/categories-topics-industries APITube tags every article with three taxonomies: 1,085 IPTC categories (medtop IDs), 69 topic slugs and 1,264 numeric industries. What each is for and how to… # Categories, Topics and Industries: What Is the Difference The three classification systems attached to every article — how big each one is, what the IDs look like and when to use which ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 6, 2026 # Categories, topics and industries: what is the difference[#](#categories-topics-and-industries-what-is-the-difference) Every article in the APITube index carries three parallel classification systems: **categories** (the industry-standard IPTC Media Topics scheme, 1,085 entries with IDs like `medtop:04000000`), **topics** (69 finer-grained subject slugs such as `industry.automotive_news`), and **industries** (1,264 business sectors with plain numeric IDs). They answer different questions — “what kind of news is this”, “what recurring subject is this about” and “which business sector does it concern” — and each has its own filter parameter. ## What are categories (IPTC Media Topics)?[#](#what-are-categories-iptc-media-topics) Categories place an article in the universal news classification maintained by the [IPTC](https://iptc.org/standards/media-topics/) — the same scheme large news agencies use. APITube’s category list has **1,085 entries**, each with an ID of the form `medtop:` followed by eight digits, for example `medtop:04000000` for economy, business and finance. The scheme is a tree: broad top-level subjects branch into narrower children, and the full indented tree is published in the docs as the [list of categories](https://docs.apitube.io/platform/news-api/list-of-categories). One behaviour to plan around: the `category.id` filter matches the exact ID you pass and does **not** automatically include a category’s children. If you want a parent subject plus two of its subtopics, pass the IDs explicitly — the filter accepts up to 3, comma-separated. See [how to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) for worked requests. ## What are topics?[#](#what-are-topics) Topics are APITube’s own, much smaller vocabulary of recurring news subjects: **69 slugs** in two families — `industry.*` (26 slugs like `industry.automotive_news`) and `market_news.*` (43 slugs like `market_news.commodities.crude_oil`). Where a category tells you an article is business news in general, a topic pins it to a named, trackable beat. The topic ID is the slug itself, passed to `topic.id`; the complete vocabulary is in the docs [list of topics](https://docs.apitube.io/platform/news-api/list-of-topics). ## What are industries?[#](#what-are-industries) Industries map an article to the business sector it concerns — useful when you monitor a market rather than a subject. The industry reference is the largest flat list of the three: **1,264 sectors**, numbered from `0` (Aerospace Defense) upward, so `industry.id` takes a plain number like `industry.id=88`. The full table with names and descriptions is the docs [list of industries](https://docs.apitube.io/platform/news-api/list-of-industries). ## How do the three appear in an API response?[#](#how-do-the-three-appear-in-an-api-response) Each article object carries three arrays. Their items look similar but differ in one detail worth knowing: * `categories[]` — `id`, `name`, `taxonomy` (normally `iptc_mediatopics`), a `links.self` URL and a `score` — the confidence of the classification. * `topics[]` — `id`, `name`, `links.self` and a `score`. * `industries[]` — `id`, `name` and `links.self`. Industry assignments carry **no score field**. All three filters follow the same rules: only IDs are accepted (there is no `category.name`\-style parameter), up to 3 comma-separated values per parameter, and each has an `ignore.*` twin (`ignore.category.id`, `ignore.topic.id`, `ignore.industry.id`) for excluding instead of including. An ID that does not exist in the reference list is rejected with a `400` error rather than silently returning nothing. # Common Questions[#](#common-questions) * [Can I filter by category or topic name instead of ID?](#can-i-filter-by-category-or-topic-name-instead-of-id) * [Which of the three should I use for monitoring?](#which-of-the-three-should-i-use-for-monitoring) * [Do I have to memorise the ID lists?](#do-i-have-to-memorise-the-id-lists) ## Can I filter by category or topic name instead of ID?[#](#can-i-filter-by-category-or-topic-name-instead-of-id) No. `category.id`, `topic.id` and `industry.id` are the only classification filters, and they take IDs. To translate a human-readable name into an ID at runtime, call the matching autocomplete endpoint — see [how to autocomplete filter values with the Suggest API](/en/articles/retrieval/autocomplete-filter-values). ## Which of the three should I use for monitoring?[#](#which-of-the-three-should-i-use-for-monitoring) Start from the question you are answering. Broad editorial slicing (“all sports news”, “all politics”) — categories. A named market beat that APITube tracks as a slug (crude oil, automotive news) — topics. Coverage about companies in a sector, regardless of the story’s subject — industries. They combine freely in one request, so a crude-oil feed limited to business coverage can pass both `topic.id` and `category.id`. ## Do I have to memorise the ID lists?[#](#do-i-have-to-memorise-the-id-lists) No. The docs publish all three reference lists in full, and for interactive inputs the suggest endpoints turn a typed fragment into the right ID on the fly. Most integrations hard-code a handful of IDs once, verify them against the docs lists, and never touch the taxonomy again. * * * ## Related Articles * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Filter News by Topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic) * [How to Filter News by Industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) --- ## How does APITube ensure data quality? URL: https://support.apitube.io/en/articles/news-data/data-quality APITube expresses data quality as per-article signals — the OPR source-authority score, headline-vs-body sentiment and bias labels — plus filters like… # How does APITube ensure data quality? The per-article quality signals APITube exposes and the filters you control ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_rank_min=6) # How does APITube ensure data quality?[#](#how-does-apitube-ensure-data-quality) APITube handles data quality in the open: instead of hiding a black-box score, it attaches **machine-readable quality signals to every article** — the source’s [OPR](/en/articles/getting-started/glossary#opr-open-pagerank) authority score, [sentiment](/en/articles/getting-started/glossary#sentiment) for the headline and the body separately, and the publisher’s political bias — and gives you filter switches to enforce your own bar. You are never forced to trust a single “quality” number; you can read the signals on each article and decide what passes. Those signals arrive inline. A normal search on `/v1/news/everything` already carries the enrichment, so you do not call a separate quality endpoint to get it. ## How does APITube express data quality?[#](#how-does-apitube-express-data-quality) APITube treats quality as two things you can act on: **signals** and **filters**. * **Signals** are fields on every article object — the source’s `source.rankings.opr`, the `sentiment` block, the `author`, and the publisher `source.bias`. They let you judge and audit each result. * **Filters** are request parameters that turn those signals into a hard cutoff — for example `is_high_quality=1`, `is_premium_source=1`, or an OPR floor with `source.rank.opr.min`. Both come from the same processing step, so a search returns judged, filterable articles rather than raw scraped text. Send your key as a header (`X-API-Key: YOUR_API_KEY`) or as the `api_key` query parameter. ## How does source authority (OPR) work as a quality signal?[#](#how-does-source-authority-opr-work-as-a-quality-signal) Every source is scored with **OPR**, an authority score from **0 to 10** for the publishing domain. APITube attaches that score to each article under `source.rankings.opr`, and you can set a floor or ceiling with `source.rank.opr.min` and `source.rank.opr.max`: ``` curl "https://api.apitube.io/v1/news/everything?source.rank.opr.min=6&api_key=YOUR_API_KEY" ``` OPR rates the **publisher’s standing**, not whether one story is accurate — every article from the same domain shares the same OPR. For the full scale and its meaning, see [what is the OPR score](/en/articles/trust-and-support/what-is-opr). ## What one-flag quality filters can I turn on?[#](#what-one-flag-quality-filters-can-i-turn-on) Instead of listing domains by hand, APITube ships ready-made switches built on the OPR bar. Each one is a precise, documented rule: * **`is_high_quality=1`** keeps an article only when **all four** conditions hold: it is not flagged as a duplicate, its source OPR is 5 or higher, it carries at least one image, and it has a named author. * **`is_verified_source=1`** keeps articles from OPR-5+ publishers that are not flagged as duplicates. * **`is_premium_source=1`** keeps only the top tier, OPR 6 or higher. Because `is_high_quality` also checks the article (image, byline), it is stricter than a source-only flag — a top publisher’s story is still dropped if it has no image or no author. Pick the right switch in [how to filter for high-quality, verified sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources). ## How does APITube flag misleading headlines?[#](#how-does-apitube-flag-misleading-headlines) Data quality is also about honesty between the headline and the body, so APITube scores both separately and exposes the mismatch. `is_clickbait=1` keeps articles where the **headline polarity differs from the body polarity** and the headline’s sentiment score is strongly charged (absolute value above 0.5) — an alarmist title over a calm story. Flip it to `is_clickbait=0` to **exclude** those articles from clean results. For finer control, `sentiment_gap.min` and `sentiment_gap.max` measure the raw distance between title and body sentiment on a **0 to 2** scale, so you can keep only articles whose headline matches their content. A full walkthrough is in [how to detect and filter clickbait](/en/articles/searching-and-filtering/content-quality/filter-clickbait). ## How can I audit why an article passed the filter?[#](#how-can-i-audit-why-an-article-passed-the-filter) Every article reports the signals the filters checked, so quality is verifiable, not implied. In each object you get the source’s `source.rankings.opr`, three-level `sentiment` (`overall`, `title`, `body`), the publisher `source.bias` (`left`, `center`, or `right`), and the `author`. Pull a sample without any quality flag, read those fields, then decide whether the built-in OPR-5 floor is enough or you want to raise it with `source.rank.opr.min`. Nothing about a result’s quality is hidden from the response. # Common Questions[#](#common-questions) * [Does a quality flag guarantee the article is accurate?](#does-a-quality-flag-guarantee-the-article-is-accurate) * [What is the fastest way to get clean results?](#what-is-the-fastest-way-to-get-clean-results) * [Does bias filtering remove low-quality sources?](#does-bias-filtering-remove-low-quality-sources) ## Does a quality flag guarantee the article is accurate?[#](#does-a-quality-flag-guarantee-the-article-is-accurate) No. OPR measures **publisher authority**, and the sentiment and clickbait signals measure **tone**, not factual accuracy. A high-OPR, non-clickbait article is a stronger, cleaner result — but the score does not verify the claims inside it. Treat these signals as reputation and consistency checks, and pair them with your own verification when accuracy is critical. ## What is the fastest way to get clean results?[#](#what-is-the-fastest-way-to-get-clean-results) Add `is_high_quality=1` to your request. It applies all four checks at once — non-duplicate, OPR 5 or higher, has an image, has a named author — so you get presentable, well-sourced articles from a single parameter without maintaining a source list. ## Does bias filtering remove low-quality sources?[#](#does-bias-filtering-remove-low-quality-sources) No. `source.bias` is a **transparency label** (`left`, `center`, or `right`), independent of authority. Filtering or excluding a bias does not raise quality — use OPR and the quality flags for that, and use `source.bias` only to balance or narrow the political leaning of your feed. For the exact field names on every article, see the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). * * * ## Related Articles * [What is the OPR (Open PageRank) score?](/en/articles/trust-and-support/what-is-opr) * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [What NLP enrichment is applied to each article?](/en/articles/news-data/nlp-enrichment) --- ## Can I access historical news archives? URL: https://support.apitube.io/en/articles/news-data/historical-archives Access historical news via APITube's /v1/news/everything search — filter any past date range with published_at.start and published_at.end, then sort and… # Can I access historical news archives? Query past news through the same everything search using the published\_at date range, then sort and paginate to walk any window ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&published_at_start=2024-01-01&published_at_end=2024-01-31) # Can I access historical news archives?[#](#can-i-access-historical-news-archives) Yes. APITube serves historical news from the **same** `/v1/news/everything` search you use for recent articles — there is no separate “archive” endpoint. You reach older articles by setting a date range with `published_at.start` and `published_at.end`, then sorting and paginating through the window. Any past period your query matches is available the same way today’s news is. Because history uses the normal search, every other filter works alongside it: you can pull articles about one company, in one language, or from one country for a fixed date range, then page through the results in publish-time order. ## Is there a separate archive endpoint?[#](#is-there-a-separate-archive-endpoint) No. Historical articles and fresh articles live behind one endpoint, `/v1/news/everything`. What makes a request “historical” is the **date filter**, not a different URL. Send your [API key](/en/articles/getting-started/glossary#api-key) as the `api_key` query parameter or the `X-API-Key` header, add a `published_at.start` / `published_at.end` range, and you are querying the archive: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2024-01-01&published_at.end=2024-01-31&api_key=YOUR_API_KEY" ``` This returns articles published in January 2024. The date filter is part of the shared filter chain, so it combines with keyword, source, [entity](/en/articles/getting-started/glossary#entity), language and every other filter in a single request — see [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) for the parameter itself. ## What date formats does the range accept?[#](#what-date-formats-does-the-range-accept) `published_at.start` and `published_at.end` accept both absolute and relative dates, so you can pin an exact window or express it relative to now: * **Absolute:** `2024-01-01` (`YYYY-MM-DD`), `01-01-2024` (`DD-MM-YYYY`), `01.01.2024` (`DD.MM.YYYY`), full ISO 8601 (`2024-01-01T00:00:00Z`), or a Unix timestamp in seconds. * **Relative:** `NOW`, `NOW-1WEEK`, `NOW-6MONTHS`, `NOW-1YEAR`, or the short forms `1w`, `6m`, `3d`, `5y` (a bare value means the past). `NOW/DAY` rounds down to the start of the day. The complete syntax for both parameters is listed in the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). Each date value must be 1 to 30 characters. An unparseable `published_at.start` returns HTTP 400 with error `ER0104`, and an unparseable `published_at.end` returns `ER0106`; a value longer than 30 characters returns `ER0105` (start) or `ER0107` (end). The example below pulls the last twelve months: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=NOW-1YEAR&published_at.end=NOW&api_key=YOUR_API_KEY" ``` ## How do I page through a long historical window?[#](#how-do-i-page-through-a-long-historical-window) By default results come back newest-first (`sort.by` defaults to `published_at`, `sort.order` to `desc`). To walk a period from oldest to newest instead, set `sort.order=asc`, then move through the results with `page` and `per_page`. `per_page` defaults to 100 and its maximum is **250** — a larger value returns error `ER0171` — so a full month is retrieved in batches: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2024-01-01&published_at.end=2024-01-31&sort.by=published_at&sort.order=asc&per_page=250&page=1&api_key=YOUR_API_KEY" ``` Increment `page` (2, 3, 4 …) to keep reading the same window. `page` must be an integer, or the request returns `ER0172`. On the **Free plan**, [pagination](/en/articles/getting-started/glossary#pagination) stops after the first **5 pages** (`ER0173`) and `per_page` is capped at 10, so a single query reaches 5 × 10 = 50 articles; a paid plan pages deeper and pulls larger pages. For the full pagination model, see [how to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). ## How far back does the archive go for my query?[#](#how-far-back-does-the-archive-go-for-my-query) APITube does not expose a single fixed “N years” number through the API, and coverage depth varies by topic, language and source. The reliable way to find the earliest available article **for your specific query** is to sort ascending and read the oldest result — request one article, oldest-first: ``` curl "https://api.apitube.io/v1/news/everything?sort.by=published_at&sort.order=asc&per_page=1&api_key=YOUR_API_KEY" ``` The `published_at` of that single article is the earliest date the archive holds for your filters. Add any filters (a source, a language, an entity) before running it to measure depth for exactly the slice you care about, rather than trusting a headline figure. ## How do I count how much history exists in a period?[#](#how-do-i-count-how-much-history-exists-in-a-period) Use `/v1/news/count` with the same date range to get the number of matching articles without downloading them. Because you are passing a date filter, the endpoint returns the real count for that window on a [live key](/en/articles/getting-started/glossary#test-key-and-live-key): ``` curl "https://api.apitube.io/v1/news/count?published_at.start=2023-01-01&published_at.end=2023-12-31&api_key=YOUR_API_KEY" ``` Stepping the range month by month is a quick way to profile how article volume changes over time before you commit to downloading. See [how to count matching articles](/en/articles/retrieval/count-articles) for the endpoint’s details and the test-key caveat. # Common Questions[#](#common-questions) * [Can I pull the entire archive in one request?](#can-i-pull-the-entire-archive-in-one-request) * [Why am I limited to 5 pages of history?](#why-am-i-limited-to-5-pages-of-history) * [Does the trends endpoint work on old data?](#does-the-trends-endpoint-work-on-old-data) * [What does published\_at without start or end do?](#what-does-published_at-without-start-or-end-do) ## Can I pull the entire archive in one request?[#](#can-i-pull-the-entire-archive-in-one-request) No. A single response is capped at `per_page=250` articles, so a large historical window is always retrieved across multiple pages. The practical pattern is to fix a date range with `published_at.start` / `published_at.end`, sort ascending, and loop `page` until the results run out — then move the window and repeat. For bulk historical extraction, narrow each window (by day, week, source, or language) so each slice fits inside the pagination limits. ## Why am I limited to 5 pages of history?[#](#why-am-i-limited-to-5-pages-of-history) The 5-page cap (`ER0173`) applies only to the **Free plan**. It limits every query — historical or recent — to the first 5 pages of results. With the Free `per_page` ceiling of 10 that is up to 50 articles per query; to page further into an archive window, upgrade to a paid plan. The date filter itself is not restricted on Free — only how deep you can paginate. ## Does the trends endpoint work on old data?[#](#does-the-trends-endpoint-work-on-old-data) Partly. `/v1/news/trends` accepts a date range but caps it at a **30-day** window (a longer range returns an error). The full-article search on `/v1/news/everything` has **no** such date-range cap, so for reading history beyond 30 days you query articles directly rather than trends. Use trends for short-window topic and entity movement, and `everything` for arbitrary historical periods. ## What does published\_at without start or end do?[#](#what-does-published_at-without-start-or-end-do) Passing a single `published_at` value (instead of the `.start` / `.end` pair) filters to a **one-day** window: APITube treats it as the start of that day and matches articles published within the following 24 hours. An unparseable single `published_at` returns `ER0109`. Use `published_at.start` and `published_at.end` when you need any window other than exactly one day. * * * ## Related Articles * [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) * [How to count matching articles without downloading them](/en/articles/retrieval/count-articles) --- ## How Does Sentiment Analysis Work? URL: https://support.apitube.io/en/articles/news-data/how-sentiment-works APITube scores every article's tone at ingestion, so each result carries a sentiment score from -1 to 1 and a positive, negative or neutral polarity. # How Does Sentiment Analysis Work? How APITube scores article tone with a -1 to 1 score and a positive, negative or neutral polarity ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&sentiment_gap_min=0.5) # How does sentiment analysis work?[#](#how-does-sentiment-analysis-work) APITube runs [sentiment](/en/articles/getting-started/glossary#sentiment) analysis on every article when it is processed, and stores the result with the article — so each result you read back already carries a sentiment reading. That reading has two parts: a numeric **score from -1 to 1**, and a **polarity** label of `positive`, `negative` or `neutral`. Because the value is precomputed and stored, the News API does not re-analyze text at query time — it reads the stored sentiment, which is what lets you filter, sort and display it instantly. Sentiment is measured at several levels of the same article: the overall article, the headline, the body, each key sentence, and each named [entity](/en/articles/getting-started/glossary#entity). Each level gets its own score and polarity, so you can ask “what is the mood of this piece?” and “how is this one company framed inside it?” separately. ## What is sentiment in the APITube News API?[#](#what-is-sentiment-in-the-apitube-news-api) Sentiment is the automated assessment of the emotional tone of an article. APITube expresses it two ways at once: * **Polarity** — a plain label: `positive`, `negative` or `neutral`. Use this when you just need the direction of the tone. * **Score** — a number from **\-1 (most negative) to 1 (most positive)**, where values close to zero are neutral. Use this when you need a threshold, a ranking, or a band. The polarity and the score describe the same tone at different resolutions: the score is the precise reading, and the polarity is the human-readable bucket it falls into. Every sentiment reading in the response gives you both. ## What do the sentiment score and polarity mean?[#](#what-do-the-sentiment-score-and-polarity-mean) The score is a float on a fixed scale from -1 to 1. A value near 1 means strongly positive tone, a value near -1 means strongly negative tone, and a value close to 0 is treated as neutral. The polarity is the label for that value. Here is the article-level `sentiment` object as returned by the API, with real example values: ``` { "sentiment": { "overall": { "score": -0.01, "polarity": "neutral" }, "title": { "score": -0.09, "polarity": "negative" }, "body": { "score": 0.07, "polarity": "positive" } } } ``` Notice that the overall, title and body layers can each land on a different polarity — a headline can read negative while the body reads mildly positive. That split is intentional and is what powers the disagreement filters described below. ## Which parts of an article get their own sentiment?[#](#which-parts-of-an-article-get-their-own-sentiment) APITube attaches sentiment at five levels of the same article, each with a `score` and `polarity`: * **Overall** — `sentiment.overall` — the tone of the whole article. * **Title** — `sentiment.title` — the tone of the headline alone. * **Body** — `sentiment.body` — the tone of the article text alone. * **Key sentences** — each item in the article’s `summary` array carries its own `sentiment` object, so you can see the tone sentence by sentence. * **Entities** — every entity in the `entities` array has its own `sentiment`, including a `mentions` breakdown that counts how often the entity was referenced positively, neutrally and negatively. The entity-level block looks like this in the response: ``` { "entities": [ { "name": "Tesla", "type": "organization", "sentiment": { "score": -0.62, "polarity": "negative", "mentions": { "positive": 1, "neutral": 2, "negative": 5 } } } ] } ``` This is why “the article is positive overall” and “the article is negative about one company in it” can both be true at the same time. To act on entity tone, see [how to get sentiment toward a company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment). ## Why can the headline and the body have different sentiment?[#](#why-can-the-headline-and-the-body-have-different-sentiment) Because the title and body are scored separately, they do not always agree — and that gap is itself a useful signal. APITube exposes it three ways: * `sentiment.mixed=1` returns articles where the title polarity differs from the body polarity, and `sentiment.consistent=1` returns articles where they match. * `sentiment_gap.min` and `sentiment_gap.max` filter on the size of the gap between the title and body scores, on a scale from **0 to 2**. * `is_clickbait=1` targets a specific pattern: a title whose polarity differs from the body **and** whose title score is strongly charged. It is a purpose-built shortcut for the “dramatic headline, flat article” case. For example, to surface articles where the headline and body diverge sharply: ``` curl "https://api.apitube.io/v1/news/everything?sentiment_gap.min=0.5&api_key=YOUR_API_KEY" ``` ## How do I use sentiment in a request?[#](#how-do-i-use-sentiment-in-a-request) Sentiment is part of the shared filter chain, so it stacks with any other filter and with sorting. Filter by tone with `sentiment.overall.polarity`, narrow to a numeric band with `sentiment.overall.score.min`/`.max`, or rank results with `sort.by=sentiment.overall.score`. This returns the most positive coverage of a company first: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Netflix&sort.by=sentiment.overall.score&sort.order=desc&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. For the full set of tone filters and score ranges, see [how to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment), and for field-by-field detail see the official [response structure reference](https://docs.apitube.io/platform/news-api/response-structure). # Common Questions[#](#common-questions) * [What sentiment values does APITube use?](#what-do-the-sentiment-score-and-polarity-mean) * [Does every article have a sentiment score?](#does-every-article-have-a-sentiment-score) * [Can I sort articles by how positive or negative they are?](#can-i-sort-articles-by-how-positive-or-negative-they-are) * [Is sentiment the same as the entity sentiment?](#is-sentiment-the-same-as-the-entity-sentiment) ## Does every article have a sentiment score?[#](#does-every-article-have-a-sentiment-score) Every article in the response includes the `sentiment` object with the `overall`, `title` and `body` layers, so the structure is always present. When a value is not available for an article, that layer defaults to a `score` of `0` and an empty `polarity` string, rather than being dropped. If you rely on sentiment, it is safe to read the field on any result; just treat an empty polarity as “not scored” rather than as neutral. ## Can I sort articles by how positive or negative they are?[#](#can-i-sort-articles-by-how-positive-or-negative-they-are) Yes. Set `sort.by=sentiment.overall.score` (or `sentiment.title.score` / `sentiment.body.score`) and choose the direction with `sort.order=asc` or `sort.order=desc`. Descending order puts the most positive articles first; ascending order puts the most negative first. Sorting works alongside any filter, so you can rank only positive English articles, or only articles about one company. ## Is sentiment the same as the entity sentiment?[#](#is-sentiment-the-same-as-the-entity-sentiment) No. `sentiment.overall` is the tone of the whole article, while each entity’s `sentiment` in the `entities` array is the tone directed at that specific company, person or brand. Use the overall value for “how does this article read?” and the entity value for “how is this one name framed?” — they are separate fields and can disagree within the same article. * * * ## Related Articles * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [What's Inside a News Article?](/en/articles/getting-started/understanding-article-data) --- ## News Data & Content URL: https://support.apitube.io/en/articles/news-data What is inside each APITube article and how the data is structured: entities, sentiment, story clusters, translation and data quality. ![](/images/collections/reports.png) # News Data & Content What's inside each article and how it's structured. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Tasha 1 author 11 articles What is actually inside an APITube article object: the fields you get back, how entities are recognised and linked, how sentiment is scored (including per-entity sentiment), how duplicate stories are grouped, and what the data-quality signals mean. Read [what data comes in an article](/en/articles/news-data/what-data-in-article) first — it walks through a full response field by field. The rest of the collection goes deeper into single topics such as [entities](/en/articles/news-data/understanding-entities) and sentiment accuracy. * [Can I access historical news archives?](/en/articles/news-data/historical-archives) * [Categories, Topics and Industries: What Is the Difference](/en/articles/news-data/categories-topics-industries) * [How accurate is the sentiment analysis?](/en/articles/news-data/sentiment-accuracy) * [How APITube handles languages and translation](/en/articles/news-data/languages-and-translation) * [How does APITube ensure data quality?](/en/articles/news-data/data-quality) * [How Does Sentiment Analysis Work?](/en/articles/news-data/how-sentiment-works) * [How story clustering and duplicate detection work](/en/articles/news-data/story-and-dedup) * [Understanding Entities: People, Companies, Locations](/en/articles/news-data/understanding-entities) * [What data is included with each article?](/en/articles/news-data/what-data-in-article) * [What Is a Story Cluster (Story vs Article)?](/en/articles/news-data/what-is-a-story) * [What NLP enrichment is applied to each article?](/en/articles/news-data/nlp-enrichment) --- ## How APITube handles languages and translation URL: https://support.apitube.io/en/articles/news-data/languages-and-translation APITube detects each article's language into the language field and ships an English translation of the title and description in translations.en. # How APITube handles languages and translation How each article's language is auto-detected, where the English translation of the headline lives, and how to filter by language ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 Updated July 31, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en%2Ces&sort_by=published_at&sort_order=desc) # How APITube handles languages and translation[#](#how-apitube-handles-languages-and-translation) APITube automatically detects the language of every article during processing and returns it as a two-letter code in each article’s `language` field. Article text is always delivered in its **original language**, and a non-English article additionally carries an English machine translation of its **headline and description** in the `translations.en` block — enough to scan foreign coverage and decide what deserves a full read. That makes “handling languages” in APITube three things: **detection** (built in, exposed on every article), **filtering** (you pass the language codes you want with `language.code`), and **translation into English** (precomputed, shipped alongside the original text rather than replacing it). ## How does APITube detect an article’s language?[#](#how-does-apitube-detect-an-articles-language) Language detection runs while the article is being parsed, before it ever reaches the API. APITube reads the article’s **title and description first** — the cleanest text available — and only falls back to the full body when that text is too short. This order matters: a page body often contains navigation and footer text in English, which can make a compact detector mislabel a Chinese or Japanese article as English. Detecting from the clean title and description avoids that. The detected value is stored as an [ISO 639-1](https://docs.apitube.io/platform/news-api/list-of-languages) two-letter code such as `en`, `fr`, `de`, `ja` or `zh`. If the language genuinely cannot be determined, the article falls back to the code `un` (undetermined). ## Where do I see an article’s language in the response?[#](#where-do-i-see-an-articles-language-in-the-response) Every article object carries a `language` field with its detected ISO 639-1 code, so you can confirm exactly what you received: ``` { "id": 123456789, "title": "…", "language": "fr" } ``` The `language` field is part of the standard enrichment returned with every article, alongside [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment) and categories. For the full set of fields, see [What NLP enrichment is applied to each article?](/en/articles/news-data/nlp-enrichment). ## How do I get news in specific languages?[#](#how-do-i-get-news-in-specific-languages) Add the `language.code` parameter with one or more ISO 639-1 codes. This returns English and Spanish articles in a single call, ordered newest first: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en,es&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` Key rules for `language.code`: * **Up to three codes**, separated by commas. Articles in **any** of those languages match (OR logic). * Each code must be **one or two characters**; the value is case-insensitive, so `EN` and `en` behave the same. * The alias `us` is treated as `en`. To keep everything **except** certain languages, use `ignore.language.code` with the same rules: ``` curl "https://api.apitube.io/v1/news/everything?ignore.language.code=fr&api_key=YOUR_API_KEY" ``` For a deeper walkthrough of single-language, multi-language and exclusion patterns, see [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). ## Does the News API translate articles?[#](#does-the-news-api-translate-articles) Yes — the headline and the description, into English, already computed by the time you receive the article. Every article object carries a `translations` block: ``` { "language": "de", "title": "Kanzler kündigt neuen Haushalt an", "translations": { "en": { "title": "Chancellor announces new budget", "description": "The government presented the budget for the next year." } } } ``` Five rules worth knowing before you build against it: * **Only the title and description are translated.** The article `body` is not — it stays in the source language, with no English counterpart anywhere in the response. * **The block is always in the response.** There is no parameter to switch translation on, and no extra cost — `translations` is part of the standard article shape, like `sentiment` or `entities`. * **The original text is never replaced.** `title` and `description` keep the source language, and `language` still reports that source language. Your code decides which of the two to show. * **English articles have an empty block.** Both fields are `null`, because the source text is already English — there is nothing to translate. * **Translation is machine translation**, computed once during article processing. It is built for scale and screening, not for publication-grade copy: expect solid gist, occasional awkward phrasing in long sentences. Translation covers **48 source languages**. A language outside that set — Macedonian, for example — is still detected, filtered and delivered normally; only its `translations.en` fields stay `null`. ## How do I read the English translation of a non-English article?[#](#how-do-i-read-the-english-translation-of-a-non-english-article) Read `translations.en.title` and fall back to `title` when it is `null`. That one line covers both English and non-English articles: ``` const headline = article.translations?.en?.title ?? article.title; ``` If the English headline is all you need, request just those fields and skip the original bodies entirely — a much smaller response: ``` curl "https://api.apitube.io/v1/news/everything?language.code=de&fl=id,language,translations.en.title,translations.en.description&api_key=YOUR_API_KEY" ``` The translation travels through every delivery format, not only JSON: `<translations>` in XML, a `Translations` column in CSV, TSV and XLSX, a `translations` column in Parquet, and the full block on every line of JSONL. RSS is the one exception — its item schema carries only the original title, link and description. Translated fields are returned in full on every plan, including Free — the only field the Free plan trims is the article body. ## Which languages does APITube support?[#](#which-languages-does-apitube-support) The canonical list of language codes accepted by `language.code` — and detected on incoming articles — lives in the documentation’s [list of supported languages](https://docs.apitube.io/platform/news-api/list-of-languages), which currently contains 60 codes. Any two-letter code from that table is valid; a code that is not on the list is rejected (see the error question below). # Common Questions[#](#common-questions) * [What does the language field contain if detection fails?](#what-does-the-language-field-contain-if-detection-fails) * [Can I request more than three languages at once?](#can-i-request-more-than-three-languages-at-once) * [What error means a language code is invalid?](#what-error-means-a-language-code-is-invalid) * [Does language.code change the language of the returned text?](#does-languagecode-change-the-language-of-the-returned-text) * [Can I search or filter by the translated text?](#can-i-search-or-filter-by-the-translated-text) * [Can I get translations into a language other than English?](#can-i-get-translations-into-a-language-other-than-english) ## What does the language field contain if detection fails?[#](#what-does-the-language-field-contain-if-detection-fails) When APITube cannot determine an article’s language, the `language` field falls back to `un` (undetermined) rather than guessing. Well-covered languages are detected reliably; `un` is the exception, not the norm. ## Can I request more than three languages at once?[#](#can-i-request-more-than-three-languages-at-once) No. Both `language.code` and `ignore.language.code` accept at most three codes. If you list more, only the **first three** are applied and the rest are silently dropped — so `language.code=en,fr,de,es` behaves as `en,fr,de`. Keep the list to three meaningful codes. ## What error means a language code is invalid?[#](#what-error-means-a-language-code-is-invalid) A code that is empty or longer than two characters returns HTTP 400 with error `ER0061` (or `ER0063` for the `ignore.language.code` variant). A well-formed two-letter code that is not in APITube’s language list returns HTTP 400 with `ER0237` (`ER0239` for the ignore variant) and a message like `language with code 'xx' not found`. ## Does language.code change the language of the returned text?[#](#does-languagecode-change-the-language-of-the-returned-text) No. `language.code` only **filters** which articles come back. Each matching article is still delivered in its original language, and its `language` field reflects that original, detected language — the English version lives separately in `translations.en` and is returned whether or not you filter by language. ## Can I search or filter by the translated text?[#](#can-i-search-or-filter-by-the-translated-text) Not yet. Keyword filters such as `title` match the **original** text, so a German article about the chancellor is found by `title=Bundeskanzler`, not by `title=chancellor`. The translation is returned for reading, not indexed for search. Two workarounds: search in the source language, or fetch a language slice with `language.code` and match `translations.en.title` yourself after retrieval. ## Can I get translations into a language other than English?[#](#can-i-get-translations-into-a-language-other-than-english) No. English is the only target language today. The response shape already allows for more — `translations` is keyed by language code, so `translations.en` would sit next to any future target — but only the `en` key is populated. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [What NLP enrichment is applied to each article?](/en/articles/news-data/nlp-enrichment) --- ## What NLP enrichment is applied to each article? URL: https://support.apitube.io/en/articles/news-data/nlp-enrichment Every APITube article arrives pre-enriched: named entities, three-level sentiment, IPTC categories, topics, industries, keywords, a summary and readability… # What NLP enrichment is applied to each article? The entities, sentiment, classification, summary and readability data returned with every article ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=Tesla&fl=title%2Centities%2Csentiment.overall%2Ccategories%2Csummary) Every article returned by the APITube News API arrives **pre-enriched**. Alongside the raw title and body, each article object already carries named [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment) scores, topical classification, a summary, keywords and readability metrics — computed during processing and delivered in the same JSON response. You do not call a separate endpoint for any of it; one search on `/v1/news/everything` returns the enrichment inline. ## What enrichment fields are added to each article?[#](#what-enrichment-fields-are-added-to-each-article) APITube adds several groups of natural-language-processing (NLP) fields on top of the scraped text. In one article object you get: * `entities` and `locations_mentioned` — recognized people, organizations, places and more. * `sentiment` — polarity and score for the overall article, the title and the body. * `categories`, `topics`, `industries` — topical classification of the article. * `summary` — key sentences pulled from the article, each with its own sentiment. * `keywords` — extracted keyword list. * `readability` — standard reading-difficulty scores. * `language` — the detected language code of the article. * Text statistics — `read_time`, `words_count`, `sentences_count`, `paragraphs_count`, `characters_count`. Each group is described below with the exact field names you will see in the response. ## How are entities extracted and typed?[#](#how-are-entities-extracted-and-typed) Each article carries an `entities` array. Every entity has an `id`, a `name`, and a `type`. The recognized types are **person, organization, location, brand, product, natural-disaster, disease, event** and **sport**. Beyond the label, each entity also includes: * `frequency` — how many times the entity is mentioned in the article. * `sentiment` — the sentiment expressed toward that specific entity (`score`, `polarity`, and a breakdown of `mentions` into positive, neutral and negative). * `title.pos` and `body.pos` — the character positions where the entity appears, so you can highlight mentions. * `links` — direct `wikipedia` and `wikidata` URLs when the entity is known. Location entities are additionally collected into a `locations_mentioned` array with `name`, `country`, `lat`, `lng` and `type`, which is handy for mapping where a story takes place. For a deeper walkthrough of the entity model, see [Understanding entities](/en/articles/news-data/understanding-entities). ## What sentiment does each article include?[#](#what-sentiment-does-each-article-include) APITube returns sentiment at three levels inside the `sentiment` object: `overall`, `title` and `body`. Each level has a numeric `score` and a `polarity` string that is one of **positive**, **negative** or **neutral**. Splitting title sentiment from body sentiment lets you detect mismatches — for example, a neutral body under an alarmist headline. On top of the article-level sentiment, every entity in the `entities` array has its own `sentiment` block, so you can measure how a story feels _about a particular company or person_ rather than the article as a whole. How the scores are produced is covered in [How does sentiment analysis work?](/en/articles/news-data/how-sentiment-works). ## How is each article classified into categories, topics and industries?[#](#how-is-each-article-classified-into-categories-topics-and-industries) APITube applies three parallel layers of classification, each returned as an array: * `categories` — mapped to the **IPTC Media Topics** taxonomy. Each entry has an `id`, a `name`, a relevance `score` and the `taxonomy` name. * `topics` — a topic label with its own relevance `score`. * `industries` — the industry the article relates to. Because categories and topics each carry a `score`, you can rank how strongly an article belongs to a subject instead of treating classification as a simple yes/no. ## What summary, keywords and readability data is included?[#](#what-summary-keywords-and-readability-data-is-included) Three more enrichment fields describe the text itself: * `summary` — an array of key sentences extracted from the article. Each sentence comes with its own `sentiment` `score` and `polarity`. * `keywords` — a list of extracted keywords for the article. * `readability` — reading-difficulty metrics including `flesch_kincaid_grade`, `flesch_reading_ease`, `automated_readability_index`, a plain-language `difficulty_level` and `target_audience`, `reading_age`, `avg_words_per_sentence` and `avg_syllables_per_word`. You also get an estimated `read_time` plus `words_count`, `sentences_count`, `paragraphs_count` and `characters_count` for quick filtering by length. ## How to request only the enrichment fields you need[#](#how-to-request-only-the-enrichment-fields-you-need) The full object is large, so use the `fl` parameter to return just the fields you care about. `fl` takes a comma-separated list and uses dot notation for nested fields: ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&fl=title,entities,sentiment.overall,categories,summary&api_key=YOUR_API_KEY" ``` That response contains only the title plus the requested enrichment blocks. See [How to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) for the full rules, and the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) for every field. # Common Questions[#](#common-questions) * [Do I need extra API calls to get the NLP data?](#do-i-need-extra-api-calls-to-get-the-nlp-data) * [Which entity types does APITube recognize?](#which-entity-types-does-apitube-recognize) * [Is enrichment available on the free plan?](#is-enrichment-available-on-the-free-plan) ## Do I need extra API calls to get the NLP data?[#](#do-i-need-extra-api-calls-to-get-the-nlp-data) No. The enrichment is embedded in the same article object returned by a normal search on `/v1/news/everything`, so entities, sentiment, categories, summary, keywords and readability all come back in a single request. ## Which entity types does APITube recognize?[#](#which-entity-types-does-apitube-recognize) The `type` field on each entity is one of: person, organization, location, brand, product, natural-disaster, disease, event or sport. Location entities are also aggregated into the article’s `locations_mentioned` array. ## Is enrichment available on the free plan?[#](#is-enrichment-available-on-the-free-plan) Yes. The enrichment fields — entities, sentiment, categories, topics, industries, summary, keywords and readability — are returned regardless of plan. On the free plan and with [test keys](/en/articles/getting-started/glossary#test-key-and-live-key), only the article body (`body`, `body_html`) is truncated (marked with `...[Upgrade subscription plan]`); the description, URLs and the NLP fields themselves are not masked. * * * ## Related Articles * [Understanding Entities: People, Companies, Locations](/en/articles/news-data/understanding-entities) * [How Does Sentiment Analysis Work?](/en/articles/news-data/how-sentiment-works) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) --- ## How accurate is the sentiment analysis? URL: https://support.apitube.io/en/articles/news-data/sentiment-accuracy APITube scores sentiment with a dictionary-based method on a -1 to 1 scale — reliable for direction and trends at scale, weaker on nuance like sarcasm or… # How accurate is the sentiment analysis? What APITube's sentiment scoring can and cannot tell you, and how to get more reliable results ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&sentiment_score_min=0.3&language_code=en) # How accurate is the sentiment analysis?[#](#how-accurate-is-the-sentiment-analysis) APITube scores [sentiment](/en/articles/getting-started/glossary#sentiment) with a fast **dictionary-based method** — it adds up the sentiment values of the individual words it recognizes in the text and returns a score from **\-1 to 1** with a `positive`, `negative` or `neutral` label. That approach is strong for reading the overall **direction** of tone across many articles, and weaker on nuance that depends on how words combine — sarcasm, irony, and negation. Treat the score as a reliable signal at scale, not as a verdict on a single sentence. APITube does **not** publish an accuracy percentage, and the response gives you a score and a polarity but **no confidence value**. So the honest answer to “how accurate is it?” is: accurate enough to sort, filter, and trend millions of articles by tone, but not a substitute for reading a specific article when the exact framing matters. ## What method does APITube use to score sentiment?[#](#what-method-does-apitube-use-to-score-sentiment) Sentiment is computed once when an article is ingested, then stored — the News API reads back the stored value and never re-analyzes text at query time. The scorer works at the **word level**: it tokenizes the text, looks each word up in a per-language sentiment dictionary, and sums the matched word scores. That total is divided by the number of tokens to produce the `comparative` score you see, on the -1 to 1 scale. The article-level `overall` value is the average of the separate title and body scores. Because only recognized dictionary words contribute, two things follow directly: text with few charged words trends toward zero, and meaning carried by sentence structure (rather than by single words) is not modeled. This is the classic trade-off of a lexicon scorer — it is fast, transparent, and consistent, but it reads words, not arguments. For the full mechanics, see [how sentiment analysis works](/en/articles/news-data/how-sentiment-works). ## How accurate is it, and where does it fall short?[#](#how-accurate-is-it-and-where-does-it-fall-short) The scorer is dependable for the coarse question — _is coverage of this topic leaning positive or negative?_ — especially when you aggregate across many articles. It is less dependable for the fine question — _is this one headline genuinely sarcastic?_ Known limitations of a word-list approach: * **Sarcasm and irony** — “Great, another delay” is positive word-by-word but negative in intent; the scorer reads the words. * **Negation and context** — meaning that flips across a phrase is not reliably captured, because scores come from individual words rather than sentence grammar. * **Domain tone** — a word that is negative in general English may be neutral in a financial or medical context, and vice versa. * **No confidence signal** — the API returns the score and polarity only. A `0.62` and a `0.08` are both “positive,” but the API does not tell you how sure it is; use the score **magnitude** as your own strength band. ## Why do so many articles come back neutral?[#](#why-do-so-many-articles-come-back-neutral) Neutral is the default outcome, so a lot of factual reporting lands there. Two mechanics drive this. First, the score is divided by the total token count, so a long, mostly factual article with only a few charged words averages close to zero. Second, values close to zero are labeled `neutral` by design. On top of that, an article whose sentiment could not be scored comes back with an **empty polarity** and a score of `0` — so treat an empty polarity as “not scored,” not as a confident neutral. A third cause is language coverage. Dictionaries are **per language**, and if an article’s language has no dictionary loaded, the scorer falls back to the **English** dictionary — which matches few of that article’s words, pushing the result toward neutral. Filtering to languages with strong dictionary coverage avoids this. ## How do I get more reliable sentiment results?[#](#how-do-i-get-more-reliable-sentiment-results) You cannot change how a stored score was computed, but you can query it more carefully: * **Filter by language first** so the score you read was produced with the right dictionary. See [how to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). * **Use score bands, not exact floats.** Ask for clearly-charged articles instead of trusting tiny differences near zero: ``` curl "https://api.apitube.io/v1/news/everything?sentiment.overall.score.min=0.3&language.code=en&api_key=YOUR_API_KEY" ``` * **Read title and body separately.** They are scored independently, so a dramatic headline can diverge from a flat body. Surface that gap with `sentiment_gap.min` (a 0-to-2 scale) or `sentiment.mixed=1`: ``` curl "https://api.apitube.io/v1/news/everything?sentiment_gap.min=0.5&language.code=en&api_key=YOUR_API_KEY" ``` * **Prefer [entity](/en/articles/getting-started/glossary#entity)\-level sentiment for “how is X framed.”** Instead of the whole-article tone, APITube scores the text windows around each mention of a company or person, which is far more targeted than the overall value — see [how to get sentiment toward a company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment). * **Aggregate.** For a trend, count polarities across hundreds of articles rather than trusting any single reading. # Common Questions[#](#common-questions) * [Does APITube give a confidence score for sentiment?](#does-apitube-give-a-confidence-score-for-sentiment) * [Is sentiment accuracy the same across languages?](#is-sentiment-accuracy-the-same-across-languages) * [Can it understand sarcasm or negation?](#can-it-understand-sarcasm-or-negation) * [Why do the title and body sometimes disagree?](#why-do-the-title-and-body-sometimes-disagree) ## Does APITube give a confidence score for sentiment?[#](#does-apitube-give-a-confidence-score-for-sentiment) No. Each sentiment reading is a `score` (from -1 to 1) and a `polarity` label; entity-level readings add a `mentions` breakdown counting positive, neutral and negative mentions. There is no separate confidence or accuracy field in the response. Use the **absolute value of the score** as a rough strength indicator: readings near ±1 are strongly charged, readings near 0 are weakly charged or neutral. For the exact field shapes, see the official [response structure reference](https://docs.apitube.io/platform/news-api/response-structure). ## Is sentiment accuracy the same across languages?[#](#is-sentiment-accuracy-the-same-across-languages) Not necessarily. Sentiment dictionaries are maintained **per language**, so accuracy tracks how well-covered that language’s dictionary is. When an article’s language has no dictionary available, the scorer falls back to the English dictionary, which will match few of the article’s words and skew the result toward neutral. If sentiment quality matters for your use case, filter to the languages you care about with `language.code` and validate on a sample. ## Can it understand sarcasm or negation?[#](#can-it-understand-sarcasm-or-negation) Not reliably. The scorer reads sentiment word by word from a dictionary rather than parsing sentence structure, so tone that depends on how words combine — sarcasm, irony, or a negation that flips a phrase — can be missed. This is inherent to a lexicon-based method. Where intent is subtle, use the score as a filter to _shortlist_ candidates and confirm the framing by reading the article. ## Why do the title and body sometimes disagree?[#](#why-do-the-title-and-body-sometimes-disagree) Because the headline and the body are scored **separately**, and the article-level `overall` value is the average of the two. A charged headline over a flat body — or the reverse — produces title and body polarities that differ, and that gap is itself a useful signal. Filter for it with `sentiment.mixed=1` (title polarity differs from body) or `sentiment_gap.min`, and read more in [how to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment). * * * ## Related Articles * [How Does Sentiment Analysis Work?](/en/articles/news-data/how-sentiment-works) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) --- ## How story clustering and duplicate detection work URL: https://support.apitube.io/en/articles/news-data/story-and-dedup How APITube story clustering and duplicate detection work: clusters build from a seed headline's keywords, and is_duplicate is a separate per-article flag. # How story clustering and duplicate detection work How APITube groups coverage of one event from a seed headline, and how the separate is\_duplicate flag drops near-identical reprints ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 5, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fstory%2F%7Barticle_id%7D&pp_article_id=1234567) # How story clustering and duplicate detection work[#](#how-story-clustering-and-duplicate-detection-work) Story clustering and duplicate detection solve **opposite** problems in APITube. Clustering **gathers** different articles that cover the same event — different sources, different wording — by matching a seed article’s headline keywords. Duplicate detection does the reverse: it flags near-identical reprints of the _same_ article, which you filter out with the `is_duplicate` parameter. One pulls varied coverage together; the other strips repeated copies apart. Neither relies on a pre-stored “story ID” stamped onto each article. A cluster is computed **on demand** from a seed article you choose, and duplicate status is a per-article flag you read at query time. This page explains the mechanics of both. For the plain-language concept of a story versus an article, start with [what is a story cluster](/en/articles/news-data/what-is-a-story). ## How does APITube build a story cluster?[#](#how-does-apitube-build-a-story-cluster) APITube builds a cluster from the **seed article’s headline**, at query time. You pass one article’s `id` to `/v1/news/story/:id`, and the endpoint runs these steps: 1. It looks up the seed article and reads its title. If the `id` matches no article, it returns `404` with error `ER0235`. 2. It **tokenizes** the title, drops stopwords (common words like “the” or “and”), and **expands** the remaining words with synonyms and morphological forms — so a match is not limited to the exact words in the seed headline. 3. It keeps only tokens of at least **two characters**. If nothing usable is left after stopwords are removed, it returns `404` with `ER0240` rather than guessing. 4. It finds other articles whose **titles** contain any of those tokens (a case-insensitive token match), and always excludes the seed article itself. ``` curl "https://api.apitube.io/v1/news/story/1234567?api_key=YOUR_API_KEY" ``` Because the cluster is seeded from any article `id`, any article can start its own story. The endpoint accepts both `GET` (id in the path) and `POST` (same path, filters in a JSON body), and the results are paginated like any search. ## How does APITube rank the articles in a story?[#](#how-does-apitube-rank-the-articles-in-a-story) APITube ranks cluster results by **how many of the seed headline’s keywords each article’s title matches**. Every candidate gets a relevance score equal to the count of matching tokens, and results are ordered by that score **descending** — an article whose headline shares more keywords with the seed ranks above one that shares fewer. So the closest coverage of the same event surfaces first, and looser matches trail behind. Matching is done on the **headline**, not the body, which keeps a cluster tight around the specific event the seed article reports. ## How does duplicate detection work, and how do you filter it?[#](#how-does-duplicate-detection-work-and-how-do-you-filter-it) Duplicate detection is a **per-article flag**, separate from clustering. Each article carries an `is_duplicate` value, and you filter on it with the `is_duplicate` parameter, which accepts exactly `0` or `1`: * `is_duplicate=0` returns only articles flagged as **not** duplicates. * `is_duplicate=1` returns only articles flagged **as** duplicates. ``` curl "https://api.apitube.io/v1/news/everything?title=election&is_duplicate=0&api_key=YOUR_API_KEY" ``` The value must be `0` or `1`: a non-numeric value returns `ER0003`, and any other number returns `ER0004`. Keep in mind that `is_duplicate` is an approximate flag rather than exhaustive reprint detection — `is_duplicate=0` thins flagged copies but does not guarantee that every syndicated reprint is dropped. Use `is_duplicate=0` when you want to thin a feed toward flagged-unique pieces, and see [how to exclude paywalled or duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) for combining it with other quality filters. ## Story clustering vs duplicate detection: what’s the difference?[#](#story-clustering-vs-duplicate-detection-whats-the-difference) A **story** groups _different_ articles — different sources and wording — that cover the same event, built by matching the seed headline’s keywords. A **duplicate** is a near-identical copy of the same article, flagged at the article level and controlled with `is_duplicate`. So the two are complementary: use the story endpoint to **gather** the spread of coverage around one event, and the `is_duplicate` filter to **thin** a result set by dropping flagged reprints. They are not the same mechanism and do not share an identifier. # Common Questions[#](#common-questions) * [Does clustering match on the article body or just the headline?](#does-clustering-match-on-the-article-body-or-just-the-headline) * [What happens if the seed headline has no usable keywords?](#what-happens-if-the-seed-headline-has-no-usable-keywords) * [How much does a story request cost?](#how-much-does-a-story-request-cost) * [Can I reuse a story cluster later?](#can-i-reuse-a-story-cluster-later) ## Does clustering match on the article body or just the headline?[#](#does-clustering-match-on-the-article-body-or-just-the-headline) Clustering matches on the **headline only**. APITube reads the seed article’s title, expands its keywords with synonyms and morphology, and searches the _titles_ of other articles for those tokens. The body text is not used to build the cluster. Headline matching keeps a story focused on the specific event the seed reports, rather than pulling in loosely related articles that merely mention the same words deep in their text. ## What happens if the seed headline has no usable keywords?[#](#what-happens-if-the-seed-headline-has-no-usable-keywords) If the seed article’s title is left with no usable tokens after stopwords are removed — for example, a headline made entirely of very short or common words — the endpoint returns `404` with error `ER0240` instead of guessing at a cluster. A `404` with `ER0235` is different: it means the `id` you passed does not match any article at all. Passing no `id` returns `400` with `ER0231`. ## How much does a story request cost?[#](#how-much-does-a-story-request-cost) A `/v1/news/story/:id` call costs **1 credit**, and you are charged only when the endpoint returns at least one related article. If no other headline overlaps the seed’s keywords, the result set is empty, that is a normal outcome rather than an error, and no credit is spent. ## Can I reuse a story cluster later?[#](#can-i-reuse-a-story-cluster-later) There is no stored story ID to save. Because a cluster is computed on demand from a seed article’s `id`, you reproduce a story later by calling `/v1/news/story/:id` again with the same seed `id`. The set of matched articles can change over time as new coverage is published and matched against the seed headline — see [how to get all articles covering the same story](/en/articles/retrieval/get-story-cluster) for the full request options. * * * ## Related Articles * [What Is a Story Cluster (Story vs Article)?](/en/articles/news-data/what-is-a-story) * [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) --- ## Understanding Entities: People, Companies, Locations URL: https://support.apitube.io/en/articles/news-data/understanding-entities Entities are the people, companies, locations and other named things APITube extracts from each article, returned with type, positions, frequency and sentiment. # Understanding Entities: People, Companies, Locations What entities are in APITube article data, the types recognized, and how each one is described in the response ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fentity%2F%7Bentity_id%7D&pp_entity_id=1034399) # Understanding entities: people, companies, locations[#](#understanding-entities-people-companies-locations) An **[entity](/en/articles/getting-started/glossary#entity)** in the APITube News API is a named thing that appears in an article — a person, a company, a place, a brand, and more. When APITube processes an article, it detects these names, resolves them to a known record, and stores them with the article. Every result you read back carries an `entities` array where each item describes one named thing: its `id`, its `type`, how often it was mentioned, where it was mentioned, and the [sentiment](/en/articles/getting-started/glossary#sentiment) expressed toward it. Because entities are precomputed and stored per article, you can both **read** them on any result and **filter** by them at query time — for example, pull only articles that mention a specific company, or only articles that speak negatively about a person. ## What is an entity in the APITube News API?[#](#what-is-an-entity-in-the-apitube-news-api) An entity is a single named thing extracted from the article’s text — not a keyword, but a resolved record with a stable numeric `id`. The same real-world company keeps the same entity `id` across every article that mentions it, which is what lets you track one name over time instead of chasing spelling variants. Each entity also links out to external references: a `self` link to the entity on the API, plus `wikipedia` and `wikidata` links when APITube has matched the name to those knowledge bases. Entities are distinct from categories, topics and industries. Those classify the _subject_ of the article; entities are the concrete _names_ mentioned inside it. ## What entity types does APITube recognize?[#](#what-entity-types-does-apitube-recognize) Every entity carries a `type` label. APITube recognizes nine types: * `person` * `location` * `organization` * `brand` * `product` * `natural-disaster` * `disease` * `event` * `sport` If a type cannot be determined, it is returned as `unknown`. The type is what tells “Apple the company” apart from “apple the fruit,” and it is also how you target a name filter: a person name filter only matches `person` entities, an organization filter only matches `organization` entities, and so on. ## What does an entity look like in an article?[#](#what-does-an-entity-look-like-in-an-article) Each item in the `entities` array is a self-contained object. Here is a real location entity as returned by the API: ``` { "id": 1034399, "name": "Germany", "type": "location", "links": { "self": "https://api.apitube.io/v1/news/entity/1034399", "wikipedia": "https://en.wikipedia.org/wiki/Germany", "wikidata": "https://www.wikidata.org/wiki/Q183" }, "frequency": 3, "sentiment": { "score": -0.42, "polarity": "negative", "mentions": { "positive": 1, "neutral": 0, "negative": 2 } }, "title": { "pos": [{ "start": 7, "end": 14 }] }, "body": { "pos": [{ "start": 113, "end": 120 }, { "start": 852, "end": 859 }] }, "metadata": { "type": "country", "country": { "code": "DE" }, "coordinates": { "lat": 51.1657, "lng": 10.4515 } } } ``` Read in plain terms: `id` is the stable numeric identifier and `name` is the display name. `frequency` is how many times the entity was mentioned in the article. The `title.pos` and `body.pos` arrays give the exact character offsets of each mention as `start` and `end` pairs, so you can highlight the name in place. The `sentiment` block is the tone directed at _this_ entity, with a `score` from -1 to 1, a `polarity` of `positive`, `negative` or `neutral`, and a `mentions` breakdown counting how many references were positive, neutral and negative. The `metadata` object holds extra detail that varies by type — for a `location` it can include the country code and coordinates, and for an `organization` it can include headquarters and key people. Locations get a second, flattened view: the article also returns a `locations_mentioned` array built from its `location` entities that have a country, giving each one as `name`, `country`, `lat`, `lng` and `type`. For a field-by-field breakdown of the whole article object, see the official [response structure reference](https://docs.apitube.io/platform/news-api/response-structure). ## How do I find articles that mention a specific entity?[#](#how-do-i-find-articles-that-mention-a-specific-entity) You filter by entity in two ways. If you know the numeric identifier, pass `entity.id` — it accepts up to three comma-separated IDs and must be numeric: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=1034399&api_key=YOUR_API_KEY" ``` If you only have a name, use the type-specific name filter: `person.name`, `organization.name`, `location.name` or `brand.name`. APITube resolves the name to its entity record before searching, so the name must match a known entity — if it doesn’t, the request returns a 400 error rather than silently matching text: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Netflix&api_key=YOUR_API_KEY" ``` Each name filter also accepts up to three comma-separated names. For a fuller walkthrough of entity search, see [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## How do I read sentiment toward a single entity?[#](#how-do-i-read-sentiment-toward-a-single-entity) Because every entity carries its own `sentiment`, an article can be positive overall while being negative about one company inside it. To act on that, filter with `entity.sentiment.polarity` (`positive`, `negative` or `neutral`) and narrow the range with `entity.sentiment.score.min` and `entity.sentiment.score.max`, both on the -1 to 1 scale. Combine it with an entity selector to ask “articles that speak negatively about this company”: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Netflix&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` For how entity tone is scored versus article-level tone, see [how to get sentiment toward a company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) and [how sentiment analysis works](/en/articles/news-data/how-sentiment-works). # Common Questions[#](#common-questions) * [Are entity IDs numeric and stable?](#are-entity-ids-numeric-and-stable) * [What is the difference between `entities` and `locations_mentioned`?](#what-is-the-difference-between-entities-and-locations_mentioned) * [Can I filter on more than three entities at once?](#can-i-filter-on-more-than-three-entities-at-once) * [What does the entity `frequency` count?](#what-does-the-entity-frequency-count) ## Are entity IDs numeric and stable?[#](#are-entity-ids-numeric-and-stable) Yes. Each entity has a numeric `id`, and the `entity.id` filter parses it as an integer — non-numeric values are rejected. The same entity keeps the same `id` across articles, so an entity ID is the reliable way to track one exact company, person or place over time, without depending on how the name was spelled in a given article. ## What is the difference between `entities` and `locations_mentioned`?[#](#what-is-the-difference-between-entities-and-locations_mentioned) The `entities` array holds every named thing of any type, including `location` entities. The `locations_mentioned` array is a convenience view derived from those location entities that carry a country: it flattens each one to `name`, `country`, `lat`, `lng` and `type`. Use `entities` for the full picture and per-entity sentiment; use `locations_mentioned` when you just need clean geographic points for a map. ## Can I filter on more than three entities at once?[#](#can-i-filter-on-more-than-three-entities-at-once) No. Both `entity.id` and the name filters (`person.name`, `organization.name`, `location.name`, `brand.name`) take at most three comma-separated values per request; extra values beyond the first three are ignored. To cover more entities, run separate requests or combine an entity filter with broader filters such as category or topic. ## What does the entity `frequency` count?[#](#what-does-the-entity-frequency-count) The `frequency` value is how many times that entity was mentioned in the single article you are reading — not how many articles mention it across the archive. A higher `frequency` means the name is more central to that specific piece. To find which entities are trending across many articles instead, aggregate with the trends endpoint on the `entity.id` field. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [What's Inside a News Article?](/en/articles/getting-started/understanding-article-data) --- ## What data is included with each article? URL: https://support.apitube.io/en/articles/news-data/what-data-in-article Every APITube article bundles content, classification, entities, three-level sentiment, a source profile, readability metrics, media and engagement data in one… # What data is included with each article? The content, classification, entity, sentiment, source and quality data bundled into every APITube article ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 5, 2026 Updated July 31, 2026 # What data is included with each article?[#](#what-data-is-included-with-each-article) Every APITube article arrives as **one JSON object** that bundles far more than the headline. Alongside the readable content, each article carries eight groups of machine-readable data: **content and identity**, **classification** (categories, topics, industries), **[entities](/en/articles/getting-started/glossary#entity)** with knowledge-graph links, **three levels of [sentiment](/en/articles/getting-started/glossary#sentiment)**, a **source profile**, **readability and length metrics**, **media and summary**, and **engagement plus status flags**. You do not run any of this yourself — the enrichment ships already computed, so you can filter, score, and route articles the moment you receive them. This page is a decision-level map of _what data you get_ per article. For the exact JSON shape field by field, see [what’s inside a news article](/en/articles/getting-started/understanding-article-data). ## What content and identity fields does each article include?[#](#what-content-and-identity-fields-does-each-article-include) The readable core of every article: * **`title`** — the headline, and **`description`** — a short plain-text summary with HTML removed. * **`body`** — the full article text as plain text, and **`body_html`** — the same content with the original HTML markup preserved. You choose the form that suits NLP, indexing, or rendering. * **`href`** — the canonical URL of the original article, and **`image`** — its lead image URL. * **`published_at`** — the publish time in ISO 8601 (UTC). * **`language`** — the detected language as an ISO 639-1 code, such as `en`. * **`translations`** — the English machine translation of a non-English article’s headline and description: `translations.en.title` and `translations.en.description` (the body is not translated). The block is always present; its fields are `null` for English articles. See [how APITube handles languages and translation](/en/articles/news-data/languages-and-translation). * **`author`** — an `{ id, name }` object when a byline was detected. ## What classification data does APITube attach?[#](#what-classification-data-does-apitube-attach) Every article is tagged with thematic labels, all as arrays of objects (not bare strings), so each tag carries context: * **`categories`** — IPTC Media Topics, each with an `id`, `name`, a relevance `score`, its `taxonomy`, and a `self` link to that category’s feed. * **`topics`** and **`industries`** — extra thematic tags, each with an `id`, `name`, and a `self` link (topics also carry a `score`). * **`keywords`** — a flat array of the salient terms extracted from the article. Because scores and links come attached, you can rank a match by relevance or jump straight to every article in the same category. ## What entity and knowledge-graph data is included?[#](#what-entity-and-knowledge-graph-data-is-included) The **`entities`** array lists the real-world things the article mentions — people, organizations, places, and more. Each entity is one of nine types: `person`, `location`, `organization`, `brand`, `product`, `natural-disaster`, `disease`, `event`, or `sport`. For each entity you get: * an `id`, `name`, and `type`; * `links` to that entity’s APITube feed and, where known, its Wikipedia and Wikidata pages; * a `frequency` count of how often it appears; * a `sentiment` block scored _toward that entity specifically_, with a `mentions` breakdown of positive, neutral, and negative references; * `title.pos` and `body.pos` arrays marking where the entity appears in the text; * a `metadata` block for known organizations (details such as headquarters and key people). A convenience array, **`locations_mentioned`**, distils the location entities that have a known country into `{ name, country, lat, lng }` so you can map an article without walking the full entity list. For the full breakdown, see [understanding entities](/en/articles/news-data/understanding-entities). ## What sentiment data comes with each article?[#](#what-sentiment-data-comes-with-each-article) APITube ships sentiment at three levels. The article-level **`sentiment`** object has three views — `overall`, `title`, and `body` — each with a numeric `score` from −1 (negative) to 1 (positive) and a `polarity` label of `positive`, `negative`, or `neutral`. On top of that, every entity carries its own sentiment, so you can tell whether a company was framed favourably even inside an article that reads neutral overall. See [how sentiment analysis works](/en/articles/news-data/how-sentiment-works) for the scoring detail. ## What source, quality and readability data is included?[#](#what-source-quality-and-readability-data-is-included) Each article is fully attributed and scored for quality: * **`source`** — a publisher profile: `domain`, `home_page_url`, `type`, a political-leaning `bias` label, `rankings.opr` (the source’s [OPR](/en/articles/getting-started/glossary#opr-open-pagerank) authority score), a `location` with country name and code, and a `favicon` URL. * **`readability`** — reading-difficulty metrics including `flesch_reading_ease`, `flesch_kincaid_grade`, `automated_readability_index`, a `difficulty_level`, a `target_audience`, an estimated `reading_age`, plus average words-per-sentence and syllables-per-word. * **Length counters** — `words_count`, `sentences_count`, `paragraphs_count`, `characters_count`, and `read_time`. ## What media, engagement and status data is included?[#](#what-media-engagement-and-status-data-is-included) Finally, each article describes its attachments, reach, and state: * **`media`** and **`links`** — arrays of `{ url, type }` for attached media and outbound links; **`summary`** is an array of key sentences, each with its own sentiment. * **`shares`** — social-share counts (`total`, `facebook`, `twitter`, `reddit`). These ramp up over roughly the first two hours after publication, so counts on a brand-new article are partial by design. * **`story`** — the cluster this article belongs to, with an `id` and a `uri` to fetch every article covering the same event. * **Status flags** — `is_breaking` marks high-importance news, `is_duplicate` flags likely near-identical reprints (an approximate signal, not exhaustive reprint detection), and `is_free` reports whether the **original** article is freely readable at its source (this is about the source, not your subscription). # Common Questions[#](#common-questions) ## Is the data the same on every endpoint?[#](#is-the-data-the-same-on-every-endpoint) Yes. Whether an article comes from a search, a single-article lookup, or the real-time stream, it is built into the **same fixed object shape** with the same field names. Fields that do not apply to a given article are still present but empty (an empty array, `null`, or `0`), so your parser never has to guess whether a field will exist. ## Do I have to receive all of this data?[#](#do-i-have-to-receive-all-of-this-data) No. Use the `fl` parameter to request only the fields you need — for example `fl=id,title,source.domain,sentiment.overall` — which shrinks the response and speeds up parsing. The field names you pass are exactly the ones on this page. See [how to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields). ## Why is some data shortened on the free plan?[#](#why-is-some-data-shortened-on-the-free-plan) On the Free plan and with [test keys](/en/articles/getting-started/glossary#test-key-and-live-key), the article body (`body`, `body_html`) is truncated and tagged with a marker like `...[Upgrade subscription plan]`; the description, `href`, `image` and source URLs come back in full. The **schema is identical** to a paid response — the field names and structure never change, only the values are shortened. A paid plan with a live key returns the full content. * * * ## Related Articles * [What's inside a news article?](/en/articles/getting-started/understanding-article-data) * [Understanding entities: people, companies, locations](/en/articles/news-data/understanding-entities) * [How does sentiment analysis work?](/en/articles/news-data/how-sentiment-works) * [How to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) --- ## What Is a Story Cluster (Story vs Article)? URL: https://support.apitube.io/en/articles/news-data/what-is-a-story A story in APITube is a cluster of articles covering the same event across sources; an article is one single item. Stories are built on demand from a seed… # What Is a Story Cluster (Story vs Article)? How APITube groups multiple articles covering the same event into one story, and how a story differs from a single article ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fstory%2F%7Barticle_id%7D&pp_article_id=1234567) # What is a story cluster (story vs article)?[#](#what-is-a-story-cluster-story-vs-article) A **story** in the APITube News API is a cluster of articles that cover the same real-world event across different sources, while an **article** is one single news item from one source. One event usually produces many articles — a dozen outlets reporting the same election result — and the story is the group that ties them together. The article is the unit you read; the story is the spread of coverage around it. APITube does not stamp a fixed story ID onto each article. Instead it builds a story **on demand** from a seed article: you pass one article’s `id` to the `/v1/news/story/:id` endpoint, and it returns the other articles whose headlines share the same keywords, ranked so the closest matches come first. That means any article can act as the seed for its own [story cluster](/en/articles/getting-started/glossary#story). ## What is the difference between a story and an article?[#](#what-is-the-difference-between-a-story-and-an-article) An article is a single, standalone record. It has a unique `id`, one source, one URL, and its own full set of fields — title, body, publication date, language, [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment) and more. When you fetch or search articles, each result is one article. A story is a _relationship_ between articles, not a separate object you store. It is the set of articles that report the same event. Because coverage of a real event is scattered across publishers, the story lets you move from “here is one report” to “here is everyone’s report of this event.” So the two answer different questions: an article answers “what does this one piece say?”, and a story answers “who else covered this, and how?” ## How does APITube build a story cluster?[#](#how-does-apitube-build-a-story-cluster) APITube builds a story from the **seed article’s headline**, at query time. It reads the seed article’s title, tokenizes it, drops stopwords, and keeps the remaining keywords (each at least two characters). It then finds other articles whose titles contain those keywords and ranks them by how many keywords overlap — an article matching more of the seed headline ranks above one matching fewer. The seed article itself is always excluded, so you get only the _other_ coverage. Because there is no pre-built cluster ID, the seed article is what defines the story. You call the endpoint with the seed’s `id` in the path: ``` curl "https://api.apitube.io/v1/news/story/1234567?api_key=YOUR_API_KEY" ``` If the seed title has no usable keywords left after stopwords are removed, the endpoint returns `ER0240` rather than guessing. For the full request, filtering and [pagination](/en/articles/getting-started/glossary#pagination) options, see [how to get all articles covering the same story](/en/articles/retrieval/get-story-cluster). ## How is a story different from a duplicate article?[#](#how-is-a-story-different-from-a-duplicate-article) A story and a duplicate are not the same thing. A story groups **different** articles — different sources, different wording — that happen to cover the same event. A duplicate is a near-identical copy of the same article, usually syndicated or reposted across sites with the same text. APITube flags duplicates at the article level, so you control them with the `is_duplicate` filter (`0` or `1`). Use `is_duplicate=0` to thin flagged reprints from a feed: ``` curl "https://api.apitube.io/v1/news/everything?title=election&is_duplicate=0&api_key=YOUR_API_KEY" ``` In short: use `is_duplicate` to **thin** flagged reprints from a stream — it is an approximate flag, not exhaustive reprint detection, so `is_duplicate=0` reduces reprints without guaranteeing every copy is removed — and use the story endpoint to **gather** the varied coverage of one event. See [how to exclude paywalled or duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) for the dedup filter. ## When should I use a story instead of a single article?[#](#when-should-i-use-a-story-instead-of-a-single-article) Use a single article when you want one item’s full content — fetch it by `id`. Use a story when you want the whole picture of one event: every source’s version, so you can compare how outlets frame it, trace it back toward the original report, or gauge how widely it spread. Because a story is seeded from any article `id`, the typical flow is: run a search, take the `id` of one result, then ask the story endpoint for the rest of the coverage around it. # Common Questions[#](#common-questions) * [Does every article belong to a stored story?](#does-every-article-belong-to-a-stored-story) * [Is there a story ID I can save and reuse?](#is-there-a-story-id-i-can-save-and-reuse) * [How much does a story request cost?](#how-much-does-a-story-request-cost) * [What happens if the story returns no other articles?](#what-happens-if-the-story-returns-no-other-articles) ## Does every article belong to a stored story?[#](#does-every-article-belong-to-a-stored-story) No. APITube does not assign each article to a fixed, pre-built story cluster. A story is computed at query time from a seed article you choose, so any article can be the starting point of its own story. As long as the seed article’s title has usable keywords, you can ask for the coverage around it. ## Is there a story ID I can save and reuse?[#](#is-there-a-story-id-i-can-save-and-reuse) There is no separate story ID to store — clusters are built on demand from a seed article’s `id`. To reproduce a story later, save the **seed article’s `id`** and call `/v1/news/story/:id` again. The set of related articles can change over time as new coverage is published and matched against the seed headline. ## How much does a story request cost?[#](#how-much-does-a-story-request-cost) A `/v1/news/story/:id` call costs **1 credit**, and you are charged only when the endpoint returns at least one related article. If no other coverage matches the seed headline, no credit is spent. The endpoint accepts both `GET` (ID in the path) and `POST` (same path, filters in a JSON body). ## What happens if the story returns no other articles?[#](#what-happens-if-the-story-returns-no-other-articles) If no other article’s headline overlaps the seed article’s keywords, you get an empty result set — that is a normal outcome, not an error, and no credit is charged. A `404` with `ER0240` is different: it means the seed article was found, but its title produced no usable keywords to match on. A `404` with `ER0235` means the `id` you passed does not match any article at all. * * * ## Related Articles * [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) * [What's Inside a News Article?](/en/articles/getting-started/understanding-article-data) --- ## How the Referral Program Works URL: https://support.apitube.io/en/articles/referrals/how-referrals-work How the APITube referral program works: share your personal ?ref link, and earn $25 in account credit while your friend gets $10 when they make their first… # How the Referral Program Works Share your link, invite friends, and earn account credit when they become paying customers ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 28, 2026 Updated July 21, 2026 # How the referral program works[#](#how-the-referral-program-works) The APITube referral program gives you **$25** in account credit for every person you invite who becomes a paying customer, and gives the person you invited a **$10** welcome credit. You share a personal referral link, your friend signs up through it, and the reward lands the first time they pay — not at sign-up. Both rewards are added straight to the account **balance** as credit you can spend on API usage. The reward fires once per invited customer, on their first payment, so it is a clean way to turn the people you onboard into ongoing API credit. ## How do you get and share your referral link?[#](#how-do-you-get-and-share-your-referral-link) Open the **Referral** page in your APITube dashboard. It shows your personal referral **code**, the ready-to-share **link**, and your stats. The link points at the main site with your code attached as a query parameter: ``` https://apitube.io/?ref=YOUR_CODE ``` ![The Referral program page of the dashboard with the personal referral link and reward stats](/images/article/dashboard-referral.png) Anyone who opens that link gets a first-touch cookie (`apitube_ref`) that remembers your code for **30 days**. “First-touch” means the first referral link a visitor opens wins — if they later arrive through someone else’s link, the original code is kept, not overwritten. The cookie is read at the moment they register, which is when the link between you and the new user is created. ## When do you (and your friend) get the reward?[#](#when-do-you-and-your-friend-get-the-reward) The reward is **not** paid when your friend signs up. At registration, APITube only records the connection between you and the new user with a **pending** status. The credit is granted later, the **first time your invitee makes a payment** — that conversion is what releases both rewards at once. So the sequence is: your friend opens your `?ref=` link → registers (status becomes _pending_) → makes their first payment → both rewards are credited and the referral is marked _rewarded_. Until that first payment happens, the referral stays pending and no credit moves. ## How much do you earn per referral?[#](#how-much-do-you-earn-per-referral) * **You (the referrer):** **$25** added to your account balance. * **Your friend (the invited user):** a **$10** welcome credit added to their balance. Both amounts are credited as account balance, so they spend exactly like topped-up [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) credit. Once your balance updates, you can confirm it from the dashboard or programmatically — see [how to check your balance via the API](/en/articles/retrieval/check-balance-api) — and put it to work with any [API key](/en/articles/account-and-dashboard/keys/manage-keys). ## How to track your referrals and rewards[#](#how-to-track-your-referrals-and-rewards) The Referral page summarizes your program with three numbers: **invited** (everyone who registered through your link), **converted** (those who paid and triggered a reward), and **earned** (the total credit you have been granted). Below the summary, each invited user is listed with their status and reward, and their email is partially masked for privacy — you see enough to recognize who you invited without exposing a full address. # Common Questions[#](#common-questions) * [Can I refer myself?](#can-i-refer-myself) * [What do the referral statuses mean?](#what-do-the-referral-statuses-mean) * [Can the same friend reward me twice?](#can-the-same-friend-reward-me-twice) * [How long does my referral link stay valid?](#how-long-does-my-referral-link-stay-valid) ## Can I refer myself?[#](#can-i-refer-myself) No. Self-referral is blocked: if the referrer and the new account share the same user or the same email address, no referral link is created and no reward is granted. The program is designed to reward bringing in genuinely new customers. ## What do the referral statuses mean?[#](#what-do-the-referral-statuses-mean) Each referral carries one of three statuses. **Pending** means the person registered through your link but has not paid yet. **Rewarded** means they made their first payment and both credits were granted. **Rejected** is a safety state used when the referrer account can no longer be found at reward time. Your _pending_ count is your pipeline; your _converted_ (rewarded) count is what actually earned you credit. ## Can the same friend reward me twice?[#](#can-the-same-friend-reward-me-twice) No. The reward fires once per invited customer, on their first payment, and the system guards against double-granting even if payment events arrive at the same time. After a referral is marked _rewarded_, later payments by that same person do not generate additional referral credit. ## How long does my referral link stay valid?[#](#how-long-does-my-referral-link-stay-valid) Your referral code itself does not expire — you can keep sharing the same link. What is time-limited is the attribution window on each visit: when someone clicks your link, their `apitube_ref` cookie remembers your code for **30 days**. If they register within that window, the referral is attributed to you. * * * ## Related Articles * [How to Check Your Balance via the API](/en/articles/retrieval/check-balance-api) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## Referrals & Rewards URL: https://support.apitube.io/en/articles/referrals How the APITube referral program works: share your personal link, invite friends, and earn account credit when they become paying customers. ![](/images/collections/account-billing.svg) # Referrals & Rewards Invite friends and earn account credit. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) By Beatrice and 1 other 2 authors 4 articles The APITube referral program pays you for bringing in new customers: share your invite link, and when someone you referred makes their first payment you receive account credit. These articles explain how the program works, how to send invites, and where to track what your referrals have earned you. Start with [how referrals work](/en/articles/referrals/how-referrals-work) for the rules and reward amounts, then [track referrals](/en/articles/referrals/track-referrals) to follow your invites in the dashboard. * [How the Referral Program Works](/en/articles/referrals/how-referrals-work) * [How to Invite Friends and Earn Credit](/en/articles/referrals/invite-and-earn) * [How to Track Your Referrals and Rewards](/en/articles/referrals/track-referrals) * [Why Hasn't My Referral Reward Been Credited?](/en/articles/referrals/referral-not-credited) --- ## How to Invite Friends and Earn Credit URL: https://support.apitube.io/en/articles/referrals/invite-and-earn Invite developers to APITube with your personal referral link and earn $25 in account credit for each one who makes a first payment — while they get $10 to… # How to Invite Friends and Earn Credit Share your referral link, and earn $25 when your invitee makes their first payment ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 5, 2026 Updated July 21, 2026 # How to invite friends and earn credit[#](#how-to-invite-friends-and-earn-credit) To invite friends and earn credit, open the **Referral program** page in your APITube dashboard, copy your personal referral link, and share it. When someone you invited makes their **first payment**, you earn **$25** in account credit and they get a **$10** welcome credit — both added straight to your balances. The invite itself is free and takes one click: the reward is not tied to the sign-up, it fires the moment your invitee first pays. This article walks through the steps to invite and what makes a referral pay out. For the full mechanics behind the program, see [how the referral program works](/en/articles/referrals/how-referrals-work). ## Where do you find your referral link to share?[#](#where-do-you-find-your-referral-link-to-share) Open the **Referral program** page from the dashboard sidebar. The share card at the top gives you two things to spread: * **Your referral link** — a ready-to-share URL that points at the APITube site with your code attached, in the form `https://apitube.io/?ref=YOUR_CODE`. * **Your code** — a short human-readable code like `APITUBE-X3K7QP`. It deliberately avoids look-alike characters (no `0`/`O` or `1`/`I`/`L`), so you can read it aloud or write it down without mistakes. The link and code are personal to your account — every logged-in user has their own — so the credit always comes back to you. ![The share card on the Referral program page with the personal referral link and code](/images/article/dashboard-referral.png) ## How to share your referral link[#](#how-to-share-your-referral-link) The share card gives you one-click ways to get the link out: 1. **Copy link** — click the copy button to put your full referral URL on the clipboard, then paste it anywhere: a DM, a Slack channel, your README, or a blog post. 2. **Share via X** — opens a pre-filled post with your link attached. 3. **Share via LinkedIn** — opens the LinkedIn share dialog for your link. 4. **Share via Email** — opens a pre-filled email with the subject and your link in the body. You can also just hand someone your **code** (`APITUBE-XXXXXX`) verbally — anyone who opens `apitube.io/?ref=` with that code gets the same 30-day attribution cookie as clicking your link. ## What does your friend have to do for you to earn?[#](#what-does-your-friend-have-to-do-for-you-to-earn) Two steps on their side turn an invite into credit: 1. **Sign up through your link.** When they open `apitube.io/?ref=YOUR_CODE`, a first-touch cookie (`apitube_ref`) remembers your code for **30 days**. If they register within that window, the referral is attributed to you and recorded with a **pending** status. 2. **Make their first payment.** The reward is released the first time your invitee pays. That first payment can be a **plan subscription** _or_ a **[Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) top-up** — either one counts as the conversion that pays out both rewards at once. Until that first payment happens, the referral stays _pending_ and no credit moves. You can watch that pipeline on the [track your referrals](/en/articles/referrals/track-referrals) page. ## How much do you earn, and where does it go?[#](#how-much-do-you-earn-and-where-does-it-go) * **You (the referrer):** **$25** added to your account **balance** per converted invitee. * **Your friend (the invited user):** a **$10** welcome credit added to their balance. Both rewards land as account balance credit, so they spend exactly like a Pay As You Go top-up — on any API request, with any key. The reward fires **once per invited customer**, on their first payment; later payments by that same person do not generate more referral credit. # Common Questions[#](#common-questions) * [Do I earn credit when someone just signs up?](#do-i-earn-credit-when-someone-just-signs-up) * [Does a Pay As You Go top-up count as their first payment?](#does-a-pay-as-you-go-top-up-count-as-their-first-payment) * [Can I share my code without a link?](#can-i-share-my-code-without-a-link) * [How many people can I invite?](#how-many-people-can-i-invite) ## Do I earn credit when someone just signs up?[#](#do-i-earn-credit-when-someone-just-signs-up) No. Signing up through your link only records the connection with a **pending** status — no credit is granted yet. The **$25** to you and **$10** to your invitee are both released the first time that person makes a payment. Until then, the referral sits in your pending pipeline. ## Does a Pay As You Go top-up count as their first payment?[#](#does-a-pay-as-you-go-top-up-count-as-their-first-payment) Yes. The conversion that releases the reward is your invitee’s first payment, whether that is a **plan subscription** or a **Pay As You Go top-up**. Both are treated as the first payment, so an invitee who tops up their balance triggers the reward the same as one who subscribes to a plan. ## Can I share my code without a link?[#](#can-i-share-my-code-without-a-link) Yes. Your code (`APITUBE-XXXXXX`) is built from unambiguous characters so it survives being read aloud or typed by hand. Anyone who visits `apitube.io/?ref=` with your code gets the same first-touch attribution as clicking the full link, and the same 30-day window applies. ## How many people can I invite?[#](#how-many-people-can-i-invite) There is no cap on invites — your code does not expire, so you can keep sharing the same link. Each person who signs up through it and makes a first payment earns you another **$25**. The 30-day limit applies only to the attribution cookie on each visit, not to how many people you invite. * * * ## Related Articles * [How the Referral Program Works](/en/articles/referrals/how-referrals-work) * [How to Track Your Referrals and Rewards](/en/articles/referrals/track-referrals) --- ## Why Hasn't My Referral Reward Been Credited? URL: https://support.apitube.io/en/articles/referrals/referral-not-credited A referral reward is only credited when the invited person makes their first payment. Check the status, the sign-up link and the self-referral rules before… # Why Hasn't My Referral Reward Been Credited? The checklist for a referral stuck on Pending — what actually releases the $25, and the cases where no reward can fire ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 6, 2026 Updated July 21, 2026 # Why hasn’t my referral reward been credited?[#](#why-hasnt-my-referral-reward-been-credited) The most common reason is simple: your invitee has registered but has not paid yet, and the referral reward is released only by their **first payment** — a subscription checkout or a balance top-up — never by the sign-up itself. Until that payment happens the referral sits in **Pending** and no credit moves in either direction. This article walks through that case and the rarer ones where a reward can never fire at all. ## First check: what does the status say?[#](#first-check-what-does-the-status-say) Open the **Referral** page in the dashboard and find the person’s row — see [how to track your referrals and rewards](/en/articles/referrals/track-referrals) for reading the table. The status answers most tickets on its own: * **Pending** — the connection is recorded and healthy; APITube is waiting for the person’s first payment. Nothing is wrong and nothing is stuck. * **Rewarded** — the credit was already granted; the row shows the amount and the date. If your balance looks unchanged, remember the reward lands on your account **balance** (spendable dollars), not on your monthly request quota. * **Rejected** — the reward could not be granted; this state is final. It is used as a safety valve when the referrer’s account can no longer be found at the moment the reward fires. If the person is missing from the table entirely, no referral was recorded at sign-up — that is the case to investigate next. ![The Referral program page where each invited person's row shows its Pending, Rewarded or Rejected status](/images/article/dashboard-referral.png) ## Did they actually sign up through your link?[#](#did-they-actually-sign-up-through-your-link) The referral connection is written **once, at registration**, when the person arrives through your `?ref=` link and creates the account in that browser. If your invitee typed the site address directly, registered on another device, or cleared cookies between clicking your link and signing up, the account is created without a referrer — and the connection **cannot be attached retroactively**. A referral that never appears in your table almost always means the sign-up happened without the link. Two protections also block the connection silently at sign-up: * **Self-referral** — an account cannot be its own referrer. Registering through your own link, or registering a new account with the **same email address** as the referrer, records no referral. * **One referrer per account** — the referrer is fixed at registration and never changes, so a person who signed up earlier without any link cannot later be “claimed” by anyone. ## What does not trigger the reward[#](#what-does-not-trigger-the-reward) A few payment-adjacent events look like they should release the credit but do not: * **Registration alone** — the sign-up creates the pending row, not the money. * **Second and later payments** — the reward fires **once** per invited customer, on the first payment; renewals never grant additional referral credit. * **The same invitee counted twice** — one person can only ever be one referral row, so duplicate payment events cannot double-pay a reward. The reward amounts themselves are fixed by the program: **$25** to you and **$10** to the person you invited, both delivered as account balance — the details are in [how the referral program works](/en/articles/referrals/how-referrals-work). # Common Questions[#](#common-questions) * [How long after the payment does the credit appear?](#how-long-after-the-payment-does-the-credit-appear) * [My friend paid but the row still says Pending — what now?](#my-friend-paid-but-the-row-still-says-pending--what-now) * [Can support add a referral my friend forgot to use the link for?](#can-support-add-a-referral-my-friend-forgot-to-use-the-link-for) ## How long after the payment does the credit appear?[#](#how-long-after-the-payment-does-the-credit-appear) The grant is processed automatically by the payment [webhook](/en/articles/getting-started/glossary#webhook), so under normal conditions the status flips to **Rewarded** and the balance updates right after the payment settles — there is no manual review step or scheduled batch to wait for. ## My friend paid but the row still says Pending — what now?[#](#my-friend-paid-but-the-row-still-says-pending--what-now) First confirm the payment really completed (an abandoned checkout counts as no payment). If it did and the row stays Pending, contact billing support at [support@apitube.io](mailto:support@apitube.io) with your account email and the approximate payment date — referral credits are an account and billing matter, so that inbox is the right channel. See [how to contact support](/en/articles/trust-and-support/contact-support) for what to include. ## Can support add a referral my friend forgot to use the link for?[#](#can-support-add-a-referral-my-friend-forgot-to-use-the-link-for) The system itself records referrals only at registration through the link, and the referrer on an account never changes afterwards. There is no self-service way to attach one after the fact — if you believe a sign-up was genuinely yours, raise it with billing support and they will look at the individual case. * * * ## Related Articles * [How the Referral Program Works](/en/articles/referrals/how-referrals-work) * [How to Track Your Referrals and Rewards](/en/articles/referrals/track-referrals) * [How to Contact Support](/en/articles/trust-and-support/contact-support) --- ## How to Track Your Referrals and Rewards URL: https://support.apitube.io/en/articles/referrals/track-referrals Track your APITube referrals from the Referral program page: three summary cards (Invited, Converted, Earned) and a table showing each referral's status and… # How to Track Your Referrals and Rewards Read the Referral program page: summary cards, statuses, and per-referral rewards ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 4, 2026 Updated July 21, 2026 # How to track your referrals and rewards[#](#how-to-track-your-referrals-and-rewards) You track referrals on the **Referral program** page in your APITube dashboard. It shows three summary cards — **Invited**, **Converted**, and **Earned** — plus a table of everyone who signed up with your link, each row carrying a status, the reward you earned, and the date they joined. The page is personal to your account: every logged-in user has their own referral code and stats, independent of any [workspace](/en/articles/getting-started/glossary#workspace) you belong to. If you are new to the program itself, start with [how the referral program works](/en/articles/referrals/how-referrals-work) and come back here to read your results. ## Where do you track referrals in APITube?[#](#where-do-you-track-referrals-in-apitube) Open the **Referral program** page from the dashboard sidebar. At the top is your share card with your personal referral code and link. Directly below it are the three summary cards, and under those is the referrals table with one row per invited user. There is no separate report to run — the page loads your current numbers as soon as you open it. ![The Referral program page: the share card with the referral link above the Invited, Converted and Earned summary cards](/images/article/dashboard-referral.png) ## What do the three summary cards show?[#](#what-do-the-three-summary-cards-show) The summary row gives you three numbers at a glance: * **Invited** — the total number of people who signed up with your link. * **Converted** — referrals who made their first payment. These are the ones that actually released a reward. * **Earned** — the total referral credit granted to you, shown in dollars (for example, `$25.00`). The difference between **Invited** and **Converted** is your pipeline: people who registered but have not paid yet. You read that “pending” group directly from the status column in the table below, rather than from a fourth card. ## How to read the referrals table[#](#how-to-read-the-referrals-table) Each row is one person you invited, newest first. The table has four columns: * **Referred** — the invited user’s email, partially masked for privacy (for example, `j•••@example.com`); if no email is available it shows **Unknown**. * **Status** — **Pending**, **Rewarded**, or **Rejected** (see below). * **Reward** — the credit you earned from that referral. A rewarded referral shows the amount (`$25.00`); anything not yet rewarded shows a dash (`—`). * **Joined** — the date that person registered through your link. The table paginates at **20 referrals per page**. Click any row to open a side panel with that referral’s **Status**, **Reward**, and — once it converts — the **Rewarded** date, so you can see exactly when the credit was granted. ## What do the referral statuses mean?[#](#what-do-the-referral-statuses-mean) Every referral carries one of three statuses: * **Pending** — the person registered through your link but has not made a payment yet. No credit has moved. * **Rewarded** — they made their first payment, and both credits were granted: **$25** to your balance and **$10** to theirs. The row now shows your reward and a rewarded date. * **Rejected** — a safety state that appears if the referrer account can no longer be found at the moment the reward would fire. No credit is granted. Your **Pending** rows are your pipeline; your **Rewarded** rows are what earned you credit and add up to the **Earned** card. # Common Questions[#](#common-questions) * [Why does a referral show no reward yet?](#why-does-a-referral-show-no-reward-yet) * [How is the invited person’s email shown?](#how-is-the-invited-persons-email-shown) * [Where does the earned credit go?](#where-does-the-earned-credit-go) * [How many referrals appear per page?](#how-many-referrals-appear-per-page) ## Why does a referral show no reward yet?[#](#why-does-a-referral-show-no-reward-yet) The reward is not paid at sign-up. A newly registered referral stays **Pending** with a `—` in the Reward column until that person makes their **first payment**. That conversion is what flips the status to **Rewarded**, fills in your `$25.00` reward, and stamps the rewarded date. ## How is the invited person’s email shown?[#](#how-is-the-invited-persons-email-shown) The email is partially masked: you see the first character, a few dots, and the full domain (for example, `j•••@example.com`). That is enough to recognize who you invited without exposing another customer’s full address. When no email is on file, the row reads **Unknown**. ## Where does the earned credit go?[#](#where-does-the-earned-credit-go) Referral rewards are added straight to your account **balance** as credit you can spend on API usage — the same way a [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) top-up spends. After a referral is rewarded, you can confirm the new balance from the dashboard or programmatically; see [how to check your balance via the API](/en/articles/retrieval/check-balance-api). ## How many referrals appear per page?[#](#how-many-referrals-appear-per-page) The referrals table shows **20 rows per page**. Use the [pagination](/en/articles/getting-started/glossary#pagination) controls to move through older referrals; the newest sign-ups always appear at the top of the first page. * * * ## Related Articles * [How the Referral Program Works](/en/articles/referrals/how-referrals-work) * [How to Check Your Balance via the API](/en/articles/retrieval/check-balance-api) --- ## How to Autocomplete Filter Values with the Suggest API URL: https://support.apitube.io/en/articles/retrieval/autocomplete-filter-values Use the APITube /v1/suggest endpoints to autocomplete categories, topics and industries: pass a prefix, get up to 100 matches with the exact ID to filter on. # How to Autocomplete Filter Values with the Suggest API Turn a few typed characters into a valid category, topic or industry ID with the /v1/suggest endpoints ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 6, 2026 Updated July 7, 2026 # How to autocomplete filter values with the Suggest API[#](#how-to-autocomplete-filter-values-with-the-suggest-api) APITube has four autocomplete endpoints — `/v1/suggest/categories`, `/v1/suggest/topics`, `/v1/suggest/industries` and `/v1/suggest/entities` — and they all work the same way: send a `prefix` string, get back a JSON array of matching options, each carrying the exact `id` the corresponding search filter expects. They are the practical answer to “how do I find a valid `category.id` (or `topic.id`, `industry.id`) without scrolling a thousand-row reference table”. ``` curl "https://api.apitube.io/v1/suggest/categories?prefix=politic&api_key=YOUR_API_KEY" ``` The [entity](/en/articles/getting-started/glossary#entity) flavour has its own walkthrough — [entity autocomplete in search inputs](/en/articles/searching-and-filtering/entities/entity-autocomplete) — so this article covers the other three, which complete the reference taxonomies rather than people and companies. ## How does the prefix parameter work?[#](#how-does-the-prefix-parameter-work) Every suggest endpoint takes exactly one required query parameter, `prefix`, plus your [API key](/en/articles/getting-started/glossary#api-key). Despite the name, the match is a case-insensitive **contains**, not a starts-with: `prefix=oil` matches “crude oil” anywhere in the name. Each call returns up to **100 matches**, ordered by internal ID, and there are no paging or limit parameters — if the list feels too long, type a longer prefix. Suggest calls are made on almost every keystroke, so two behaviours matter: they do **not** spend your request quota (suggest lookups are free), and you should still debounce the input in your UI so a fast typist fires one request per pause, not one per character. ## What does each endpoint return?[#](#what-does-each-endpoint-return) The response is a bare JSON array (there is no `results` wrapper, unlike the news endpoints). The fields per item differ slightly by endpoint: * `/v1/suggest/categories` — `id` (an IPTC code like `medtop:11000000`), `name`, `taxonomy` and `links.self`. The `id` goes into `category.id`. * `/v1/suggest/topics` — `id` (a slug such as `market_news.commodities.crude_oil`), `name` and `links.self`. The `id` goes into `topic.id`. * `/v1/suggest/industries` — `id` (a plain number), `name` and `links.self`. The `id` goes into `industry.id`. Each of `category.id`, `topic.id` and `industry.id` accepts up to **3 comma-separated values** in a search, and none of them accepts a name — which is exactly why the suggest endpoints exist. The full parameter syntax lives in the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). ``` curl "https://api.apitube.io/v1/suggest/topics?prefix=crypto&api_key=YOUR_API_KEY" ``` ## What errors should a typeahead handle?[#](#what-errors-should-a-typeahead-handle) Two request-level failures cover almost everything: * **Empty or missing `prefix`** → HTTP `400` with error code `ER0346` (“Prefix in query required”). Do not fire the call until the input has at least one character. * **Missing API key** → HTTP `401` with error code `ER0201`. Suggest requires authentication like every other endpoint, so send the key as the `X-API-Key` header or the `api_key` query parameter. One more edge to know about: if your API key is restricted to specific endpoint scopes, the key needs the `suggest` scope, otherwise the call returns `403` with `ER0603` — see [how to limit a key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes). # Common Questions[#](#common-questions) * [Do suggest requests cost anything?](#do-suggest-requests-cost-anything) * [Can I get more than 100 suggestions?](#can-i-get-more-than-100-suggestions) * [Where do I browse the full lists instead of autocompleting?](#where-do-i-browse-the-full-lists-instead-of-autocompleting) ## Do suggest requests cost anything?[#](#do-suggest-requests-cost-anything) No. Suggest lookups are not billed against your plan — no request is deducted, whatever your plan is. Your key still authenticates the call, but wiring autocomplete into a search form will not eat the quota you want to spend on actual news requests. ## Can I get more than 100 suggestions?[#](#can-i-get-more-than-100-suggestions) No — 100 per call is a hard cap and there is no page or limit parameter. In practice a dropdown never needs that many options; a longer, more specific prefix is the intended way to narrow the list. If you need the complete taxonomy rather than matches, use the reference lists in the documentation instead. ## Where do I browse the full lists instead of autocompleting?[#](#where-do-i-browse-the-full-lists-instead-of-autocompleting) The documentation publishes every valid value: [all categories](https://docs.apitube.io/platform/news-api/list-of-categories), [all topics](https://docs.apitube.io/platform/news-api/list-of-topics) and [all industries](https://docs.apitube.io/platform/news-api/list-of-industries). Suggest is for interactive inputs; the static lists are better when you are hard-coding a known set of IDs into your integration. * * * ## Related Articles * [How to Use Entity Autocomplete in Search Inputs](/en/articles/searching-and-filtering/entities/entity-autocomplete) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Combine Multiple Filters in One Request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) --- ## How to Check Your API Balance and Remaining Quota URL: https://support.apitube.io/en/articles/retrieval/check-balance-api Call the /v1/balance endpoint to check the remaining request quota (points) on your API key. It returns your balance and never consumes any quota. # How to Check Your API Balance and Remaining Quota Use /v1/balance to read your remaining points — without spending a request ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 # How to check your API key balance and remaining quota[#](#how-to-check-your-api-key-balance-and-remaining-quota) To check how much quota is left on your key, send a `GET` request to the `/v1/balance` endpoint. It returns the remaining **points** for the key you pass — and, unlike every other endpoint, checking your balance does not consume any of those points. This reads the balance for one key: ``` curl "https://api.apitube.io/v1/balance?api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. The endpoint is read-only and accepts `GET` only. ## What does the /v1/balance endpoint return?[#](#what-does-the-v1balance-endpoint-return) `/v1/balance` returns a small JSON object that echoes your key and reports the points remaining on the account it belongs to: ``` { "api_key": "YOUR_API_KEY", "points": 1500 } ``` The `points` field is your remaining request quota — the same pool that normal search and retrieval calls draw from. Every successful call to an endpoint like `/v1/news/everything` deducts one point, so `points` tells you how many standard requests you have left before you run out. ## How do I authenticate a balance request?[#](#how-do-i-authenticate-a-balance-request) `/v1/balance` accepts your [API key](/en/articles/getting-started/glossary#api-key) in any of three ways — the same options every News API endpoint supports: * **Authorization header** — `Authorization: Bearer YOUR_API_KEY` * **X-API-Key header** — `X-API-Key: YOUR_API_KEY` * **Query parameter** — `?api_key=YOUR_API_KEY` Using the header keeps your key out of URLs and server logs, which is the safer choice for anything server-side: ``` curl "https://api.apitube.io/v1/balance" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Does checking your balance cost anything?[#](#does-checking-your-balance-cost-anything) No. A call to `/v1/balance` does not deduct any points, so you can check your remaining quota as often as you need without eating into it. It is still an authenticated request, so it counts toward the [per-minute rate limit](/en/articles/troubleshooting/rate-limit-errors): **50 requests per minute** on a [live key](/en/articles/getting-started/glossary#test-key-and-live-key) (**15** on a test key), and repeated violations lead to a temporary ban after 30 of them. Don’t poll it in a tight loop — check it on a sensible schedule (for example, once a minute or before a batch job) rather than on every single request. ## How to read your plan and balance from the response headers[#](#how-to-read-your-plan-and-balance-from-the-response-headers) You don’t always need a separate balance call. Every authenticated response from the News API — including `/v1/balance` itself — carries a set of headers that report your current state: * `x-points-remaining` — remaining request quota (same number as the `points` field) * `x-subscription-plan` — your current plan (for example `basic`), or `free` * `x-balance-remaining` — your [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance, in cents * `x-apitube-mode` — `live` or `test`, so you know which key you used * `x-budget-remaining` — present only when a monthly pay-as-you-go limit is set Because these come back on ordinary requests, you can track quota straight from your search responses and reserve `/v1/balance` for a dedicated, content-free check. If you only need a number from your data instead of your account, [count matching articles without downloading them](/en/articles/retrieval/count-articles) follows the same lightweight pattern. ## When should you check your balance?[#](#when-should-you-check-your-balance) Use `/v1/balance` whenever you want to know your standing before it bites you: * **Avoid running out mid-job** — normal endpoints return `402` with error code `ER0176` once your points hit zero; checking ahead lets you top up or pause first. * **Dashboards and alerts** — surface remaining points to your team, or fire a warning when the number drops below a threshold. * **CI and deploy checks** — confirm a key still has quota before a scheduled pipeline depends on it. For the full picture of how keys and credentials work, see the official [authentication guide](https://docs.apitube.io/platform/news-api/authentication) on the APITube docs. # Common Questions[#](#common-questions) * [Does checking my balance use a request?](#does-checking-my-balance-use-a-request) * [What does the points number mean?](#what-does-the-points-number-mean) * [Can I see my balance without a separate call?](#can-i-see-my-balance-without-a-separate-call) * [What errors can /v1/balance return?](#what-errors-can-v1balance-return) ## Does checking my balance use a request?[#](#does-checking-my-balance-use-a-request) It does not spend any **points** — the balance check is free in quota terms. It is still a real HTTP request, so it counts toward the per-minute [rate limit](/en/articles/getting-started/glossary#rate-limit) (50/min on a live key, 15/min on a test key). In short: it won’t drain your quota, but don’t hammer it. ## What does the points number mean?[#](#what-does-the-points-number-mean) `points` is your remaining standard request quota. Endpoints such as `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/count` each deduct one point per successful call. When `points` reaches zero, those endpoints return `402` (`ER0176`) until you upgrade, top up, or your quota resets. ## Can I see my balance without a separate call?[#](#can-i-see-my-balance-without-a-separate-call) Yes. Every authenticated response includes the `x-points-remaining` header, so you can read your remaining quota directly from any search or retrieval response without calling `/v1/balance` at all. The companion headers `x-subscription-plan` and `x-balance-remaining` report your plan and pay-as-you-go balance on the same responses. ## What errors can /v1/balance return?[#](#what-errors-can-v1balance-return) If the key is missing you get `401` (`ER0201`); if it is invalid you get `401` (`ER0202`); an expired key returns `401` (`ER0230`). Exceeding the rate limit returns `429` (`ER0203`), and continued abuse triggers a temporary ban (`ER0204`). Each error response carries a [request id](/en/articles/getting-started/glossary#request-id) you can quote to support. * * * ## Related Articles * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Get Top Headlines from the News API](/en/articles/retrieval/get-top-headlines) --- ## How to Compare News Trends Between Two Periods URL: https://support.apitube.io/en/articles/retrieval/compare-trends Compare news trends between two periods with /v1/news/trends: use compare with a compare_window to get change_percent, or time_bucket to build a time series. # How to Compare News Trends Between Two Periods Use compare and time\_bucket on /v1/news/trends to measure change over time ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Ftrends&field=entity.id&published_at_start=NOW-7DAYS&compare=true&compare_window=7DAYS) # How to compare news trends between two periods[#](#how-to-compare-news-trends-between-two-periods) To compare news trends between two periods, call `/v1/news/trends` with `compare=true` and a `compare_window`. The endpoint counts each value in your current window, then counts the same window shifted back by `compare_window`, and returns the difference per value as `previous_count`, `change_absolute` and `change_percent`. This compares the top [entities](/en/articles/getting-started/glossary#entity) in the last 7 days against the 7 days before: ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&published_at.start=NOW-7DAYS&compare=true&compare_window=7DAYS&api_key=YOUR_API_KEY" ``` This is the period-over-period mode built on top of the ranking described in [How to discover trending topics and entities](/en/articles/retrieval/discover-trends). Pass your key as the `api_key` query parameter or an `X-API-Key` header, with `GET` (query parameters) or `POST` (JSON body). ## How does the compare\_window work?[#](#how-does-the-compare_window-work) `compare_window` is the offset between your two periods, not a second date range. The endpoint takes your current window (set by `published_at.start` / `published_at.end`, or the default last 30 days) and shifts a copy of it backwards by `compare_window` to build the “previous” period. So with a 7-day current window and `compare_window=7DAYS`, you compare this week against last week. Set `compare_window=1YEAR` to compare the same recent window against the matching window a year ago. `compare_window` is **required** whenever `compare=true`; omitting or mistyping it returns error `ER0352`. It accepts the same relative-duration formats as the [date filters](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) — `24HOURS`, `7DAYS`, `1WEEK`, or short aliases like `1w` and `2m`. The shift is clamped between **1 hour and 1 year**. ## What does the comparison response add?[#](#what-does-the-comparison-response-add) With `compare=true`, every trend keeps its normal `count` and gains three fields: ``` { "status": "ok", "field": "entity.id", "compare_window": "7DAYS", "trends": [ { "value": { "id": 1599, "name": "OpenAI", "type_id": 3, "wikidata_id": "Q21708200" }, "count": 412, "previous_count": 250, "change_absolute": 162, "change_percent": 64.8 } ], "request_id": "8a4d1f6c-3e75-49b2-b8c0-2f9a6d4e1c73" } ``` `previous_count` is the value’s count in the shifted period, `change_absolute` is `count − previous_count`, and `change_percent` is the percentage change. When a value had **zero** articles in the previous period but appears now, `change_percent` is reported as `100` — that flags a genuinely new trend. The response echoes the `compare_window` you used. ## How to rank by the biggest movers[#](#how-to-rank-by-the-biggest-movers) By default the list is ranked by `count`, so a story that is large but flat sits at the top. To surface what is moving instead, add `sort=change`: it orders the trends by `change_percent`, so the fastest risers (or, with `order=asc`, the fastest fallers) come first. The `change` sort mode is only available when `compare=true`. ``` curl "https://api.apitube.io/v1/news/trends?field=topic.id&compare=true&compare_window=1WEEK&sort=change&api_key=YOUR_API_KEY" ``` ## How to see the trend as a time series[#](#how-to-see-the-trend-as-a-time-series) A second way to study change over time is `time_bucket`, which breaks the current window into intervals instead of comparing to a past one. Set it to `hour`, `day`, `week` or `month`, and each value comes back with a `buckets` map of counts per interval plus a `total`: ``` curl "https://api.apitube.io/v1/news/trends?field=category.id&published_at.start=NOW-14DAYS&time_bucket=day&api_key=YOUR_API_KEY" ``` ``` { "status": "ok", "field": "category.id", "time_bucket": "day", "trends": [ { "value": "medtop:04000000", "total": 318, "buckets": { "2026-06-25": 41, "2026-06-26": 55 } } ] } ``` In `time_bucket` mode the `value` is the raw id (it is not enriched with a name), and results are ordered by `total` descending. Use `compare` when you want a single period-over-period delta, and `time_bucket` when you want the day-by-day shape; run them as separate requests rather than combining the two in one call. ## What are the limits and cost?[#](#what-are-the-limits-and-cost) The current window is **capped at 30 days** (and defaults to the last 30 days if you pass no dates) — a wider range returns `ER0353`. The `compare_window` offset is separate from that cap and may reach a year back. `field` is required and accepts up to five comma-separated values from `source.id`, `category.id`, `topic.id`, `industry.id` and `entity.id`; `per_page` defaults to 10 and maxes at 100. Each call costs **1 point** regardless of compare or bucketing. On a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) the structure returns but every `value` is masked as `[Upgrade subscription plan]`, so use a live key for real comparisons. # Common Questions[#](#common-questions) * [What is the difference between compare and time\_bucket?](#what-is-the-difference-between-compare-and-time_bucket) * [Why does change\_percent show 100?](#why-does-change_percent-show-100) * [Can I compare against a period more than 30 days ago?](#can-i-compare-against-a-period-more-than-30-days-ago) * [Which error codes apply when comparing?](#which-error-codes-apply-when-comparing) ## What is the difference between compare and time\_bucket?[#](#what-is-the-difference-between-compare-and-time_bucket) `compare` returns one delta per value — the current count versus the same window shifted back by `compare_window` — which answers “is this up or down versus last period?”. `time_bucket` returns a series of counts split by `hour`, `day`, `week` or `month`, which answers “what shape did it take across the window?”. Use `compare` for a headline change number and `time_bucket` to chart the curve. ## Why does change\_percent show 100?[#](#why-does-change_percent-show-100) A `change_percent` of `100` means the value had no articles in the previous period and appears in the current one, so it is treated as a brand-new trend rather than a normal percentage rise. Read it together with `change_absolute` and `count` to judge how big the new entry actually is. ## Can I compare against a period more than 30 days ago?[#](#can-i-compare-against-a-period-more-than-30-days-ago) Yes. The 30-day cap applies only to the current window you measure; the `compare_window` offset can reach back up to a year. For example, keep a 7-day current window and set `compare_window=1YEAR` to compare this week against the same week last year. ## Which error codes apply when comparing?[#](#which-error-codes-apply-when-comparing) `ER0352` means `compare_window` is missing or malformed while `compare=true`. `ER0350` means `field` is missing or invalid, and `ER0353` means your date range exceeds 30 days. The usual codes also apply: `ER0201`/`ER0202` (401) for a missing or invalid key, `ER0176` (402) when you are out of points, and `ER0203` (429) for the 50-requests-per-minute [rate limit](/en/articles/getting-started/glossary#rate-limit) on a live key. * * * ## Related Articles * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Count News Articles Without Downloading Them URL: https://support.apitube.io/en/articles/retrieval/count-articles Use the /v1/news/count endpoint to get the number of articles matching your filters without loading any content — same filters as search, one point per call. # How to Count News Articles Without Downloading Them Use /v1/news/count to get a total that matches your filters, with no article content ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fcount&language_code=en&published_at_start=NOW-7DAYS) # How to count matching articles without downloading them[#](#how-to-count-matching-articles-without-downloading-them) To get just the **number** of articles matching your filters — without loading any content — call the `/v1/news/count` endpoint. It accepts the same filters as the main search but runs a single `count(*)` query, so it is cheaper and faster when all you need is the total. This counts English articles published in the last 7 days: ``` curl "https://api.apitube.io/v1/news/count?language.code=en&published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. ## What does the count endpoint return?[#](#what-does-the-count-endpoint-return) `/v1/news/count` returns a small JSON object with the total and a [request id](/en/articles/getting-started/glossary#request-id) — never any article bodies: ``` { "status": "ok", "count": 12345, "request_id": "3a7e5d21-9c4b-4f8a-b2e1-6f0d9a3c5e88" } ``` The `count` field is the number of articles that match the filters you sent, `status` is always `ok` on success, and `request_id` uniquely identifies the call. Because no content is loaded, the response stays tiny no matter how many articles match. ## How to count articles matching your filters[#](#how-to-count-articles-matching-your-filters) The endpoint supports every filter available on the main `/v1/news/everything` search — language, title, date range, category, source and the rest. Add the filters you would normally use for a search, and you get the count for exactly that result set. You can call it with `GET` (filters as query parameters) or `POST` (filters as a JSON body); the two are equivalent. A `POST` example that counts English articles mentioning “climate change” in the title since the start of 2026: ``` curl -X POST "https://api.apitube.io/v1/news/count" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "climate change", "language.code": "en", "published_at.start": "2026-01-01" }' ``` Because the filters are identical to search, you can build a query in the search endpoints first, confirm it returns what you expect, then swap the path to `/v1/news/count` to get the total. For the full filter set, see the [Searching & Filtering News](/en/articles/searching-and-filtering) section, including [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## How much does a count request cost?[#](#how-much-does-a-count-request-cost) Each `/v1/news/count` call costs **1 point** — regardless of how large the matching count is. That fixed cost is what makes count attractive: estimating the size of a 2-million-article result set costs the same as estimating a 5-article one, and you never pay to transfer content you do not need. ## When should you use count instead of search?[#](#when-should-you-use-count-instead-of-search) Reach for `/v1/news/count` whenever you need a number, not the articles themselves: * **Dashboards and KPIs** — show “articles mentioning your brand this week” without fetching them. * **Sample-size estimation** — check how many results a query has before deciding whether to page through them. * **Progress bars and [pagination](/en/articles/getting-started/glossary#pagination) planning** — learn the total up front so you know how many pages to request. If you need the actual articles, use the search endpoints instead; if you only need the tally, count is the cheaper, faster path. # Common Questions[#](#common-questions) * [Can I call count with POST?](#can-i-call-count-with-post) * [Why is my count capped at 100?](#why-is-my-count-capped-at-100) * [Does the count include article content?](#does-the-count-include-article-content) * [What errors can count return?](#what-errors-can-count-return) ## Can I call count with POST?[#](#can-i-call-count-with-post) Yes. `/v1/news/count` accepts both `GET` and `POST`. With `GET`, pass filters as query parameters; with `POST`, send them as a JSON body and set `Content-Type: application/json`. Both methods run the same query and return the same response. ## Why is my count capped at 100?[#](#why-is-my-count-capped-at-100) If you are using a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)**, the count is capped (it returns at most 100) so the key cannot reveal the true catalogue size. Switch to a live key to get the real number for your filters. ## Does the count include article content?[#](#does-the-count-include-article-content) No. `/v1/news/count` runs a count-only query and returns just `status`, `count` and `request_id`. It never loads article titles, bodies or metadata, which is exactly why it is faster and lighter than a full search. ## What errors can count return?[#](#what-errors-can-count-return) Common errors mirror the rest of the API: `ER0201`/`ER0202` (HTTP 401) when the [API key](/en/articles/getting-started/glossary#api-key) is missing or invalid, `ER0176` (HTTP 402) when your account has no points left, and `ER0203` (HTTP 429) when you exceed the [rate limit](/en/articles/getting-started/glossary#rate-limit). Each error response includes the `request_id` to help you trace the call. * * * ## Related Articles * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Get Top Headlines from the News API](/en/articles/retrieval/get-top-headlines) --- ## How to Discover Trending Topics and Entities URL: https://support.apitube.io/en/articles/retrieval/discover-trends Use the /v1/news/trends endpoint to rank the top entities, categories, topics, industries or sources in news matching your filters, with trending and compare… # How to Discover Trending Topics and Entities Use /v1/news/trends to rank the top entities, categories, topics and sources in your results ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Ftrends&field=entity.id&per_page=10&title=technology) # How to discover trending topics and entities[#](#how-to-discover-trending-topics-and-entities) To find what is trending — the most-covered [entities](/en/articles/getting-started/glossary#entity), categories, topics, industries or sources — call the `/v1/news/trends` endpoint with a `field` to aggregate on. It runs a grouped count over the articles that match your filters and returns the top values ranked by how many articles mention each one. This returns the top 10 trending entities in technology coverage: ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&per_page=10&title=technology&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header, and call the endpoint with `GET` (filters as query parameters) or `POST` (filters as a JSON body). Trends is a **paid-plan endpoint**: a free key gets `403 ER0706` (`Trends API is not available on the free plan.`) before the aggregation runs, so nothing is charged. ## Which fields can you trend on?[#](#which-fields-can-you-trend-on) The `field` parameter is **required** and decides what gets ranked. Five fields are allowed: * `entity.id` — trending people, companies, locations and other entities (enriched with name, type and Wikidata id) * `category.id` — trending IPTC categories (enriched with name and taxonomy) * `topic.id` — trending topics * `industry.id` — trending industries * `source.id` — trending sources (enriched with name and domain) You can aggregate up to **5 fields in one call** by passing them comma-separated, for example `field=entity.id,category.id`. An unknown or missing field returns error `ER0350`. ## How to narrow trends to a topic, language or date[#](#how-to-narrow-trends-to-a-topic-language-or-date) Trends are computed over the articles your filters select, so every standard search filter works here too — `title`, `language.code`, `source.domain`, `published_at.start`, `published_at.end` and the rest. Add the filters you would use for a normal search, and the ranking covers exactly that slice. This finds the top categories in English-language news from the last 7 days: ``` curl "https://api.apitube.io/v1/news/trends?field=category.id&language.code=en&published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` If you do not pass any dates, the endpoint defaults to the **last 30 days**. The date range is also **capped at 30 days** — a wider span returns error `ER0353`. For the full filter list, see the [Searching & Filtering News](/en/articles/searching-and-filtering) section, including [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## What does the trends response look like?[#](#what-does-the-trends-response-look-like) A single-field response carries the request echo plus a `trends` array, ranked by `count` (descending) by default: ``` { "status": "ok", "field": "entity.id", "per_page": 10, "offset": 0, "total_count": 842, "total_articles": 15730, "sort": "count", "order": "desc", "mincount": 1, "trends": [ { "value": { "id": 1599, "name": "OpenAI", "type_id": 3, "wikidata_id": "Q21708200" }, "count": 412, "percentage": 2.62, "growth_rate": 5.1 } ], "request_id": "5e9c3a17-8b2d-4f61-9a04-7d1e6c8b3f92" } ``` For each trend, `count` is how many matching articles reference the value, `percentage` is its share of all matching articles, and `growth_rate` is the publication velocity (articles per hour between the first and last article seen). `total_count` is the number of distinct values found and `total_articles` is the size of the filtered set. ## How to control the ranking and size[#](#how-to-control-the-ranking-and-size) A few parameters shape the list: * `per_page` — how many top values to return per field (default `10`, **max 100**). * `offset` — skip results for [pagination](/en/articles/getting-started/glossary#pagination) (default `0`). * `sort` — `count` (default), `value` (alphabetical) or `growth_rate`. * `order` — `desc` (default) or `asc`. * `mincount` — drop values with fewer than N articles (default `1`, max `10000`); useful to cut noise from long-tail mentions. ## How to measure what is rising, not just popular[#](#how-to-measure-what-is-rising-not-just-popular) Popularity and momentum are different questions. Add `trending=true` to compute a **trending score** for each value: the ratio of its recent 2-day average to its 14-day average, so a score above 1 means rising and below 1 means declining. Each trend then also includes `trending_history` (daily counts). Tune the window with `trending_days` (default 14, between 7 and 30): ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&trending=true&trending_days=14&api_key=YOUR_API_KEY" ``` By default the values come back ordered by article count. Sorting directly by the trending score requires compare mode: combine `trending=true` with `compare=true` (and a `compare_window`) and then add `sort=trending_score` — on a plain trending request that sort is ignored and results stay ordered by count. To compare two periods directly, use `compare=true` with a `compare_window` such as `7DAYS` (required, else error `ER0352`). Each trend then gains `previous_count`, `change_absolute` and `change_percent`, and `sort=change` orders by the biggest movers. ## How much does a trends request cost?[#](#how-much-does-a-trends-request-cost) Each `/v1/news/trends` call costs **1 point**, no matter how many fields you aggregate or how large the matching set is. On a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** the structure and counts come back, but each trend `value` is replaced with the placeholder `[Upgrade subscription plan]` — switch to a live key to see real entity and category values. # Common Questions[#](#common-questions) * [Can I get trends for several fields at once?](#can-i-get-trends-for-several-fields-at-once) * [Why is per\_page capped at 100?](#why-is-per_page-capped-at-100) * [How far back can trends look?](#how-far-back-can-trends-look) * [What errors can the trends endpoint return?](#what-errors-can-the-trends-endpoint-return) ## Can I get trends for several fields at once?[#](#can-i-get-trends-for-several-fields-at-once) Yes. Pass up to five comma-separated values in `field`, for example `field=entity.id,category.id,source.id`. The response then returns a `trends` object keyed by field name, each holding its own ranked array, so one request can power an entity list, a category breakdown and a source breakdown together. ## Why is per\_page capped at 100?[#](#why-is-per_page-capped-at-100) The trends endpoint returns aggregated top values, not raw articles, so `per_page` is limited to 100 results per field (default 10). This differs from the article search endpoints. If you need to walk further down the ranking, increase `offset` and request the next slice. ## How far back can trends look?[#](#how-far-back-can-trends-look) Trends are computed over a rolling window of at most **30 days**. Omit the dates to use the default last-30-days window, or set `published_at.start` / `published_at.end` within a 30-day span. A wider range returns error `ER0353`, so split long studies into 30-day chunks. ## What errors can the trends endpoint return?[#](#what-errors-can-the-trends-endpoint-return) Beyond the field and date errors above, the usual API codes apply: `ER0201`/`ER0202` (HTTP 401) when the [API key](/en/articles/getting-started/glossary#api-key) is missing or invalid, `ER0706` (HTTP 403) on a free key, `ER0176` (HTTP 402) when your account has no points left, and `ER0203` (HTTP 429) when you exceed the [rate limit](/en/articles/getting-started/glossary#rate-limit) of 50 requests per minute on a live key (200 on Corporate, 15 on a test key). Repeated violations trigger a temporary ban (`ER0204`). Every response includes the `request_id` for tracing. * * * ## Related Articles * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Get a Single Article by ID from the News API URL: https://support.apitube.io/en/articles/retrieval/get-article-by-id Use the /v1/news/article endpoint to fetch the full content of one or more articles by ID — pass a single id or a comma-separated list of up to 100, for one… # How to Get a Single Article by ID from the News API Use /v1/news/article to fetch the full content of one or more articles by their IDs ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Farticle&id=1234567) # How to get a single article by ID[#](#how-to-get-a-single-article-by-id) To fetch the full content of one article when you already know its ID, call the `/v1/news/article` endpoint with the `id` parameter. The endpoint returns the same complete article object you get from search — title, body, source, [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment) and the rest — for the IDs you ask for. This fetches one article: ``` curl "https://api.apitube.io/v1/news/article?id=1234567&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. The `id` you pass is the same `id` value returned in every search and retrieval result, so the typical flow is: run a search, store the `id` of an article, then re-fetch its full content later by ID. ## How do I fetch several articles at once?[#](#how-do-i-fetch-several-articles-at-once) Pass a comma-separated list of IDs to the `id` parameter and the endpoint returns one object per matching article in the `results` array. A single call accepts up to **100 IDs** — anything beyond the first 100 is dropped, so split larger batches across multiple requests: ``` curl "https://api.apitube.io/v1/news/article?id=1234567,1234568,1234569&api_key=YOUR_API_KEY" ``` The endpoint accepts both `GET` (IDs as a query parameter) and `POST` (IDs in a JSON body); the two are equivalent. A `POST` example: ``` curl -X POST "https://api.apitube.io/v1/news/article" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": "1234567,1234568" }' ``` ## What does the article endpoint return?[#](#what-does-the-article-endpoint-return) `/v1/news/article` returns the same JSON envelope as the search endpoints — `status`, the [pagination](/en/articles/getting-started/glossary#pagination) fields (`limit`, `page`, `has_next_pages`, `next_page`, `has_previous_page`, `previous_page`), an `export` block of ready-made download URLs, and `request_id` — wrapping a `results` array with one full article object per ID found. Because you fetch by ID, `has_next_pages` is always `false` (there is no next page to page into): ``` { "status": "ok", "limit": 100, "page": 1, "has_next_pages": false, "next_page": "", "request_id": "b4c8e19f-2a6d-47c3-9e15-8f2b0d7a4c63", "results": [ { "id": 1234567, "href": "https://example.com/some-story", "title": "...", "published_at": "2026-06-20T08:00:00.000Z", "language": "en", "body": "...", "source": { "domain": "example.com" }, "sentiment": { "overall": { "polarity": "positive" } } } ] } ``` Each object carries the standard article fields, including `id`, `href`, `published_at`, `title`, `description`, `body`, `body_html`, `language`, `author`, `image`, `categories`, `topics`, `industries`, `entities` and `source`. If an ID does not match any article, it is simply absent from `results` — the endpoint does not raise an error for unknown IDs, so a request with three IDs where one is missing returns two objects. ## How to return only the fields you need[#](#how-to-return-only-the-fields-you-need) If you only need part of the article object, add the `fl` parameter with a comma-separated list of field paths. This trims the response to those fields, which keeps payloads small when you fetch many IDs: ``` curl "https://api.apitube.io/v1/news/article?id=1234567&fl=id,title,href,published_at&api_key=YOUR_API_KEY" ``` ## How much does fetching an article by ID cost?[#](#how-much-does-fetching-an-article-by-id-cost) Each `/v1/news/article` call costs **1 credit**, regardless of how many IDs you pass in one request — fetching 100 articles in a single call costs the same one credit as fetching one. You are only charged when at least one article is returned: if none of the IDs match, no credit is spent. For a quick way to size a result set before fetching, see [How to count news articles without downloading them](/en/articles/retrieval/count-articles). # Common Questions[#](#common-questions) * [Can I fetch more than 100 articles in one call?](#can-i-fetch-more-than-100-articles-in-one-call) * [Why is the article body truncated?](#why-is-the-article-body-truncated) * [What errors can the article endpoint return?](#what-errors-can-the-article-endpoint-return) * [Where do I get the article ID?](#where-do-i-get-the-article-id) ## Can I fetch more than 100 articles in one call?[#](#can-i-fetch-more-than-100-articles-in-one-call) No. A single `/v1/news/article` request keeps only the first 100 IDs from the `id` list and ignores the rest. To fetch more, break your IDs into batches of 100 and send one request per batch. ## Why is the article body truncated?[#](#why-is-the-article-body-truncated) Article content is masked on **Free-plan keys and on [test keys](/en/articles/getting-started/glossary#test-key-and-live-key)** (the ones starting with `api_test_`). Both return a truncated body with an upgrade marker instead of the full text, so you can preview the shape of the response without revealing full content. Use a live key on a paid plan to receive the complete `body` and `body_html`. ## What errors can the article endpoint return?[#](#what-errors-can-the-article-endpoint-return) The most common ones are: `ER0232` (HTTP 400) when the `id` parameter is missing, `ER0201`/`ER0202` (HTTP 401) when the [API key](/en/articles/getting-started/glossary#api-key) is missing or invalid, and `ER0176` (HTTP 402) when your account has no credits left. Each error response includes the `request_id` to help you trace the call. ## Where do I get the article ID?[#](#where-do-i-get-the-article-id) Every search and retrieval result includes an `id` field — that value is what you pass to `/v1/news/article`. Run any query from the [Searching & Filtering News](/en/articles/searching-and-filtering) section, read the `id` from each result, and re-fetch the full article later by that ID. * * * ## Related Articles * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Get Top Headlines from the News API](/en/articles/retrieval/get-top-headlines) --- ## How to Get Local and Geo-Targeted News URL: https://support.apitube.io/en/articles/retrieval/get-local-news Use the /v1/news/local endpoint to rank news by distance from a lat/lng or place name, with distance_km, relevance ranking and an optional local insights… # How to Get Local and Geo-Targeted News Use /v1/news/local to rank articles by distance from a lat/lng or place name, with local insights ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Flocal&lat=52.52&lng=13.40&radius=50) # How to get local and geo-targeted news[#](#how-to-get-local-and-geo-targeted-news) To get news around a place, call the `/v1/news/local` endpoint with a center point — either `lat` and `lng` coordinates or a `place` name — and a `radius` in kilometers. Unlike a plain geo filter, this endpoint sorts results by distance and adds `distance_km` and `nearest_location` to every article. This request returns news within 50 km of central Berlin, nearest first: ``` curl "https://api.apitube.io/v1/news/local?lat=52.52&lng=13.40&radius=50&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. The `radius` defaults to 50 km when omitted and accepts any positive number up to 20000 km; a zero, negative or out-of-range value returns HTTP 400 with error `ER0409`. ## How is /v1/news/local different from the geo filter on the main search?[#](#how-is-v1newslocal-different-from-the-geo-filter-on-the-main-search) The `/v1/news/local` endpoint uses bare `lat`, `lng` and `radius` parameters, while the geo filter on `/v1/news/everything` uses the dotted `location.lat`, `location.lng` and `location.radius` form. They overlap on “find articles near a point”, but `/v1/news/local` adds things the filter does not: it sorts by proximity, returns a per-article `distance_km` and `nearest_location`, accepts a `place` name, and can attach a local intelligence dashboard. If you only need a geographic constraint on a normal search, use the filter instead — see [How to find news near a coordinate or bounding box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius). `/v1/news/local` supports the same filters as `/v1/news/everything`, so you can layer language, date, [sentiment](/en/articles/getting-started/glossary#sentiment), source and other parameters on top of the geo search in the same request. ## How to search local news by place name[#](#how-to-search-local-news-by-place-name) Instead of coordinates, pass a `place` name and APITube geocodes it to a center point for you: ``` curl "https://api.apitube.io/v1/news/local?place=Berlin&radius=30&api_key=YOUR_API_KEY" ``` Place names are resolved against APITube’s [entity](/en/articles/getting-started/glossary#entity) graph and matched on a word boundary, so `Paris` will not accidentally match `Parish`. Ambiguous names resolve to the best candidate — add a `country` parameter (an ISO 3166-1 alpha-2 code such as `de` or `fr`) to disambiguate, or pass explicit `lat`/`lng`, which always take precedence over `place`. When a place is used, the response echoes the resolved name and entity id in its `query` block. If the name cannot be geocoded, the request returns `ER0421`. ## How to sort local news by distance, date or relevance[#](#how-to-sort-local-news-by-distance-date-or-relevance) The `sort` parameter accepts three values and defaults to `distance` (nearest first): * `distance` — closest articles first. * `published_at` — newest first. * `relevance` — a composite of proximity, source authority, recency and importance; this adds a `relevance_score` to every article. When you sort by relevance, the `ranking` parameter picks a weighting preset: `balanced` (default), `proximity` (closer wins), `authority` (bigger sources win) or `fresh` (recency wins). This returns the most relevant Berlin coverage, favoring authoritative sources: ``` curl "https://api.apitube.io/v1/news/local?lat=52.52&lng=13.40&radius=50&sort=relevance&ranking=authority&api_key=YOUR_API_KEY" ``` The effective weights are returned in `ranking_weights`, and you can override any of them with the `w.distance`, `w.opr`, `w.recency` and `w.important` parameters. ## What does each local result include?[#](#what-does-each-local-result-include) Every article in `results` is the standard article object enriched with geo fields: * `distance_km` — distance from your center to the nearest matched location in the article. * `nearest_location` — an object with `entity_id`, `name`, `lat`, `lng` and `country` for that closest place. * `relevance_score` — present only when `sort=relevance`. The response also carries a `query` block (the `lat`, `lng`, `radius_km` and `sort` it used) and `total`, the exact number of matching articles inside the radius. [Pagination](/en/articles/getting-started/glossary#pagination) uses `page` and `per_page`, which defaults to 100 and is capped at 250 — 50 on Starter, 10 on Free; a higher `per_page` returns `ER0171`. ## How to add a local insights dashboard[#](#how-to-add-a-local-insights-dashboard) Pass the `insights` parameter — a comma-separated list — to compute aggregate intelligence over the radius. Allowed blocks are: `mood`, `hotspots`, `events`, `entities`, `bias`, `sources`, `timeline`, `top_categories`, `top_topics`, `breaking`, `velocity` and `movers`. This returns Berlin articles plus local mood, density hotspots and a breaking-news count: ``` curl "https://api.apitube.io/v1/news/local?lat=52.52&lng=13.40&radius=50&insights=mood,hotspots,breaking&api_key=YOUR_API_KEY" ``` The results appear under a `local_insights` object alongside the article list. An unknown insight value returns `ER0420`. The `movers` block surfaces entities and topics accelerating against their 14-day baseline — useful the same way the [trends endpoint](/en/articles/retrieval/discover-trends) is, but scoped to your radius. # Common Questions[#](#common-questions) * [How much does a /v1/news/local request cost?](#how-much-does-a-v1newslocal-request-cost) * [What is the maximum search radius?](#what-is-the-maximum-search-radius) * [Why do I get error ER0421?](#why-do-i-get-error-er0421) * [Can I combine local news with other filters?](#can-i-combine-local-news-with-other-filters) ## How much does a /v1/news/local request cost?[#](#how-much-does-a-v1newslocal-request-cost) A `/v1/news/local` call costs 1 point for the article listing, plus 1 additional point for each requested insight block. A request with no `insights` costs 1 point; a request with `insights=mood,hotspots,breaking` costs 4 points (1 + 3). Skip the `insights` parameter when you only need the ranked articles. ## What is the maximum search radius?[#](#what-is-the-maximum-search-radius) The `radius` is measured in kilometers, defaults to 50 when omitted, and accepts any positive number up to 20000 km. A radius of zero, a negative value or anything above 20000 km returns HTTP 400 with error `ER0409`. You must also supply a center: send `lat` and `lng` together (or a `place`), otherwise the request returns `ER0406`. An out-of-range latitude returns `ER0407` and an out-of-range longitude returns `ER0408`. ## Why do I get error ER0421?[#](#why-do-i-get-error-er0421) Error `ER0421` means APITube could not geocode the `place` name you sent. Try a more specific name, add a `country` code to disambiguate it, or pass explicit `lat`/`lng` coordinates instead of a place name. Coordinates skip geocoding entirely and always take precedence over `place`. ## Can I combine local news with other filters?[#](#can-i-combine-local-news-with-other-filters) Yes. `/v1/news/local` runs the same filter chain as the main search, so you can mix the geo center with language, date range, sentiment, source and sorting in one request. This returns recent English-language news near Berlin: ``` curl "https://api.apitube.io/v1/news/local?lat=52.52&lng=13.40&radius=50&language.code=en&sort=published_at&api_key=YOUR_API_KEY" ``` For the full list of filters you can layer on top, see the [parameters reference](https://docs.apitube.io/platform/news-api/everything). * * * ## Related Articles * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) --- ## How to Get the Raw Article Body and HTML URL: https://support.apitube.io/en/articles/retrieval/get-raw-body Use the /v1/news/raw endpoint to fetch the full article body as plain text and as HTML, filtered by date or source, for one credit per request. # How to Get the Raw Article Body and HTML Use /v1/news/raw to retrieve the full article text as both plain text and HTML ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 5, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fraw) # How to get the raw article body and HTML[#](#how-to-get-the-raw-article-body-and-html) To fetch the full text of a news article as both clean plain text and original HTML in one call, use the `/v1/news/raw` endpoint. Each result carries a `body` field (the article as plain text, with all tags stripped) and a `body_html` field (the same content as minified HTML), alongside the title, link, author and source. This is the endpoint to reach for when you need the actual written content of articles rather than just metadata. A basic request: ``` curl "https://api.apitube.io/v1/news/raw?api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. The endpoint accepts both `GET` (parameters in the query string) and `POST` (parameters in a JSON body) — the two are equivalent. ## What does /v1/news/raw return?[#](#what-does-v1newsraw-return) `/v1/news/raw` returns the same JSON envelope as the search endpoints — `status`, the [pagination](/en/articles/getting-started/glossary#pagination) fields (`limit`, `path`, `page`, `has_next_pages`, `next_page`, `has_previous_page`, `previous_page`), `request_id` and a `results` array. Each object in `results` contains the fields below: ``` { "status": "ok", "limit": 100, "path": "https://api.apitube.io/v1/news/raw?api_key=YOUR_API_KEY", "page": 1, "has_next_pages": true, "next_page": "https://api.apitube.io/v1/news/raw?api_key=YOUR_API_KEY&page=2", "has_previous_page": false, "previous_page": "", "request_id": "7d1f9a34-6c2e-4b58-a903-1e5c8d2f7b40", "results": [ { "id": 1234567, "title": "...", "href": "https://example.com/some-story", "created_at": "2026-06-20T08:00:00", "description": "...", "body": "Full article text as plain text...", "body_html": "<p>Full article text as HTML...</p>", "author": "Jane Doe", "keywords": ["technology", "ai"], "source": { "id": 42, "domain": "example.com", "home_page_url": "https://example.com", "type": "news", "bias": "center", "rankings": { "opr": 4.2 }, "location": { "country_name": "United States", "country_code": "us" }, "favicon": "https://www.google.com/s2/favicons?domain=https://example.com" } } ] } ``` The two content fields are the point of this endpoint: `body` is the article rendered as plain text (HTML tags removed and whitespace collapsed), while `body_html` keeps the markup so you can render it yourself. The `created_at` field carries the article’s publish timestamp, and `keywords` carries an array of the source-provided category strings (an empty array if the feed provided none). The `source` object is the full publisher record — `domain`, `home_page_url`, `type`, `bias`, `rankings.opr` ([Open PageRank](/en/articles/getting-started/glossary#opr-open-pagerank)), `location` and `favicon` — the same shape you get on the enriched endpoints. Note that the raw feed does **not** carry the NLP enrichment (`language`, `categories`, `topics`, `entities`, `sentiment`), so those fields are absent here. ## How to narrow raw results by date[#](#how-to-narrow-raw-results-by-date) Restrict results to a publish-date window with `published_at.start` and `published_at.end`. Both accept an ISO date or datetime: ``` curl "https://api.apitube.io/v1/news/raw?published_at.start=2026-06-01&published_at.end=2026-06-20&api_key=YOUR_API_KEY" ``` You can also pass a single `published_at` value to match one day. For the full set of date options shared across the API, see [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## How to filter raw results by source[#](#how-to-filter-raw-results-by-source) Limit results to specific sources with `source.id`, a comma-separated list of **up to three numeric source IDs**. To exclude sources instead, use `ignore.source.id` (also up to three IDs): ``` curl "https://api.apitube.io/v1/news/raw?source.id=42,57&api_key=YOUR_API_KEY" ``` Note that the raw endpoint matches on the numeric `source.id`, not on a domain name. ## How to sort and paginate raw results[#](#how-to-sort-and-paginate-raw-results) Sort with `sort.by` — accepted values are `id`, `published_at` and `created_at` — together with `sort.order` set to `asc` or `desc`. The default is `id` in `desc` order, so the newest stored articles come first. Page through results with `page` and `per_page`; `per_page` has a maximum of **250**, or **50** on Starter and **10** on Free (a larger value returns error `ER0171`). ``` curl "https://api.apitube.io/v1/news/raw?sort.by=published_at&sort.order=desc&per_page=50&api_key=YOUR_API_KEY" ``` ## How much does a raw request cost?[#](#how-much-does-a-raw-request-cost) Each `/v1/news/raw` call costs **1 credit**, regardless of how many articles come back. You are only charged when at least one article is returned: if the filters match nothing, no credit is spent. # Common Questions[#](#common-questions) * [How is /v1/news/raw different from /v1/news/article?](#how-is-v1newsraw-different-from-v1newsarticle) * [Why is the body truncated or marked “Upgrade subscription plan”?](#why-is-the-body-truncated-or-marked-upgrade-subscription-plan) * [Can I export raw results to CSV or RSS?](#can-i-export-raw-results-to-csv-or-rss) * [Which errors can the raw endpoint return?](#which-errors-can-the-raw-endpoint-return) ## How is /v1/news/raw different from /v1/news/article?[#](#how-is-v1newsraw-different-from-v1newsarticle) `/v1/news/raw` is focused on the written content: it returns `body` and `body_html` plus a small set of fields (`id`, `title`, `href`, `created_at`, `description`, `author`, `keywords`, `source`). It does not include the NLP enrichment — [entities](/en/articles/getting-started/glossary#entity), [sentiment](/en/articles/getting-started/glossary#sentiment), categories, topics — that a full article object carries. When you need that enrichment, fetch the article by ID with [How to get a single article by ID](/en/articles/retrieval/get-article-by-id) instead. ## Why is the body truncated or marked “Upgrade subscription plan”?[#](#why-is-the-body-truncated-or-marked-upgrade-subscription-plan) Article content is masked on **Free-plan keys and on [test keys](/en/articles/getting-started/glossary#test-key-and-live-key)** (the ones starting with `api_test_`). On those keys the `body` and `body_html` are cut to a short preview followed by a `...[Upgrade subscription plan]` marker, so you can inspect the response shape without seeing the full text. Use a live key on a paid plan to receive the complete body. ## Can I export raw results to CSV or RSS?[#](#can-i-export-raw-results-to-csv-or-rss) No. [Export formats](/en/articles/getting-started/glossary#export-format) such as CSV, XLSX and RSS are not available on `/v1/news/raw` — the endpoint returns JSON only. Export options apply to the search endpoints, not to the raw store. ## Which errors can the raw endpoint return?[#](#which-errors-can-the-raw-endpoint-return) The most common ones are `ER0201`/`ER0202` (HTTP 401) when the API key is missing or invalid, `ER0176` (HTTP 402) when your account has no credits left, and `ER0171` (HTTP 400) when `per_page` is above your plan ceiling (250, 50 on Starter, 10 on Free). Every error response includes the `request_id` so you can trace the call. * * * ## Related Articles * [How to Get a Single Article by ID from the News API](/en/articles/retrieval/get-article-by-id) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Get All Articles Covering the Same Story URL: https://support.apitube.io/en/articles/retrieval/get-story-cluster Use the /v1/news/story/:id endpoint to find other articles covering the same story as a given article, matched by its title keywords and ranked by keyword… # How to Get All Articles Covering the Same Story Use /v1/news/story/:id to find related coverage of one article across other sources ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fstory%2F%7Barticle_id%7D&pp_article_id=1234567) # How to get all articles covering the same story[#](#how-to-get-all-articles-covering-the-same-story) To find every article that covers the same story as one you already have, call the `/v1/news/story/:id` endpoint with that article’s ID in the path. The endpoint reads the source article’s title, pulls out its meaningful keywords, and returns other articles whose titles share those keywords — ranked so the closest matches come first. This finds related coverage of article `1234567`: ``` curl "https://api.apitube.io/v1/news/story/1234567?api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. The ID you put in the path is the same `id` value returned by every search and retrieval result, so the typical flow is: run a search, take the `id` of one article, then ask the story endpoint for the rest of the coverage around it. ## How does APITube decide which articles belong to the same story?[#](#how-does-apitube-decide-which-articles-belong-to-the-same-story) The story endpoint does not rely on a pre-built cluster ID. Instead, it works from the source article’s headline: it tokenizes the title, drops stopwords, and keeps the remaining keywords (each at least two characters). It then searches for other articles whose titles contain those keywords and ranks them by how many keywords overlap — an article matching more of the source headline’s keywords ranks above one matching fewer. The source article itself is always excluded from the results, so you only get the _other_ coverage. Because matching is keyword-based, the most reliable inputs are articles with a clear, specific headline. If the source title has no usable keywords after stopwords are removed, the endpoint returns `ER0240` (HTTP 404) rather than guessing. ## How to narrow a story to one language, date range or source[#](#how-to-narrow-a-story-to-one-language-date-range-or-source) The story endpoint accepts the same filters as a normal search, so you can scope the related coverage. Add any standard filter alongside the path ID — for example, restrict it to English coverage and to one source: ``` curl "https://api.apitube.io/v1/news/story/1234567?language.code=en&source.domain=reuters.com&api_key=YOUR_API_KEY" ``` You can also limit by date with `published_at.start` and `published_at.end` (see [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range)), or by any other filter from the [Searching & Filtering News](/en/articles/searching-and-filtering) section. Results are paginated: `per_page` defaults to 100 and accepts up to **250**, or **50** on Starter and **10** on Free (a higher value returns `ER0171`), and `page` walks through the matches. ## What does the story endpoint return?[#](#what-does-the-story-endpoint-return) The response is the standard JSON envelope: a `results` array of full article objects plus paging fields and a `request_id`: ``` { "status": "ok", "limit": 100, "page": 1, "has_next_pages": false, "results": [ { "id": 7654321, "href": "https://example.com/same-story-different-source", "title": "...", "published_at": "2026-06-20T08:00:00.000Z", "language": "en", "source": { "domain": "example.com" } } ], "request_id": "c2e6a48b-1d59-4f37-8b0a-9c3e7d1f2a56" } ``` Each object carries the usual article fields — `id`, `href`, `published_at`, `title`, `body`, `body_html`, `language`, `author`, `image`, `categories`, `topics`, `industries`, `entities` and `source` — the same shape you get from [fetching an article by ID](/en/articles/retrieval/get-article-by-id). To trim the payload, add `fl` with a comma-separated list of field paths, for example `fl=id,title,href,published_at`. ## How much does a story request cost?[#](#how-much-does-a-story-request-cost) Each `/v1/news/story/:id` call costs **1 credit**, and you are only charged when the endpoint returns at least one related article. If no other coverage matches the source headline, no credit is spent. The endpoint accepts both `GET` (ID in the path) and `POST` (same path, filters in a JSON body); the two are equivalent. # Common Questions[#](#common-questions) * [Why did I get “Article not found”?](#why-did-i-get-article-not-found) * [Why are the article bodies truncated?](#why-are-the-article-bodies-truncated) * [What errors can the story endpoint return?](#what-errors-can-the-story-endpoint-return) * [Is the source article included in the results?](#is-the-source-article-included-in-the-results) ## Why did I get “Article not found”?[#](#why-did-i-get-article-not-found) A `404` with `ER0235` means the ID you passed in the path does not match any article in the index — double-check that you copied the `id` from a recent search or retrieval result. A separate `404` with `ER0240` means the article _was_ found, but its title had no usable keywords left after stopwords were removed, so there was nothing to match a story on. ## Why are the article bodies truncated?[#](#why-are-the-article-bodies-truncated) Article content is masked on **Free-plan keys and on [test keys](/en/articles/getting-started/glossary#test-key-and-live-key)** (those starting with `api_test_`). Both return a shortened body with an upgrade marker instead of the full text, so you can preview the response shape without full content. Use a live key on a paid plan to receive the complete `body` and `body_html`. ## What errors can the story endpoint return?[#](#what-errors-can-the-story-endpoint-return) The common ones are: `ER0231` (HTTP 400) when no article ID is supplied, `ER0235` (HTTP 404) when the ID matches no article, `ER0240` (HTTP 404) when the title yields no keywords, `ER0201`/`ER0202` (HTTP 401) when the [API key](/en/articles/getting-started/glossary#api-key) is missing or invalid, and `ER0176` (HTTP 402) when your account has no credits left. Every error response includes the `request_id` for tracing. ## Is the source article included in the results?[#](#is-the-source-article-included-in-the-results) No. The endpoint always excludes the article whose ID you passed, so `results` contains only the _other_ articles covering the same story. To read the source article’s own full content, fetch it separately with [`/v1/news/article`](/en/articles/retrieval/get-article-by-id). * * * ## Related Articles * [How to Get a Single Article by ID from the News API](/en/articles/retrieval/get-article-by-id) * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) --- ## How to Get Top Headlines from the News API URL: https://support.apitube.io/en/articles/retrieval/get-top-headlines Use the /v1/news/top-headlines endpoint to fetch important, high-authority news (OPR rank ≥ 5). Same filters as search, sorted newest-first, 1 point per call. # How to Get Top Headlines from the News API Use /v1/news/top-headlines to fetch important news from high-authority sources ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Ftop-headlines&language_code=en) # How to get top headlines[#](#how-to-get-top-headlines) To get the most important news from high-authority sources, call the `/v1/news/top-headlines` endpoint. It returns the same article objects as the main search, but pre-filtered down to stories flagged as important **and** published by sources with an Open Page Rank ([OPR](/en/articles/getting-started/glossary#opr-open-pagerank)) of at least 5. By default the results come back newest-first. This fetches the current English top headlines: ``` curl "https://api.apitube.io/v1/news/top-headlines?language.code=en&api_key=YOUR_API_KEY" ``` You can pass your key as the `api_key` query parameter or as an `X-API-Key` header. ## What makes an article a top headline?[#](#what-makes-an-article-a-top-headline) `/v1/news/top-headlines` applies two built-in conditions that the regular search does not: * The article is flagged as **important** (a breaking or high-significance story). * The source has an **OPR score of 5 or higher** — OPR (Open Page Rank) measures a publisher’s authority, so this keeps low-authority sites out. Everything that matches both conditions is eligible; everything else is excluded before your own filters even run. That is the entire difference between top-headlines and a normal search — it is a curated, high-authority slice of the same catalogue. ## How is top-headlines different from the main search?[#](#how-is-top-headlines-different-from-the-main-search) Apart from those two conditions, `/v1/news/top-headlines` accepts **exactly the same parameters** as `/v1/news/everything`: the full filter set, sorting, [pagination](/en/articles/getting-started/glossary#pagination), faceting, highlighting and [export formats](/en/articles/getting-started/glossary#export-format) all work identically. Anything you can do on the main search, you can do here on top of the high-authority pre-filter. That means you can take a query you already use for search, swap the path to `/v1/news/top-headlines`, and get the same query restricted to important, authoritative stories. For the complete list of filters you can combine, see the [Searching & Filtering News](/en/articles/searching-and-filtering) section. ## How to narrow top headlines by language, country or category[#](#how-to-narrow-top-headlines-by-language-country-or-category) Add filters as query parameters (GET) or as a JSON body (POST). For example, to get the most relevant business top headlines using an IPTC category code, sorted by relevance: ``` curl "https://api.apitube.io/v1/news/top-headlines?category.id=medtop:13000000&sort.by=relevance&sort.order=desc&api_key=YOUR_API_KEY" ``` A few common filters you can layer on: * `language.code=en` — limit to a language (2-letter code). * `source.domain=bbc.com` — limit to a specific publisher’s domain. * `published_at.start=2026-06-01` — only headlines on or after a date. * `category.id=medtop:13000000` — a single IPTC category. See [How to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category). ## How are top headlines sorted, and can I change it?[#](#how-are-top-headlines-sorted-and-can-i-change-it) By default, results are sorted by `published_at` in descending order — newest headlines first. Override it with `sort.by` and `sort.order`. Supported sort modes include `relevance`, `engagement`, `quality`, `controversy`, `trust` and `published_at`. For example, `sort.by=engagement&sort.order=desc` surfaces the headlines getting the most social traction first. ## What does the top-headlines response look like?[#](#what-does-the-top-headlines-response-look-like) The response has the same shape as a normal search response, plus one field unique to this endpoint: a `headlines` array containing just the titles, alongside the full `results` array. ``` { "status": "ok", "limit": 100, "page": 1, "has_next_pages": true, "request_id": "9f2c1e7a-4b3d-4c8e-a1f0-2d6b8c4e7a11", "headlines": [ "Central bank holds rates steady amid inflation concerns", "Major automaker recalls 200,000 vehicles over a brake fault" ], "results": [ { "id": 123456789, "href": "https://example.com/markets/central-bank-holds-rates", "published_at": "2026-06-26T09:15:00Z", "title": "Central bank holds rates steady amid inflation concerns", "language": "en", "source": { "id": 4232, "domain": "example.com", "rankings": { "opr": 7 } } } ] } ``` The `headlines` array is handy when you only want to render a list of titles. Each object in `results` carries the usual article fields — `id`, `href`, `published_at`, `title`, `description`, `body`, `language`, `source`, `categories`, `entities`, `sentiment` and the rest — the same shape returned by the search endpoints (see the [API response structure](https://docs.apitube.io/platform/news-api/response-structure)). ## How much does a top-headlines request cost?[#](#how-much-does-a-top-headlines-request-cost) Each call that returns results costs **1 point**, the same as a search request — regardless of how many headlines come back. If the query matches nothing, no point is spent. You can page through results with `page` and `per_page` (default 100, maximum 250 — 200 on Basic, 50 on Starter, 10 on Free); requesting more than your plan allows returns error `ER0171`. # Common Questions[#](#common-questions) * [Can I call top-headlines with POST?](#can-i-call-top-headlines-with-post) * [Why do I get fewer results than the main search?](#why-do-i-get-fewer-results-than-the-main-search) * [Why is the article content truncated?](#why-is-the-article-content-truncated) * [What errors can top-headlines return?](#what-errors-can-top-headlines-return) ## Can I call top-headlines with POST?[#](#can-i-call-top-headlines-with-post) Yes. `/v1/news/top-headlines` accepts both `GET` and `POST`. With `GET`, send filters as query parameters; with `POST`, send them as a JSON body with `Content-Type: application/json`. Both run the same query and return the same response. ## Why do I get fewer results than the main search?[#](#why-do-i-get-fewer-results-than-the-main-search) Because top-headlines always applies its two built-in conditions — important article **and** source OPR ≥ 5 — on top of your filters. A query that returns thousands of articles on `/v1/news/everything` will return far fewer here, since most articles either are not flagged important or come from lower-authority sources. If you need everything matching your filters, use the search endpoints instead. If you only need a count, see [How to count matching articles without downloading them](/en/articles/retrieval/count-articles). ## Why is the article content truncated?[#](#why-is-the-article-content-truncated) If you are using a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** or are on the **free plan**, article content is truncated (a preview, with an upgrade marker in place of the full body). This applies to top-headlines just like any other endpoint. Switch to a live key on a paid plan to receive full article bodies. ## What errors can top-headlines return?[#](#what-errors-can-top-headlines-return) The errors mirror the rest of the API: `ER0201`/`ER0202` (HTTP 401) when the [API key](/en/articles/getting-started/glossary#api-key) is missing or invalid, `ER0176` (HTTP 402) when your account has no points left, and `ER0203` (HTTP 429) when you exceed the [rate limit](/en/articles/getting-started/glossary#rate-limit) (50 requests per minute on paid plans, 10 on the free plan; repeated violations lead to a temporary ban). Each response includes a `request_id` to help you trace the call. * * * ## Related Articles * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) --- ## News Endpoints & Retrieval URL: https://support.apitube.io/en/articles/retrieval Beyond search: get top headlines, local news, a single article, a story cluster, article counts and trends from the APITube News API. ![](/images/collections/insights-dashboard.svg) # News Endpoints & Retrieval Headlines, local news, clusters and trends. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Kent and 1 other 2 authors 10 articles Task-shaped recipes for getting specific things out of the API: fetch one article by its id, pull the raw article body, count matching articles without retrieving them, compare topic trends over time, get local news for a region, and check your remaining balance programmatically. Each article is a complete worked example — request, response and the parameters that matter — so you can copy the pattern and swap in your own filters. * [How to Autocomplete Filter Values with the Suggest API](/en/articles/retrieval/autocomplete-filter-values) * [How to Check Your API Balance and Remaining Quota](/en/articles/retrieval/check-balance-api) * [How to Compare News Trends Between Two Periods](/en/articles/retrieval/compare-trends) * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Get a Single Article by ID from the News API](/en/articles/retrieval/get-article-by-id) * [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) * [How to Get Local and Geo-Targeted News](/en/articles/retrieval/get-local-news) * [How to Get the Raw Article Body and HTML](/en/articles/retrieval/get-raw-body) * [How to Get Top Headlines from the News API](/en/articles/retrieval/get-top-headlines) --- ## How to Filter News by Author URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-author Use author.name or author.id to filter APITube News API results to specific bylines — up to three at once with OR logic — plus ignore.author.* and has_author. # How to Filter News by Author Narrow News API results to specific bylines with author.name, author.id and has\_author ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&author_name=Reuters) # How to filter news by author[#](#how-to-filter-news-by-author) To return only articles written by a specific person or agency, add the `author.name` parameter with the byline you want, for example `author.name=Reuters`. The APITube News API matches it against the authors it already tracks and returns only matching articles. You can pass up to three names separated by commas, and articles by **any** of them are returned (OR logic). ``` curl "https://api.apitube.io/v1/news/everything?author.name=Reuters&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit every author parameter, no author filter is applied and articles from all bylines are returned. ## What is the author.name parameter?[#](#what-is-the-authorname-parameter) `author.name` takes one or more author names, like `AFP` or `Ezra Klein`. Each name must be 1 to 100 characters long; anything outside that range returns HTTP 400 with error `ER0071`. Every name is looked up against the authors APITube tracks. If a name is not found, the request fails with HTTP 400 and error `ER0204` and a message like `author with name 'Jane Doe' not found` — the whole request stops, so one unknown name blocks the entire call. Because the name must match an author already in the directory, the safest way to get the exact spelling is to read it from a response first: run a broad search, then copy the `author.name` (or the numeric `author.id`) straight from an article and reuse it in your next request. ## How to filter by one or more authors[#](#how-to-filter-by-one-or-more-authors) Pass a single name to read just that byline, or a comma-separated list to combine several. This request pulls articles from two news agencies in one call: ``` curl "https://api.apitube.io/v1/news/everything?author.name=AFP,Reuters&api_key=YOUR_API_KEY" ``` The maximum is three authors per request. If you list more than three, only the first three are used and the rest are silently dropped. Author filtering is part of the shared filter chain, so it combines with other filters and with sorting: ``` curl "https://api.apitube.io/v1/news/everything?author.name=Reuters&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` ## How to filter by author ID instead of name[#](#how-to-filter-by-author-id-instead-of-name) Every author also has a numeric `author.id`. Filtering by ID avoids spelling mismatches and is the most reliable way to pin results to one byline. Pass up to three IDs, comma-separated: ``` curl "https://api.apitube.io/v1/news/everything?author.id=12345,67890&api_key=YOUR_API_KEY" ``` Each ID must be an integer of 1 to 20 characters. A non-numeric value returns `ER0064`, and an out-of-range length returns `ER0066` — both HTTP 400. Unlike `author.name`, an `author.id` is not checked against the directory, so a valid-looking ID that matches no author simply returns no articles instead of an error. ## How to exclude specific authors[#](#how-to-exclude-specific-authors) To return everything **except** certain bylines, use `ignore.author.name` or `ignore.author.id`. Both follow the same rules — comma-separated, up to three values. This keeps all coverage except two wire services: ``` curl "https://api.apitube.io/v1/news/everything?ignore.author.name=AFP,Reuters&api_key=YOUR_API_KEY" ``` As with the positive filter, an unknown name in `ignore.author.name` returns `ER0205`, so the excluded names must also be tracked authors. The numeric variant `ignore.author.id` returns `ER0067` for a non-numeric value and `ER0069` for a bad length. ## How to require or exclude an attributed author[#](#how-to-require-or-exclude-an-attributed-author) Many articles have no named author at all. Use `has_author` to keep only the ones that do — or only the ones that don’t. Pass `has_author=1` to require an attributed author, or `has_author=0` to return only articles without one: ``` curl "https://api.apitube.io/v1/news/everything?has_author=1&category.id=medtop:04000000&api_key=YOUR_API_KEY" ``` `has_author` accepts only `0` or `1`; any other value returns HTTP 400 with error `ER0070`. This pairs well with a [category filter](/en/articles/searching-and-filtering/by-attribute/filter-by-category) when you want signed reporting on a topic and want to drop unattributed aggregator items. ## What does the author object in the response contain?[#](#what-does-the-author-object-in-the-response-contain) Every article in the response carries an `author` object so you can confirm the byline and reuse it: ``` { "author": { "id": 12345, "name": "Reuters" } } ``` The `id` and `name` here are exactly the values you pass back into `author.id` and `author.name` for follow-up requests. When an article has no attributed author, the `author.id` is `null`. To also limit results to a single publisher at the same time, combine author filtering with [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source). # Common Questions[#](#common-questions) * [How many authors can I filter by at once?](#how-many-authors-can-i-filter-by-at-once) * [Should I use author.name or author.id?](#should-i-use-authorname-or-authorid) * [What error do I get for an unknown author?](#what-error-do-i-get-for-an-unknown-author) * [How do I find articles that have no author?](#how-do-i-find-articles-that-have-no-author) ## How many authors can I filter by at once?[#](#how-many-authors-can-i-filter-by-at-once) Up to three per parameter. `author.name`, `author.id`, `ignore.author.name` and `ignore.author.id` each accept a comma-separated list, and only the first three values are applied — extra values beyond the third are silently ignored. Multiple authors in one parameter use OR logic, so an article matches if it was written by any of them. ## Should I use author.name or author.id?[#](#should-i-use-authorname-or-authorid) Both target the same authors. `author.name` is easier to read and write because you use the byline directly, but it must exactly match a tracked author or the request fails with `ER0204`. `author.id` is more robust: it is a fixed numeric identifier and is not validated against the directory, so it never blocks the request. Read either value from an article’s `author` object to get the exact match. ## What error do I get for an unknown author?[#](#what-error-do-i-get-for-an-unknown-author) A name that APITube does not track returns HTTP 400 with error `ER0204` (`author with name '…' not found`) for `author.name`, or `ER0205` for `ignore.author.name`. A name shorter than 1 or longer than 100 characters returns `ER0071` (`ER0073` for the ignore variant). Because the request stops on the first bad name, confirm the spelling from a response before filtering. ## How do I find articles that have no author?[#](#how-do-i-find-articles-that-have-no-author) Set `has_author=0`. This returns only articles where no author was attributed, which is common for wire-service reposts and automated aggregators. Use `has_author=1` for the opposite — only signed articles. Any value other than `0` or `1` returns error `ER0070`. * * * ## Related Articles * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) --- ## How to Filter News by Category URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-category Use category.id to limit APITube News API results to IPTC categories like Sport — up to three at once with OR logic — and ignore.category.id to exclude them. # How to Filter News by Category Narrow News API results to IPTC categories with category.id ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&category_id=medtop%3A15000000) # How to filter news by category[#](#how-to-filter-news-by-category) To return only articles that belong to a subject category, add the `category.id` parameter with an IPTC category code, for example `category.id=medtop:15000000` for Sport. You can pass up to three codes separated by commas, and an article is returned if it matches **any** of them (OR logic). Every code must be a category APITube already tracks. ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:15000000&api_key=YOUR_API_KEY" ``` You can also send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `category.id`, no category filter is applied and articles from all categories are returned. ## What is the category.id parameter?[#](#what-is-the-categoryid-parameter) `category.id` takes one or more category codes from the IPTC taxonomy. IPTC codes look like `medtop:15000000` (Sport) — a `medtop:` prefix followed by the numeric topic ID. The category filter is part of the shared filter chain, so it works on `/v1/news/everything` and on the other search endpoints described below. Each code you pass is checked against the categories APITube tracks. If a code does not exist, the request fails with HTTP 400 and error `ER0206` and a message like `category with ID 'medtop:99999999' not found` — the whole request stops, so one unknown code blocks the entire call. Confirm a code exists first with the suggest endpoint (see below). ## How to filter by one or more categories[#](#how-to-filter-by-one-or-more-categories) Pass a single code to read one category, or a comma-separated list to combine several. This request pulls articles from two categories in one call, returning anything that matches either: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:15000000,medtop:04000000&api_key=YOUR_API_KEY" ``` The maximum is three codes per request; extra codes beyond the third are dropped. Because `category.id` runs in the shared filter chain, it also combines with other filters and with sorting: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:15000000&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` That request returns the newest English articles in the Sport category. To restrict the time window too, add [`published_at.start` and `published_at.end`](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## How to find the right category ID[#](#how-to-find-the-right-category-id) Use the `/v1/suggest/categories` endpoint to look up a category by name before you filter. Pass a `prefix` and it returns matching categories, each with an `id`, `name`, `taxonomy` and a ready-made `links.self` URL: ``` curl "https://api.apitube.io/v1/suggest/categories?prefix=sport&api_key=YOUR_API_KEY" ``` The `id` it returns is the exact value to drop into `category.id` — no conversion needed. The `prefix` parameter is required; omitting it returns HTTP 400 with error `ER0346`, and a missing [API key](/en/articles/getting-started/glossary#api-key) returns `401 ER0201`. For the complete reference of IPTC categories, see the [list of supported categories](https://docs.apitube.io/platform/news-api/list-of-categories) in the official docs. ## How to exclude a category[#](#how-to-exclude-a-category) To return everything **except** a category, use `ignore.category.id`. It follows the same rules — comma-separated, up to three codes. This keeps every category but drops Sport: ``` curl "https://api.apitube.io/v1/news/everything?ignore.category.id=medtop:15000000&api_key=YOUR_API_KEY" ``` As with the positive filter, an unknown code in `ignore.category.id` stops the request with HTTP 400 and error `ER0207`, so the excluded codes must also be tracked categories. You can combine `category.id` and `ignore.category.id` in the same request to include one set of categories while removing another. ## Which endpoints support category filtering?[#](#which-endpoints-support-category-filtering) The `category.id` and `ignore.category.id` parameters work on `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. There is also a dedicated category endpoint, `/v1/news/category/{taxonomy}/{id}`, that returns a single category’s articles. The simplest way to get a correct URL for it is the `links.self` field returned by `/v1/suggest/categories`. An unknown category on that endpoint returns HTTP 404 with error `ER0241`. ## What does the category data look like in the response?[#](#what-does-the-category-data-look-like-in-the-response) Every article in the response carries a `categories` array so you can see how it was classified: ``` { "categories": [ { "id": 314, "name": "Sport", "taxonomy": "iptc_mediatopics", "links": { "self": "https://api.apitube.io/v1/news/category/iptc_mediatopics/medtop:15000000" } } ] } ``` Each entry also includes a `score` field reflecting how strongly the article maps to that category. The `links.self` URL fetches all articles in the same category. To discover the code you pass to `category.id`, use `/v1/suggest/categories` rather than the `id` in this object. If you only need a tally per category instead of the articles themselves, see [How to count news articles without downloading them](/en/articles/retrieval/count-articles). # Common Questions[#](#common-questions) * [How many categories can I filter by at once?](#how-many-categories-can-i-filter-by-at-once) * [What category codes does category.id accept?](#what-category-codes-does-categoryid-accept) * [What error do I get for an unknown category?](#what-error-do-i-get-for-an-unknown-category) * [Can I include and exclude categories in the same request?](#can-i-include-and-exclude-categories-in-the-same-request) ## How many categories can I filter by at once?[#](#how-many-categories-can-i-filter-by-at-once) Up to three per parameter. `category.id` and `ignore.category.id` each accept a comma-separated list, and only the first three codes are applied — extra codes beyond the third are ignored. Multiple codes use OR logic, so an article is returned if it matches any one of them. ## What category codes does category.id accept?[#](#what-category-codes-does-categoryid-accept) `category.id` accepts IPTC category codes such as `medtop:15000000`. Each code is matched against the categories APITube tracks. The reliable way to get a valid code is `/v1/suggest/categories?prefix=NAME`, whose `id` field is exactly what `category.id` expects. ## What error do I get for an unknown category?[#](#what-error-do-i-get-for-an-unknown-category) A code APITube does not track returns HTTP 400 with error `ER0206` (`category with ID '…' not found`) for `category.id`, or `ER0207` for `ignore.category.id`. The request stops on the first unknown code, so validate each code with `/v1/suggest/categories` before filtering. ## Can I include and exclude categories in the same request?[#](#can-i-include-and-exclude-categories-in-the-same-request) Yes. `category.id` and `ignore.category.id` can be combined with each other and with other filters such as `language.code`, `published_at.start` or `source.domain`. The positive filter limits results to the listed categories, and the ignore filter removes any you do not want from whatever remains. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) --- ## How to Filter News by Country and Location URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location Use source.country.code to return APITube News API articles from publishers in specific countries — up to three at once, comma-separated, with OR logic. # How to Filter News by Country and Location Restrict News API results to publishers in specific countries with source.country.code ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_country_code=us) # How to filter news by country and location[#](#how-to-filter-news-by-country-and-location) To return news from publishers in a specific country, add the `source.country.code` parameter with a two-letter country code, for example `source.country.code=us`. You can pass up to three codes separated by commas, and articles from a source in **any** of those countries are returned (OR logic). ``` curl "https://api.apitube.io/v1/news/everything?source.country.code=us&api_key=YOUR_API_KEY" ``` You can also send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `source.country.code`, no country filter is applied and articles from sources in all countries are returned. ## What does source.country.code filter on?[#](#what-does-sourcecountrycode-filter-on) `source.country.code` filters by the country the **news source** is registered in — the publisher’s country — not the country a story is about. A US publisher writing about France is matched by `source.country.code=us`, not `fr`. If you want articles about a place (where the event happened), use the location filters described below instead. The code is a two-letter country code such as `us`, `gb`, `de`, `jp` or `fr`. The value is case-insensitive, so `US` and `us` behave the same way. The full set of accepted codes is in the [list of countries](https://docs.apitube.io/platform/news-api/list-of-countries) in the documentation. ## How to request a single country[#](#how-to-request-a-single-country) Pass one code to keep results to publishers in that country. This request returns articles from Japanese sources: ``` curl "https://api.apitube.io/v1/news/everything?source.country.code=jp&api_key=YOUR_API_KEY" ``` ## How to request multiple countries at once[#](#how-to-request-multiple-countries-at-once) Separate codes with commas to match sources in **any** of the listed countries. This pulls articles from US, German and British publishers in a single call: ``` curl "https://api.apitube.io/v1/news/everything?source.country.code=us,de,gb&api_key=YOUR_API_KEY" ``` The maximum is three countries per request. If you list more than three, only the first three are used — the rest are silently dropped, so keep the list to three meaningful codes. ## How to exclude a country with ignore.source.country.code[#](#how-to-exclude-a-country-with-ignoresourcecountrycode) To keep everything **except** sources in certain countries, use `ignore.source.country.code`. It follows the same rules — comma-separated, up to three codes. A common pattern is to drop both a country and its language at the same time: ``` curl "https://api.apitube.io/v1/news/everything?ignore.source.country.code=fr&ignore.language.code=fr&api_key=YOUR_API_KEY" ``` For language filtering on its own, see [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). ## How to filter by the location a story is about[#](#how-to-filter-by-the-location-a-story-is-about) Country filtering matches the publisher, not the place in the news. To filter by geography — where an event happened — APITube has separate location parameters: `location.lat`, `location.lng` and `location.radius` (a radius in kilometres, up to 20000), `location.bbox` for a bounding box, and `has_location_geo=1` to keep only articles that carry coordinates. These run on the regular search endpoints, the same way country filtering does. See [How to find news near a coordinate or bounding box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) for the full syntax, or [How to get local and geo-targeted news](/en/articles/retrieval/get-local-news) for the dedicated `/v1/news/local` endpoint that ranks results by distance from a point. ## Which endpoints support country filtering?[#](#which-endpoints-support-country-filtering) `source.country.code` is part of the shared filter chain, so it works on the main search and retrieval endpoints, including `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. You can combine it with other filters — for example, negative coverage from US, British and German publishers in the health category: ``` curl "https://api.apitube.io/v1/news/everything?sentiment.overall.polarity=negative&source.country.code=us,gb,de&category.id=medtop:07000000&api_key=YOUR_API_KEY" ``` # Common Questions[#](#common-questions) * [What country codes does APITube accept?](#what-country-codes-does-apitube-accept) * [How many countries can I request at once?](#how-many-countries-can-i-request-at-once) * [What error do I get for an invalid country code?](#what-error-do-i-get-for-an-invalid-country-code) * [Does source.country.code filter by where the news happened?](#does-sourcecountrycode-filter-by-where-the-news-happened) ## What country codes does APITube accept?[#](#what-country-codes-does-apitube-accept) APITube accepts two-letter country codes such as `us`, `gb`, `de`, `jp` or `fr`. Each code must be exactly two characters. The full set is on the [list of countries](https://docs.apitube.io/platform/news-api/list-of-countries) in the documentation. ## How many countries can I request at once?[#](#how-many-countries-can-i-request-at-once) Up to three per request, in both `source.country.code` and `ignore.source.country.code`. Codes beyond the third are ignored, so a request like `source.country.code=us,gb,de,fr` only applies `us,gb,de`. ## What error do I get for an invalid country code?[#](#what-error-do-i-get-for-an-invalid-country-code) A code that is not exactly two characters returns HTTP 400 with error `ER0246` (or `ER0247` for the ignore variant). A well-formed two-letter code that does not exist in APITube returns HTTP 400 with `ER0212` (`ER0213` for ignore) and a message like `source country code 'xx' not found`. ## Does source.country.code filter by where the news happened?[#](#does-sourcecountrycode-filter-by-where-the-news-happened) No. `source.country.code` matches the country of the publishing source, not the location a story covers. To filter by the place an event happened, use the location parameters (`location.lat`/`location.lng`/`location.radius`, `location.bbox`) or the `/v1/news/local` endpoint. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) --- ## How to Filter News by Date Range URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-date-range Use published_at.start and published_at.end to filter APITube News API results to a date range — with absolute dates, ISO 8601 timestamps or relative NOW-7DAYS… # How to Filter News by Date Range Limit results to a time window with published\_at.start and published\_at.end ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 Updated July 29, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&published_at_start=2024-01-01&published_at_end=2024-01-31) # How to filter news by date range[#](#how-to-filter-news-by-date-range) To limit results to a time window, add the `published_at.start` and `published_at.end` parameters to your request. Both bounds are **inclusive**, and either one can be left off to leave that side of the range open. This request returns articles published in January 2024: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2024-01-01&published_at.end=2024-01-31&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Dates without a time zone are read as UTC midnight, so `2024-01-01` means `2024-01-01T00:00:00` UTC. ## What parameters set a date range?[#](#what-parameters-set-a-date-range) APITube has three optional date parameters, and they all accept the same value formats: * `published_at.start` — the earliest publication date to include (inclusive). * `published_at.end` — the latest publication date to include (inclusive). * `published_at` — a single day. The API returns every article published during that whole 24-hour day, from `00:00:00` up to the same time the next day. Use `start` and `end` together for a window, or pass just one of them for an open-ended search. Sending only `published_at.start` means “from this date onward”, and only `published_at.end` means “up to this date”. ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2024-06-01&api_key=YOUR_API_KEY" ``` ## Which date formats are accepted?[#](#which-date-formats-are-accepted) `published_at.start`, `published_at.end` and `published_at` all accept absolute dates in several formats: * `2024-12-25` — `YYYY-MM-DD` * `2024-12-25T10:30:00Z` — ISO 8601 with time, in UTC * `2024-12-25T10:30:00+03:00` — ISO 8601 with a time-zone offset * `25-12-2024` — `DD-MM-YYYY` * `25.12.2024` — `DD.MM.YYYY` * `1735084800` — a Unix timestamp in seconds Each value must be between 1 and 30 characters long. A `YYYY-MM-DD` date with no time is anchored to midnight UTC. ## How do I use relative dates like the last 7 days?[#](#how-do-i-use-relative-dates-like-the-last-7-days) Instead of hard-coding a calendar date, you can pass a relative, Solr-style expression that APITube resolves at request time. This returns articles from the last 7 days: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` The supported relative forms are: * `NOW` — the current moment. * `NOW-7DAYS`, `NOW+1MONTH` — an offset before or after now. * `NOW/DAY`, `NOW/MONTH` — rounded down to the start of that period, in UTC. * `NOW-1DAY/DAY` — an offset combined with rounding (here, the start of yesterday). * `7DAYS`, `1WEEK`, `2MONTHS` — a bare amount, read as that long ago. * `1w`, `3d`, `4h`, `5y` — short aliases for week, day, hour and year. The available units are hours, days, weeks, months and years. So “everything since the start of this month” is `published_at.start=NOW/MONTH`, and “all of yesterday” is: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=NOW-1DAY/DAY&published_at.end=NOW/DAY&api_key=YOUR_API_KEY" ``` ## How do I sort articles within the range by date?[#](#how-do-i-sort-articles-within-the-range-by-date) Results are sorted by `published_at` in descending order — newest first — by default. To read the oldest matching articles first, add `sort.order=asc` — see [how to sort news by relevance, date or quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) for every ordering mode: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=NOW-30DAYS&sort.by=published_at&sort.order=asc&api_key=YOUR_API_KEY" ``` A date range combines with any other filter, so you can scope a feed to a time window and a language at once. For language filtering, see [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). The full date syntax also lives in the canonical [parameter reference](https://docs.apitube.io/platform/news-api/everything). ## Is there a maximum width for a date range?[#](#is-there-a-maximum-width-for-a-date-range) The range is unlimited **unless the same request also searches article headlines**. A request filtered by `category.id`, `entity.id`, `source.domain`, `language.code`, [sentiment](/en/articles/getting-started/glossary#sentiment) or any other non-headline parameter can span the whole archive in one call — `published_at.start=2020-01-01` with no end date is a valid request. Add a headline filter and a **31-day ceiling** kicks in. The parameters that trigger it are `title`, `title_starts_with`, `title_ends_with`, `title_pattern` and the Boolean `query`. Three outcomes are possible: Request Result Headline filter, no `published_at` dates at all Runs against the last 31 days. HTTP 200 with warning `ER0366` in `meta.warnings` and header `x-query-window-clamped: 31` Headline filter, `start` and `end` 31 days apart or less Runs exactly as written Headline filter, range wider than 31 days HTTP 400 with error `ER0110` The open-ended form deserves care here, because it interacts with the ceiling in a way that is easy to miss: `published_at.start=2024-01-01` on its own means “from that date until now”, so paired with a `title` filter it is a multi-year window and returns `ER0110`. Give an archive search an explicit `published_at.end` within the same month and it goes through. ``` # 200 — archive month, headline filter, window inside the ceiling curl "https://api.apitube.io/v1/news/everything?title=inflation&published_at.start=2026-05-01&published_at.end=2026-05-31&api_key=YOUR_API_KEY" ``` The reason is cost: articles are stored partitioned by publication month, so the date range decides how much of the archive a headline search has to read, and a year-wide window reads nearly all of it. See [how to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title) for the headline-search side of this rule and the month-by-month pattern for longer periods. # Common Questions[#](#common-questions) * [Are the start and end dates inclusive?](#are-the-start-and-end-dates-inclusive) * [What does the single published\_at parameter return?](#what-does-the-single-published_at-parameter-return) * [Can I leave one side of the range open?](#can-i-leave-one-side-of-the-range-open) * [What error do I get for an invalid date?](#what-error-do-i-get-for-an-invalid-date) * [Does the 31-day ceiling apply to the single published\_at parameter?](#does-the-31-day-ceiling-apply-to-the-single-published_at-parameter) ## Are the start and end dates inclusive?[#](#are-the-start-and-end-dates-inclusive) Yes. An article published exactly on `published_at.start` or `published_at.end` is kept in the results — the filter uses inclusive bounds on both ends. ## What does the single published\_at parameter return?[#](#what-does-the-single-published_at-parameter-return) `published_at=2024-12-25` returns every article published during that day, from `2024-12-25T00:00:00` up to `2024-12-26T00:00:00`. Use it when you want one specific calendar day rather than a range built from `start` and `end`. ## Can I leave one side of the range open?[#](#can-i-leave-one-side-of-the-range-open) Yes. Send only `published_at.start` for “from this date onward”, or only `published_at.end` for “up to this date”. The bound you omit stays open, so the other limit alone decides the results. One exception: if the request also filters headlines, an open `published_at.start` older than 31 days exceeds the search-window ceiling and returns `ER0110`. An open `published_at.end` is always safe — the missing start is filled in 31 days before it. ## What error do I get for an invalid date?[#](#what-error-do-i-get-for-an-invalid-date) A value that is not a recognized format returns HTTP 400 with an error code: `ER0104` for a bad `published_at.start`, `ER0106` for `published_at.end`, and `ER0109` for `published_at`. Correct the value to one of the supported formats and retry. ## Does the 31-day ceiling apply to the single published\_at parameter?[#](#does-the-31-day-ceiling-apply-to-the-single-published_at-parameter) No. `published_at=2024-12-25` selects one calendar day, which is already inside the ceiling, so it is never rejected and never triggers the `ER0366` warning — even together with a headline filter. Use it whenever you want a specific day of the archive searched by headline: `title=inflation&published_at=2024-12-25` is a valid request no matter how old the date is. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to Sort News by Relevance, Date or Quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) * [How to Search News by Title](/en/articles/searching-and-filtering/keyword-search/search-by-title) --- ## How to Find News Near a Coordinate or Bounding Box URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius Search the APITube News API for articles near a point with location.lat, location.lng and location.radius, or inside a rectangle with location.bbox. # How to Find News Near a Coordinate or Bounding Box Geo-search APITube News with location.lat, location.lng, location.radius and location.bbox ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&location_lat=52.52&location_lng=13.40&location_radius=50) # How to find news near a coordinate or bounding box[#](#how-to-find-news-near-a-coordinate-or-bounding-box) To find news near a point, send `location.lat`, `location.lng` and `location.radius` (in kilometers) to the APITube News API. The request below returns articles within 50 km of central Berlin: ``` curl "https://api.apitube.io/v1/news/everything?location.lat=52.52&location.lng=13.40&location.radius=50&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. These geographic filters are part of the shared filter chain, so they work on the standard `/v1/news/everything` search — you are **not** limited to the dedicated `/v1/news/local` endpoint. ## How does radius search work?[#](#how-does-radius-search-work) Radius search needs three parameters together: `location.lat` (latitude, −90 to 90), `location.lng` (longitude, −180 to 180) and `location.radius` (the distance in kilometers). The radius is measured from the `lat`/`lng` center point, and `location.radius` accepts any positive number up to 20000 km. APITube matches every article whose attached coordinates fall inside that circle. If you send a radius without both coordinates, the request fails with HTTP 400 and error `ER0406` (`location.lat and location.lng are required when using radius filters`). An out-of-range latitude returns `ER0407`, an out-of-range longitude returns `ER0408`, and a radius that is zero, negative or above 20000 km returns `ER0409`. ## How to run a ring search with a minimum radius[#](#how-to-run-a-ring-search-with-a-minimum-radius) To exclude the area immediately around your center point — a “ring” or “doughnut” search — add `location.radius.min`. With both bounds set, APITube returns articles whose distance is greater than `location.radius.min` and less than or equal to `location.radius`. This finds news between 20 km and 100 km of Berlin, skipping the inner city: ``` curl "https://api.apitube.io/v1/news/everything?location.lat=52.52&location.lng=13.40&location.radius.min=20&location.radius=100&api_key=YOUR_API_KEY" ``` `location.radius.min` also works on its own: sent without `location.radius`, it returns everything farther than that minimum distance. The minimum must be smaller than the maximum, otherwise the request returns `ER0411`. If you send neither `location.radius` nor `location.radius.min` while using coordinates, you get `ER0412`. ## How to search inside a bounding box[#](#how-to-search-inside-a-bounding-box) When you want a rectangle instead of a circle, use `location.bbox` with four comma-separated values in the order `minLat,maxLat,minLng,maxLng`. This example covers the New York City area: ``` curl "https://api.apitube.io/v1/news/everything?location.bbox=40.0,45.0,-74.0,-73.0&api_key=YOUR_API_KEY" ``` The bounding box must contain exactly four numbers, or the request returns `ER0400`. Latitudes outside −90 to 90 return `ER0401` and longitudes outside −180 to 180 return `ER0402`. The minimum latitude must not exceed the maximum (`ER0403`), and the same rule applies to longitude (`ER0404`). A bounding box is the simplest way to constrain results to a city, metro region or country shape. ## How to keep only articles that have coordinates[#](#how-to-keep-only-articles-that-have-coordinates) Not every article carries geographic coordinates. To filter purely on coordinate presence — without a circle or rectangle — use `has_location_geo`. Send `has_location_geo=1` to keep only geotagged articles, or `has_location_geo=0` to keep only articles without coordinates: ``` curl "https://api.apitube.io/v1/news/everything?has_location_geo=1&api_key=YOUR_API_KEY" ``` Any value other than `0` or `1` returns `ER0405`. This is useful as a pre-filter before mapping results, since articles with no coordinates cannot be plotted. ## What do geo coordinates look like in the response?[#](#what-do-geo-coordinates-look-like-in-the-response) Each article includes a `locations_mentioned` array describing the places detected in it. Every entry carries a `name`, a `country` code, the `lat` and `lng` coordinates, and a `type`: ``` { "locations_mentioned": [ { "name": "Berlin", "country": "de", "lat": 52.52, "lng": 13.40, "type": "..." } ] } ``` These are the same coordinates the radius and bounding-box filters match against, so you can map results directly without a separate geocoding step. ## Which endpoints support geo filtering?[#](#which-endpoints-support-geo-filtering) The geographic filters belong to the shared filter chain, so `location.lat`/`location.lng`/`location.radius`, `location.bbox` and `has_location_geo` all work on `/v1/news/everything` and the other search and retrieval endpoints that run the chain. APITube also ships a purpose-built `/v1/news/local` endpoint for geo-targeted queries. You can combine geo filters with any other parameter — for example, recent English coverage near Berlin: ``` curl "https://api.apitube.io/v1/news/everything?location.lat=52.52&location.lng=13.40&location.radius=50&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` See [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) and [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) to layer those filters on top, and the [parameters reference](https://docs.apitube.io/platform/news-api/everything) for the full list. # Common Questions[#](#common-questions) * [What units is location.radius in?](#what-units-is-locationradius-in) * [What is the maximum radius I can search?](#what-is-the-maximum-radius-i-can-search) * [Why do I get error ER0406?](#why-do-i-get-error-er0406) * [Can I combine geo search with other filters?](#can-i-combine-geo-search-with-other-filters) ## What units is location.radius in?[#](#what-units-is-locationradius-in) `location.radius` and `location.radius.min` are both in kilometers. A value of `50` means a 50 km radius from the `location.lat`/`location.lng` center. You do not pass meters or miles — APITube converts kilometers internally when measuring distance to each article’s coordinates. ## What is the maximum radius I can search?[#](#what-is-the-maximum-radius-i-can-search) `location.radius` accepts any positive number up to 20000 km. A radius of zero, a negative number or anything above 20000 km returns HTTP 400 with error `ER0409`. The same 20000 km ceiling applies to `location.radius.min`, which additionally must be smaller than `location.radius`. ## Why do I get error ER0406?[#](#why-do-i-get-error-er0406) Error `ER0406` means you sent a radius parameter without both coordinates. `location.lat` and `location.lng` are required whenever you use `location.radius` or `location.radius.min`. Add both coordinates, and make sure latitude is between −90 and 90 (`ER0407`) and longitude is between −180 and 180 (`ER0408`). ## Can I combine geo search with other filters?[#](#can-i-combine-geo-search-with-other-filters) Yes. Geographic filters run inside the standard filter chain, so you can mix `location.lat`/`location.lng`/`location.radius` or `location.bbox` with language, date range, source, [sentiment](/en/articles/getting-started/glossary#sentiment) and sorting in the same request. Filters combine with AND logic, so each one narrows the result set further. For source-level narrowing, see [How to filter news by source](/en/articles/searching-and-filtering/by-attribute/filter-by-source). * * * ## Related Articles * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) --- ## How to Filter News by Industry URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-industry Use industry.id in the APITube News API to return only articles from a business sector — up to three numeric IDs at once with OR logic — plus… # How to Filter News by Industry Narrow News API results to a business sector with the industry.id parameter ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&industry_id=400) # How to filter news by industry[#](#how-to-filter-news-by-industry) To return only articles from a specific business sector, add the `industry.id` parameter to your `/v1/news/everything` request with a numeric industry identifier, for example `industry.id=400`. The APITube News API checks the ID against the industries it tracks and returns only articles tagged with that industry. You can pass up to three industry IDs separated by commas, and an article is returned if it is tagged with **any** of them (OR logic). ``` curl "https://api.apitube.io/v1/news/everything?industry.id=400&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `industry.id`, no industry filter is applied and articles from every sector are returned. ## What is the industry.id parameter?[#](#what-is-the-industryid-parameter) `industry.id` takes a numeric industry identifier such as `400`. The value must be an integer — a non-numeric value returns HTTP 400 with error `ER0121` (`Invalid industry.id value`). Each ID can be 1 to 20 characters long; an empty or over-length value returns HTTP 400 with error `ER0123`. Every ID is looked up against the industries APITube tracks, and if one is not found the request fails with HTTP 400 and error `ER0210` and a message like `industry with ID '999999' not found`. The request stops on the first unknown ID, so one bad value blocks the whole call. ## How is an industry different from a topic or category?[#](#how-is-an-industry-different-from-a-topic-or-category) An industry is a numeric sector tag filtered with `industry.id` (for example `400`). It is a different layer from a topic. A value like `industry.crypto_news` is **not** an industry ID — it is a [topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic), passed as `topic.id=industry.crypto_news`, and it uses a named slug rather than a number. A [category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) is yet another layer: a broad IPTC media-topic code such as `medtop:04000000`. The three can be combined in one request to scope by sector, subject and section at once. ## How to filter by one or more industries[#](#how-to-filter-by-one-or-more-industries) Pass a single ID to read one sector, or a comma-separated list to combine several. This request pulls articles tagged with either of two industries in one call: ``` curl "https://api.apitube.io/v1/news/everything?industry.id=400,438&api_key=YOUR_API_KEY" ``` The maximum is three industries per request. If you list more than three, only the first three are used and the rest are silently dropped. Industry filtering is part of the shared filter chain, so it combines with other filters and with sorting: ``` curl "https://api.apitube.io/v1/news/everything?industry.id=400,438&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` ## How to exclude an industry[#](#how-to-exclude-an-industry) To return everything **except** a sector, use `ignore.industry.id`. It follows the same rules — comma-separated, numeric, up to three values. This keeps general coverage while dropping articles from two industries: ``` curl "https://api.apitube.io/v1/news/everything?ignore.industry.id=400,438&api_key=YOUR_API_KEY" ``` A non-numeric value in `ignore.industry.id` returns `ER0124`, an empty or over-length value returns `ER0126`, and an unknown ID returns `ER0211` — all HTTP 400. You can pass `industry.id` and `ignore.industry.id` in the same request to include one sector while excluding another. ## How to find a valid industry ID[#](#how-to-find-a-valid-industry-id) Use the `/v1/suggest/industries` endpoint to look up an industry before you filter. Pass a `prefix` and it returns matching industries, each with its numeric `id`, its `name` and a ready-made `links.self` URL: ``` curl "https://api.apitube.io/v1/suggest/industries?prefix=energy&api_key=YOUR_API_KEY" ``` The `prefix` parameter is required; omitting it returns HTTP 400 with error `ER0346`. Take the `id` from a result and drop it straight into `industry.id`. The full set of supported industries is also listed in the [APITube industries reference](https://docs.apitube.io/platform/news-api/list-of-industries). ## What does the industries object in the response contain?[#](#what-does-the-industries-object-in-the-response-contain) Every article in the response carries an `industries` array so you can see which sectors it was tagged with and reuse them: ``` { "industries": [ { "id": 400, "name": "Financial Services", "links": { "self": "https://api.apitube.io/v1/news/industry/400" } } ] } ``` The `id` here is exactly the integer you pass back into `industry.id` for follow-up requests, and `name` is the human-readable label. The `links.self` URL points at the `/v1/news/industry/{id}` endpoint, which returns articles for that industry directly. To pin a sector to one subject at the same time, combine it with [How to filter news by topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic). # Common Questions[#](#common-questions) * [How many industries can I filter by at once?](#how-many-industries-can-i-filter-by-at-once) * [Is industry.id a number or a name?](#is-industryid-a-number-or-a-name) * [What error do I get for an unknown industry?](#what-error-do-i-get-for-an-unknown-industry) * [How do I discover available industry IDs?](#how-to-find-a-valid-industry-id) ## How many industries can I filter by at once?[#](#how-many-industries-can-i-filter-by-at-once) Up to three per parameter. `industry.id` and `ignore.industry.id` each accept a comma-separated list, and only the first three values are applied — extra values beyond the third are silently ignored. Multiple IDs in one parameter use OR logic, so an article matches if it is tagged with any of them. ## Is industry.id a number or a name?[#](#is-industryid-a-number-or-a-name) A number. `industry.id` accepts only numeric IDs such as `400`; a non-numeric value returns HTTP 400 with error `ER0121`. Do not confuse it with `topic.id=industry.crypto_news`, which is a named topic slug, not an industry. Look up the numeric ID with `/v1/suggest/industries` before filtering. ## What error do I get for an unknown industry?[#](#what-error-do-i-get-for-an-unknown-industry) An industry ID that APITube does not track returns HTTP 400 with error `ER0210` (`industry with ID '…' not found`) for `industry.id`, or `ER0211` for `ignore.industry.id`. A non-numeric value returns `ER0121` (`ER0124` for the ignore variant), and an empty or over-length value returns `ER0123` (`ER0126`). Because the request stops on the first bad ID, confirm the industry with `/v1/suggest/industries` before filtering. * * * ## Related Articles * [How to Filter News by Topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) --- ## How to Filter News by Language URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-language Use the language.code parameter to return APITube News API articles in specific languages — up to three at once, comma-separated, with OR logic. # How to Filter News by Language Restrict News API results to one or more languages with language.code ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 Updated July 31, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en) # How to filter news by language[#](#how-to-filter-news-by-language) To return news in a specific language, add the `language.code` parameter to your request with an [ISO 639-1](https://docs.apitube.io/platform/news-api/list-of-languages) language code, for example `language.code=en`. You can pass up to three codes separated by commas, and articles in **any** of those languages are returned (OR logic). ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&api_key=YOUR_API_KEY" ``` You can also send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `language.code` entirely, no language filter is applied and articles in all detected languages are returned. ## What is the language.code parameter?[#](#what-is-the-languagecode-parameter) `language.code` takes one or more ISO 639-1 codes — the two-letter codes like `en` (English), `fr` (French), `de` (German), `es` (Spanish), `ja` (Japanese) or `zh` (Chinese). Each code must be one or two characters long. The value is case-insensitive, so `EN` and `en` behave the same way. One convenience alias exists: `us` is treated as `en`. Sending `language.code=us` returns English articles, which is handy when you map a country code straight into the language field. ## How to request a single language[#](#how-to-request-a-single-language) Pass a single code to keep results in one language. This request returns only French articles: ``` curl "https://api.apitube.io/v1/news/everything?language.code=fr&api_key=YOUR_API_KEY" ``` Every article in the response carries a `language` field with its ISO 639-1 code, so you can confirm what you received: ``` { "id": 123456789, "title": "…", "language": "fr" } ``` ## How to request multiple languages at once[#](#how-to-request-multiple-languages-at-once) Separate codes with commas to match articles in **any** of the listed languages. This pulls English, Japanese and German articles in a single call: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en,ja,de&api_key=YOUR_API_KEY" ``` The maximum is three languages per request. If you list more than three, only the first three are used — the rest are silently dropped, so keep the list to three meaningful codes. ## How to exclude a language with ignore.language.code[#](#how-to-exclude-a-language-with-ignorelanguagecode) To keep everything **except** certain languages, use `ignore.language.code`. It follows the same rules — comma-separated, up to three codes. This excludes French articles while returning all other languages: ``` curl "https://api.apitube.io/v1/news/everything?ignore.language.code=fr&api_key=YOUR_API_KEY" ``` `language.code` and `ignore.language.code` can be combined with other filters. A common pattern is to drop both a country and its language at the same time: ``` curl "https://api.apitube.io/v1/news/everything?ignore.source.country.code=fr&ignore.language.code=fr&api_key=YOUR_API_KEY" ``` For more on country filtering, see [How to filter news by country and location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location). ## Which endpoints support language filtering?[#](#which-endpoints-support-language-filtering) Language filtering is part of the shared filter chain, so it works on the main search and retrieval endpoints, including `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. You can also combine it with sorting and source quality, for example to read high-authority business coverage across three languages: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en,ja,de&source.rank.opr.min=6&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` # Common Questions[#](#common-questions) * [What language codes does APITube accept?](#what-language-codes-does-apitube-accept) * [How many languages can I request at once?](#how-many-languages-can-i-request-at-once) * [What error do I get for an invalid language code?](#what-error-do-i-get-for-an-invalid-language-code) * [Does language.code translate articles?](#does-languagecode-translate-articles) ## What language codes does APITube accept?[#](#what-language-codes-does-apitube-accept) APITube accepts ISO 639-1 codes that are one or two characters long, such as `en`, `fr`, `de` or `zh`. The full set is on the [list of supported languages](https://docs.apitube.io/platform/news-api/list-of-languages) in the documentation. The alias `us` resolves to `en`. ## How many languages can I request at once?[#](#how-many-languages-can-i-request-at-once) Up to three per request, in both `language.code` and `ignore.language.code`. Codes beyond the third are ignored, so a request like `language.code=en,fr,de,es` only applies `en,fr,de`. ## What error do I get for an invalid language code?[#](#what-error-do-i-get-for-an-invalid-language-code) A code that is empty or longer than two characters returns HTTP 400 with error `ER0061` (or `ER0063` for the ignore variant). A well-formed code that does not exist in APITube returns HTTP 400 with `ER0237` (`ER0239` for ignore) and a message like `language with code 'xx' not found`. ## Does language.code translate articles?[#](#does-languagecode-translate-articles) No. `language.code` filters articles by the language they were originally published and detected in — it does not change the text you get back. The English translation is delivered separately in each article’s `translations.en` block regardless of this filter, so a `language.code=de` request returns German text in `title`/`body`, plus an English version of the headline and description in `translations.en`. See [How APITube handles languages and translation](/en/articles/news-data/languages-and-translation). * * * ## Related Articles * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Filter News by Country and Location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location) * [How APITube handles languages and translation](/en/articles/news-data/languages-and-translation) --- ## How to Filter News by Source or Domain URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-source Use source.domain or source.id to restrict APITube News API results to specific publishers — up to three at once — and ignore.source.* to exclude them. # How to Filter News by Source or Domain Limit News API results to specific publishers with source.domain and source.id ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 Updated July 7, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_domain=theguardian.com) # How to filter news by source or domain[#](#how-to-filter-news-by-source-or-domain) To return articles only from specific publishers, add the `source.domain` parameter with one or more website domains, for example `source.domain=theguardian.com`. You can pass up to three domains separated by commas, and articles from **any** of those sources are returned (OR logic). Each domain must match a publisher APITube already tracks. ``` curl "https://api.apitube.io/v1/news/everything?source.domain=theguardian.com&api_key=YOUR_API_KEY" ``` You can also send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `source.domain`, no source filter is applied and articles from all publishers are returned. ## What is the source.domain parameter?[#](#what-is-the-sourcedomain-parameter) `source.domain` takes one or more publisher domains, like `nytimes.com` or `bbc.co.uk`. The value is case-insensitive, so `NYTimes.com` and `nytimes.com` behave the same. Each domain may be 1 to 255 characters long; anything outside that range returns HTTP 400 with error `ER0057`. Every domain you pass is matched against the publishers APITube tracks. If a domain is not in the directory, the request fails with HTTP 400 and error `ER0214` and a message like `source domain name 'example.com' not found` — the whole request stops, so one unknown domain blocks the entire call. That is why it pays to confirm a domain exists first (see below). ## How to filter by one or more domains[#](#how-to-filter-by-one-or-more-domains) Pass a single domain to read just that publisher, or a comma-separated list to combine several. This request pulls articles from three newspapers in one call: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=theguardian.com,foxnews.com,nytimes.com&api_key=YOUR_API_KEY" ``` The maximum is three domains per request. If you list more than three, only the first three are used and the rest are silently dropped, so keep the list to three meaningful domains. Source filtering is part of the shared filter chain, so it also combines with other filters and with sorting: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=theguardian.com,nytimes.com&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` ## How to filter by source ID instead of domain[#](#how-to-filter-by-source-id-instead-of-domain) Every publisher also has a numeric `source.id`. Filtering by ID avoids domain typos and survives a publisher changing its domain. Pass up to three IDs, comma-separated: ``` curl "https://api.apitube.io/v1/news/everything?source.id=12345,67890&api_key=YOUR_API_KEY" ``` Each ID must be a non-negative integer of 1 to 20 characters. A non-numeric value returns `ER0050`, a negative value returns `ER0051`, and an out-of-range length returns `ER0052` — all HTTP 400. ## How to exclude specific sources[#](#how-to-exclude-specific-sources) To return everything **except** certain publishers, use `ignore.source.domain` or `ignore.source.id`. Both follow the same rules — comma-separated, up to three values. This excludes two tabloids while keeping all other sources: ``` curl "https://api.apitube.io/v1/news/everything?ignore.source.domain=foxnews.com,nypost.com&api_key=YOUR_API_KEY" ``` As with the positive filters, an unknown domain in `ignore.source.domain` returns `ER0215`, so the excluded domains must also be tracked publishers. ## How to find a source’s domain or ID[#](#how-to-find-a-sources-domain-or-id) You already have the `source.domain` — it is simply the publisher’s website address, such as `theguardian.com`. To get the numeric `source.id`, run any search filtered by that domain and read the `id` from the `source` object on a returned article (shown below); that `id` stays stable even if the publisher later moves to a new domain. You can also filter by a publisher’s country with `source.country.code` (a two-letter code, up to three) — see [How to filter news by country and location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location). ## What does the source object in the response contain?[#](#what-does-the-source-object-in-the-response-contain) Every article in the response carries a `source` object so you can confirm where it came from: ``` { "source": { "id": 12345, "domain": "theguardian.com", "home_page_url": "https://www.theguardian.com", "type": "news", "rankings": { "opr": 7 }, "location": { "country_name": "United Kingdom", "country_code": "gb" } } } ``` The `id` and `domain` here are exactly the values you pass back into `source.id` and `source.domain` for follow-up requests. To narrow results to a single language at the same time, combine source filtering with [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). # Common Questions[#](#common-questions) * [How many sources can I filter by at once?](#how-many-sources-can-i-filter-by-at-once) * [Should I use source.domain or source.id?](#should-i-use-sourcedomain-or-sourceid) * [What error do I get for an unknown domain?](#what-error-do-i-get-for-an-unknown-domain) * [Can I include and exclude sources in the same request?](#can-i-include-and-exclude-sources-in-the-same-request) ## How many sources can I filter by at once?[#](#how-many-sources-can-i-filter-by-at-once) Up to three per parameter. `source.domain`, `source.id`, `ignore.source.domain` and `ignore.source.id` each accept a comma-separated list, and only the first three values are applied — extra values beyond the third are silently ignored. ## Should I use source.domain or source.id?[#](#should-i-use-sourcedomain-or-sourceid) Both target the same publishers. `source.domain` is easier to read and write because you use the website address directly. `source.id` is more stable: it is a fixed numeric identifier that does not change even if a publisher moves to a new domain. To translate a domain into its `id`, filter a search by `source.domain` and read the `id` from the `source` object in any returned article. ## What error do I get for an unknown domain?[#](#what-error-do-i-get-for-an-unknown-domain) A domain that APITube does not track returns HTTP 400 with error `ER0214` (`source domain name '…' not found`) for `source.domain`, or `ER0215` for `ignore.source.domain`. A domain shorter than 1 or longer than 255 characters returns `ER0057` (`ER0059` for the ignore variant). Because the request stops on the first bad domain, double-check each domain (for example by running a search filtered on it) before relying on it. ## Can I include and exclude sources in the same request?[#](#can-i-include-and-exclude-sources-in-the-same-request) Yes. `source.domain` and `ignore.source.domain` can be combined with each other and with other filters such as `language.code`, `published_at.start` or `category.id`. The positive filter limits results to the listed publishers, and the ignore filter removes any you do not want from whatever remains. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Country and Location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location) * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) --- ## How to Filter News by Topic URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute/filter-by-topic Use topic.id in the APITube News API to return only articles about a subject like industry.crypto_news — up to three at once with OR logic — plus… # How to Filter News by Topic Narrow News API results to a subject with the topic.id parameter ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&topic_id=industry.crypto_news) # How to filter news by topic[#](#how-to-filter-news-by-topic) To return only articles about a specific subject, add the `topic.id` parameter to your `/v1/news/everything` request with a topic identifier, for example `topic.id=industry.crypto_news`. The APITube News API matches it against the topics it tracks and returns only articles tagged with that topic. You can pass up to three topic IDs separated by commas, and articles tagged with **any** of them are returned (OR logic). ``` curl "https://api.apitube.io/v1/news/everything?topic.id=industry.crypto_news&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `topic.id`, no topic filter is applied and articles on every topic are returned. ## What is the topic.id parameter?[#](#what-is-the-topicid-parameter) `topic.id` takes a topic identifier such as `industry.crypto_news` — a named subject tag, not a free-text keyword. Each value may be up to 80 characters; an empty or over-length value returns HTTP 400 with error `ER0117`. Every ID is looked up against the topics APITube tracks, and if one is not found the request fails with HTTP 400 and error `ER0208` and a message like `topic with ID 'foo' not found`. The whole request stops on the first unknown topic, so one bad ID blocks the entire call. Topics are a different layer from categories. A topic like `industry.crypto_news` is a specific subject tag, while a [category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) is an IPTC media-topic code such as `medtop:04000000`. You can use both in the same request to combine a broad section with a precise subject. ## How to filter by one or more topics[#](#how-to-filter-by-one-or-more-topics) Pass a single topic to read just that subject, or a comma-separated list to combine several. This request pulls articles tagged with either of two topics in one call: ``` curl "https://api.apitube.io/v1/news/everything?topic.id=industry.crypto_news,industry.financial_news&api_key=YOUR_API_KEY" ``` The maximum is three topics per request. If you list more than three, only the first three are used and the rest are silently dropped. Topic filtering is part of the shared filter chain, so it combines with other filters and with sorting: ``` curl "https://api.apitube.io/v1/news/everything?topic.id=industry.crypto_news&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` ## How to exclude a topic[#](#how-to-exclude-a-topic) To return everything **except** a subject, use `ignore.topic.id`. It follows the same rules — comma-separated, up to three values. This keeps general coverage while dropping crypto stories: ``` curl "https://api.apitube.io/v1/news/everything?ignore.topic.id=industry.crypto_news&api_key=YOUR_API_KEY" ``` As with the positive filter, an unknown ID in `ignore.topic.id` returns `ER0209`, and an empty or over-length value returns `ER0120` — both HTTP 400. You can pass `topic.id` and `ignore.topic.id` in the same request to include one subject while excluding another. ## How to find a valid topic.id[#](#how-to-find-a-valid-topicid) Use the `/v1/suggest/topics` endpoint to look up topics before you filter. Pass a `prefix` and it returns matching topics, each with its `id`, `name` and a ready-made `links.self` URL: ``` curl "https://api.apitube.io/v1/suggest/topics?prefix=crypto&api_key=YOUR_API_KEY" ``` The `prefix` parameter is required; omitting it returns HTTP 400 with error `ER0346`. Take the `id` from a result and drop it straight into `topic.id`. The full set of supported topics is also listed in the [APITube topics reference](https://docs.apitube.io/platform/news-api/list-of-topics). ## What does the topics object in the response contain?[#](#what-does-the-topics-object-in-the-response-contain) Every article in the response carries a `topics` array so you can see which subjects it was tagged with and reuse them: ``` { "topics": [ { "id": "industry.crypto_news", "name": "Crypto News", "score": 0.82, "links": { "self": "https://api.apitube.io/v1/news/topic/industry.crypto_news" } } ] } ``` The `id` here is exactly the value you pass back into `topic.id` for follow-up requests, `name` is the human-readable label, and `score` reflects how strongly the article matches that topic. The `links.self` URL points at the `/v1/news/topic/{id}` endpoint, which returns articles for that topic directly. To pin a topic to one publisher at the same time, combine it with [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source). # Common Questions[#](#common-questions) * [How many topics can I filter by at once?](#how-many-topics-can-i-filter-by-at-once) * [What is the difference between a topic and a category?](#what-is-the-difference-between-a-topic-and-a-category) * [What error do I get for an unknown topic?](#what-error-do-i-get-for-an-unknown-topic) * [How do I discover available topic IDs?](#how-to-find-a-valid-topicid) ## How many topics can I filter by at once?[#](#how-many-topics-can-i-filter-by-at-once) Up to three per parameter. `topic.id` and `ignore.topic.id` each accept a comma-separated list, and only the first three values are applied — extra values beyond the third are silently ignored. Multiple topics in one parameter use OR logic, so an article matches if it is tagged with any of them. ## What is the difference between a topic and a category?[#](#what-is-the-difference-between-a-topic-and-a-category) A topic is a specific subject tag such as `industry.crypto_news`, filtered with `topic.id`. A category is a broad IPTC media-topic code such as `medtop:04000000`, filtered with `category.id` (see [How to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category)). Use a category to scope a whole section like business, and a topic to zero in on a narrower subject within or across sections. Both can be combined in one request. ## What error do I get for an unknown topic?[#](#what-error-do-i-get-for-an-unknown-topic) A topic ID that APITube does not track returns HTTP 400 with error `ER0208` (`topic with ID '…' not found`) for `topic.id`, or `ER0209` for `ignore.topic.id`. An empty value or one longer than 80 characters returns `ER0117` (`ER0120` for the ignore variant). Because the request stops on the first bad ID, confirm the topic with `/v1/suggest/topics` before filtering. * * * ## Related Articles * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) --- ## Filter by Attributes URL: https://support.apitube.io/en/articles/searching-and-filtering/by-attribute Narrow APITube News API results by language, country, location, date, source, category, topic, industry and author. # Filter by Attributes Language, country, date, source and more. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Tasha 1 author 9 articles * [How to Filter News by Author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Filter News by Country and Location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Filter News by Industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to Filter News by Topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic) * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) --- ## How to Exclude Paywalled or Duplicate Articles URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates Remove paywalled and duplicate stories from APITube News API results using the is_paywall=0 and is_duplicate=0 parameters, plus the is_high_quality shortcut. # How to Exclude Paywalled or Duplicate Articles Use is\_paywall=0 and is\_duplicate=0 to keep only freely readable, unique articles ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&is_paywall=0&is_duplicate=0) # How to exclude paywalled or duplicate articles[#](#how-to-exclude-paywalled-or-duplicate-articles) To drop stories that sit behind a publisher paywall, add `is_paywall=0`; to drop near-identical reprints of the same story, add `is_duplicate=0`. Both parameters accept exactly `0` or `1`. Send them together to get a clean feed of freely readable, unique articles: ``` curl "https://api.apitube.io/v1/news/everything?is_paywall=0&is_duplicate=0&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Without these two parameters no paywall or duplicate filter is applied, so paywalled and duplicate articles come back mixed in with everything else. ## How does is\_paywall=0 work?[#](#how-does-is_paywall0-work) `is_paywall=0` keeps only articles that are freely readable on the source website, and `is_paywall=1` does the opposite — it returns only articles locked behind the publisher’s paywall. The flag describes the **article itself**: whether the original story sits behind a paywall on the source site. It is not a flag about your APITube plan, and it does not change how much article body your key receives. ``` curl "https://api.apitube.io/v1/news/everything?is_paywall=0&api_key=YOUR_API_KEY" ``` Any value other than `0` or `1` is rejected with a `400` error: a non-numeric value returns error code `ER0005`, and a number that is not `0` or `1` returns `ER0006` with the message that `is_paywall` must be 0 or 1. ## How does is\_duplicate=0 work?[#](#how-does-is_duplicate0-work) `is_duplicate=0` removes articles that APITube has flagged as duplicates — a reprint or syndicated copy of the same story — and returns the versions that are not flagged. Duplicate flagging is a best-effort heuristic, so it will not catch every reprint; treat `is_duplicate=0` as a way to reduce repeats rather than a guarantee of fully unique results. Flip it to `is_duplicate=1` to return **only** the flagged duplicates instead, which is useful when you want to see how widely a single story was picked up. ``` curl "https://api.apitube.io/v1/news/everything?is_duplicate=0&api_key=YOUR_API_KEY" ``` Like the paywall flag, `is_duplicate` accepts only `0` or `1`. A non-numeric value returns error code `ER0003`, and a number that is not `0` or `1` returns `ER0004`. ## How to combine both into one clean feed[#](#how-to-combine-both-into-one-clean-feed) The two parameters stack with each other and with the rest of the filter chain using AND logic, so each one narrows the results further. A common pattern is “unique, freely readable articles from high-ranked sources in one topic”: ``` curl "https://api.apitube.io/v1/news/everything?is_paywall=0&is_duplicate=0&source.rank.opr.min=6&category.id=medtop:04000000&api_key=YOUR_API_KEY" ``` You can layer any other filter on top. To restrict by the publishing outlet as well, see [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source). The full parameter list lives in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Is there a shortcut for clean, high-quality results?[#](#is-there-a-shortcut-for-clean-high-quality-results) Yes. `is_high_quality=1` is a bundle that, among other conditions, already excludes duplicates for you: it keeps only articles that are not duplicates, come from a higher-ranked source, carry at least one image, and have a named author. Use it when you want one flag instead of stacking several: ``` curl "https://api.apitube.io/v1/news/everything?is_high_quality=1&api_key=YOUR_API_KEY" ``` `is_high_quality` accepts only `0` or `1`; any other value returns error code `ER0303`. Because the bundle already pins `is_duplicate=0`, you only need to add `is_paywall=0` on top if you also want to drop paywalled stories. ## How do I confirm a result is free and unique?[#](#how-do-i-confirm-a-result-is-free-and-unique) Each article in the response carries an `is_free` boolean and an `is_duplicate` boolean, so you can check the flags on every result you receive. Watch the naming difference: the paywall **filter** is `is_paywall`, but the **response field** that reports paywall status is `is_free`. So an article returned by `is_paywall=0` comes back with its `is_free` field set to `true`, and an article kept by `is_duplicate=0` comes back with `is_duplicate` set to `false`. ## Which endpoints support these filters?[#](#which-endpoints-support-these-filters) `is_paywall` and `is_duplicate` belong to the shared filter chain, so they behave the same way on the main search and retrieval endpoints — including `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/count`. Because `/v1/news/count` runs the same chain, you can measure how many unique, non-paywalled articles match before downloading any of them by sending the same parameters to that endpoint. See [How to count matching articles without downloading them](/en/articles/retrieval/count-articles). # Common Questions[#](#common-questions) * [What happens if I leave these parameters out?](#what-happens-if-i-leave-these-parameters-out) * [Does is\_paywall depend on my subscription plan?](#does-is_paywall-depend-on-my-subscription-plan) * [What does is\_duplicate=1 return?](#what-does-is_duplicate1-return) * [Why am I getting a 400 error on is\_paywall?](#why-am-i-getting-a-400-error-on-is_paywall) ## What happens if I leave these parameters out?[#](#what-happens-if-i-leave-these-parameters-out) When you omit `is_paywall` and `is_duplicate`, no paywall or duplicate filter is applied, so the response includes paywalled articles and duplicate copies alongside everything else. Add `is_paywall=0` and `is_duplicate=0` to remove them. ## Does is\_paywall depend on my subscription plan?[#](#does-is_paywall-depend-on-my-subscription-plan) No. `is_paywall` describes the source article — whether the original story is behind the publisher’s paywall — not your APITube plan. It is an attribute of the article, so `is_paywall=0` and `is_paywall=1` simply split results by that attribute. ## What does is\_duplicate=1 return?[#](#what-does-is_duplicate1-return) `is_duplicate=1` returns only the articles APITube flagged as duplicates of another story, instead of hiding them. It is the inverse of `is_duplicate=0`, which returns only the unique versions. ## Why am I getting a 400 error on is\_paywall?[#](#why-am-i-getting-a-400-error-on-is_paywall) `is_paywall` accepts only `0` or `1`. A non-numeric value returns error code `ER0005`, and a number outside `0`/`1` returns `ER0006`. The duplicate flag behaves the same way, returning `ER0003` and `ER0004` respectively. * * * ## Related Articles * [How to Find News Articles With Images or Videos](/en/articles/searching-and-filtering/content-quality/filter-by-media) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) --- ## How to Filter by Media Quality and Social-Ready Images URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-by-media-quality Filter APITube News API articles by image resolution and social-ready dimensions with has_hq_images, has_4k_images, is_instagram_ready and… # How to Filter by Media Quality and Social-Ready Images Keep only articles with high-resolution, Instagram- or Twitter-ready images using the News API media filters ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&has_hq_images=1) # How to filter by media quality and social-ready images[#](#how-to-filter-by-media-quality-and-social-ready-images) To return only articles whose images meet a quality bar, add a media flag such as `has_hq_images=1` (images at least 1200px wide) to your News API request. For example, this keeps articles that carry a high-quality image: ``` curl "https://api.apitube.io/v1/news/everything?has_hq_images=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Every media flag is a `0`/`1` toggle: pass `1` to require the condition. Each of these filters runs on the shared filter chain, so the same parameters work on `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/count`. ## How to filter by image resolution[#](#how-to-filter-by-image-resolution) Three flags gate articles by the width of their largest image, each with a fixed pixel threshold: * `has_hq_images=1` — at least one image is 1200px wide or more. * `has_fullhd_images=1` — at least one image reaches Full HD width (1920px+). * `has_4k_images=1` — at least one image reaches 4K width (3840px+). This request returns only articles that ship a 4K-width image: ``` curl "https://api.apitube.io/v1/news/everything?has_4k_images=1&api_key=YOUR_API_KEY" ``` There is also `has_mobile_optimized_images=1`, which matches articles whose largest image sits in the 320–800px range — handy when you want lightweight images for a mobile feed rather than the biggest file available. ## What does is\_media\_rich actually require?[#](#what-does-is_media_rich-actually-require) `is_media_rich=1` is stricter than it sounds: it matches articles that contain **both** at least one image **and** at least one video. It is not a “lots of images” flag — an article with ten photos and no video will not match `is_media_rich=1`. Use it when you specifically need mixed image-and-video coverage: ``` curl "https://api.apitube.io/v1/news/everything?is_media_rich=1&api_key=YOUR_API_KEY" ``` If you only care about images or only about videos, use `has_image=1` or `has_video=1` instead, or set explicit counts with `media.images.count.min` and `media.videos.count.min`. ## How to find Instagram- and Twitter-ready images[#](#how-to-find-instagram--and-twitter-ready-images) Two flags pre-check images against social-platform dimensions so you don’t have to inspect pixels yourself: * `is_instagram_ready=1` — at least 1080px wide with a roughly square or 4 portrait aspect ratio. * `is_twitter_card_ready=1` — at least 800px wide and landscape (wider than it is tall). There is also `has_social_share_image=1`, which matches Open Graph–compatible images that are at least 1200×630px — the size used for link previews when an article is shared. To pull recent articles that already have a share-ready preview image: ``` curl "https://api.apitube.io/v1/news/everything?has_social_share_image=1&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` ## How to set exact image dimensions and counts[#](#how-to-set-exact-image-dimensions-and-counts) When the preset flags aren’t precise enough, control the numbers directly. The `media.images.count` parameter (plus `.min` and `.max` variants) bounds how many images an article must have, and `media.images.width.min/max` and `media.images.height.min/max` bound their pixel size: ``` curl "https://api.apitube.io/v1/news/everything?media.images.count.min=2&media.images.width.min=1200&media.images.height.min=630&api_key=YOUR_API_KEY" ``` This returns articles with two or more images, each pipeline-measured at 1200px wide and 630px tall or larger. Related flags refine shape and quantity: `has_multiple_images=1` requires two or more images, while `is_landscape_media=1` and `is_portrait_media=1` filter by orientation, and `has_thumbnail=1` requires a small image (300px wide or less) to exist. ## What values do the media filters accept?[#](#what-values-do-the-media-filters-accept) Every boolean media flag accepts only `0` or `1`. Passing anything else — for example `has_4k_images=2` — returns an HTTP 400 with a specific error code (`ER0254` for `has_4k_images`, `ER0233` for `is_media_rich`, and so on). The numeric parameters like `media.images.count` must be non-negative integers, otherwise the request also fails with a 400. These filters stack with any other filter, so you can combine media quality with bias, language or category in one call — see [How to filter news by source political bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) for a stacking example, and the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) for the full list. # Common Questions[#](#common-questions) * [Does is\_media\_rich mean “has many images”?](#does-is_media_rich-mean-has-many-images) * [Which pixel widths do the resolution flags use?](#which-pixel-widths-do-the-resolution-flags-use) * [Can I combine media filters with other filters?](#can-i-combine-media-filters-with-other-filters) * [What happens if I pass an invalid value?](#what-happens-if-i-pass-an-invalid-value) ## Does is\_media\_rich mean “has many images”?[#](#does-is_media_rich-mean-has-many-images) No. `is_media_rich=1` requires an article to have at least one image and at least one video together. An article with many images but no video does not match. For image-only or video-only needs, use `has_image=1`, `has_video=1`, or explicit `media.images.count.min` / `media.videos.count.min` values. ## Which pixel widths do the resolution flags use?[#](#which-pixel-widths-do-the-resolution-flags-use) `has_hq_images` checks for an image 1200px wide or wider, `has_fullhd_images` for 1920px+, and `has_4k_images` for 3840px+. `is_instagram_ready` needs 1080px+ with a square or 4 ratio, `is_twitter_card_ready` needs 800px+ landscape, and `has_social_share_image` needs at least 1200×630px. ## Can I combine media filters with other filters?[#](#can-i-combine-media-filters-with-other-filters) Yes. The media filters run in the same shared filter chain as language, source, category and [sentiment](/en/articles/getting-started/glossary#sentiment) filters, so you can stack them freely in a single request. For example, you can require a 4K image and [read time](/en/articles/searching-and-filtering/content-quality/filter-by-readtime-readability) together, or filter for high-quality images in one language sorted newest-first. ## What happens if I pass an invalid value?[#](#what-happens-if-i-pass-an-invalid-value) A boolean flag with a value other than `0` or `1` returns an HTTP 400 and a filter-specific error code (such as `ER0254` for `has_4k_images`). A numeric parameter such as `media.images.count` that is not a valid non-negative integer also returns a 400, so the request fails fast instead of silently ignoring the value. * * * ## Related Articles * [How to Filter News by Source Political Bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Filter News by Read Time and Readability](/en/articles/searching-and-filtering/content-quality/filter-by-readtime-readability) --- ## How to Find News Articles With Images or Videos URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-by-media Filter APITube News API results to articles that contain images or videos using has_image, has_video and the media.images.count / media.videos.count parameters. # How to Find News Articles With Images or Videos Use has\_image, has\_video and the media.\* parameters to keep only articles that carry visual media ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&has_image=1) # How to find news articles with images or videos[#](#how-to-find-news-articles-with-images-or-videos) To keep only articles that contain a picture, add `has_image=1`; to keep only those with a video, add `has_video=1`. Both are flags that accept exactly `0` or `1`. This request returns recent articles that have at least one image: ``` curl "https://api.apitube.io/v1/news/everything?has_image=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Without these flags, no media filter is applied and articles with or without media are returned together. ## How do has\_image and has\_video work?[#](#how-do-has_image-and-has_video-work) `has_image=1` matches articles whose image count is at least one, and `has_video=1` matches articles whose video count is at least one. Set the flag to `0` to do the opposite: `has_image=0` returns only articles that have **no** images, and `has_video=0` only articles with no videos. Any value other than `0` or `1` is rejected with a `400` error — `has_image` returns error code `ER0041` and `has_video` returns `ER0042`, both with the message that the flag must be 0 or 1. Every article in the response carries a `media` array. Each entry in that array has a `url` and a `type`, so once results come back you can read the media attached to each article directly. ## How to require an exact or minimum number of images[#](#how-to-require-an-exact-or-minimum-number-of-images) Use `media.images.count` to match an **exact** image count — `media.images.count=3` returns only articles that have exactly three images, not three or more. This is the most common surprise with the parameter, so reach for the range variants when you want a threshold: ``` curl "https://api.apitube.io/v1/news/everything?media.images.count.min=2&api_key=YOUR_API_KEY" ``` `media.images.count.min` matches articles with at least that many images, and `media.images.count.max` caps the count. The same three forms exist for video: `media.videos.count`, `media.videos.count.min` and `media.videos.count.max`. Mixing a minimum and a maximum builds a range — for example, between two and five images: ``` curl "https://api.apitube.io/v1/news/everything?media.images.count.min=2&media.images.count.max=5&api_key=YOUR_API_KEY" ``` ## How to find articles with both images and a video[#](#how-to-find-articles-with-both-images-and-a-video) Set `is_media_rich=1` to require an article to carry at least one image **and** at least one video at the same time. It is a single shortcut for the common “fully illustrated” case: ``` curl "https://api.apitube.io/v1/news/everything?is_media_rich=1&api_key=YOUR_API_KEY" ``` ## How to filter for high-resolution images[#](#how-to-filter-for-high-resolution-images) Two flags raise the bar on image resolution. `has_hq_images=1` keeps articles whose largest image is at least 1200 pixels wide, and `has_4k_images=1` requires a width of at least 3840 pixels. Both accept only `0` or `1`. This pulls articles with high-quality artwork suitable for large layouts: ``` curl "https://api.apitube.io/v1/news/everything?has_hq_images=1&api_key=YOUR_API_KEY" ``` ## How to combine media filters with other parameters[#](#how-to-combine-media-filters-with-other-parameters) Media parameters stack with each other and with the rest of the filter chain using AND logic — every condition you add narrows the results further. A practical pattern is “articles with a picture, newest first, sorted by how many images they carry”: ``` curl "https://api.apitube.io/v1/news/everything?has_image=1&sort.by=media.images.count&sort.order=desc&api_key=YOUR_API_KEY" ``` You can layer any other filter on top. To restrict by the publishing source as well, see [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source); to narrow by the political lean of those sources, see [How to filter news by source political bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias). All media parameters are listed in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Which endpoints support the media filters?[#](#which-endpoints-support-the-media-filters) The media filters belong to the shared filter chain, so they work the same way on the main search and retrieval endpoints — including `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/count`. Because `/v1/news/count` runs the same chain, you can count how many articles carry media without downloading them by sending the same parameters to that endpoint. # Common Questions[#](#common-questions) * [Does has\_image=1 mean exactly one image?](#does-has_image1-mean-exactly-one-image) * [Why does media.images.count=3 return so few results?](#why-does-mediaimagescount3-return-so-few-results) * [How do I find articles with no media?](#how-do-i-find-articles-with-no-media) * [What does is\_media\_rich require?](#what-does-is_media_rich-require) ## Does has\_image=1 mean exactly one image?[#](#does-has_image1-mean-exactly-one-image) No. `has_image=1` matches articles with **at least one** image, not exactly one. To pin an exact count use `media.images.count`, and to set a floor use `media.images.count.min`. ## Why does media.images.count=3 return so few results?[#](#why-does-mediaimagescount3-return-so-few-results) `media.images.count` is an exact match, so `media.images.count=3` only returns articles with precisely three images. If you meant “three or more”, switch to `media.images.count.min=3` instead. ## How do I find articles with no media?[#](#how-do-i-find-articles-with-no-media) Send `has_image=0` to return articles with no images, or `has_video=0` for articles with no videos. Both flags accept only `0` or `1`; any other value returns a `400` error (`ER0041` for `has_image`, `ER0042` for `has_video`). ## What does is\_media\_rich require?[#](#what-does-is_media_rich-require) `is_media_rich=1` requires an article to have at least one image **and** at least one video together. If you only need one or the other, use `has_image=1` or `has_video=1` instead. * * * ## Related Articles * [How to Filter News by Source Political Bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) --- ## How to Filter News by Read Time and Readability URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-by-readtime-readability Filter APITube News API results by estimated reading time in minutes and by readability scores like Flesch Reading Ease, grade level, difficulty and target… # How to Filter News by Read Time and Readability Use read\_time and readability parameters to match articles by length and reading difficulty ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&read_time_max=4&is_easy_read=1) # How to filter news by read time and readability[#](#how-to-filter-news-by-read-time-and-readability) To match articles by length, add the `read_time` parameter (estimated reading time **in minutes**); to match by reading difficulty, add a `readability.*` parameter such as `readability.ease`. For example, `read_time.max=4` keeps only short articles, and `is_easy_read=1` keeps only articles that are easy to read. ``` curl "https://api.apitube.io/v1/news/everything?read_time.max=4&is_easy_read=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Both the read-time and readability filters are part of the shared filter chain, so they work together with every other filter in a single request. ## How to filter news by reading time[#](#how-to-filter-news-by-reading-time) `read_time` matches articles by their estimated reading time in minutes. Use the exact form `read_time`, or bound a range with `read_time.min` and `read_time.max`: ``` curl "https://api.apitube.io/v1/news/everything?read_time.min=2&read_time.max=6&api_key=YOUR_API_KEY" ``` The request above returns articles that take between 2 and 6 minutes to read. There are also five convenience flags so you don’t have to remember the cut-offs — each maps to a fixed range in minutes: * `is_quick_read=1` — read time of 2 minutes or less * `is_short_read=1` — read time under 3 minutes * `is_medium_read=1` — read time of 3 to 7 minutes * `is_long_read=1` — read time of 5 minutes or more * `is_deep_dive=1` — read time of 10 minutes or more Each flag accepts `0` or `1`; passing a value of `1` applies the filter. Every article in the response carries a top-level `read_time` field (in minutes), so you can confirm the length of each result. ## How to filter news by readability score[#](#how-to-filter-news-by-readability-score) The `readability.*` family filters articles by how hard the text is to read, using three standard metrics. Each metric supports an exact match plus a `.min` / `.max` range: * `readability.ease` — Flesch Reading Ease, a 0–100 score where **higher means easier**. `readability.ease.min=60` keeps plain-language articles. * `readability.fk_grade` — Flesch-Kincaid Grade Level, 0–30, where the value is roughly the US school grade needed to follow the text. Lower is easier. * `readability.ari` — Automated Readability Index, 0–30, another grade-level estimate. ``` curl "https://api.apitube.io/v1/news/everything?readability.ease.min=60&readability.fk_grade.max=10&api_key=YOUR_API_KEY" ``` For the two convenience shortcuts based on Flesch Reading Ease, `is_easy_read=1` keeps articles scoring 60 or above, and `is_difficult_read=1` keeps articles scoring below 40. Each result includes a `readability` object with `flesch_reading_ease`, `flesch_kincaid_grade` and `automated_readability_index`, so you can see the exact scores behind the filter. ## How to filter by difficulty level, audience and reading age[#](#how-to-filter-by-difficulty-level-audience-and-reading-age) Two categorical parameters group articles without you having to pick a numeric cut-off. `readability.difficulty` accepts `beginner`, `intermediate`, `advanced` or `expert` (case-insensitive). `readability.audience` accepts `children`, `general`, `professional` or `academic`: ``` curl "https://api.apitube.io/v1/news/everything?readability.audience=general&readability.difficulty=intermediate&api_key=YOUR_API_KEY" ``` You can also target a recommended reader age with `readability.age`, or a range with `readability.age.min` and `readability.age.max`, accepting values from 6 to 22. The response `readability` object exposes the matching `difficulty_level`, `target_audience` and `reading_age` for each article. ## How to sort and combine read time with other filters[#](#how-to-sort-and-combine-read-time-with-other-filters) `read_time` is also a valid sort key. This request returns easy-to-read general-audience articles, shortest first: ``` curl "https://api.apitube.io/v1/news/everything?is_easy_read=1&readability.audience=general&sort.by=read_time&sort.order=asc&api_key=YOUR_API_KEY" ``` Because these filters share the chain with language, date, source and bias filters, you can stack them freely. To narrow the language of the results, see [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language); to bias the source lean, see [How to filter news by source political bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias). Full definitions live in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Which endpoints support read time and readability?[#](#which-endpoints-support-read-time-and-readability) Both filter families run in the shared filter chain, so they work on `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/entity`, on both `GET` (query string) and `POST` (request body) requests. # Common Questions[#](#common-questions) * [What unit is read\_time measured in?](#what-unit-is-read_time-measured-in) * [What is the difference between readability.ease and readability.fk\_grade?](#what-is-the-difference-between-readabilityease-and-readabilityfk_grade) * [What happens if I pass an invalid value?](#what-happens-if-i-pass-an-invalid-value) * [Can I combine read time and readability in one request?](#can-i-combine-read-time-and-readability-in-one-request) ## What unit is read\_time measured in?[#](#what-unit-is-read_time-measured-in) `read_time`, `read_time.min` and `read_time.max` are all measured in **minutes**, and so are the convenience flags. For example, `is_deep_dive=1` matches articles with a read time of 10 minutes or more. ## What is the difference between readability.ease and readability.fk\_grade?[#](#what-is-the-difference-between-readabilityease-and-readabilityfk_grade) `readability.ease` is the Flesch Reading Ease score on a 0–100 scale where **higher values are easier** to read. `readability.fk_grade` is the Flesch-Kincaid Grade Level, where a lower value means easier text. They measure the same underlying difficulty from opposite directions, so a high `readability.ease` value usually corresponds to a low `readability.fk_grade` value. ## What happens if I pass an invalid value?[#](#what-happens-if-i-pass-an-invalid-value) Unlike some filters that silently ignore bad input, the read-time and readability filters validate their values. A non-numeric `read_time`, or a `readability.difficulty` outside `beginner`, `intermediate`, `advanced` and `expert`, returns an `HTTP 400` error with a specific code (for example `ER0187` for an invalid `read_time`) rather than running the search. Check the value before retrying. ## Can I combine read time and readability in one request?[#](#can-i-combine-read-time-and-readability-in-one-request) Yes. Read-time and readability parameters run in the same filter chain, so you can apply several at once — for instance `read_time.max=6` together with `is_easy_read=1` — to return short, plain-language articles in a single call. * * * ## Related Articles * [How to Filter News by Source Political Bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) --- ## How to Filter News by Source Political Bias URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-by-source-bias Use the source.bias parameter to return APITube News API articles from left, center or right-leaning sources — up to three values, comma-separated, with OR… # How to Filter News by Source Political Bias Restrict News API results to left, center or right-leaning sources with source.bias ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_bias=center) # How to filter news by the political bias of the source[#](#how-to-filter-news-by-the-political-bias-of-the-source) To return news from sources of a specific political lean, add the `source.bias` parameter with one of three values — `left`, `center` or `right`. For example, `source.bias=center` returns only articles published by center-leaning sources. ``` curl "https://api.apitube.io/v1/news/everything?source.bias=center&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `source.bias`, no bias filter is applied and articles from sources of any lean are returned. ## What is the source.bias parameter?[#](#what-is-the-sourcebias-parameter) `source.bias` filters articles by the political lean assigned to the publishing source. It accepts exactly three values — `left`, `center` and `right` — and the value is case-insensitive, so `LEFT` and `left` behave the same. Filtering by `source.bias` only matches sources that have an assigned lean; sources with no bias classification are not included in a bias-filtered request. The same three values work in the reverse direction through `ignore.source.bias`, which excludes a lean instead of requiring it. Both parameters are documented in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## How to filter for a single political lean[#](#how-to-filter-for-a-single-political-lean) Pass one value to keep results from a single lean. This request returns only articles from left-leaning sources: ``` curl "https://api.apitube.io/v1/news/everything?source.bias=left&api_key=YOUR_API_KEY" ``` Every article in the response carries a `source` object that includes a `bias` field, so you can confirm the lean of each result you receive. ## How to combine multiple biases in one request[#](#how-to-combine-multiple-biases-in-one-request) Separate values with commas to match articles from **any** of the listed leans (OR logic). This pulls center and right-leaning coverage in a single call: ``` curl "https://api.apitube.io/v1/news/everything?source.bias=center,right&api_key=YOUR_API_KEY" ``` The maximum is three values per request. Since there are only three possible leans, `source.bias=left,center,right` is the same as applying no bias filter at all — it matches every classified source. ## How to exclude a bias with ignore.source.bias[#](#how-to-exclude-a-bias-with-ignoresourcebias) To keep everything **except** a certain lean, use `ignore.source.bias`. It follows the same rules — comma-separated, up to three values. This excludes left-leaning sources while returning center and right coverage: ``` curl "https://api.apitube.io/v1/news/everything?ignore.source.bias=left&api_key=YOUR_API_KEY" ``` `source.bias` combines with any other filter. A common pattern is to read recent center-leaning coverage in one language, newest first: ``` curl "https://api.apitube.io/v1/news/everything?source.bias=center&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` For language filtering, see [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language); to bound the time window, see [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## Which endpoints support source.bias?[#](#which-endpoints-support-sourcebias) `source.bias` is part of the shared source filter chain, so it works on the main search and retrieval endpoints, including `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/count`. Each of these accepts the parameter on both `GET` (query string) and `POST` (request body) requests. # Common Questions[#](#common-questions) * [Which bias values does source.bias accept?](#which-bias-values-does-sourcebias-accept) * [How many biases can I request at once?](#how-many-biases-can-i-request-at-once) * [What happens if I pass an invalid bias value?](#what-happens-if-i-pass-an-invalid-bias-value) * [Does source.bias work together with other filters?](#does-sourcebias-work-together-with-other-filters) ## Which bias values does source.bias accept?[#](#which-bias-values-does-sourcebias-accept) `source.bias` accepts three values: `left`, `center` and `right`. These are the only recognized leans — there is no separate “unbiased” or “neutral” value. The same three apply to `ignore.source.bias`. ## How many biases can I request at once?[#](#how-many-biases-can-i-request-at-once) Up to three per request, in both `source.bias` and `ignore.source.bias`. Because there are only three leans in total, listing all three is equivalent to not filtering by bias. ## What happens if I pass an invalid bias value?[#](#what-happens-if-i-pass-an-invalid-bias-value) An unrecognized value, such as `source.bias=neutral`, returns HTTP 400 with error code `ER0294` and the message `source.bias must be one of: left, center, right.`. The check covers every value in a comma-separated list, so `source.bias=left,neutral` fails as well rather than quietly filtering on `left` alone. The `ignore.source.bias` parameter behaves the same way and reports `ER0295`. ## Does source.bias work together with other filters?[#](#does-sourcebias-work-together-with-other-filters) Yes. `source.bias` runs in the same filter chain as language, date, source domain, category and [sentiment](/en/articles/getting-started/glossary#sentiment) filters, so you can stack it freely. For example, you can combine `source.bias` with `language.code` and `sort.by` to read the newest center-leaning English coverage in a single request. * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Detect and Filter Clickbait Articles URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-clickbait Detect clickbait with is_clickbait=1 or exclude it with is_clickbait=0 in the APITube News API, and tune the title-vs-body gap with sentiment_gap.min/max. # How to Detect and Filter Clickbait Articles Surface or hide clickbait with is\_clickbait and the sentiment\_gap parameters ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 26, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&is_clickbait=1&category_id=medtop%3A04000000) # How to detect and filter clickbait[#](#how-to-detect-and-filter-clickbait) To find or hide clickbait, add the `is_clickbait` parameter to a News API request. `is_clickbait=1` returns articles whose headline emotion clashes with the body, while `is_clickbait=0` keeps only articles whose headline and body agree. For example, this returns suspected clickbait within a single category: ``` curl "https://api.apitube.io/v1/news/everything?is_clickbait=1&category.id=medtop:04000000&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `is_clickbait`, no clickbait filter is applied and articles are returned regardless of their headline-to-body [sentiment](/en/articles/getting-started/glossary#sentiment) match. ## What does the is\_clickbait parameter do?[#](#what-does-the-is_clickbait-parameter-do) `is_clickbait` is a sentiment-mismatch heuristic, not a machine-learning label. An article is treated as clickbait when its title sentiment **polarity differs** from its body polarity **and** the title carries strong emotion — specifically when the absolute title sentiment score is greater than `0.5`. In plain terms: an emotionally charged headline sitting on top of a differently-toned story. `is_clickbait=1` returns those mismatched articles. `is_clickbait=0` returns the opposite set — articles where the title and body polarity match, or where the title is only mildly emotional. The parameter accepts exactly two values, `0` or `1`; any other value returns HTTP 400 with error code `ER0342` (`is_clickbait must be 0 or 1.`). ## How to find clickbait articles[#](#how-to-find-clickbait-articles) Set `is_clickbait=1` to surface headlines that oversell or misrepresent the story underneath. Pair it with a category to focus the scan — `category.id` takes any IPTC Media Topic code (here `medtop:04000000`): ``` curl "https://api.apitube.io/v1/news/everything?is_clickbait=1&category.id=medtop:04000000&api_key=YOUR_API_KEY" ``` Each article in the response carries a `sentiment` object with separate `title` and `body` entries (each holding a `score` and `polarity`), so you can inspect the exact mismatch that flagged it. To pick a category ID, see [How to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category). ## How to exclude clickbait and keep consistent articles[#](#how-to-exclude-clickbait-and-keep-consistent-articles) For a cleaner feed, set `is_clickbait=0`. This keeps articles whose headline and body sentiment line up, dropping the sensationalized mismatches. Combine it with a trust signal such as `is_verified_source=1` to favour straight reporting: ``` curl "https://api.apitube.io/v1/news/everything?is_clickbait=0&is_verified_source=1&api_key=YOUR_API_KEY" ``` This is a good default for editorial digests, alerting, or any pipeline where a misleading headline would cause a false signal. ## How to tune sensitivity with sentiment\_gap[#](#how-to-tune-sensitivity-with-sentiment_gap) `is_clickbait` uses a fixed threshold, but you can measure the headline-to-body distance directly with `sentiment_gap`. The gap is the absolute difference between the title sentiment score and the body sentiment score, on a `0`–`2` scale, regardless of direction. Use `sentiment_gap.min` to require at least a certain mismatch: ``` curl "https://api.apitube.io/v1/news/everything?sentiment_gap.min=0.5&api_key=YOUR_API_KEY" ``` A higher `sentiment_gap.min` means a larger emotional disconnect between headline and body. Use `sentiment_gap.max` for the reverse — articles whose headline closely matches the body tone, optionally combined with a source-rank floor: ``` curl "https://api.apitube.io/v1/news/everything?sentiment_gap.max=0.2&source.rank.opr.min=5&api_key=YOUR_API_KEY" ``` Both bounds must be floats between `0` and `2`. Out-of-range values return `ER0344` (`sentiment_gap.min`) or `ER0249` (`sentiment_gap.max`); non-numeric values return `ER0343` or `ER0345`. ## How to combine clickbait detection with other filters[#](#how-to-combine-clickbait-detection-with-other-filters) `is_clickbait` and `sentiment_gap` stack with every other filter, so you can narrow by category, require an extra-wide gap, and sort by overall sentiment in one call: ``` curl "https://api.apitube.io/v1/news/everything?is_clickbait=1&category.id=medtop:11000000&sentiment_gap.min=0.3&sort.by=sentiment.overall.score&api_key=YOUR_API_KEY" ``` If you only care about whether the headline and body disagree — without the strong-emotion requirement of `is_clickbait` — use `sentiment.consistent=1` (matching polarity) or `sentiment.mixed=1` (differing polarity) instead. To strip out low-quality noise alongside clickbait, see [How to exclude paywalled or duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates). All three parameters are documented in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Which endpoints support is\_clickbait?[#](#which-endpoints-support-is_clickbait) `is_clickbait` and `sentiment_gap` run in the shared sentiment filter chain, so they work on the main search and retrieval endpoints — including `/v1/news/everything`, `/v1/news/top-headlines` and `/v1/news/count` — on both `GET` (query string) and `POST` (request body) requests. # Common Questions[#](#common-questions) * [What values does is\_clickbait accept?](#what-values-does-is_clickbait-accept) * [What is the difference between is\_clickbait and sentiment\_gap?](#what-is-the-difference-between-is_clickbait-and-sentiment_gap) * [Does is\_clickbait use a machine-learning model?](#does-is_clickbait-use-a-machine-learning-model) * [How do I just exclude clickbait from my feed?](#how-do-i-just-exclude-clickbait-from-my-feed) ## What values does is\_clickbait accept?[#](#what-values-does-is_clickbait-accept) `is_clickbait` accepts only `0` or `1`. Use `1` to return suspected clickbait and `0` to return articles whose headline and body sentiment are consistent. Any other value returns HTTP 400 with error code `ER0342`. ## What is the difference between is\_clickbait and sentiment\_gap?[#](#what-is-the-difference-between-is_clickbait-and-sentiment_gap) `is_clickbait=1` is a preset: it requires both a polarity mismatch and a strong title sentiment (absolute score above `0.5`). `sentiment_gap.min` and `sentiment_gap.max` instead let you set the exact title-to-body sentiment distance yourself, on a `0`–`2` scale, without the polarity-mismatch condition. Use `is_clickbait` for a one-shot flag and `sentiment_gap` when you need to dial sensitivity. ## Does is\_clickbait use a machine-learning model?[#](#does-is_clickbait-use-a-machine-learning-model) No. `is_clickbait` is a rule based on sentiment scores: it compares the title and body sentiment polarity and checks whether the title sentiment is strong. It does not run a dedicated clickbait classifier, so treat the results as a signal to review rather than a final verdict. ## How do I just exclude clickbait from my feed?[#](#how-do-i-just-exclude-clickbait-from-my-feed) Add `is_clickbait=0` to your request. It returns articles whose title and body sentiment agree (or whose headline is only mildly emotional), which removes the sensationalized mismatches from your results. Combine it with `is_verified_source=1` or a `source.rank.opr.min` floor for a stricter, cleaner feed. * * * ## Related Articles * [How to Filter News by Source Political Bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) --- ## How to Filter for High-Quality, Verified Sources URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources Use is_high_quality=1 in the APITube News API to keep only non-duplicate articles from well-ranked publishers (OPR 5+) that have an image and a named author. # How to Filter for High-Quality, Verified Sources Keep only non-duplicate, well-ranked articles with is\_high\_quality ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&is_high_quality=1) # How to filter for high-quality, verified sources[#](#how-to-filter-for-high-quality-verified-sources) To return only trustworthy articles in a single step, add `is_high_quality=1` to your `/v1/news/everything` request. The flag keeps articles that come from a well-ranked publisher ([OPR](/en/articles/getting-started/glossary#opr-open-pagerank) 5 or higher), are not duplicates, carry at least one image, and have a named author — one switch that screens out thin and low-quality content without listing domains by hand. ``` curl "https://api.apitube.io/v1/news/everything?is_high_quality=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. The flag accepts only `0` or `1`; any other value returns HTTP 400 with error `ER0303` (`is_high_quality must be 0 or 1.`). ## What does is\_high\_quality actually check?[#](#what-does-is_high_quality-actually-check) `is_high_quality=1` is a composite filter: an article is kept only when **all four** of these conditions are true at once. * **Not a duplicate** — the article is not flagged as a copy of another story. * **Well-ranked source** — the publisher’s OPR (Open Page Rank) is 5 or higher. * **Has an image** — the article carries at least one image. * **Has a named author** — a byline is attached to the article. Because every condition must pass, `is_high_quality` is stricter than a source-only filter: even a top-tier publisher is dropped if the specific article is a duplicate, has no image, or has no byline. Use it when you want clean, presentable results — for a feed, a newsletter, or a dataset — rather than maximum coverage. ## How is high-quality different from verified or premium sources?[#](#how-is-high-quality-different-from-verified-or-premium-sources) `is_high_quality` builds on the same source-authority bar as a verified source (OPR 5 and above) and then adds article-level checks (no duplicate, an image, a byline). The `is_verified_source` and `is_premium_source` flags look **only** at the publisher’s OPR — `is_verified_source=1` keeps OPR 5+ and drops duplicates, while `is_premium_source=1` keeps the top tier at OPR 6+. Neither one requires an image or an author. So pick `is_high_quality` when you care about the article itself being complete and clean; pick the source flags when you only care about publisher authority. For the source-only flags, see [how to filter for premium and verified sources](/en/articles/searching-and-filtering/content-quality/filter-premium-verified-sources). ## How to set your own source-rank floor[#](#how-to-set-your-own-source-rank-floor) `is_high_quality` fixes the OPR floor at 5. If you want a different cutoff, filter on the rank directly with `source.rank.opr.min` (and its companion `source.rank.opr.max`). OPR is scored on a 0–10 scale, so pass a whole number: ``` curl "https://api.apitube.io/v1/news/everything?is_high_quality=1&source.rank.opr.min=7&api_key=YOUR_API_KEY" ``` That keeps high-quality articles and raises the publisher floor to OPR 7. A non-numeric value returns `ER0044`, a negative value returns `ER0045`, and a value whose length is outside 1–10 characters returns `ER0046`. ## How to confirm why an article passed the filter[#](#how-to-confirm-why-an-article-passed-the-filter) Every article reports its publisher’s OPR under `source.rankings.opr`, so you can verify the rank that the filter checked: ``` { "source": { "domain": "example.com", "rankings": { "opr": 7 } } } ``` Pull a sample without the flag, read the `source.rankings.opr` values you are getting, then decide whether the built-in OPR-5 floor is enough or you want to raise it with `source.rank.opr.min`. ## How to combine high-quality with other filters[#](#how-to-combine-high-quality-with-other-filters) `is_high_quality` runs in the shared filter chain, so it stacks with every other parameter and with sorting. This returns the newest English high-quality articles about elections: ``` curl "https://api.apitube.io/v1/news/everything?is_high_quality=1&language.code=en&title=elections&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` If you only need the duplicate-removal part of the filter on its own, or want to drop paywalled articles too, see [how to exclude paywalled or duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates). # Common Questions[#](#common-questions) * [What values does is\_high\_quality accept?](#what-values-does-is_high_quality-accept) * [Does is\_high\_quality=0 filter anything?](#does-is_high_quality0-filter-anything) * [Why did a real article get dropped?](#why-did-a-real-article-get-dropped) ## What values does is\_high\_quality accept?[#](#what-values-does-is_high_quality-accept) Only `0` or `1`. Any other value returns HTTP 400 with error `ER0303` (`is_high_quality must be 0 or 1.`). Leave the parameter off entirely when you do not want the filter. ## Does is\_high\_quality=0 filter anything?[#](#does-is_high_quality0-filter-anything) No. Sending `is_high_quality=0` is accepted but applies no constraint — it does **not** return only low-quality articles. The four checks are added only when the value is `1`. ## Why did a real article get dropped?[#](#why-did-a-real-article-get-dropped) `is_high_quality` removes an article when any single condition fails: it is a duplicate, its source OPR is below 5, it has no image, or it has no named author. If you want trustworthy publishers but cannot accept losing image-less or author-less stories, use `source.rank.opr.min` for a pure source-rank floor instead of `is_high_quality`. * * * ## Related Articles * [How to Filter for Premium and Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-premium-verified-sources) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) --- ## How to Filter for Premium and Verified Sources URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality/filter-premium-verified-sources Use is_premium_source and is_verified_source in the APITube News API to keep only high-OPR publishers, and is_verified_source to also drop duplicate articles. # How to Filter for Premium and Verified Sources Keep only high-authority publishers with is\_premium\_source and is\_verified\_source ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&is_premium_source=1) # How to filter for premium and verified sources[#](#how-to-filter-for-premium-and-verified-sources) To keep only articles from high-authority publishers, add `is_premium_source=1` or `is_verified_source=1` to your `/v1/news/everything` request. Both flags filter on the source’s [OPR](/en/articles/getting-started/glossary#opr-open-pagerank) (Open Page Rank), a publisher-authority score on a 0–10 scale. `is_premium_source=1` keeps the strongest publishers (OPR 6 and above); `is_verified_source=1` is a slightly broader bar (OPR 5 and above) that also removes duplicate articles. ``` curl "https://api.apitube.io/v1/news/everything?is_premium_source=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Both flags accept only `0` or `1`; any other value returns HTTP 400, with error `ER0195` for `is_premium_source` and `ER0196` for `is_verified_source`. ## What is the difference between premium and verified sources?[#](#what-is-the-difference-between-premium-and-verified-sources) `is_premium_source` and `is_verified_source` both raise the OPR floor of your results, but to different levels. `is_premium_source=1` keeps articles whose source has an OPR of 6 or higher — the tightest authority filter. `is_verified_source=1` keeps sources with an OPR of 5 or higher **and** drops any article flagged as a duplicate, so it trades a little authority for de-duplicated coverage. Verified is the better default when you want trustworthy publishers without losing breadth; premium is for when you only want the top tier. OPR (Open Page Rank) is a publisher-authority metric scored from 0 to 10. A higher OPR means a more trustworthy source, so filtering by these flags is a fast way to screen out low-quality publishers without naming domains one by one. ## How to keep only premium sources[#](#how-to-keep-only-premium-sources) Set `is_premium_source=1` to require an OPR of 6 or higher. Because it runs in the shared filter chain, it combines with any other filter and with sorting: ``` curl "https://api.apitube.io/v1/news/everything?is_premium_source=1&language.code=en&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` That returns the newest English articles from top-tier publishers. The flag only acts when set to `1`: passing `is_premium_source=0` is accepted but applies no constraint (it does **not** return only non-premium sources), so leave the flag off entirely when you do not want to filter. ## How to keep verified sources and drop duplicates[#](#how-to-keep-verified-sources-and-drop-duplicates) Set `is_verified_source=1` to require an OPR of 5 or higher and exclude duplicate articles in a single step: ``` curl "https://api.apitube.io/v1/news/everything?is_verified_source=1&title=elections&api_key=YOUR_API_KEY" ``` The built-in duplicate removal is what separates `is_verified_source` from `is_premium_source`. If you specifically want to control duplicates on their own, or alongside paywalled content, see [how to exclude paywalled or duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates). ## How to set a custom OPR threshold[#](#how-to-set-a-custom-opr-threshold) If OPR 5 or 6 is not the cutoff you want, filter on the score directly with `source.rank.opr.min` (and its companion `source.rank.opr.max`). It compares against the same OPR value, so `source.rank.opr.min=6` is exactly equivalent to `is_premium_source=1`: ``` curl "https://api.apitube.io/v1/news/everything?source.rank.opr.min=7&api_key=YOUR_API_KEY" ``` `source.rank.opr.min` must be a number of 0 or greater (a non-numeric value returns `ER0044`, a negative value returns `ER0045`, and a value outside 1–10 characters returns `ER0046`). Use it to pick any floor on the 0–10 scale; use the `is_premium_source` / `is_verified_source` shortcuts when the standard cutoffs are enough. ## How to see a source’s OPR in the response[#](#how-to-see-a-sources-opr-in-the-response) Every article carries the publisher’s OPR under `source.rankings.opr`, so you can confirm why an article passed or failed the filter: ``` { "source": { "domain": "example.com", "rankings": { "opr": 7 } } } ``` Inspecting `source.rankings.opr` is the quickest way to calibrate your threshold: pull a sample without the flag, look at the OPR values you are getting, then set `is_premium_source`, `is_verified_source` or `source.rank.opr.min` accordingly. To screen publishers by their editorial slant instead of their authority, combine these flags with [source bias filtering](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias). # Common Questions[#](#common-questions) * [What OPR score does each flag require?](#what-is-the-difference-between-premium-and-verified-sources) * [Does is\_premium\_source=0 return non-premium sources?](#how-to-keep-only-premium-sources) * [Can I combine premium and verified with other filters?](#can-i-combine-premium-and-verified-with-other-filters) * [What error do these flags return for a bad value?](#what-error-do-these-flags-return-for-a-bad-value) ## Can I combine premium and verified with other filters?[#](#can-i-combine-premium-and-verified-with-other-filters) Yes. `is_premium_source` and `is_verified_source` run in the shared filter chain, so they stack with `language.code`, `title`, `published_at.start`/`published_at.end`, `source.bias` and the rest. You can also pass both flags together; because each only adds a constraint when set to `1`, sending `is_verified_source=1` with another filter simply narrows the same result set. ## What error do these flags return for a bad value?[#](#what-error-do-these-flags-return-for-a-bad-value) Both flags accept only `0` or `1`. Any other value returns HTTP 400: `is_premium_source` returns error `ER0195` (`is_premium_source must be 0 or 1`) and `is_verified_source` returns `ER0196` (`is_verified_source must be 0 or 1`). For the custom threshold parameter, a non-numeric `source.rank.opr.min` returns `ER0044` and an out-of-range length returns `ER0046`. * * * ## Related Articles * [How to Filter News by the Political Bias of the Source](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) --- ## Content & Quality URL: https://support.apitube.io/en/articles/searching-and-filtering/content-quality Filter APITube News API results by media quality, source bias, clickbait, paywall and duplicate status. # Content & Quality Filter by quality, bias, clickbait and paywall. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) By Beatrice 1 author 8 articles * [How to Detect and Filter Clickbait Articles](/en/articles/searching-and-filtering/content-quality/filter-clickbait) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) * [How to Filter by Media Quality and Social-Ready Images](/en/articles/searching-and-filtering/content-quality/filter-by-media-quality) * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [How to Filter for Premium and Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-premium-verified-sources) * [How to Filter News by Read Time and Readability](/en/articles/searching-and-filtering/content-quality/filter-by-readtime-readability) * [How to Filter News by Source Political Bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Find News Articles With Images or Videos](/en/articles/searching-and-filtering/content-quality/filter-by-media) --- ## How to Browse the Companies Directory URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/companies-directory Use the APITube News API /v1/companies endpoint to search a directory of organizations and brands by name or Wikidata ID, then open a profile for coverage… # How to Browse the Companies Directory Search organizations and brands with /v1/companies, then open one profile with /v1/companies/:id for Wikidata metadata, coverage stats and recent articles ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 23, 2026 # How to browse the companies directory and view profiles[#](#how-to-browse-the-companies-directory-and-view-profiles) Call `GET /v1/companies` to search a directory of organizations and brands, and `GET /v1/companies/:id` to open a single profile with Wikidata-enriched metadata, coverage statistics and recent articles. Filter the list by `name` or `wikidata_id`, page through it with `page` and `per_page`, then take the `id` from any result and request its profile or pass it back into a news search. ``` curl "https://api.apitube.io/v1/companies?name=Tesla&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. ## What is the companies directory?[#](#what-is-the-companies-directory) The companies directory is the set of organizations and brands APITube tracks as named [entities](/en/articles/getting-started/glossary#entity). Unlike the [people directory](/en/articles/searching-and-filtering/entities/people-directory), which returns only persons, `GET /v1/companies` returns two entity types at once: `organization` and `brand`. So a single result’s `type` field is either `organization` (a company, agency or institution) or `brand` (a product brand or label) — both live in this directory. It is the company-only view of the same entities you match in a search, so the `id` you read here is the exact value you pass back into a news query as `entity.id`. The list never mixes in people or locations. To pivot from a company straight to its news coverage, follow the `links.articles` URL on any record, which points to `/v1/news/entity/:id`. ## How to search companies by name or Wikidata ID[#](#how-to-search-companies-by-name-or-wikidata-id) `GET /v1/companies` accepts four query parameters: * `name` — filter by company name as a substring match (matches any record whose name contains the text). * `wikidata_id` — filter by a Wikidata ID, given as either `Q478214` or `478214`. * `page` — page number, starting at `1` (default `1`). * `per_page` — results per page, default `100`. The ceiling depends on your plan: `10` on Free, `50` on Starter, `200` on Basic, `250` on Professional and Corporate. ``` curl "https://api.apitube.io/v1/companies?name=Coca-Cola&per_page=20&api_key=YOUR_API_KEY" ``` Spaces in a name should be URL-encoded. A `per_page` above your plan’s ceiling returns HTTP 400 with error `ER0171` (“Limit is out of range.”), and the message names the limit that applies to your key; a non-numeric `page` returns `ER0172`. The response wraps the records in a small envelope: ``` { "status": "ok", "limit": 20, "page": 1, "has_next_pages": true, "results": [] } ``` `has_next_pages` is `true` only when a further record actually exists: the endpoint asks the database for `per_page + 1` rows and reports the extra one without returning it. A page that comes back exactly full is therefore still `false` when nothing follows it, so you never spend a request on an empty page. To walk the whole directory, keep incrementing `page` until `has_next_pages` is `false`. ## What does a company record contain?[#](#what-does-a-company-record-contain) Each entry in `results` (and the body of a single profile) shares the same shape: ``` { "id": 1580517, "name": "Tesla, Inc.", "type": "organization", "links": { "self": "https://api.apitube.io/v1/companies/1580517", "articles": "https://api.apitube.io/v1/news/entity/1580517", "wikipedia": "https://en.wikipedia.org/wiki/Tesla,_Inc.", "wikidata": "https://www.wikidata.org/wiki/Q478214" }, "profile": {} } ``` `id` is the numeric entity ID, `type` is `organization` or `brand`, and `links` gives you ready-made URLs: `self` for the profile, `articles` for coverage, plus `wikipedia` and `wikidata` (each an empty string when APITube has no link for that company). `profile` holds the Wikidata-enriched metadata — fields such as `headquarters` and `key_people` — and varies by company; it may be `null` when no metadata is stored. ## How to open a single company profile[#](#how-to-open-a-single-company-profile) Take the `id` and request `GET /v1/companies/:id`. The profile returns the same company fields plus two extra blocks: a `coverage` summary and `recent_articles`. ``` curl "https://api.apitube.io/v1/companies/1580517?api_key=YOUR_API_KEY" ``` If the ID does not exist, or it belongs to an entity that is not a company (not an `organization` or `brand`), the endpoint returns HTTP 404 with error `ER0151` (“Company not found.”). `recent_articles` is a list of up to 5 of the company’s most recent articles as full article objects; on a free plan or a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) the article body is truncated to a preview. ## What is in the coverage block?[#](#what-is-in-the-coverage-block) The `coverage` block aggregates how the company has appeared in the news. It includes: * `article_count` — total matching articles. * `first_seen` and `last_seen` — the earliest and latest article dates (`YYYY-MM-DD`, or `null`). * `sentiment` — counts of `positive`, `neutral` and `negative` coverage. * `momentum` — `last_30_days` vs `previous_30_days` plus a `change_pct`. * `timeline` — monthly counts (up to 24 months). * `top_sources`, `top_topics`, `top_countries`, `top_languages` and `related_entities` — each up to 10 entries with a `count`. ``` curl "https://api.apitube.io/v1/companies/1580517?coverage=false&api_key=YOUR_API_KEY" ``` Add `coverage=false` to skip the whole block when you only need the profile and recent articles — the request is lighter and returns no `coverage` key. For the full list of accepted parameters and values, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). ## How are companies directory requests billed?[#](#how-are-companies-directory-requests-billed) Each successful directory call costs one request. The single-profile endpoint (`/v1/companies/:id`) always charges one request when it returns a profile. The list endpoint (`/v1/companies`) only charges when it returns at least one match, so a search that finds nobody does not cost a request. Both endpoints require a valid [API key](/en/articles/getting-started/glossary#api-key) and reject missing or invalid keys with an authentication error. # Common Questions[#](#common-questions) * [How do I get the company ID to filter news?](#how-do-i-get-the-company-id-to-filter-news) * [What’s the difference between an organization and a brand?](#whats-the-difference-between-an-organization-and-a-brand) * [Why did a profile request return ER0151?](#why-did-a-profile-request-return-er0151) * [How do I skip the coverage statistics?](#how-do-i-skip-the-coverage-statistics) ## How do I get the company ID to filter news?[#](#how-do-i-get-the-company-id-to-filter-news) Search `GET /v1/companies?name=` for the company, read the `id` from the matching record, and pass it back into a news search as `entity.id`. The directory and the search filter use the same entity IDs, so the value is interchangeable and exact. You can also filter by name with `organization.name` or `brand.name`, but those expect an exact name match, so the numeric `entity.id` is the safer bridge. See [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) for the full filter syntax. ## What’s the difference between an organization and a brand?[#](#whats-the-difference-between-an-organization-and-a-brand) The companies directory returns both entity types together. An `organization` is a company, agency or institution; a `brand` is a product brand or label. The `type` field on each record tells you which one you are looking at. Both are searchable through `GET /v1/companies` and both expose the same record shape, so you rarely need to care about the distinction — but if you later filter news by name instead of ID, organizations use `organization.name` and brands use `brand.name`. ## Why did a profile request return ER0151?[#](#why-did-a-profile-request-return-er0151) `GET /v1/companies/:id` returns HTTP 404 with `ER0151` (“Company not found.”) when no entity has that ID, or when the ID belongs to an entity that is not a company — for example a person or a location. Confirm the ID by searching `GET /v1/companies` first, since that endpoint only ever lists organizations and brands. ## How do I skip the coverage statistics?[#](#how-do-i-skip-the-coverage-statistics) Append `coverage=false` to the profile request. The response then omits the `coverage` block entirely and still returns the company fields and `recent_articles`. Use it when you only need the company’s name, links and latest stories and do not want the aggregated counts and timeline. Note that this trims only a few kilobytes: `recent_articles` carries five **complete** article objects (body, entities and all), which is the bulk of a profile response — around 140 KB of a typical 170 KB reply. To turn the same ID into an ongoing feed, see [how to monitor news about a company or brand](/en/articles/searching-and-filtering/entities/monitor-company-news). * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) --- ## How to Use Entity Autocomplete in Search Inputs URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/entity-autocomplete Use the APITube /v1/suggest/entities endpoint to power a typeahead: pass a prefix and get matching people, companies and brands with the entity.id to filter on. # How to Use Entity Autocomplete in Search Inputs Build a typeahead with /v1/suggest/entities to turn what a user types into a stable entity.id ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 27, 2026 Updated July 7, 2026 # How to use entity autocomplete in search inputs[#](#how-to-use-entity-autocomplete-in-search-inputs) Call `GET /v1/suggest/entities` with a `prefix` to power an autocomplete (typeahead) box: as the user types, the endpoint returns the [entities](/en/articles/getting-started/glossary#entity) APITube already tracks whose name matches, each with a stable numeric `id` you can drop straight into the `entity.id` search filter. This is the reliable way to turn free text like “tesl” into the exact entity a user means before you run a news search. ``` curl "https://api.apitube.io/v1/suggest/entities?prefix=Tesla&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Both forms are accepted on every request. ## What does /v1/suggest/entities return?[#](#what-does-v1suggestentities-return) The endpoint returns a JSON **array** of matching entities (not a wrapped object). Each item has the same shape: ``` [ { "id": 5012, "name": "SpaceX", "type": "organization", "links": { "self": "https://api.apitube.io/v1/news/entity/...", "wikipedia": "https://en.wikipedia.org/wiki/SpaceX", "wikidata": "https://www.wikidata.org/wiki/Q193701" }, "metadata": {} } ] ``` * `id` — the stable numeric entity ID. This is the value you pass to `entity.id` in a search (not the number inside `links.self`, which points to that entity’s own news endpoint). * `name` — the canonical entity name. * `type` — one of `person`, `location`, `organization`, `brand`, `product`, `natural-disaster`, `disease`, `event`, `sport` or `unknown`. * `links` — `wikipedia` and `wikidata` URLs when known (empty string when not), plus a `self` link. * `metadata` — extra structured fields about the entity when available. ## How does prefix matching work?[#](#how-does-prefix-matching-work) Despite the name, `prefix` matches any part of the entity name and is **case-insensitive** — `prefix=tesla` matches “Tesla” wherever the text appears in the name, not only names that start with it. Results are ordered by internal ID (ascending) and capped at **100 entities** per call, which is plenty for a dropdown. There is no separate “minimum length” rule, but a longer prefix returns fewer, sharper matches, so trigger the call after the user has typed 2–3 characters to keep the list tight. ``` curl "https://api.apitube.io/v1/suggest/entities?prefix=micros&api_key=YOUR_API_KEY" ``` ## How to turn a suggestion into a news search[#](#how-to-turn-a-suggestion-into-a-news-search) The whole point of autocomplete is the hand-off to a real search. Take the `id` from the suggestion the user picked and pass it to `entity.id` on `/v1/news/everything`: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=5012&api_key=YOUR_API_KEY" ``` `entity.id` accepts up to three IDs, comma-separated, with OR logic (an article matches if it mentions any of them), and each value must be an integer of 1 to 30 characters. Because it is a fixed identifier rather than a name, `entity.id` never fails on an unknown value — a valid-looking ID that matches nothing simply returns no articles. For everything you can do once you have the ID, see [How to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## What errors can the endpoint return?[#](#what-errors-can-the-endpoint-return) There are two request-level errors to handle in your typeahead: * **Missing `prefix`** → HTTP 400 with error `ER0346`. Skip the call entirely until the input has at least one character. * **Missing [API key](/en/articles/getting-started/glossary#api-key)** → HTTP 401 with error `ER0201`. Send the key on every suggest call, exactly like a search. Because suggest is hit on nearly every keystroke, debounce the input (wait ~200–300 ms after typing stops) so you fire one request per pause instead of one per character. APITube exposes the same autocomplete pattern for other facets too — `/v1/suggest/categories`, `/v1/suggest/topics` and `/v1/suggest/industries` — each taking a `prefix` and returning matching options for that filter. For the full list of search parameters these IDs feed into, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Does prefix have to be the start of the name?](#does-prefix-have-to-be-the-start-of-the-name) * [How many suggestions are returned?](#how-many-suggestions-are-returned) * [Which ID do I pass to entity.id?](#which-id-do-i-pass-to-entityid) * [Can I autocomplete only people or only companies?](#can-i-autocomplete-only-people-or-only-companies) ## Does prefix have to be the start of the name?[#](#does-prefix-have-to-be-the-start-of-the-name) No. `prefix` is matched case-insensitively against the whole entity name, so it behaves like a “contains” search — `prefix=york` will match “New York”. Use the most distinctive part of the name to keep the list short, and let the user pick the exact entity from the returned `name` and `type`. ## How many suggestions are returned?[#](#how-many-suggestions-are-returned) Up to 100 matching entities per call, ordered by internal ID. That is more than a dropdown needs, so you can safely render just the first handful and let the user refine the prefix to narrow the rest. ## Which ID do I pass to entity.id?[#](#which-id-do-i-pass-to-entityid) The top-level `id` field of each suggestion. That value is the stable entity ID, and it is exactly what `entity.id` expects in a `/v1/news/everything` request. Do not use the number embedded in `links.self` — that link is the entity’s own news endpoint and uses a different internal reference. ## Can I autocomplete only people or only companies?[#](#can-i-autocomplete-only-people-or-only-companies) The endpoint returns all matching entity types in one list, but every item carries a `type` field (`person`, `organization`, `brand`, `location` and so on). Filter the results client-side by `type` if your input is meant for one kind of entity, then pass the chosen `id` to `entity.id`, which works for any type. To browse a curated list of one type instead of a typeahead, see the [people directory](/en/articles/searching-and-filtering/entities/people-directory). * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Get Sentiment Toward a Specific Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) --- ## How to Find News Mentioning a Person or Company URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/find-news-by-entity Use person.name, organization.name or a numeric entity.id to find APITube News API articles that mention a specific person, company or brand. # How to Find News Mentioning a Person or Company Filter News API results to articles that mention a specific person, company or brand with person.name, organization.name and entity.id ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Netflix) # How to find news mentioning a person or company[#](#how-to-find-news-mentioning-a-person-or-company) To return only articles that mention a specific person or company, add `person.name` for people or `organization.name` for companies — for example `person.name=Elon Musk` or `organization.name=Netflix`. APITube looks each name up against the [entities](/en/articles/getting-started/glossary#entity) it already tracks and returns only articles where that entity is actually mentioned. For an exact, unambiguous match, use the numeric `entity.id` instead. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Netflix&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit every entity parameter, no entity filter is applied and articles mentioning anyone are returned. ## What is entity filtering?[#](#what-is-entity-filtering) APITube tags every article with the named entities it mentions — people, companies, brands, locations and more. Entity filtering keeps only the articles linked to the entity you ask for, instead of matching loose keywords. That means `organization.name=Apple` returns coverage about the company Apple, not articles that happen to contain the word “apple”. Each entity has a type, and the parameter you use picks the type: * `person.name` matches people (type `person`). * `organization.name` matches companies and organizations. * `brand.name` matches brands. * `location.name` matches places. Use the parameter that matches what you are tracking. A company name passed to `person.name` will not be found, because that parameter only looks at people. Four more types have their own filters — `disaster.name`, `disease.name`, `event.name` and `sport.name` — while the `product` and `unknown` types have **no** name filter at all: there is no `product.name` parameter, and sending one is silently ignored (the response comes back unfiltered). Reach those entities through `entity.id`, which works for every type. ## How to find news about a person, company or brand[#](#how-to-find-news-about-a-person-company-or-brand) Pass the exact name to the matching parameter. Each accepts up to three values separated by commas, and articles mentioning **any** of them are returned (OR logic): ``` curl "https://api.apitube.io/v1/news/everything?person.name=Elon Musk&api_key=YOUR_API_KEY" ``` ``` curl "https://api.apitube.io/v1/news/everything?brand.name=Coca-Cola&api_key=YOUR_API_KEY" ``` Spaces in a name should be URL-encoded (`Elon%20Musk`). Each name must be 1 to 120 characters long. The name has to match an entity APITube already tracks: an unknown `person.name` returns HTTP 400 with error `ER0216`, an unknown `organization.name` returns `ER0220`, and an unknown `brand.name` returns `ER0222`. Because the request stops on the first name it cannot resolve, confirm the spelling before filtering — the easiest way is to read it from a response or from entity autocomplete (below). ## How to filter by a precise entity ID[#](#how-to-filter-by-a-precise-entity-id) Names can be ambiguous, so APITube gives every entity a stable numeric `entity.id`. Filtering by ID is the most reliable way to pin results to one entity, and it works for any type — person, company, brand or location — without choosing a type-specific parameter: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=314&api_key=YOUR_API_KEY" ``` `entity.id` accepts up to three IDs, comma-separated, with OR logic. Each value must be an integer of 1 to 30 characters; a non-numeric value returns error `ER0127` and an out-of-range length returns `ER0128`, both HTTP 400. Unlike a name, an `entity.id` is not checked against the directory, so a valid-looking ID that matches no entity simply returns no articles instead of failing the request. To discover the right ID, use entity autocomplete: `GET /v1/suggest/entities` with a `prefix` returns matching entities, each with its `id`, `name` and `type`. A missing `prefix` returns error `ER0346`. ``` curl "https://api.apitube.io/v1/suggest/entities?prefix=Tesla&api_key=YOUR_API_KEY" ``` ## How to combine and exclude entities[#](#how-to-combine-and-exclude-entities) Different entity parameters combine with AND, so listing a person and a company in the same request returns only articles that mention **both**. This is useful for narrowing to coverage about one person at one company: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Elon Musk&organization.name=Tesla&api_key=YOUR_API_KEY" ``` To return everything **except** a given entity, use the `ignore.` variants — `ignore.entity.id`, `ignore.person.name` and `ignore.organization.name` — which follow the same rules (comma-separated, up to three). An unknown name in `ignore.person.name` returns `ER0217`, and `ignore.organization.name` returns `ER0221`. Entity filtering is part of the shared filter chain, so it also combines with [author](/en/articles/searching-and-filtering/by-attribute/filter-by-author), language, date and sorting filters in one request. ## How to get sentiment toward a specific company or person[#](#how-to-get-sentiment-toward-a-specific-company-or-person) When you select an entity, you can also restrict results by the tone expressed **toward that entity** using `entity.sentiment.polarity` (`positive`, `negative` or `neutral`) and the numeric range `entity.sentiment.score.min` / `entity.sentiment.score.max` (each between `-1` and `1`): ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Netflix&entity.sentiment.polarity=positive&api_key=YOUR_API_KEY" ``` These three parameters only work **next to an entity selector** — `entity.id` or one of the `*.name` filters. On their own they would have to scan every entity mention ever indexed, so the request is refused with `400 ER0293`. A polarity other than the three allowed values returns `ER0290`; a score outside `-1`…`1` returns `ER0291` (min) or `ER0292` (max). This is [sentiment](/en/articles/getting-started/glossary#sentiment) aimed at the entity itself, which is different from the article’s overall tone — see [How to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) for the document-level filter. ## What does the entities object in the response contain?[#](#what-does-the-entities-object-in-the-response-contain) Every article carries an `entities` array, so you can confirm the match and reuse the exact `id` in follow-up requests: ``` { "entities": [ { "id": 314, "name": "Netflix", "type": "organization", "frequency": 4, "sentiment": { "score": 0.42, "polarity": "positive" } } ] } ``` The `id` here is exactly the value you pass back into `entity.id`, the `type` tells you which name parameter applies, `frequency` is how many times the entity is mentioned, and `sentiment` is the tone toward that entity. For the full list of accepted names and values, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [How many people or companies can I filter by at once?](#how-many-people-or-companies-can-i-filter-by-at-once) * [Should I use a name or an entity.id?](#should-i-use-a-name-or-an-entityid) * [What is the difference between person.name and organization.name?](#what-is-the-difference-between-personname-and-organizationname) * [How do I find an entity’s ID?](#how-do-i-find-an-entitys-id) ## How many people or companies can I filter by at once?[#](#how-many-people-or-companies-can-i-filter-by-at-once) Up to three per parameter. `entity.id`, `person.name`, `organization.name`, `brand.name` and their `ignore.` variants each accept a comma-separated list, and only the first three values are applied. Multiple values inside one parameter use OR logic, so an article matches if it mentions any of them. Different parameters combine with AND, so adding a second parameter narrows the results. ## Should I use a name or an entity.id?[#](#should-i-use-a-name-or-an-entityid) Both target the same entities. A name (`person.name`, `organization.name`, `brand.name`) is easier to read, but it must exactly match a tracked entity or the request fails — for example `ER0216` for an unknown person or `ER0220` for an unknown organization. A numeric `entity.id` is more robust: it is a fixed identifier, is not validated against the directory, and never blocks the request — an unknown ID just returns no articles. Read either value from an article’s `entities` array. ## What is the difference between person.name and organization.name?[#](#what-is-the-difference-between-personname-and-organizationname) They look up different entity types. `person.name` only matches people, and `organization.name` only matches companies and organizations, so passing a company to `person.name` returns “not found”. If you are unsure of the type, filter by `entity.id` instead, which is type-agnostic and matches the exact entity regardless of whether it is a person, company, brand or location. ## How do I find an entity’s ID?[#](#how-do-i-find-an-entitys-id) Call `GET /v1/suggest/entities?prefix=` with the start of the name. The response lists matching entities with their `id`, `name` and `type`, which you can drop straight into `entity.id`. You can also read the `id` from the `entities` array of any article in a normal search response and reuse it in your next request. * * * ## Related Articles * [How to Filter News by Author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) --- ## Entities, People & Companies URL: https://support.apitube.io/en/articles/searching-and-filtering/entities Find APITube News API articles that mention a specific person, company, brand or location using entity filters and entity autocomplete. # Entities, People & Companies Find articles about a person, company or place. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Tasha 1 author 7 articles * [How to Browse the Companies Directory](/en/articles/searching-and-filtering/entities/companies-directory) * [How to Browse the People Directory](/en/articles/searching-and-filtering/entities/people-directory) * [How to Find Journalists by Byline and Beat](/en/articles/searching-and-filtering/entities/journalists-directory) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to Track News About a Specific Person](/en/articles/searching-and-filtering/entities/track-news-about-a-person) * [How to Use Entity Autocomplete in Search Inputs](/en/articles/searching-and-filtering/entities/entity-autocomplete) --- ## How to Find Journalists by Byline and Beat URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/journalists-directory Use the APITube /v1/journalists directory to search reporters by name and open a profile with their outlets, coverage stats and recent articles. # How to Find Journalists by Byline and Beat Search the journalists directory with /v1/journalists, then open a profile for outlets, coverage stats and recent articles ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 23, 2026 # How to find journalists by byline and beat[#](#how-to-find-journalists-by-byline-and-beat) To look up reporters, call `GET /v1/journalists` to search the directory by name, then call `GET /v1/journalists/:id` to open a single profile with the journalist’s outlets, coverage statistics and most recent articles. The directory normalizes bylines by name, so the same reporter writing for several outlets is merged into one record with an `outlets` array. ``` curl "https://api.apitube.io/v1/journalists?name=Jane%20Doe&api_key=YOUR_API_KEY" ``` Send the key as the `X-API-Key` header instead of the `api_key` query parameter if you prefer. With no `name`, the endpoint returns the full directory page by page. ## How to search the journalists directory[#](#how-to-search-the-journalists-directory) `GET /v1/journalists` lists journalists and accepts a `name` filter that does a partial (substring) match, so `name=Jane` returns every byline containing “Jane”. Paginate with `page` (default `1`) and `per_page` (default `100`). The `per_page` ceiling depends on your plan — `10` on Free, `50` on Starter, `200` on Basic, `250` on Professional and Corporate — and asking for more returns HTTP 400 with error `ER0171`, whose message names the limit that applies to your key; a non-numeric `page` returns `ER0172` and a non-numeric `per_page` returns `ER0170`. ``` curl "https://api.apitube.io/v1/journalists?name=climate&per_page=50&page=2&api_key=YOUR_API_KEY" ``` The list response wraps the matches and tells you whether more pages exist: ``` { "status": "ok", "limit": 100, "page": 1, "has_next_pages": true, "results": [ { "id": 84213, "name": "Jane Doe", "outlets": [ { "id": 512, "name": "The Verge", "domain": "theverge.com" } ], "outlet_count": 2, "links": { "self": "https://api.apitube.io/v1/journalists/84213", "articles": "https://api.apitube.io/v1/news/everything?author.id=84213" } } ] } ``` `has_next_pages` is `true` only when a further record actually exists: the endpoint asks the database for `per_page + 1` rows and reports the extra one without returning it, so a page that comes back exactly full still reads `false` when nothing follows it. `outlet_count` is the number of outlet records merged into that journalist and appears on the list endpoint only. The `links.articles` URL is ready to use, but read it precisely: it filters by **one** `author.id` — the record you opened — while `coverage.article_count` on the profile counts every record merged under that name. A reporter published across three outlets has three author records, so the link returns a subset: for author `570` the profile reports 412 articles and `author.id=570` matches 191. `author.name` does not solve it either — it resolves to a single record too. Use `coverage` for the totals and `author.id` when you need one exact byline — see [how to filter news by author](/en/articles/searching-and-filtering/by-attribute/filter-by-author). ## What is in a journalist profile?[#](#what-is-in-a-journalist-profile) `GET /v1/journalists/:id` returns one journalist’s `id`, `name`, the `outlets` they publish under (each with `id`, `name` and `domain`), a `links` block, a `coverage` summary, and `recent_articles` — up to five full article objects. A missing ID returns HTTP 404 with error `ER0151`. ``` curl "https://api.apitube.io/v1/journalists/84213?api_key=YOUR_API_KEY" ``` The `coverage` block aggregates everything that journalist has written: ``` { "coverage": { "article_count": 1284, "first_seen": "2023-02-11", "last_seen": "2026-06-25", "sentiment": { "positive": 540, "neutral": 612, "negative": 132 }, "momentum": { "last_30_days": 41, "previous_30_days": 37, "change_pct": 11 }, "timeline": [ { "period": "2026-06-01", "count": 41 } ], "top_topics": [ { "id": 123, "name": "Artificial Intelligence", "count": 88 } ], "top_entities": [ { "id": 314, "name": "OpenAI", "count": 57 } ], "top_countries": [ { "id": 840, "name": "United States", "code": "us", "count": 700 } ], "top_languages": [ { "id": 1, "name": "English", "code": "en", "count": 1200 } ] } } ``` That is how you read a reporter’s **beat**: `top_topics` and `top_entities` show what they cover most, `momentum` compares the last 30 days against the previous 30 (`change_pct` is `null` when there is no prior activity to compare), and `timeline` breaks output down by month. Use `top_entities` the same way you would the article-level [entity](/en/articles/getting-started/glossary#entity) filter — see [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## How to skip the coverage block[#](#how-to-skip-the-coverage-block) Coverage runs several aggregate queries, so when you only need the name, outlets and links, add `coverage=false` to skip it and get a lighter, faster response: ``` curl "https://api.apitube.io/v1/journalists/84213?coverage=false&api_key=YOUR_API_KEY" ``` With `coverage=false` the profile omits the `coverage` object while still returning `recent_articles`. # Common Questions[#](#common-questions) * [How are journalists with the same name handled?](#how-are-journalists-with-the-same-name-handled) * [How do I get every article a journalist wrote?](#how-do-i-get-every-article-a-journalist-wrote) * [Does each directory call count as a request?](#does-each-directory-call-count-as-a-request) * [Why are the article bodies in recent\_articles cut off?](#why-are-the-article-bodies-in-recent_articles-cut-off) ## How are journalists with the same name handled?[#](#how-are-journalists-with-the-same-name-handled) The directory merges records by exact name, so one reporter publishing across multiple outlets becomes a single profile with an `outlets` array. The trade-off is that true namesakes — two different people who share a name — and generic bylines such as “admin” can be merged into one profile. Finer disambiguation is planned for a later release. When you need a precise scope, filter the actual articles by `author.id`, which targets a single byline record. ## How do I get every article a journalist wrote?[#](#how-do-i-get-every-article-a-journalist-wrote) Take the `id` from the directory and pass it to the search endpoint as `author.id`, exactly the URL given in `links.articles`: `GET /v1/news/everything?author.id=84213`. The `author.id` filter accepts up to three IDs separated by commas with OR logic, so you can pull several bylines at once and combine them with any other search filter. ## Does each directory call count as a request?[#](#does-each-directory-call-count-as-a-request) Yes — a successful `/v1/journalists` or `/v1/journalists/:id` call charges one request against your plan. The list endpoint is the exception that helps you: if a search returns zero matches, no request is charged. ## Why are the article bodies in recent\_articles cut off?[#](#why-are-the-article-bodies-in-recent_articles-cut-off) On a free plan or a [test key](/en/articles/getting-started/glossary#test-key-and-live-key), the article bodies inside `recent_articles` are truncated to a preview, the same masking applied across the News API. Use a live key on a paid plan to receive the full text. For the complete list of accepted parameters and values, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). * * * ## Related Articles * [How to Filter News by Author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) --- ## How to Monitor News About a Company or Brand URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/monitor-company-news Monitor news about a company or brand with organization.name or brand.name, narrow to negative coverage with entity.sentiment.polarity, and stream new mentions… # How to Monitor News About a Company or Brand Track a company or brand with organization.name, brand.name, entity.id and entity-level sentiment ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Tesla) # How to monitor news about a company or brand[#](#how-to-monitor-news-about-a-company-or-brand) To monitor a company, add `organization.name` to your search — for example `organization.name=Tesla`. For a consumer brand, use `brand.name` instead, such as `brand.name=Coca-Cola`. APITube resolves the name against the [entities](/en/articles/getting-started/glossary#entity) it tracks and returns only articles that actually mention that company or brand, and results come back newest-first by default — so a single repeated request is already a working monitor. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Because the default sort is publication date, descending, the first article in the response is the most recent mention — no `sort` parameter needed. ## How do I set up ongoing monitoring for a company?[#](#how-do-i-set-up-ongoing-monitoring-for-a-company) Monitoring is the same entity filter you would use for a one-off search, run on a schedule. Pick the parameter that matches what you are tracking: * `organization.name` matches companies and organizations (for example `organization.name=Netflix`). * `brand.name` matches consumer brands (for example `brand.name=Samsung Galaxy`). Each parameter accepts up to three values separated by commas with OR logic, so you can watch a few brands at once: `brand.name=Coca-Cola,Samsung Galaxy`. Names must be 1 to 120 characters and must match a tracked entity — an unknown `organization.name` returns HTTP 400 with error `ER0220`, and an unknown `brand.name` returns `ER0222`. Confirm the spelling first by reading it from a result or from entity autocomplete (`GET /v1/suggest/entities?prefix=`). For the full mechanics of entity matching, see [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## How do I make company monitoring precise?[#](#how-do-i-make-company-monitoring-precise) Company names are often ambiguous — many firms share a name, and a word like “Apple” matches both the company and the fruit. To pin monitoring to exactly one company, filter by its numeric `entity.id` instead of its name: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=314&api_key=YOUR_API_KEY" ``` `entity.id` accepts up to three IDs (comma-separated, OR logic) and is type-agnostic, so the same parameter works for a company, a brand or a product. A non-numeric value returns error `ER0127`. Unlike a name, an `entity.id` is not checked against the directory, so it never blocks the request — a stable ID is the most reliable anchor for a long-running monitor. Read the ID from the `entities` array of any matching article and reuse it. ## How do I catch only negative coverage about a company?[#](#how-do-i-catch-only-negative-coverage-about-a-company) For reputation monitoring you usually care about negative mentions. Add `entity.sentiment.polarity=negative` to keep only articles whose tone **toward that company** is negative: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` `entity.sentiment.polarity` accepts `positive`, `negative` or `neutral`; any other value returns `ER0290`. You can tighten it with the numeric range `entity.sentiment.score.min` and `entity.sentiment.score.max`, each between `-1` and `1` (out-of-range values return `ER0291` or `ER0292`). This is [sentiment](/en/articles/getting-started/glossary#sentiment) aimed at the company itself, which is not the same as the article’s overall tone — see [how to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) for the full breakdown. ## How do I narrow monitoring to recent or excluded mentions?[#](#how-do-i-narrow-monitoring-to-recent-or-excluded-mentions) Add a date window so each poll only returns fresh coverage. `published_at.start` and `published_at.end` are inclusive and accept relative values, so `published_at.start=NOW-7DAYS` means “the last seven days”: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Netflix&published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` To filter out a competitor or a noisy source while watching your own company, use `ignore.organization.name` — for example `ignore.organization.name=The Walt Disney Company`. An unknown name there returns `ER0221`. Entity filters combine with AND across parameters, so `organization.name=Netflix&language.code=en` returns only English-language Netflix coverage. ## How do I get company mentions in real time instead of polling?[#](#how-do-i-get-company-mentions-in-real-time-instead-of-polling) Instead of re-running a search every few minutes, open a [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream that pushes each new matching article as it is published. The stream accepts the same entity filters: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?organization.name=Tesla" ``` `GET /v1/news/stream` checks for new matches about every 30 seconds, sends up to 50 articles per cycle, and keeps the connection open for up to 6 hours before asking you to reconnect. Streaming draws on a separate streaming quota rather than your normal request credits. See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for resume handling and message format. For the complete list of accepted parameters, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Should I use organization.name or brand.name?](#should-i-use-organizationname-or-brandname) * [How many companies can I monitor in one request?](#how-many-companies-can-i-monitor-in-one-request) * [Why does my company filter return no articles?](#why-does-my-company-filter-return-no-articles) ## Should I use organization.name or brand.name?[#](#should-i-use-organizationname-or-brandname) They look up different entity types. `organization.name` matches the legal company or organization, while `brand.name` matches a consumer-facing brand. A brand passed to `organization.name` may return “not found” (`ER0220`) if APITube tracks it as a brand rather than a company. If you are unsure of the type, filter by `entity.id` instead, which matches the exact entity regardless of whether it is a company, brand or product. ## How many companies can I monitor in one request?[#](#how-many-companies-can-i-monitor-in-one-request) Up to three per parameter. `organization.name`, `brand.name`, `entity.id` and their `ignore.` variants each accept a comma-separated list, and only the first three values are applied. Multiple values inside one parameter use OR logic, so an article matches if it mentions any of them. To watch more than three companies, run several requests or several streams. ## Why does my company filter return no articles?[#](#why-does-my-company-filter-return-no-articles) Either the name resolved but there is no recent coverage, or your other filters are too tight. A name filter fails loudly — an unknown `organization.name` returns `ER0220` rather than an empty list — so if you get a clean empty response, the entity was found but matched nothing. Widen the date window (drop `published_at.start`), remove `entity.sentiment.polarity`, or switch to the entity’s numeric `entity.id` to rule out a name mismatch. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Get Sentiment Toward a Specific Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Browse the People Directory URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/people-directory Use the APITube News API /v1/people endpoint to search a directory of known persons by name or Wikidata ID, then open a profile for coverage stats. # How to Browse the People Directory Search known persons with /v1/people and open one profile with /v1/people/:id for Wikidata metadata, coverage stats and recent articles ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 23, 2026 # How to browse the people directory and view profiles[#](#how-to-browse-the-people-directory-and-view-profiles) Call `GET /v1/people` to search a directory of known persons — public figures, politicians and executives — and `GET /v1/people/:id` to open a single profile with Wikidata-enriched metadata, coverage statistics and recent articles. Filter the list by `name` or `wikidata_id`, page through it with `page` and `per_page`, then take the `id` from any result and request its profile. ``` curl "https://api.apitube.io/v1/people?name=Elon&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. ## What is the people directory?[#](#what-is-the-people-directory) The people directory is the set of persons APITube already tracks as named [entities](/en/articles/getting-started/glossary#entity) (entity type `person`). `GET /v1/people` returns those records so you can look someone up by name, confirm their entity `id`, and read the Wikidata profile APITube stores for them. It is the people-only view of the same entities you match in a search with `person.name` or `entity.id`, so the `id` you read here is the exact value you pass back into a [news query](/en/articles/searching-and-filtering/entities/find-news-by-entity). The list never mixes in companies or locations: it only returns records of type `person`. To pivot from a person to their news coverage, follow the `links.articles` URL on any record, which points to `/v1/news/entity/:id`. ## How to search people by name or Wikidata ID[#](#how-to-search-people-by-name-or-wikidata-id) `GET /v1/people` accepts four query parameters: * `name` — filter by a person’s name as a substring match. * `wikidata_id` — filter by a Wikidata ID, given as either `Q317521` or `317521`. * `page` — page number, starting at `1` (default `1`). * `per_page` — results per page, default `100`. The ceiling depends on your plan: `10` on Free, `50` on Starter, `200` on Basic, `250` on Professional and Corporate. ``` curl "https://api.apitube.io/v1/people?name=Angela%20Merkel&per_page=20&api_key=YOUR_API_KEY" ``` Spaces in a name should be URL-encoded (`Angela%20Merkel`). A `per_page` above your plan’s ceiling returns HTTP 400 with error `ER0171`, and the message names the limit that applies to your key (“Your plan allows up to 200 results per page.”). The response wraps the records in a small envelope: ``` { "status": "ok", "limit": 20, "page": 1, "has_next_pages": true, "results": [] } ``` `has_next_pages` is `true` only when a further record actually exists: the endpoint asks the database for `per_page + 1` rows and reports the extra one without returning it. A page that comes back exactly full is therefore still `false` when nothing follows it, so you never spend a request on an empty page. To walk the whole directory, keep incrementing `page` until `has_next_pages` is `false`. ## What does a person record contain?[#](#what-does-a-person-record-contain) Each entry in `results` (and the body of a single profile) is the same shape: ``` { "id": 1895133, "name": "Elon Musk", "type": "person", "links": { "self": "https://api.apitube.io/v1/people/1895133", "articles": "https://api.apitube.io/v1/news/entity/1895133", "wikipedia": "https://en.wikipedia.org/wiki/Elon_Musk", "wikidata": "https://www.wikidata.org/wiki/Q317521" }, "profile": {} } ``` `id` is the numeric entity ID, `type` is always `person` for this endpoint, and `links` gives you ready-made URLs: `self` for the profile, `articles` for coverage, plus `wikipedia` and `wikidata` (each an empty string when APITube has no link for that person). `profile` holds the Wikidata-enriched metadata, which varies by person and may be `null`. ## How to open a single person profile[#](#how-to-open-a-single-person-profile) Take the `id` and request `GET /v1/people/:id`. The profile returns the same person fields plus two extra blocks: a `coverage` summary and `recent_articles`. ``` curl "https://api.apitube.io/v1/people/1895133?api_key=YOUR_API_KEY" ``` If the ID does not exist, or it belongs to an entity that is not a person, the endpoint returns HTTP 404 with error `ER0151` (“Person not found.”). `recent_articles` is a list of up to 5 of the person’s most recent articles as full article objects; on a free plan or a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) the article body is truncated to a preview. ## What is in the coverage block?[#](#what-is-in-the-coverage-block) The `coverage` block aggregates how the person has appeared in the news. It includes: * `article_count` — total matching articles. * `first_seen` and `last_seen` — the earliest and latest article dates (`YYYY-MM-DD`, or `null`). * `sentiment` — counts of `positive`, `neutral` and `negative` coverage. * `momentum` — `last_30_days` vs `previous_30_days` plus a `change_pct`. * `timeline` — monthly counts (up to 24 months). * `top_sources`, `top_topics`, `top_countries`, `top_languages` and `related_entities` — each up to 10 entries with a `count`. ``` curl "https://api.apitube.io/v1/people/1895133?coverage=false&api_key=YOUR_API_KEY" ``` Add `coverage=false` to skip the whole block when you only need the profile and recent articles — the request is lighter and returns no `coverage` key. For the full list of accepted parameters and values, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). ## How are people directory requests billed?[#](#how-are-people-directory-requests-billed) Each successful directory call costs one request. The single-profile endpoint (`/v1/people/:id`) always charges one request when it returns a profile. The list endpoint (`/v1/people`) only charges when it returns at least one match, so a search that finds nobody does not cost a request. Both endpoints require a valid [API key](/en/articles/getting-started/glossary#api-key) and reject missing or invalid keys with an authentication error. # Common Questions[#](#common-questions) * [How do I get the entity ID to filter news?](#how-do-i-get-the-entity-id-to-filter-news) * [Can I look someone up by their Wikidata page?](#can-i-look-someone-up-by-their-wikidata-page) * [Why did a profile request return ER0151?](#why-did-a-profile-request-return-er0151) * [How do I skip the coverage statistics?](#how-do-i-skip-the-coverage-statistics) ## How do I get the entity ID to filter news?[#](#how-do-i-get-the-entity-id-to-filter-news) Search `GET /v1/people?name=` for the person, read the `id` from the matching record, and pass it back into a news search as `entity.id`. The directory and the search filter use the same entity IDs, so the value is interchangeable. Alternatively, read the `id` straight from the `entities` array of any article, or use [entity autocomplete](/en/articles/searching-and-filtering/entities/entity-autocomplete) for type-ahead lookups. ## Can I look someone up by their Wikidata page?[#](#can-i-look-someone-up-by-their-wikidata-page) Yes. Pass `wikidata_id` to `GET /v1/people`, using either the `Q`\-prefixed form (`Q317521`) or the bare number (`317521`). This is the most precise way to find one specific person, because names can be ambiguous while a Wikidata ID maps to exactly one entity. ## Why did a profile request return ER0151?[#](#why-did-a-profile-request-return-er0151) `GET /v1/people/:id` returns HTTP 404 with `ER0151` (“Person not found.”) when no entity has that ID, or when the ID belongs to an entity that is not a person — for example a company or a location. Confirm the ID by searching `GET /v1/people` first, since that endpoint only ever lists persons. ## How do I skip the coverage statistics?[#](#how-do-i-skip-the-coverage-statistics) Append `coverage=false` to the profile request. The response then omits the `coverage` block entirely and still returns the person fields and `recent_articles`. Use it when you only need the person’s name, links and latest stories and do not want the aggregated counts and timeline. It saves only a few kilobytes, though: the five `recent_articles` are **complete** article objects (body, entities and all) and make up most of the response — roughly 140 KB out of 170 KB. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [Using Entity Autocomplete in Search Inputs](/en/articles/searching-and-filtering/entities/entity-autocomplete) --- ## How to Track News About a Specific Person URL: https://support.apitube.io/en/articles/searching-and-filtering/entities/track-news-about-a-person Track news about a specific person with person.name or a numeric entity.id, separate people who share a name, follow sentiment and stream new mentions live. # How to Track News About a Specific Person Monitor a public figure over time with person.name, a numeric entity.id, date windows and a live SSE stream ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&person_name=Tim) # How to track news about a specific person[#](#how-to-track-news-about-a-specific-person) To track a specific person, add `person.name` to a `/v1/news/everything` search — for example `person.name=Tim Cook`. APITube resolves the name against the people it already tracks and returns only articles that actually mention that person. Results come back newest-first by default, so re-running the same request on a schedule is already a working monitor — no `sort` parameter required. ``` curl "https://api.apitube.io/v1/news/everything?person.name=Tim Cook&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. The first article in the response is always the most recent mention, because the default sort is publication date in descending order. ## How do I set up ongoing tracking for a person?[#](#how-do-i-set-up-ongoing-tracking-for-a-person) Tracking a person is the `person.name` filter run on a schedule. The parameter matches people only ([entity](/en/articles/getting-started/glossary#entity) type `person`), so a company name passed to it returns “not found”. A few rules to know before you build the monitor: * `person.name` accepts up to three names separated by commas, with OR logic — `person.name=Elon Musk,Tim Cook` returns articles mentioning **either** person. * Each name must be 1 to 120 characters and must match a tracked person. An unknown `person.name` returns HTTP 400 with error `ER0216`, so the request fails loudly instead of returning an empty list. * Spaces should be URL-encoded (`Tim%20Cook`). Because a name filter fails on the first name it cannot resolve, confirm the spelling before you schedule the job. For the full mechanics of how names map to entities, see [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## How do I tell apart two people with the same name?[#](#how-do-i-tell-apart-two-people-with-the-same-name) Names are ambiguous — many people share one. To pin tracking to exactly one person, filter by their numeric `entity.id` instead of their name: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=314&api_key=YOUR_API_KEY" ``` `entity.id` accepts up to three IDs (comma-separated, OR logic) and is type-agnostic. Each value must be an integer of 1 to 30 characters; a non-numeric value returns error `ER0127` and an out-of-range length returns `ER0128`. Unlike a name, an `entity.id` is not checked against the directory, so it never blocks the request — a stable ID is the most reliable anchor for a long-running monitor. To find the right ID, use entity autocomplete: `GET /v1/suggest/entities` with a `prefix` returns matching entities, each with its `id`, `name` and `type`. A missing `prefix` returns error `ER0346`. ``` curl "https://api.apitube.io/v1/suggest/entities?prefix=Tim&api_key=YOUR_API_KEY" ``` You can also read the `id` straight from the `entities` array of any article in a normal search response, then reuse it. ## How do I only fetch mentions since my last check?[#](#how-do-i-only-fetch-mentions-since-my-last-check) Add a date window so each poll returns just the fresh coverage. `published_at.start` and `published_at.end` are inclusive and accept relative values, so `published_at.start=NOW-1DAYS` means “the last 24 hours”: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Tim Cook&published_at.start=NOW-1DAYS&api_key=YOUR_API_KEY" ``` Relative expressions like `NOW`, `NOW-7DAYS` and `NOW-1WEEK` are resolved server-side, so your scheduled job never has to compute timestamps. Both bounds are 1 to 30 characters; an invalid value returns `ER0104` (start) or `ER0106` (end). To keep a competitor or noisy figure out of the results while you track your subject, use `ignore.person.name` — an unknown name there returns `ER0217`. ## How do I follow sentiment toward the person?[#](#how-do-i-follow-sentiment-toward-the-person) When you select a person, you can also restrict results by the tone expressed **toward that person** with `entity.sentiment.polarity` (`positive`, `negative` or `neutral`): ``` curl "https://api.apitube.io/v1/news/everything?person.name=Tim Cook&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` A polarity other than the three allowed values returns `ER0290`. You can tighten it with the numeric range `entity.sentiment.score.min` and `entity.sentiment.score.max`, each between `-1` and `1` (out-of-range values return `ER0291` or `ER0292`). This is [sentiment](/en/articles/getting-started/glossary#sentiment) aimed at the person specifically, which is not the same as the article’s overall tone — see [how to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) for the entity-level breakdown. ## How do I track a person in real time instead of polling?[#](#how-do-i-track-a-person-in-real-time-instead-of-polling) Instead of re-running a search every few minutes, open a [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream that pushes each new matching article as it is published. The stream accepts the same entity filters: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?person.name=Tim Cook" ``` `GET /v1/news/stream` checks for new matches about every 30 seconds, sends up to 50 articles per cycle, sends a heartbeat every 30 seconds, and keeps the connection open for up to 6 hours before asking you to reconnect (error `ER0362`). Streaming draws on a separate streaming quota rather than your normal request credits. See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for resume handling and message format. For the complete list of accepted parameters, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Should I track by person.name or entity.id?](#should-i-track-by-personname-or-entityid) * [How many people can I track in one request?](#how-many-people-can-i-track-in-one-request) * [Why does my person filter return no articles?](#why-does-my-person-filter-return-no-articles) * [How do I confirm the article really mentions the right person?](#how-do-i-confirm-the-article-really-mentions-the-right-person) ## Should I track by person.name or entity.id?[#](#should-i-track-by-personname-or-entityid) Both target the same people. A `person.name` is easier to read, but it must exactly match a tracked person or the request fails with `ER0216`. A numeric `entity.id` is more robust for a long-running monitor: it is a fixed identifier, is not validated against the directory, and never blocks the request — an unknown ID simply returns no articles. For anyone whose name is shared by several people, `entity.id` is the safer anchor. ## How many people can I track in one request?[#](#how-many-people-can-i-track-in-one-request) Up to three per parameter. `person.name`, `entity.id` and their `ignore.` variants each accept a comma-separated list, and only the first three values are applied. Multiple values inside one parameter use OR logic, so an article matches if it mentions any of them. To watch more than three people, run several requests or open several streams. ## Why does my person filter return no articles?[#](#why-does-my-person-filter-return-no-articles) Either the name resolved but there is no recent coverage, or your other filters are too tight. A name filter fails loudly — an unknown `person.name` returns `ER0216` rather than an empty list — so a clean empty response means the person was found but matched nothing. Widen the date window (drop `published_at.start`), remove `entity.sentiment.polarity`, or switch to the person’s numeric `entity.id` to rule out a name mismatch. ## How do I confirm the article really mentions the right person?[#](#how-do-i-confirm-the-article-really-mentions-the-right-person) Every article carries an `entities` array. Each entry has the person’s `id`, `name`, `type`, a `frequency` count of how many times they are mentioned, and the `sentiment` toward them. Read the `id` from there to lock future requests to the exact person with `entity.id`, and check `frequency` to tell a passing mention from an article that is actually about them. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Filter News by Event Type URL: https://support.apitube.io/en/articles/searching-and-filtering/events/filter-by-event-type Use event.type in the APITube News API to return only articles about a detected event such as ipo or layoffs — up to five at once with OR logic — or… # How to Filter News by Event Type Use event.type and event.category to return only articles about a specific kind of event ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&event_type=layoffs) # How to filter news by event type[#](#how-to-filter-news-by-event-type) To return only articles about a specific kind of event, add the `event.type` parameter to your `/v1/news/everything` request with an event code such as `event.type=layoffs`. APITube detects the main event in each article and returns only the articles whose event matches. You can pass up to five event types separated by commas, and an article is returned if it matches **any** of them (OR logic). ``` curl "https://api.apitube.io/v1/news/everything?event.type=layoffs&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If you omit `event.type`, no event filter is applied and articles about every kind of event (and none) are returned. ## What event types can I filter by?[#](#what-event-types-can-i-filter-by) Event types are grouped into three categories: **business**, **society** and **environment**. Business covers events like `merger-acquisition`, `ipo`, `layoffs`, `bankruptcy`, `funding-round`, `earnings`, `lawsuit`, `data-breach` and `recall`. Society covers `election`, `protest`, `crime`, `terrorism`, `accident`, `scandal` and `conflict`. Environment covers `earthquake`, `hurricane`, `flood`, `wildfire`, `drought` and `volcanic-eruption`. Codes are lower-case and hyphenated. A code that is not on the list returns HTTP 400 with error `ER0502`, and the message names the invalid value and points you to the event-types endpoint. An empty `event.type` returns `ER0501`. To filter by an event without naming each code, use `event.category` with `business`, `society` or `environment` — an unknown category returns `ER0503`: ``` curl "https://api.apitube.io/v1/news/everything?event.category=business&api_key=YOUR_API_KEY" ``` `event.category=business` is shorthand for every business event type at once, so it returns articles about mergers, IPOs, layoffs, earnings and the rest in one request. ## How to filter by one or more event types[#](#how-to-filter-by-one-or-more-event-types) Pass a single code to read one event type, or a comma-separated list to combine several. This request pulls articles about either of two business events in one call: ``` curl "https://api.apitube.io/v1/news/everything?event.type=merger-acquisition,ipo&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` The maximum is five event types per request; extra values beyond the fifth are dropped. Event filtering is part of the shared filter chain, so it combines with any other filter — language, date range, source or [entity](/en/articles/searching-and-filtering/entities/find-news-by-entity): ``` curl "https://api.apitube.io/v1/news/everything?event.type=data-breach&language.code=en&api_key=YOUR_API_KEY" ``` ## How to exclude an event type[#](#how-to-exclude-an-event-type) To return everything **except** a kind of event, use `ignore.event.type`. It follows the same rules — comma-separated, up to five codes, validated against the same list (an invalid code returns `ER0504`). This keeps broad coverage while dropping earnings stories: ``` curl "https://api.apitube.io/v1/news/everything?ignore.event.type=earnings&api_key=YOUR_API_KEY" ``` You can pass `event.type` (or `event.category`) and `ignore.event.type` in the same request to include one kind of event while excluding another. ## How do I get the full list of event types?[#](#how-do-i-get-the-full-list-of-event-types) Call the `GET /v1/news/event-types` endpoint to fetch every valid `event.type` value together with its category, so you never have to guess a code: ``` curl "https://api.apitube.io/v1/news/event-types?api_key=YOUR_API_KEY" ``` The response is a JSON object with a `status`, a `categories` array (`business`, `society`, `environment`) and an `event_types` array where each item carries a `code` and the `category` it belongs to: ``` { "status": "ok", "categories": ["business", "society", "environment"], "event_types": [ { "code": "merger-acquisition", "category": "business" }, { "code": "ipo", "category": "business" } ] } ``` Take a `code` from the list and drop it straight into `event.type`. The same catalogue is documented in the [APITube event types reference](https://docs.apitube.io/platform/news-api/reference/event-types). # Common Questions[#](#common-questions) * [How many event types can I filter by at once?](#how-many-event-types-can-i-filter-by-at-once) * [What is the difference between event.type and event.category?](#what-is-the-difference-between-eventtype-and-eventcategory) * [What error do I get for an unknown event type?](#what-error-do-i-get-for-an-unknown-event-type) * [How do I get the full list of event types?](#how-do-i-get-the-full-list-of-event-types) ## How many event types can I filter by at once?[#](#how-many-event-types-can-i-filter-by-at-once) Up to five per parameter. `event.type` and `ignore.event.type` each accept a comma-separated list, and only the first five values are applied — anything beyond the fifth is dropped. Multiple types in one parameter use OR logic, so an article matches if its detected event is any of them. ## What is the difference between event.type and event.category?[#](#what-is-the-difference-between-eventtype-and-eventcategory) `event.type` targets one specific event code such as `ipo` or `wildfire`. `event.category` targets a whole group — `business`, `society` or `environment` — and matches every event type inside it. Use `event.type` when you want precise events, and `event.category` when you want a broad sweep of a domain. They can be combined with each other and with [breaking-news filtering](/en/articles/searching-and-filtering/events/monitor-breaking-news) in the same request. ## What error do I get for an unknown event type?[#](#what-error-do-i-get-for-an-unknown-event-type) An event code that APITube does not recognise returns HTTP 400 with error `ER0502` for `event.type` (the message lists the invalid code and points you to `/v1/news/event-types`), or `ER0504` for `ignore.event.type`. An empty `event.type` returns `ER0501`, and an unknown `event.category` returns `ER0503`. Fetch the valid codes from `GET /v1/news/event-types` before filtering to avoid these errors. * * * ## Related Articles * [How to Monitor Breaking News and Real-Time Events](/en/articles/searching-and-filtering/events/monitor-breaking-news) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) --- ## Events & Breaking News URL: https://support.apitube.io/en/articles/searching-and-filtering/events Filter APITube News API results to breaking news and real-time events, and stream new matching articles as they are published. # Events & Breaking News Filter to breaking news and live events. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Tasha 1 author 3 articles * [How to Filter News by Event Type](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to Filter News by Natural Disaster and Disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) * [How to Monitor Breaking News and Real-Time Events](/en/articles/searching-and-filtering/events/monitor-breaking-news) --- ## How to Monitor Breaking News and Real-Time Events URL: https://support.apitube.io/en/articles/searching-and-filtering/events/monitor-breaking-news Filter APITube News API results to breaking news with is_breaking=1, and push new matching articles in real time using the /v1/news/stream SSE endpoint. # How to Monitor Breaking News and Real-Time Events Use is\_breaking=1 to keep only breaking stories, and stream them live with the SSE endpoint ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&is_breaking=1) # How to monitor breaking news and real-time events[#](#how-to-monitor-breaking-news-and-real-time-events) To keep only articles flagged as breaking news, add `is_breaking=1` to a search request. It is a flag that accepts exactly `0` or `1`, and on its own it returns the newest breaking stories first. This request pulls current breaking news: ``` curl "https://api.apitube.io/v1/news/everything?is_breaking=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Without this flag, no breaking filter is applied and breaking and regular articles come back together. ## What does is\_breaking do?[#](#what-does-is_breaking-do) `is_breaking=1` matches only articles that the pipeline marked as breaking or important; `is_breaking=0` returns only the regular ones. The flag accepts nothing but `0` or `1`. A non-numeric value is rejected with a `400` error and code `ER0185`, and any other number returns `400` with code `ER0186` and the message that `is_breaking` must be 0 or 1. Every article in the response carries an `is_breaking` field set to `true` or `false`, so you can confirm the flag on each result and use it in your own logic even when you did not filter on it. ## How to get the freshest breaking news first[#](#how-to-get-the-freshest-breaking-news-first) The default sort order is by publish time, newest first, so a plain `is_breaking=1` already returns the most recent breaking stories at the top. You can make that explicit, or pick a different ranking. This request keeps the breaking filter and sorts by publish time descending, returning only a few compact fields: ``` curl "https://api.apitube.io/v1/news/everything?fl=id,title,source.domain,published_at&is_breaking=1&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` To rank breaking stories by social traction instead of recency, sort by engagement. This pattern surfaces the breaking articles that are spreading fastest: ``` curl "https://api.apitube.io/v1/news/everything?is_breaking=1&media.images.count.min=2&sort.by=engagement&sort.order=desc&api_key=YOUR_API_KEY" ``` ## How to stream breaking news in real time[#](#how-to-stream-breaking-news-in-real-time) Filtering returns what already exists. To receive breaking articles the moment they are published, open the [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream` with the same parameters. The stream runs the same filter chain, so `is_breaking=1` narrows the live feed exactly as it does on search: ``` curl -N "https://api.apitube.io/v1/news/stream?is_breaking=1&api_key=YOUR_API_KEY" ``` The connection polls for new matching articles every 30 seconds and sends a heartbeat every 30 seconds to keep the socket open. Each delivered article counts as one request against your stream quota. If the connection drops, reconnect with the `Last-Event-Id` header set to the id of the last article you received, and the stream resumes after that point instead of replaying everything. ## How to track regional breaking events[#](#how-to-track-regional-breaking-events) Because `is_breaking` belongs to the shared filter chain, it stacks with every other filter using AND logic. Pair it with a geographic radius to watch breaking news around one place — here, within 100 km of central London: ``` curl "https://api.apitube.io/v1/news/everything?location.lat=51.5074&location.lng=-0.1278&location.radius=100&is_breaking=1&api_key=YOUR_API_KEY" ``` You can layer language, category, source or any other filter on top. For the full geo syntax, see [How to find news near a coordinate or bounding box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius). Every parameter used here is listed in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Which endpoints support the breaking filter?[#](#which-endpoints-support-the-breaking-filter) `is_breaking` works the same way across the shared filter chain — including `/v1/news/everything`, `/v1/news/count` and the `/v1/news/stream` SSE feed. Because `/v1/news/count` runs the same chain, you can count how many breaking articles match without downloading them by sending `is_breaking=1` to that endpoint. The `/v1/news/top-headlines` endpoint is a related shortcut: it already returns only important articles from high-ranked sources, so reach for [Top Headlines](/en/articles/retrieval/get-top-headlines) when you want a curated breaking feed without building the filter yourself. # Common Questions[#](#common-questions) * [Does is\_breaking=1 guarantee the story is from the last few minutes?](#does-is_breaking1-guarantee-the-story-is-from-the-last-few-minutes) * [What value other than 0 or 1 can I pass?](#what-value-other-than-0-or-1-can-i-pass) * [How is streaming different from polling search?](#how-is-streaming-different-from-polling-search) * [Why use top-headlines instead of is\_breaking?](#why-use-top-headlines-instead-of-is_breaking) ## Does is\_breaking=1 guarantee the story is from the last few minutes?[#](#does-is_breaking1-guarantee-the-story-is-from-the-last-few-minutes) No. `is_breaking=1` filters by the breaking flag the pipeline assigns, not by a time window. To bound recency, combine it with a date filter or sort by `published_at` descending so the newest breaking articles sit at the top. ## What value other than 0 or 1 can I pass?[#](#what-value-other-than-0-or-1-can-i-pass) None. `is_breaking` accepts only `0` or `1`. A non-numeric value returns `400` with code `ER0185`, and any other number returns `400` with code `ER0186` stating the flag must be 0 or 1. ## How is streaming different from polling search?[#](#how-is-streaming-different-from-polling-search) Search returns articles that already match at request time. The `/v1/news/stream` SSE endpoint keeps the connection open and delivers new matching articles as they are published, polling every 30 seconds with a heartbeat every 30 seconds, and each delivered article counts against your stream quota. ## Why use top-headlines instead of is\_breaking?[#](#why-use-top-headlines-instead-of-is_breaking) `/v1/news/top-headlines` already restricts results to important articles from high-ranked sources, so it is a ready-made breaking feed. Use `is_breaking=1` on `/v1/news/everything` when you want full control over the rest of the filter chain. * * * ## Related Articles * [How to Get Top Headlines](/en/articles/retrieval/get-top-headlines) * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) --- ## How to Filter News by Natural Disaster and Disease URL: https://support.apitube.io/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks Use disaster.name and disease.name to filter APITube News API articles to a specific natural disaster or disease outbreak, and combine them with date and… # How to Filter News by Natural Disaster and Disease Filter News API results to natural disasters and disease outbreaks with disaster.name and disease.name ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&disaster_name=Great) # How to filter news by natural disaster and disease[#](#how-to-filter-news-by-natural-disaster-and-disease) To follow coverage of a specific natural disaster or disease outbreak, use the `disaster.name` and `disease.name` filters on `/v1/news/everything`. APITube tags articles with the named [entities](/en/articles/getting-started/glossary#entity) they mention, and these two parameters keep only the articles linked to a disaster (type `natural-disaster`) or a disease (type `disease`). This returns articles mentioning a wildfire event: ``` curl "https://api.apitube.io/v1/news/everything?disaster.name=Great Hanshin Earthquake&api_key=YOUR_API_KEY" ``` You can send the key as an `X-API-Key` header instead of the `api_key` query parameter, and call the endpoint with `GET` (query parameters) or `POST` (JSON body). Because these are entity filters, not keyword matches, `disease.name=influenza` returns coverage about the disease itself rather than every article that merely contains the word. ## How to filter news by a natural disaster[#](#how-to-filter-news-by-a-natural-disaster) Pass the disaster’s name to `disaster.name`. It matches entities of type `natural-disaster` (entity type id 6), so it covers events like earthquakes, floods, hurricanes and wildfires that APITube already tracks. The parameter accepts up to **three** names separated by commas, and an article matches if it mentions **any** of them (OR logic). Each name must be 1 to 120 characters, and spaces should be URL-encoded: ``` curl "https://api.apitube.io/v1/news/everything?disaster.name=Great%20Hanshin%20Earthquake&api_key=YOUR_API_KEY" ``` The name has to match a disaster entity APITube tracks. An unknown `disaster.name` returns HTTP 400 with error `ER0224`, and a name outside the 1–120 character range returns `ER0148`. Because the request stops on the first name it cannot resolve, confirm the spelling first — see [how to use entity autocomplete](/en/articles/searching-and-filtering/entities/entity-autocomplete) to look names up. ## How to track a disease outbreak[#](#how-to-track-a-disease-outbreak) `disease.name` works the same way for entities of type `disease` (entity type id 7) — illnesses and outbreaks such as influenza, measles or dengue. It also accepts up to three comma-separated names with OR logic, each 1 to 120 characters: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=malaria,dengue fever&api_key=YOUR_API_KEY" ``` An unknown `disease.name` returns error `ER0226`, and a name outside the length range returns `ER0152`. To watch everything **except** a disease, use `ignore.disease.name` (an unknown name there returns `ER0227`); the disaster equivalent is `ignore.disaster.name` (`ER0225`). ## How do I find the exact disaster or disease name to use?[#](#how-do-i-find-the-exact-disaster-or-disease-name-to-use) Both filters resolve the name against the entities APITube tracks, so the name must match one of them. The reliable way to find a valid value is entity autocomplete: call `GET /v1/suggest/entities` with a `prefix`, and each result includes its `id`, `name` and `type`. A `type` of `natural-disaster` confirms a value for `disaster.name`, and `disease` confirms one for `disease.name`. A missing `prefix` returns error `ER0346`. ``` curl "https://api.apitube.io/v1/suggest/entities?prefix=dengue&api_key=YOUR_API_KEY" ``` Check the `type` field before filtering: passing a disease name to `disaster.name` will not resolve, because each parameter only looks at its own entity type. ## How to combine outbreak filters with dates and sentiment[#](#how-to-combine-outbreak-filters-with-dates-and-sentiment) `disaster.name` and `disease.name` are part of the shared filter chain, so they combine with every other search filter in one request. Add `published_at.start` and `published_at.end` to scope an outbreak to a window, or `language.code` and sorting to shape the feed — the same way you would for any [entity filter](/en/articles/searching-and-filtering/entities/find-news-by-entity). Different parameters combine with AND, so the example below returns recent articles that mention the disease **and** carry negative [sentiment](/en/articles/getting-started/glossary#sentiment) toward it: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=influenza&published_at.start=NOW-7DAYS&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` You can restrict results by the tone expressed **toward the disaster or disease itself** with `entity.sentiment.polarity` (`positive`, `negative` or `neutral`) and the numeric range `entity.sentiment.score.min` / `entity.sentiment.score.max` (each between `-1` and `1`). A polarity outside the three allowed values returns `ER0290`; a score outside `-1`…`1` returns `ER0291` (min) or `ER0292` (max). For live coverage as events develop, pair these filters with [breaking-news monitoring](/en/articles/searching-and-filtering/events/monitor-breaking-news). The full parameter list lives in the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [What is the difference between disaster.name, disease.name and event.name?](#what-is-the-difference-between-disastername-diseasename-and-eventname) * [How many disasters or diseases can I track in one request?](#how-many-disasters-or-diseases-can-i-track-in-one-request) * [Why does my disaster or disease name return an error?](#why-does-my-disaster-or-disease-name-return-an-error) * [Can I exclude a disaster or disease from my results?](#can-i-exclude-a-disaster-or-disease-from-my-results) ## What is the difference between disaster.name, disease.name and event.name?[#](#what-is-the-difference-between-disastername-diseasename-and-eventname) They target different entity types. `disaster.name` matches natural-disaster entities (type id 6), `disease.name` matches disease entities (type id 7), and `event.name` matches general event entities (type id 8). Use the parameter that matches what you are tracking — an earthquake belongs under `disaster.name`, an outbreak under `disease.name`. If you are unsure of the type, check it with entity autocomplete first. In practice the first two are the useful ones: the disaster and disease directories are well populated (`disease.name=influenza` matches over 100,000 articles), while the **event directory is nearly empty**. Named events people expect to work — `Super Bowl`, `World Cup`, `Olympics` — are not in it and return `400 ER0228`. Track events through [`event.type` and `event.category`](/en/articles/searching-and-filtering/events/filter-by-event-type) instead, or through a headline search with `title`. ## How many disasters or diseases can I track in one request?[#](#how-many-disasters-or-diseases-can-i-track-in-one-request) Up to three per parameter. `disaster.name`, `disease.name` and their `ignore.` variants each accept a comma-separated list, and only the first three values are applied. Multiple values inside one parameter use OR logic, so an article matches if it mentions any of them. Adding a second parameter narrows results with AND. ## Why does my disaster or disease name return an error?[#](#why-does-my-disaster-or-disease-name-return-an-error) The name must match an entity APITube already tracks. An unknown `disaster.name` returns `ER0224` and an unknown `disease.name` returns `ER0226`, both HTTP 400, and the request stops at the first unresolved name. A name shorter than 1 or longer than 120 characters returns `ER0148` (disaster) or `ER0152` (disease). Confirm the exact spelling and entity type through `GET /v1/suggest/entities?prefix=` before filtering. ## Can I exclude a disaster or disease from my results?[#](#can-i-exclude-a-disaster-or-disease-from-my-results) Yes. Use `ignore.disaster.name` or `ignore.disease.name` with the same rules — up to three comma-separated names, each 1 to 120 characters. They keep articles that do **not** mention the named disaster or disease. An unknown name returns `ER0225` for `ignore.disaster.name` and `ER0227` for `ignore.disease.name`. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Monitor Breaking News and Real-Time Events](/en/articles/searching-and-filtering/events/monitor-breaking-news) --- ## Searching & Filtering News URL: https://support.apitube.io/en/articles/searching-and-filtering Search and filter the APITube News API by keyword, language, country, source, category, sentiment and more. ![](/images/collections/analysis-tools.png) # Searching & Filtering News Search and filter news by keyword and more. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) By Tasha and 2 others 3 authors 43 articles This is the largest collection in the help center, because search is where the APITube News API earns its keep. The guides below cover keyword and phrase search, filtering by attributes such as source, language and country, sentiment and entity filters, event filters, content-quality controls, and how to sort and shape the response. Every parameter mentioned here is documented in the official [parameter reference](https://docs.apitube.io/platform/news-api/everything) on docs.apitube.io. A good starting point is [combining filters](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) — most real queries use two or three filters together. ## [Keyword & Title Search](/en/articles/searching-and-filtering/keyword-search) * * * * [How to Exclude Keywords or Sources from News](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources) * [How to Refine Your Title Search](/en/articles/searching-and-filtering/keyword-search/refine-title-search) * [How to Search for an Exact Phrase in News Titles](/en/articles/searching-and-filtering/keyword-search/exact-phrase-search) * [How to Search News by Title](/en/articles/searching-and-filtering/keyword-search/search-by-title) * [How to Search News in Plain English](/en/articles/searching-and-filtering/keyword-search/natural-language-search) * [How to Use AND, OR and NOT in News Search](/en/articles/searching-and-filtering/keyword-search/boolean-search) ## [Content & Quality](/en/articles/searching-and-filtering/content-quality) * * * * [How to Detect and Filter Clickbait Articles](/en/articles/searching-and-filtering/content-quality/filter-clickbait) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) * [How to Filter by Media Quality and Social-Ready Images](/en/articles/searching-and-filtering/content-quality/filter-by-media-quality) * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [How to Filter for Premium and Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-premium-verified-sources) * [How to Filter News by Read Time and Readability](/en/articles/searching-and-filtering/content-quality/filter-by-readtime-readability) * [How to Filter News by Source Political Bias](/en/articles/searching-and-filtering/content-quality/filter-by-source-bias) * [How to Find News Articles With Images or Videos](/en/articles/searching-and-filtering/content-quality/filter-by-media) ## [Entities, People & Companies](/en/articles/searching-and-filtering/entities) * * * * [How to Browse the Companies Directory](/en/articles/searching-and-filtering/entities/companies-directory) * [How to Browse the People Directory](/en/articles/searching-and-filtering/entities/people-directory) * [How to Find Journalists by Byline and Beat](/en/articles/searching-and-filtering/entities/journalists-directory) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to Track News About a Specific Person](/en/articles/searching-and-filtering/entities/track-news-about-a-person) * [How to Use Entity Autocomplete in Search Inputs](/en/articles/searching-and-filtering/entities/entity-autocomplete) ## [Events & Breaking News](/en/articles/searching-and-filtering/events) * * * * [How to Filter News by Event Type](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to Filter News by Natural Disaster and Disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) * [How to Monitor Breaking News and Real-Time Events](/en/articles/searching-and-filtering/events/monitor-breaking-news) ## [Filter by Attributes](/en/articles/searching-and-filtering/by-attribute) * * * * [How to Filter News by Author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Filter News by Country and Location](/en/articles/searching-and-filtering/by-attribute/filter-by-country-and-location) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Filter News by Industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to Filter News by Topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic) * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) ## [Sentiment](/en/articles/searching-and-filtering/sentiment) * * * * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) ## [Sorting, Pagination & Shaping](/en/articles/searching-and-filtering/sorting-and-shaping) * * * * [How to Aggregate News Results with Facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) * [How to Combine Multiple Filters in One Request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) * [How to Highlight Matching Terms in Search Results](/en/articles/searching-and-filtering/sorting-and-shaping/highlight-terms) * [How to Paginate Through News API Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) * [How to Return Only Specific Fields with fl](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) * [How to Sort News by Controversy, Trust and Social Shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) * [How to Sort News by Rank, Length and Sentiment](/en/articles/searching-and-filtering/sorting-and-shaping/sort-news) * [How to Sort News by Relevance, Date or Quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) --- ## How to Use AND, OR and NOT in News Search URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search/boolean-search Use AND, OR and NOT in the APITube News API query parameter to combine keywords, match alternatives, exclude terms and group conditions with parentheses. # How to Use AND, OR and NOT in News Search Build boolean searches with the query parameter — combine, alternate and exclude keywords ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 Updated August 15, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&query=bitcoin) # How to use AND, OR and NOT in search[#](#how-to-use-and-or-and-not-in-search) The APITube News API has a boolean search language behind one parameter: `query`. Send it to `/v1/news/everything` and you can join keywords with `AND`, offer alternatives with `OR`, and drop terms with `NOT` (or the `-` prefix), grouping any of them with parentheses. A bare word searches the article **headline** by default, so `query=bitcoin AND ethereum` finds headlines that contain both words. ``` curl "https://api.apitube.io/v1/news/everything?query=bitcoin AND ethereum&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter. In a real request, URL-encode the `query` value — spaces, parentheses and quotes must be percent-encoded. The boolean language is opt-in: it only runs when you pass `query=`. Leave it out and your existing flat filters (`title=`, `language.code=`, and the rest) work exactly as before. ## What does the query parameter do?[#](#what-does-the-query-parameter-do) The `query` parameter adds boolean logic on top of the same fields the flat filters already cover. Operator precedence is **`NOT` first, then `AND`, then `OR`**, and parentheses override that order. A bare term with no field prefix targets the headline, which means `query=tesla` is the same as `query=title:tesla`. Everything you build with `query` is combined with any flat parameters in the same request using `AND`, so you can mix both styles: ``` curl "https://api.apitube.io/v1/news/everything?read_time.min=2&query=title:bitcoin&api_key=YOUR_API_KEY" ``` ## How to combine keywords with AND[#](#how-to-combine-keywords-with-and) Put `AND` between two conditions to require **both**. A plain space between terms means the same thing — an implicit `AND` — so `query=bitcoin ethereum` and `query=bitcoin AND ethereum` are identical. Both headline words must be present for an article to match: ``` curl "https://api.apitube.io/v1/news/everything?query=tesla AND recall&api_key=YOUR_API_KEY" ``` ## How to match either keyword with OR[#](#how-to-match-either-keyword-with-or) Use `OR` to accept **any** of several terms. When the words target the same field, scope them once and list the alternatives in parentheses — `title:(tesla OR ford)` matches a headline containing either name: ``` curl "https://api.apitube.io/v1/news/everything?query=title:(tesla OR ford)&api_key=YOUR_API_KEY" ``` Because `AND` binds tighter than `OR`, write `(a OR b) AND c` with explicit parentheses whenever you want the alternation evaluated first. ## How to exclude keywords with NOT[#](#how-to-exclude-keywords-with-not) `NOT` removes anything that matches the condition after it. The `-` prefix is a shorthand for the same thing, so `NOT lawsuit` and `-lawsuit` behave alike. In a flat chain, `NOT` negates only the operand directly after it — `query=tesla AND NOT lawsuit AND ford` keeps Tesla-and-Ford headlines while dropping the ones that mention a lawsuit: ``` curl "https://api.apitube.io/v1/news/everything?query=tesla AND NOT lawsuit&api_key=YOUR_API_KEY" ``` `NOT` works on **every** field, not just the headline, which makes it the general replacement for the `ignore.*` parameters: `NOT source.country.code:ru` does the same job as `ignore.source.country.code=ru`. For the dedicated exclusion parameters, see [How to exclude keywords or sources from news](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources). ## How to group conditions with parentheses[#](#how-to-group-conditions-with-parentheses) Parentheses set evaluation order and let a `NOT` apply to a whole group instead of a single term. `query=tesla AND NOT (recall OR lawsuit)` keeps Tesla headlines but removes any that mention a recall **or** a lawsuit: ``` curl "https://api.apitube.io/v1/news/everything?query=tesla AND NOT (recall OR lawsuit)&api_key=YOUR_API_KEY" ``` You can nest groups up to 10 levels deep and use up to 64 conditions in one query, with a maximum query length of 4000 characters. Crossing any of those limits returns HTTP 400 with error `ER0703`. ## How to run boolean logic across other fields[#](#how-to-run-boolean-logic-across-other-fields) Field names in `query` are the exact names of the flat parameters, so the boolean language reaches the whole filter set — language, source, category, date, media and more. This pulls English-language headlines about Tesla or Ford, but excludes Russian publishers: ``` curl "https://api.apitube.io/v1/news/everything?query=title:(tesla OR ford) AND language.code:en AND NOT source.country.code:ru&api_key=YOUR_API_KEY" ``` When a value contains a special character — a colon, space or parenthesis — wrap it in double quotes, for example `category.id:"medtop:04000000"`. To filter by language on its own, see [How to filter news by language](/en/articles/searching-and-filtering/by-attribute/filter-by-language). The full field reference lives on the [official News API parameter docs](https://docs.apitube.io/platform/news-api/everything). ## What operators are not supported[#](#what-operators-are-not-supported) The boolean language deliberately leaves out a few Lucene-style operators because the underlying index can’t serve them. Fuzzy matching (`term~2`), wildcards (`ter*`, `te?t`), boosting (`term^3`) and regular expressions all return HTTP 400 with error `ER0704`. There is also no full-text search over the article **body** — bare terms always match the headline. For partial-title matching, use `title.starts_with`, `title.ends_with` or `title.pattern` instead of a wildcard. # Common Questions[#](#common-questions) * [Does a bare keyword search the article body?](#does-a-bare-keyword-search-the-article-body) * [Is a space the same as AND or OR?](#is-a-space-the-same-as-and-or-or) * [Can I still use my flat filters with query?](#can-i-still-use-my-flat-filters-with-query) * [Why does my fuzzy or wildcard query fail?](#why-does-my-fuzzy-or-wildcard-query-fail) ## Does a bare keyword search the article body?[#](#does-a-bare-keyword-search-the-article-body) No. A term with no field prefix targets the **headline** only, so `query=inflation` is shorthand for `query=title:inflation`. The boolean language has no full-text search over the article body; the index only holds the title. If you need partial matches within the headline, use `title.starts_with`, `title.ends_with` or `title.pattern`. ## Is a space the same as AND or OR?[#](#is-a-space-the-same-as-and-or-or) A space between two conditions is an implicit `AND`, not `OR`. `query=tesla ford` requires both words in the headline, exactly like `query=tesla AND ford`. To accept either word, you must write `OR` explicitly — `query=title:(tesla OR ford)`. ## Can I still use my flat filters with query?[#](#can-i-still-use-my-flat-filters-with-query) Yes. The `query` parameter is added to the request as a single condition joined to your flat parameters with `AND`. You can send `read_time.min=2&query=title:bitcoin` together, and both apply. Without `query=`, nothing changes and the flat filters behave exactly as they always have. ## Why does my fuzzy or wildcard query fail?[#](#why-does-my-fuzzy-or-wildcard-query-fail) Fuzzy matching (`~`), wildcards (`*`, `?`), boosting (`^`) and regex are not supported and return HTTP 400 with error `ER0704`. An unknown field name returns `ER0702`, and a syntax error such as an unclosed parenthesis returns `ER0701`. Check that every field name matches a real parameter and that your parentheses and quotes are balanced. * * * ## Related Articles * [How to Exclude Keywords or Sources from News](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources) * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Search News in Plain English](/en/articles/searching-and-filtering/keyword-search/natural-language-search) --- ## How to Search for an Exact Phrase in News Titles URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search/exact-phrase-search Wrap keywords in double quotes to match an exact phrase in article titles: exact word order, no synonym or stem expansion, on the /v1/news/everything endpoint. # How to Search for an Exact Phrase in News Titles Wrap your keywords in double quotes to match a phrase exactly, instead of any title that contains the words ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to search for an exact phrase in news titles[#](#how-to-search-for-an-exact-phrase-in-news-titles) To match an exact phrase, wrap the whole `title` value in **double quotes**. On `/v1/news/everything`, `title="Federal Reserve"` returns only articles whose title contains that literal phrase — the words together, in order — instead of every article that happens to mention “federal” and “reserve” somewhere. The safest way to send a quoted phrase is with `--data-urlencode`, so the quotes survive the shell and URL encoding: ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode 'title="Federal Reserve"' \ --data-urlencode "api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter. The request above returns headlines that contain the exact phrase “Federal Reserve”. ## What is the difference between quoted and unquoted title search?[#](#what-is-the-difference-between-quoted-and-unquoted-title-search) The quotes change how `title` is matched. Without them, the search is broad; with them, it is literal. * **Unquoted** — `title=Federal Reserve` matches titles that contain **both** words as separate tokens, in any order and any position, and it also expands each word with synonyms and word-stems. A title like “Reserve currency and the federal budget” can match. * **Quoted** — `title="Federal Reserve"` matches only titles where the phrase **“federal reserve”** appears as written, the words adjacent and in order. There is **no** synonym or stem expansion, so the match is much tighter. Use unquoted search when you want reach, and an exact phrase when you want precision — proper names, institutions, product names or quotes where word order matters. ## How does exact-phrase matching behave?[#](#how-does-exact-phrase-matching-behave) An exact-phrase match is case-insensitive and looks for the phrase as a contiguous run of characters inside the title. “Federal Reserve” and “federal reserve” match the same articles; the order and adjacency of the words are required. Because there is no synonym or morphology expansion inside quotes, the phrase has to be present literally — a near-synonym or a different word ending will not match. The phrase inside the quotes must be at least **3 characters** long; a shorter phrase returns HTTP 400 with error `ER0340` (an empty `title=""` is treated as an unquoted search, not an error). The whole `title` value, quotes included, is capped at **100 characters** (`ER0007`). These limits apply to the quoted phrase only — the rest of your filters are unaffected. ## How to combine an exact phrase with other filters and exclusions[#](#how-to-combine-an-exact-phrase-with-other-filters-and-exclusions) Exact-phrase search is just a `title` value, so every other filter still applies. Narrow a phrase by language, source or date, and remove unwanted articles with `ignore.title`, which drops any article whose title contains the given words: ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode 'title="electric vehicle"' \ --data-urlencode "language.code=en" \ --data-urlencode "ignore.title=opinion,review" \ --data-urlencode "api_key=YOUR_API_KEY" ``` This returns English headlines containing the exact phrase “electric vehicle” while excluding titles that mention “opinion” or “review”. To restrict the phrase to specific publishers, add a [source filter](/en/articles/searching-and-filtering/by-attribute/filter-by-source); to remove terms, see [how to exclude keywords or sources](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources). If you need logic across several words rather than one fixed phrase, use the Boolean query language described in [how to use AND, OR and NOT in news search](/en/articles/searching-and-filtering/keyword-search/boolean-search). The canonical parameter list is in the [official News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Why does a quoted phrase return fewer results?](#why-does-a-quoted-phrase-return-fewer-results) * [Does exact-phrase search use synonyms or word stems?](#does-exact-phrase-search-use-synonyms-or-word-stems) * [What length limits apply to a phrase?](#what-length-limits-apply-to-a-phrase) * [Does the phrase search the article body too?](#does-the-phrase-search-the-article-body-too) ## Why does a quoted phrase return fewer results?[#](#why-does-a-quoted-phrase-return-fewer-results) A quoted phrase is stricter than the same words unquoted. Unquoted, `title=Federal Reserve` matches any title with both words in any order, plus synonym and stem variants. Quoted, `title="Federal Reserve"` requires the exact phrase, adjacent and in order, with no expansion — so it naturally returns a smaller, more precise set. If you are getting too few results, drop the quotes to widen the match. ## Does exact-phrase search use synonyms or word stems?[#](#does-exact-phrase-search-use-synonyms-or-word-stems) No. Inside quotes there is no synonym or morphology expansion: the phrase must appear literally in the title. This is the trade-off that makes phrase search precise. If you want variants — plurals, stems and synonyms — use an unquoted `title` value, which expands each word automatically. ## What length limits apply to a phrase?[#](#what-length-limits-apply-to-a-phrase) The phrase between the quotes must be 3 to 200 characters, and a phrase shorter than that returns error `ER0340`. Separately, the entire `title` value, including the quote characters, must stay within 100 characters or you get error `ER0007`. In practice the 100-character cap on the whole value is the limit you will hit first for long phrases. ## Does the phrase search the article body too?[#](#does-the-phrase-search-the-article-body-too) No. The `title` parameter — quoted or not — matches against the article title only. There is no synonym expansion inside quotes and no body-text matching here; phrase search is a title filter. To shape results further, combine it with filters such as language, source and date on the same `/v1/news/everything` request. * * * ## Related Articles * [How to Use AND, OR and NOT in News Search](/en/articles/searching-and-filtering/keyword-search/boolean-search) * [How to Exclude Keywords or Sources](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources) * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) --- ## How to Exclude Keywords or Sources from News URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources Use ignore.title to remove articles by headline keyword and ignore.source.* to exclude specific publishers, domains and countries in the APITube News API. # How to Exclude Keywords or Sources from News Drop unwanted topics with ignore.title and unwanted publishers with ignore.source.\* ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 Updated July 7, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=AI&ignore_title=layoffs%2Cjob) # How to exclude keywords or sources[#](#how-to-exclude-keywords-or-sources) To remove results you don’t want, the APITube News API gives you a family of `ignore.*` parameters. `ignore.title` drops any article whose headline contains a keyword, and `ignore.source.domain`, `ignore.source.id` and `ignore.source.country.code` drop specific publishers. Every `ignore.*` parameter attaches to `/v1/news/everything` and runs alongside your positive filters, so you can keep what you want and subtract what you don’t in a single request. ``` curl "https://api.apitube.io/v1/news/everything?title=AI&ignore.title=layoffs,job losses&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. The request above keeps AI headlines but removes the layoffs angle. ## How to exclude keywords from results[#](#how-to-exclude-keywords-from-results) `ignore.title` removes any article whose **headline** contains the word you pass. This request drops celebrity coverage from a general feed: ``` curl "https://api.apitube.io/v1/news/everything?ignore.title=celebrity&api_key=YOUR_API_KEY" ``` List several terms separated by commas, and an article is removed if its title contains **any** of them: ``` curl "https://api.apitube.io/v1/news/everything?title=AI&ignore.title=layoffs,job losses&api_key=YOUR_API_KEY" ``` Two details matter. First, `ignore.title` checks the article **title only** — it does not scan the body text, so a word that appears deep in the article but not in the headline will not trigger an exclusion. Second, APITube expands the term against its dictionary before excluding, so close word forms of the keyword (for example a plural or singular variant) are caught as well. The value must be between 2 and 100 characters; anything outside that range returns HTTP 400 with error `ER0008`. ## How to exclude specific sources[#](#how-to-exclude-specific-sources) Use `ignore.source.domain` to drop a publisher by its website address, or `ignore.source.id` to drop it by numeric ID. Both accept a comma-separated list of up to three values. This request keeps every source except two tabloids: ``` curl "https://api.apitube.io/v1/news/everything?ignore.source.domain=foxnews.com,nypost.com&api_key=YOUR_API_KEY" ``` Each domain must be a publisher APITube already tracks. An unknown domain returns HTTP 400 with error `ER0215`, and the whole request stops on the first bad value, so confirm a domain exists before you exclude it. The full rules for source filtering are in [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source). ## How to exclude every source from a country[#](#how-to-exclude-every-source-from-a-country) `ignore.source.country.code` removes all publishers registered in a country. Pass a two-letter country code, up to three at once: ``` curl "https://api.apitube.io/v1/news/everything?ignore.source.country.code=fr,de&api_key=YOUR_API_KEY" ``` A code that is not exactly two characters returns error `ER0247`, and a country code APITube does not recognise returns `ER0213` — both HTTP 400. ## How to exclude an author[#](#how-to-exclude-an-author) `ignore.author.name` removes articles written under a specific byline. List up to three names, separated by commas: ``` curl "https://api.apitube.io/v1/news/everything?ignore.author.name=John Smith&api_key=YOUR_API_KEY" ``` The name must match an author APITube tracks; an unknown name returns `ER0205`, and a name outside the 1–100 character range returns `ER0073`. For including authors instead of excluding them, see [How to filter news by author](/en/articles/searching-and-filtering/by-attribute/filter-by-author). ## How exclusion combines with the rest of your query[#](#how-exclusion-combines-with-the-rest-of-your-query) Every `ignore.*` parameter is part of the same shared filter chain as the positive filters, so they stack in one request. This pulls English AI news, drops the layoffs angle, and removes one tabloid — all at once: ``` curl "https://api.apitube.io/v1/news/everything?title=AI&language.code=en&ignore.title=layoffs&ignore.source.domain=nypost.com&api_key=YOUR_API_KEY" ``` The positive filters (`title`, `language.code`) decide what is eligible, and the `ignore.*` filters subtract from that set. You can read the canonical list of every parameter on the [official News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Does ignore.title also search the article body?](#does-ignoretitle-also-search-the-article-body) * [How many values can each ignore parameter take?](#how-many-values-can-each-ignore-parameter-take) * [What happens if I exclude a domain APITube doesn’t track?](#what-happens-if-i-exclude-a-domain-apitube-doesnt-track) * [Can I include and exclude in the same request?](#can-i-include-and-exclude-in-the-same-request) ## Does ignore.title also search the article body?[#](#does-ignoretitle-also-search-the-article-body) No. `ignore.title` matches the article **headline** only. If a keyword appears in the body of an article but not in its title, that article is still returned. This is the same field the positive `title` parameter searches, so keyword inclusion and exclusion both operate on the headline. ## How many values can each ignore parameter take?[#](#how-many-values-can-each-ignore-parameter-take) `ignore.source.domain`, `ignore.source.id`, `ignore.source.country.code` and `ignore.author.name` each accept up to three comma-separated values; anything beyond the third is silently dropped. `ignore.title` accepts multiple comma-separated keywords and removes an article if its headline contains any of them. ## What happens if I exclude a domain APITube doesn’t track?[#](#what-happens-if-i-exclude-a-domain-apitube-doesnt-track) The request fails with HTTP 400 and error `ER0215` (`source domain name '…' not found`), and it stops on the first unrecognised domain. Confirm each domain is one APITube tracks before adding it to `ignore.source.domain`. ## Can I include and exclude in the same request?[#](#can-i-include-and-exclude-in-the-same-request) Yes. Positive filters like `title`, `source.domain` or `language.code` define the candidate set, and the `ignore.*` filters remove from it. You can combine any of them — for example keep `source.domain=theguardian.com` while still applying `ignore.title=opinion` to skip opinion pieces from that publisher. * * * ## Related Articles * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to Filter News by Author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) --- ## Keyword & Title Search URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search Search the APITube News API by headline keywords, exact phrases, Boolean logic or a plain-English prompt, and exclude the keywords or sources you don't want. # Keyword & Title Search Keywords, phrases, Boolean logic and plain English. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) By Kent 1 author 6 articles * [How to Exclude Keywords or Sources from News](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources) * [How to Refine Your Title Search](/en/articles/searching-and-filtering/keyword-search/refine-title-search) * [How to Search for an Exact Phrase in News Titles](/en/articles/searching-and-filtering/keyword-search/exact-phrase-search) * [How to Search News by Title](/en/articles/searching-and-filtering/keyword-search/search-by-title) * [How to Search News in Plain English](/en/articles/searching-and-filtering/keyword-search/natural-language-search) * [How to Use AND, OR and NOT in News Search](/en/articles/searching-and-filtering/keyword-search/boolean-search) --- ## How to Search News in Plain English URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search/natural-language-search Use the prompt parameter to describe the news you want in plain English. APITube turns the sentence into filters and returns them in meta.prompt. # How to Search News in Plain English Send a sentence in the prompt parameter and the News API builds the filters for you ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to search news in plain English[#](#how-to-search-news-in-plain-english) Send your request as a sentence in the `prompt` parameter and the APITube News API turns it into real filters before it searches. The sentence must be **3 to 500 characters**, and the parameters it produced come back in `meta.prompt`, so you can always see what actually ran. ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "prompt=Tesla and Elon Musk news in English for the last 10 days" \ --data-urlencode "api_key=YOUR_API_KEY" ``` That one request is the equivalent of writing `person.name=Elon Musk`, `organization.name=Tesla`, `language.code=en` and `published_at.start=NOW-10DAY` yourself. You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter, and `prompt` also works in a `POST` body. `prompt` is a premium feature: it works on **Basic, Professional and Corporate**. A Free or Starter key gets `403` with error `ER0706` and is not charged. The filters themselves are available on every plan — see [how to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title) to write them by hand. ## What does the prompt parameter do?[#](#what-does-the-prompt-parameter-do) The `prompt` parameter is translated into the API’s ordinary parameters **on the server, before the search runs**. It is not a separate search engine and it is not a summary layer: after the translation, the request behaves exactly like a hand-written one, so sorting, [pagination](/en/articles/getting-started/glossary#pagination), field selection and [export formats](/en/articles/getting-started/glossary#export-format) all still apply. The translation can produce headline keywords and exact phrases (`title`), [entity](/en/articles/getting-started/glossary#entity) filters (`person.name`, `organization.name`, `location.name`, `brand.name`, `event.name`, `disease.name`, `disaster.name`, `sport.name`), taxonomy filters (`category.id`, `topic.id`, `industry.id`), `source.domain`, `author.name`, `language.code`, `source.country.code`, a date range, `sentiment.overall.polarity`, `sort.by`, `sort.order`, `per_page`, and the boolean flags `is_breaking`, `has_image`, `has_video`, `is_paywall` and `is_long_read`. Two limits are worth knowing up front. Each filter takes at most **3 values**, so a prompt naming eight companies will lose five of them. And broad sections are picked from the **17 top-level IPTC categories** only — a narrow subject becomes a topic or a headline keyword instead, which keeps a wide question from silently turning into a narrow one. ## How do I see which filters my prompt produced?[#](#how-do-i-see-which-filters-my-prompt-produced) Read `meta.prompt` in the response. Every JSON response to a request that used `prompt` carries it: ``` { "meta": { "prompt": { "text": "positive Tesla coverage from German publishers this month", "applied": { "organization.name": "Tesla", "source.country.code": "de", "sentiment.overall.polarity": "positive", "published_at.start": "NOW/MONTH" }, "ignored": [ { "field": "topic.id", "value": "electric vehicles", "reason": "not_found" } ], "cached": true } } } ``` `applied` is the request that actually ran — this is the field to check first when results look wrong. `ignored` lists everything that was understood but not used, and `cached` tells you whether this wording had been parsed before. Note that periods are stored as date math (`NOW-10DAY`, `NOW/MONTH`), not as calendar dates. The expression is resolved on every request, so a saved prompt keeps meaning “the last 10 days” next month too. ## Why was part of my prompt ignored?[#](#why-was-part-of-my-prompt-ignored) Each entry in `meta.prompt.ignored` carries a `reason`: * **`not_found`** — the name is not in APITube’s reference books. Entity names are not simply dropped: they fall back to a headline keyword, so the request still returns something sensible instead of a `400`. To filter precisely, look the real name up first, as described in [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). * **`explicit_param`** — you sent that parameter yourself and your value was kept. This is deliberate: an explicit parameter always beats the prompt, so you can pin `language.code=de` and let the prompt handle the topic. * **`unsupported_on_endpoint`** — the endpoint does not accept that filter. This happens on `/v1/news/raw`, which only uses the dates, `sort.order` and `per_page` out of a prompt. * **`invalid_date`** — the period could not be read as a date or as date math. * **`title_too_long`** — the term did not fit the 100-character `title` budget and was dropped whole rather than cut in half. * **`title_window_clamped`** — the prompt asked for a headline search over more than 31 days, so the start date was moved to the 31-day limit that applies to every title search. ## Which endpoints accept a prompt?[#](#which-endpoints-accept-a-prompt) `prompt` works on `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/local`, `/v1/news/count`, `/v1/news/trends`, the `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity` endpoints, and both real-time streams (`/v1/news/stream` and `/v1/news/ws`). `/v1/news/raw` accepts it too, but applies only the dates, `sort.order` and `per_page` it understands — everything else comes back in `meta.prompt.ignored` with `reason: unsupported_on_endpoint`. `/v1/news/raw` accepts it but applies only part of it. `/v1/news/article`, `/v1/news/story`, `/v1/fact-check` and the suggest endpoints ignore `prompt` completely — no translation runs there and nothing is charged. The [SSE](/en/articles/getting-started/glossary#sse-stream) stream applies the filters but returns no `meta.prompt`, because an SSE response has no JSON envelope. The [WebSocket](/en/articles/getting-started/glossary#websocket) stream echoes the expanded filters in its `subscribed` acknowledgement frame instead. ## How much does a prompt cost?[#](#how-much-does-a-prompt-cost) Translating a prompt costs **2 points** on top of the endpoint’s usual cost, and only when that exact wording has not been parsed before. Interpretations are cached for **24 hours** against the normalized text, so `Tesla NEWS` and `tesla news` count as the same entry and the repeat is free. `meta.prompt.cached` tells you which one happened. ## Which plans include the prompt parameter?[#](#which-plans-include-the-prompt-parameter) `prompt` is available on **Basic, Professional and Corporate**. On the Free and Starter plans the request returns `403` with error code `ER0706` and nothing is charged, because the plan is checked before the language model is called. Every filter a prompt would build — `title`, entity filters, categories, dates, [sentiment](/en/articles/getting-started/glossary#sentiment) — works on every plan; `prompt` is the paid convenience of having them written for you, and each new wording runs a language-model call on APITube’s side. Plan `prompt` Free No — `403 ER0706` Starter No — `403 ER0706` Basic Yes Professional Yes Corporate Yes Your quota is checked at the same point, so an account out of points gets the usual `402` rather than paying for a translation. See [compare APITube plans](/en/articles/billing/plans/compare-plans) for the rest of the tier differences. ## How is this different from Ask News and the MCP server?[#](#how-is-this-different-from-ask-news-and-the-mcp-server) All three let you ask in plain language, but the language is interpreted in different places. The `prompt` parameter is interpreted **inside the API** and returns normal JSON. [Ask News](/en/articles/account-and-dashboard/ask-news/what-is-ask-news) is a chat interface in the dashboard that calls the API for you and writes an answer. The [MCP server](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) lets an AI assistant build the filters on its side and call the API itself. If you are writing code, `prompt` is usually the one you want: one HTTP request, no assistant in the loop, and a machine-readable record of how your sentence was read. The full parameter reference lives in the [official News API parameter docs](https://docs.apitube.io/platform/news-api/everything#prompt). # Common Questions[#](#common-questions) * [What do errors ER0706, ER0800, ER0801 and ER0802 mean?](#what-do-errors-er0706-er0800-er0801-and-er0802-mean) * [Can I mix a prompt with normal filters?](#can-i-mix-a-prompt-with-normal-filters) * [Does the prompt search inside the article body?](#does-the-prompt-search-inside-the-article-body) * [Can a prompt invent a category or entity that does not exist?](#can-a-prompt-invent-a-category-or-entity-that-does-not-exist) * [Why did my prompt return no articles?](#why-did-my-prompt-return-no-articles) ## What do errors ER0706, ER0800, ER0801 and ER0802 mean?[#](#what-do-errors-er0706-er0800-er0801-and-er0802-mean) `ER0706` is HTTP 403 and means the plan does not include `prompt` — Free and Starter keys get it, and nothing is charged. The same number is also used by the Fact Check endpoint and by the boolean `query` parser, so match on the HTTP status and message, not on the code alone. `ER0800` is HTTP 400 and means the prompt is shorter than 3 or longer than 500 characters. `ER0801` is HTTP 502 and means the translation service was unavailable — nothing is charged, so retry. `ER0802` is HTTP 400 and means nothing usable came out of the prompt: either no filter was found in the sentence, or everything it produced was overridden by your explicit parameters or unsupported on that endpoint. There is no silent fallback, which is intentional — a failed translation should not look like an answer. ## Can I mix a prompt with normal filters?[#](#can-i-mix-a-prompt-with-normal-filters) Yes, and the mix is predictable: any parameter you send explicitly wins, and the prompt’s version of it is reported in `meta.prompt.ignored` with `reason: explicit_param`. This is the recommended pattern for production code — pin the parts that must be exact, such as `language.code` or `source.domain`, and let the prompt cover the topic. ## Does the prompt search inside the article body?[#](#does-the-prompt-search-inside-the-article-body) No. APITube’s search covers headlines, not article bodies, and a prompt cannot change that. Wording that no structured field covers becomes a `title` search — up to 3 terms, 100 characters in total — exactly as if you had passed those keywords yourself. ## Can a prompt invent a category or entity that does not exist?[#](#can-a-prompt-invent-a-category-or-entity-that-does-not-exist) No. The language model returns names, never identifiers; IDs are looked up afterwards against APITube’s own reference books. Entity names are matched exactly, ignoring case, so a near miss is not accepted — the entity book has no generic “Earthquake”, only specific ones like “2013 Aceh earthquake”, and picking one of those would quietly replace a broad question with a single event. ## Why did my prompt return no articles?[#](#why-did-my-prompt-return-no-articles) Check `meta.prompt.applied` before anything else. The most common causes are a filter combination that is simply too narrow, an entity that fell back to a headline keyword after `not_found`, or a date range you did not intend. Remove one filter at a time from the `applied` set by rewriting the sentence, or send those parameters by hand once you know which one is emptying the result. * * * ## Related Articles * [How to Search News by Title](/en/articles/searching-and-filtering/keyword-search/search-by-title) * [How to Use AND, OR and NOT in News Search](/en/articles/searching-and-filtering/keyword-search/boolean-search) * [How to Combine Multiple Filters in One Request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) --- ## How to Refine Your Title Search URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search/refine-title-search Refine an APITube News API title search with title_starts_with, title_ends_with and title_pattern to match the beginning, end or any substring of a headline. # How to Refine Your Title Search Match the start, end or any substring of a headline with title\_starts\_with, title\_ends\_with and title\_pattern ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title_starts_with=breaking) # How to refine your title search[#](#how-to-refine-your-title-search) When a plain `title` search returns too much, narrow it by matching a specific part of the headline: use `title_starts_with` to match the beginning, `title_ends_with` to match the end, and `title_pattern` to match any substring anywhere in the title. All three are query parameters on `/v1/news/everything` and work alongside every other filter. ``` curl "https://api.apitube.io/v1/news/everything?title_starts_with=breaking&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. ## How is title\_pattern different from title?[#](#how-is-title_pattern-different-from-title) The plain `title` parameter matches **whole words** (tokens) in the headline, so `title=ai` finds the word “AI” but not “Jamaica”. The `title_pattern` parameter matches a **substring** instead, using a `LIKE '%term%'` test, so it can match inside a longer word. Reach for `title_pattern` when you want loose, partial matching, and stick with `title` when you want clean word matches. ``` # whole-word match: finds the word "ai" curl "https://api.apitube.io/v1/news/everything?title=ai&api_key=YOUR_API_KEY" # substring match: also matches "email", "campaign", "detail"… curl "https://api.apitube.io/v1/news/everything?title_pattern=ai&api_key=YOUR_API_KEY" ``` Because `title_pattern` matches partial words, keep the term specific — a short or generic substring will pull in unrelated headlines. ## How to match the start or end of a headline[#](#how-to-match-the-start-or-end-of-a-headline) `title_starts_with` matches headlines whose title **begins** with your term, and `title_ends_with` matches headlines whose title **ends** with it. Both are case-insensitive (the API lowercases the title before comparing) and apply to the whole headline string, not to individual words. ``` # headlines that begin with "Apple" curl "https://api.apitube.io/v1/news/everything?title_starts_with=Apple&api_key=YOUR_API_KEY" # headlines that end with "2026" curl "https://api.apitube.io/v1/news/everything?title_ends_with=2026&api_key=YOUR_API_KEY" ``` These are handy for structured headlines — alerts that lead with a keyword, recurring column names, or titles that close with a year or location. ## What are the length limits and error codes?[#](#what-are-the-length-limits-and-error-codes) Each refining parameter validates its length before running and returns HTTP 400 with a specific error code if the value is out of range. A value shorter than 2 characters is rejected, so always pass at least two characters: * `title_starts_with` — 2 to 100 characters, otherwise error `ER0009`. * `title_ends_with` — 2 to 100 characters, otherwise error `ER0010`. * `title_pattern` — 2 to 200 characters, otherwise error `ER0011`. For comparison, the plain `title` parameter is 2 to 100 characters (`ER0007`). The wider 200-character ceiling on `title_pattern` lets you paste a longer substring when you need it. ## Do these parameters expand synonyms and word forms?[#](#do-these-parameters-expand-synonyms-and-word-forms) Yes. Like the plain `title` filter, all three refining parameters pass your term through APITube’s query expansion (synonyms and morphological forms) before matching. Each expanded variant is combined with OR, so the request matches headlines containing any form of the term, not only the exact spelling you typed. This means a single `title_pattern` can quietly match several related spellings — useful for recall, but another reason to keep the term specific when you want precision. You can combine these parameters with each other and with any other filter (language, date, source, category) in the same request — the title conditions are added on top of the rest of your query. For the full list of accepted parameters and values, see the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Which parameter should I use to match part of a word?](#which-parameter-should-i-use-to-match-part-of-a-word) * [Are title\_starts\_with and title\_ends\_with case-sensitive?](#are-title_starts_with-and-title_ends_with-case-sensitive) * [Why did my title refinement return a 400 error?](#why-did-my-title-refinement-return-a-400-error) * [Can I combine these with a normal title search?](#can-i-combine-these-with-a-normal-title-search) ## Which parameter should I use to match part of a word?[#](#which-parameter-should-i-use-to-match-part-of-a-word) Use `title_pattern`. It performs a substring match (`LIKE '%term%'`), so it matches the term anywhere inside the headline, including inside a longer word. The plain [`title` search](/en/articles/searching-and-filtering/keyword-search/search-by-title) matches whole words only, and `title_starts_with` / `title_ends_with` anchor to the start or end of the entire title, so none of those will match a fragment in the middle of a word the way `title_pattern` does. ## Are title\_starts\_with and title\_ends\_with case-sensitive?[#](#are-title_starts_with-and-title_ends_with-case-sensitive) No. Both convert the headline to lowercase before testing the prefix or suffix, so `title_starts_with=apple` and `title_starts_with=Apple` return the same results. The match is anchored to the whole title string: `title_starts_with` checks the first characters of the headline, and `title_ends_with` checks the last characters. ## Why did my title refinement return a 400 error?[#](#why-did-my-title-refinement-return-a-400-error) The value was out of its allowed length range. `title_starts_with` and `title_ends_with` accept 2 to 100 characters (`ER0009` / `ER0010`), and `title_pattern` accepts 2 to 200 characters (`ER0011`). The most common cause is passing a single character — every refining parameter requires at least two. ## Can I combine these with a normal title search?[#](#can-i-combine-these-with-a-normal-title-search) Yes. You can send `title`, `title_starts_with`, `title_ends_with` and `title_pattern` together, and mix them with any other filter. Each adds its own condition to the query, so the result must satisfy all of them at once. For exact multi-word matching, see [how to search for an exact phrase](/en/articles/searching-and-filtering/keyword-search/exact-phrase-search) using quotes in the `title` parameter. * * * ## Related Articles * [How to Search News by Title](/en/articles/searching-and-filtering/keyword-search/search-by-title) * [How to Search for an Exact Phrase](/en/articles/searching-and-filtering/keyword-search/exact-phrase-search) --- ## How to Search News by Title URL: https://support.apitube.io/en/articles/searching-and-filtering/keyword-search/search-by-title Use the title parameter on /v1/news/everything to search article headlines by keyword: multiple words are matched with AND, plus synonym and word-stem… # How to Search News by Title Pass keywords to the title parameter to match article headlines — every word is required, and each one expands to its synonyms and word stems ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 Updated August 15, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to search news by title[#](#how-to-search-news-by-title) To search news by title, send your keywords in the `title` parameter on the `/v1/news/everything` endpoint. `title=bitcoin` returns articles whose headline mentions Bitcoin. The value must be **2 to 100 characters**; anything shorter or longer returns HTTP 400 with error `ER0007`. ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=bitcoin" \ --data-urlencode "api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` parameter. The `title` filter matches the article **title only** — it does not search the article body. ## How does multi-word title search work?[#](#how-does-multi-word-title-search-work) When you pass more than one word, every word is required: the match uses **AND** between words, so the headline has to contain all of them. Words can be separated by either a **space** or a **comma** — both are treated the same way, and both mean AND (a comma here is _not_ an OR). So `title=electric vehicle` and `title=electric,vehicle` behave identically and both return only headlines that contain _both_ “electric” and “vehicle”. ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=electric vehicle" \ --data-urlencode "api_key=YOUR_API_KEY" ``` Matching is done on **whole tokens**, not substrings, so a short word will not match inside a longer one — searching `title=ai` matches the word “AI” but not “Jamaica”. Token matching is also case-insensitive: “Bitcoin”, “bitcoin” and “BITCOIN” all match the same articles. ## Does title search match synonyms and word variations?[#](#does-title-search-match-synonyms-and-word-variations) Yes. Each word in an unquoted `title` value is expanded with its **synonyms** and **word stems** (morphology) before matching, and those variants are combined with OR inside that word’s group. A search for `title=car` can therefore also match headlines that use a known synonym or a different word form, which widens reach without you listing every variant by hand. Very common words (stopwords such as “the” or “of”) are dropped from the query, so they do not narrow your results. This expansion is what makes an unquoted keyword search broad. If you need the words to appear together in a fixed order with no expansion, wrap them in quotes for an [exact-phrase search](/en/articles/searching-and-filtering/keyword-search/exact-phrase-search) instead — `title="electric vehicle"` matches that literal phrase only. ## How to remove unwanted headlines with ignore.title[#](#how-to-remove-unwanted-headlines-with-ignoretitle) To drop articles you do not want, add `ignore.title`. It excludes any article whose title contains the given words (also 2 to 100 characters, error `ER0008` otherwise). Combine it with `title` and any other filter on the same request: ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=AI" \ --data-urlencode "ignore.title=layoffs,job losses" \ --data-urlencode "language.code=en" \ --data-urlencode "api_key=YOUR_API_KEY" ``` This returns English headlines mentioning “AI” while removing any that also mention “layoffs” or “job losses”. For more elaborate include/exclude logic across several words, see [how to use AND, OR and NOT in news search](/en/articles/searching-and-filtering/keyword-search/boolean-search). ## How are title results sorted?[#](#how-are-title-results-sorted) By default, results are ordered by **publish date, newest first** — not by how well they match your keywords. To rank by match quality instead, add `sort.by=relevance`. Relevance scoring rewards an exact title match the most, then a headline that _starts with_ your term, then a headline that simply contains it as a token, and it further boosts recent, high-ranked and breaking articles. The canonical parameter list is in the [official News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=interest rates" \ --data-urlencode "sort.by=relevance" \ --data-urlencode "api_key=YOUR_API_KEY" ``` ## How far back can a title search go?[#](#how-far-back-can-a-title-search-go) A title search covers at most **31 days of publish dates per request**. Send `title` without any dates and the API searches the last 31 days, then tells you so: the response carries a warning with code `ER0366` in `meta.warnings` and an `x-query-window-clamped: 31` header. Send `published_at.start` and `published_at.end` more than 31 days apart and the request is rejected with HTTP 400 and error `ER0110`. ``` # Rejected — a 90-day window with a title search returns ER0110 curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=bitcoin" \ --data-urlencode "published_at.start=2026-04-01" \ --data-urlencode "published_at.end=2026-06-30" \ --data-urlencode "api_key=YOUR_API_KEY" ``` The same 31-day ceiling applies to `title_starts_with`, `title_ends_with`, `title_pattern` and the Boolean `query` parameter, on every plan and every endpoint — including CSV and XLSX exports, the [SSE](/en/articles/getting-started/glossary#sse-stream) stream and [WebSocket](/en/articles/getting-started/glossary#websocket). It exists because headline full-text search is the heaviest query the News API runs, and its cost grows with every extra month the window touches. Watch out for an **open-ended** start date: `title=bitcoin&published_at.start=2024-01-01` with no end date runs from that date to right now, which is far more than 31 days, so it also returns `ER0110`. Pair every archive start with an end date inside the same month. To cover a longer period, walk it one month-sized window at a time and page through each window: ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "title=bitcoin" \ --data-urlencode "published_at.start=2026-04-01" \ --data-urlencode "published_at.end=2026-04-30" \ --data-urlencode "api_key=YOUR_API_KEY" ``` Filters that do not touch the headline are not limited at all. A search by `category.id`, `entity.id`, `source.domain` or `language.code` can span any period in a single request — see [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) for the accepted date formats, including relative values such as `NOW-7DAYS`. # Common Questions[#](#common-questions) * [Is a comma in the title value an AND or an OR?](#is-a-comma-in-the-title-value-an-and-or-an-or) * [Why does title=ai not match “Jamaica”?](#why-does-titleai-not-match-jamaica) * [How do I match a prefix or a substring in the title?](#how-do-i-match-a-prefix-or-a-substring-in-the-title) * [What are the length limits on the title parameter?](#what-are-the-length-limits-on-the-title-parameter) * [Why did my title search return error ER0110?](#why-did-my-title-search-return-error-er0110) ## Is a comma in the title value an AND or an OR?[#](#is-a-comma-in-the-title-value-an-and-or-an-or) A comma is an **AND**, the same as a space. Both `title=electric,vehicle` and `title=electric vehicle` require every word to appear in the headline. There is no comma-separated OR mode on the `title` parameter; if you need true OR logic between alternatives, use the Boolean query language covered in the boolean-search article. ## Why does title=ai not match “Jamaica”?[#](#why-does-titleai-not-match-jamaica) Because title search matches **whole tokens**, not substrings. “ai” is matched as a standalone word, so it hits the headline word “AI” but not the letters _ai_ inside “Jamaica”. This keeps short keywords from accidentally matching unrelated longer words. ## How do I match a prefix or a substring in the title?[#](#how-do-i-match-a-prefix-or-a-substring-in-the-title) Use the dedicated parameters: `title_starts_with` matches headlines that begin with your text, `title_ends_with` matches those that end with it, and `title_pattern` does a substring (LIKE) match anywhere in the headline. These are separate from `title` and let you target the start, end or any part of the headline. ## What are the length limits on the title parameter?[#](#what-are-the-length-limits-on-the-title-parameter) The `title` value must be 2 to 100 characters, otherwise the request fails with HTTP 400 and error `ER0007`. The same 2-to-100 limit applies to `ignore.title` (`ER0008`). When you use an exact phrase in quotes, the phrase inside the quotes must additionally be at least 3 characters (`ER0340`). ## Why did my title search return error ER0110?[#](#why-did-my-title-search-return-error-er0110) Error `ER0110` means the `published_at` range on a title search is wider than the 31-day maximum. Two requests trigger it: a `published_at.start` and `published_at.end` pair more than 31 days apart, and a `published_at.start` older than 31 days with no end date at all. The error message reports the limit and the width of the range you asked for, so you can see how far over you are. Fix it by narrowing the window to 31 days or less, or by dropping the headline filter if you can select the articles another way — for example by `category.id` or `entity.id`, which carry no range limit. * * * ## Related Articles * [How to Search for an Exact Phrase in News Titles](/en/articles/searching-and-filtering/keyword-search/exact-phrase-search) * [How to Use AND, OR and NOT in News Search](/en/articles/searching-and-filtering/keyword-search/boolean-search) * [How to Exclude Keywords or Sources](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Search News in Plain English](/en/articles/searching-and-filtering/keyword-search/natural-language-search) --- ## How to Get Sentiment Toward a Company or Person URL: https://support.apitube.io/en/articles/searching-and-filtering/sentiment/entity-level-sentiment Filter news by sentiment toward a specific company or person with entity.sentiment.polarity and score.min/max plus organization.name, person.name or entity.id. # How to Get Sentiment Toward a Company or Person Use entity.sentiment.\* to filter on the tone directed at a specific entity, not the whole article ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum June 26, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Tesla&entity_sentiment_polarity=negative) # How to get sentiment toward a specific company or person[#](#how-to-get-sentiment-toward-a-specific-company-or-person) To filter by the tone aimed at a specific company or person — not the article’s overall mood — pair an [entity](/en/articles/getting-started/glossary#entity) selector with the `entity.sentiment.*` parameters. For example, to return articles that speak **negatively** about Tesla: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` The `entity.sentiment.polarity` constraint is matched against each entity’s own [sentiment](/en/articles/getting-started/glossary#sentiment) inside the article, so you get coverage where _Tesla specifically_ is framed negatively — even if the rest of the article is upbeat. ## What is entity-level sentiment versus article sentiment?[#](#what-is-entity-level-sentiment-versus-article-sentiment) Entity-level sentiment is the tone an article expresses **toward one entity** it mentions. It is different from article sentiment, which scores the whole piece. A single article can be broadly positive while still being negative about one company in it — for instance, a market roundup that praises the sector but criticizes one firm. * **Article sentiment** — the overall tone of the article. Filter it with `sentiment.overall.polarity`. See [How to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment). * **Entity sentiment** — the tone toward a named company, person or brand in the article. Filter it with `entity.sentiment.polarity` plus a selector like `organization.name`. Use entity sentiment when you are monitoring how a specific brand or person is portrayed; use article sentiment when you care about the mood of the coverage as a whole. ## Which parameters set entity sentiment?[#](#which-parameters-set-entity-sentiment) Three parameters constrain the sentiment toward the selected entity: * `entity.sentiment.polarity` — `positive`, `negative` or `neutral`. Any other value returns `400` with error code `ER0290`. * `entity.sentiment.score.min` — a number from `-1` to `1`; the lower bound of the entity’s sentiment score. Out-of-range values return `ER0291`. * `entity.sentiment.score.max` — a number from `-1` to `1`; the upper bound. Out-of-range values return `ER0292`. You can use polarity on its own, a score range on its own, or combine them. This returns articles where Apple is strongly negative — a score between `-1` and `-0.3`: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Apple&entity.sentiment.score.min=-1&entity.sentiment.score.max=-0.3&api_key=YOUR_API_KEY" ``` ## How to pick which entity the sentiment applies to[#](#how-to-pick-which-entity-the-sentiment-applies-to) The sentiment filter attaches to whichever [entity selector](/en/articles/searching-and-filtering/entities/find-news-by-entity) you send. The selectors that work with `entity.sentiment.*` include: * `organization.name` — a company, e.g. `organization.name=Netflix` * `person.name` — a person, e.g. `person.name=Elon Musk` * `brand.name` — a brand * `entity.id` — a numeric entity ID (integer; use it when you already know the exact entity) Each name selector accepts up to **3** comma-separated values. Names are resolved to entities before the query runs, so a name the system does not recognize returns an error (for example, an unknown `organization.name` returns `ER0220`) rather than silently empty results. Track a person’s portrayal like this: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Elon%20Musk&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` If you send `entity.sentiment.*` **without** any selector, it matches articles that contain _any_ entity with that sentiment — useful for surfacing strongly negative coverage across the board, but far broader than a targeted brand check. ## How does entity sentiment appear in the response?[#](#how-does-entity-sentiment-appear-in-the-response) Every article in the response carries an `entities` array, and each entity reports its own sentiment block: ``` { "entities": [ { "id": 12345, "name": "Tesla", "type": "organization", "sentiment": { "score": -0.62, "polarity": "negative", "mentions": { "positive": 1, "neutral": 2, "negative": 5 } } } ] } ``` The `score` is a number from `-1` to `1`, `polarity` is the label your filter matched on, and `mentions` counts how many times the entity was referenced positively, neutrally and negatively. After filtering, read this block to confirm exactly how each result framed your entity. # Common Questions[#](#common-questions) * [Can I combine entity sentiment with other filters?](#can-i-combine-entity-sentiment-with-other-filters) * [What is the difference from sentiment.overall.polarity?](#what-is-the-difference-from-sentimentoverallpolarity) * [Why did my request return an error instead of results?](#why-did-my-request-return-an-error-instead-of-results) ## Can I combine entity sentiment with other filters?[#](#can-i-combine-entity-sentiment-with-other-filters) Yes. `entity.sentiment.*` runs as part of the standard filter chain on `/v1/news/everything`, so you can add `language.code`, `published_at.start`, `category.id` and any other filter in the same request. For example, restrict negative Tesla coverage to English articles from the last week by adding `language.code=en` and a date range alongside the entity parameters. ## What is the difference from sentiment.overall.polarity?[#](#what-is-the-difference-from-sentimentoverallpolarity) `sentiment.overall.polarity` filters on the article’s overall tone, while `entity.sentiment.polarity` filters on the tone toward the entity you name. If you want “articles that are negative about Tesla,” use the entity version; if you want “articles that are negative overall,” use the overall version. They can be combined when you need both conditions. ## Why did my request return an error instead of results?[#](#why-did-my-request-return-an-error-instead-of-results) The most common causes are validation errors: an invalid `entity.sentiment.polarity` value returns `ER0290`, and a score outside `-1` to `1` returns `ER0291` (min) or `ER0292` (max). If you used a name selector, an unrecognized name returns a “not found” error (such as `ER0220` for an organization) — check the spelling or use the numeric `entity.id` instead. For the full parameter reference, see the [News API parameters](https://docs.apitube.io/platform/news-api/everything) documentation. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) --- ## How to Filter News by Sentiment URL: https://support.apitube.io/en/articles/searching-and-filtering/sentiment/filter-by-sentiment Use sentiment.overall.polarity to get positive, negative or neutral APITube articles, or sentiment.overall.score.min/max to filter by a score from -1 to 1. # How to Filter News by Sentiment Return positive, negative or neutral articles with sentiment.overall.polarity ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&sentiment_polarity=positive) # How to filter news by sentiment[#](#how-to-filter-news-by-sentiment) To return only articles with a given tone, add the `sentiment.overall.polarity` parameter with `positive`, `negative` or `neutral`. The APITube News API tags every article with a [sentiment](/en/articles/getting-started/glossary#sentiment) polarity, and this filter keeps only the articles that match. This returns positive-toned coverage: ``` curl "https://api.apitube.io/v1/news/everything?sentiment.overall.polarity=positive&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. If you omit any sentiment parameter, no sentiment filter is applied and articles of every tone are returned. ## What sentiment values can I filter by?[#](#what-sentiment-values-can-i-filter-by) `sentiment.overall.polarity` accepts three values: `positive`, `negative` and `neutral`. The value is case-insensitive, and anything else returns HTTP 400 — `ER0298` for `sentiment.overall.polarity`, `ER0296` for `sentiment.title.polarity`, `ER0297` for `sentiment.body.polarity`. Polarity is the simplest sentiment filter — it answers “is the overall tone good, bad or flat?” without you having to reason about numbers. Sentiment is measured on three separate layers, and each has its own polarity parameter: * `sentiment.overall.polarity` — the article’s overall tone. * `sentiment.title.polarity` — the tone of the headline only. * `sentiment.body.polarity` — the tone of the article body only. This matters because a headline and the body it sits on do not always agree. The split lets you target, for example, articles whose body reads negative even when the headline is neutral. ## How to filter by a numeric sentiment score[#](#how-to-filter-by-a-numeric-sentiment-score) For finer control than positive/negative/neutral, filter by the numeric score. Every sentiment layer is also scored on a scale from **\-1 (most negative) to 1 (most positive)**, where values near 0 are neutral. Use `.score.min` and `.score.max` to set a range. This returns only strongly positive articles: ``` curl "https://api.apitube.io/v1/news/everything?sentiment.overall.score.min=0.5&api_key=YOUR_API_KEY" ``` The score parameters are `sentiment.overall.score`, `sentiment.overall.score.min` and `sentiment.overall.score.max`, with matching `sentiment.title.*` and `sentiment.body.*` variants. A value outside the -1 to 1 range, or a non-numeric value, returns HTTP 400 with a sentiment validation error (for example `ER0095` for an out-of-range `sentiment.overall.score.min`). Combine a minimum and a maximum to bracket a band, such as mildly negative coverage: ``` curl "https://api.apitube.io/v1/news/everything?sentiment.overall.score.min=-0.5&sentiment.overall.score.max=-0.1&api_key=YOUR_API_KEY" ``` ## How to find articles where the headline and body disagree[#](#how-to-find-articles-where-the-headline-and-body-disagree) Two boolean helpers compare the title tone against the body tone. `sentiment.mixed=1` returns articles where the title polarity differs from the body polarity, and `sentiment.consistent=1` returns articles where they match. Both accept only `0` or `1` (an invalid value returns `ER0243` for mixed or `ER0244` for consistent): ``` curl "https://api.apitube.io/v1/news/everything?sentiment.mixed=1&api_key=YOUR_API_KEY" ``` A mismatch between an emotionally charged headline and a flatter body is a common signal of clickbait. For a purpose-built filter on that pattern, see [How to detect and filter clickbait](/en/articles/searching-and-filtering/content-quality/filter-clickbait). ## How to combine sentiment with other filters[#](#how-to-combine-sentiment-with-other-filters) Sentiment is part of the shared filter chain, so it stacks with any other filter and with sorting. This returns the newest positive English articles about a company: ``` curl "https://api.apitube.io/v1/news/everything?sentiment.overall.polarity=positive&language.code=en&organization.name=Netflix&sort.by=published_at&sort.order=desc&api_key=YOUR_API_KEY" ``` The same sentiment parameters work on `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. To narrow by subject at the same time, pair sentiment with [a category filter](/en/articles/searching-and-filtering/by-attribute/filter-by-category). ## What does the sentiment data look like in the response?[#](#what-does-the-sentiment-data-look-like-in-the-response) Every article carries a `sentiment` object with all three layers, so you can read the exact score and polarity behind the filter: ``` { "sentiment": { "overall": { "score": 0.62, "polarity": "positive" }, "title": { "score": 0.10, "polarity": "neutral" }, "body": { "score": 0.71, "polarity": "positive" } } } ``` Each layer reports a `score` from -1 to 1 and a `polarity` label. These are the same values the filters act on: `sentiment.overall.polarity` matches `sentiment.overall.polarity` in this object, and `sentiment.body.score.min` matches `sentiment.body.score`. # Common Questions[#](#common-questions) * [What is the difference between polarity and score?](#what-sentiment-values-can-i-filter-by) * [Can I filter the headline and body separately?](#can-i-filter-the-headline-and-body-separately) * [What sentiment score range does the API use?](#what-sentiment-score-range-does-the-api-use) * [Which endpoints support sentiment filtering?](#which-endpoints-support-sentiment-filtering) ## Can I filter the headline and body separately?[#](#can-i-filter-the-headline-and-body-separately) Yes. `sentiment.title.polarity` and `sentiment.title.score(.min/.max)` filter on the headline alone, while `sentiment.body.polarity` and `sentiment.body.score(.min/.max)` filter on the article body. Use `sentiment.overall.*` when you want one combined tone, and the title or body variants when the two parts of an article may disagree. ## What sentiment score range does the API use?[#](#what-sentiment-score-range-does-the-api-use) Every sentiment score runs from -1 to 1: -1 is the most negative, 1 is the most positive, and values near 0 are neutral. Any `.score`, `.score.min` or `.score.max` value outside that range is rejected with an HTTP 400 sentiment error, so keep your thresholds within -1 to 1. ## Which endpoints support sentiment filtering?[#](#which-endpoints-support-sentiment-filtering) The sentiment parameters work on `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. Because they run in the shared filter chain, they combine freely with other filters such as `language.code`, `published_at.start` and `category.id`, and with `sort.by`. * * * ## Related Articles * [How to Detect and Filter Clickbait](/en/articles/searching-and-filtering/content-quality/filter-clickbait) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) --- ## Sentiment URL: https://support.apitube.io/en/articles/searching-and-filtering/sentiment Filter APITube News API results by sentiment polarity and score across the overall article, the title and the body. # Sentiment Filter by sentiment polarity and score. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Tasha 1 author 2 articles * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) --- ## How to Aggregate News Results with Facets URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets Use the APITube News API facet parameter to get aggregated article counts grouped by source, language, sentiment, topic or date — without downloading every… # How to Aggregate News Results with Facets Use the facet parameter to get grouped article counts for dashboards, filtered navigation and analytics ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=tesla&facet=true&facet_field=source.id%2Clanguage.id) # How to aggregate news results with facets[#](#how-to-aggregate-news-results-with-facets) The APITube News API `facet` parameter returns grouped counts of matching articles instead of (or alongside) the articles themselves. Set `facet=true` and list the fields you want to group by in `facet.field` — for example `facet.field=source.id,language.id` — and the response gains a `facets` object with the count of articles per value. This is how you build filtered navigation, analytics dashboards, and distribution charts without downloading and counting articles yourself. ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&facet=true&facet.field=source.id,language.id&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Faceting runs inside the same search request — you do not call a separate endpoint for it. ## How does the facet parameter work?[#](#how-does-the-facet-parameter-work) Faceting is enabled with `facet=true` (or `facet=1`). When it is on, `facet.field` is required and takes a comma-separated list of up to 5 fields. The API groups every article that matches your filters by each listed field and returns the count per value. The grouping uses the same `WHERE` conditions as your search, so facet counts always reflect the filters you applied — a [source filter](/en/articles/searching-and-filtering/by-attribute/filter-by-source), a date range, a keyword, and so on. Counts are computed across the full matching set, not just the page you requested. Your `page` and `per_page` values shape the `results` array, but the facet counts ignore [pagination](/en/articles/getting-started/glossary#pagination) and report the totals for everything that matches. The response adds a `facets` object keyed by each field name. Each entry is an array of `{ value, count }` pairs: ``` { "status": "ok", "results": [...], "facets": { "source.id": [ { "value": 12345, "count": 150 }, { "value": 12346, "count": 120 } ], "language.id": [ { "value": 1, "count": 450 }, { "value": 2, "count": 120 } ] } } ``` ## Which fields can I facet on?[#](#which-fields-can-i-facet-on) You can group by many article attributes. Common choices include: * **Source and language:** `source.id`, `source.country.id`, `source.bias`, `source.rank.opr`, `language.id`, `author.id` * **Classification:** `category.id`, `topic.id`, `industry.id`, `entity.id` * **[Sentiment](/en/articles/getting-started/glossary#sentiment):** `sentiment.overall.polarity`, `sentiment.title.polarity`, `sentiment.body.polarity`, `sentiment.strength` * **Article attributes:** `is_duplicate`, `is_free`, `is_important`, `read_time`, `content.length`, `media.images.count`, `media.videos.count` * **Time:** `published.year`, `published.month`, `published.day_of_week`, `published.hour`, `published.weekday`, `published.time_of_day` Faceting on `entity.id` is a fast way to find the most-mentioned people, companies and brands inside a result set — useful when you want to know _who_ a topic is about, which pairs well with [finding news by entity](/en/articles/searching-and-filtering/entities/find-news-by-entity). ``` curl "https://api.apitube.io/v1/news/everything?topic.id=business&facet=true&facet.field=entity.id,sentiment.overall.polarity&api_key=YOUR_API_KEY" ``` ## How to control how many facet values come back[#](#how-to-control-how-many-facet-values-come-back) Two optional parameters shape the lists: * `facet.limit` — the maximum number of values returned per field. Default is `10`, and the cap is `100`. * `facet.mincount` — the minimum count a value needs to appear. Default is `1`, so by default every value with at least one article is included. For most fields the values are ordered by count, highest first, so the top entries are the largest groups. Time-based and computed fields (such as `published.year` or `content.length`) are ordered by their value instead. ``` curl "https://api.apitube.io/v1/news/everything?facet=true&facet.field=source.id&facet.limit=20&facet.mincount=5&api_key=YOUR_API_KEY" ``` ## How to facet over ranges (dates and numbers)[#](#how-to-facet-over-ranges-dates-and-numbers) Beyond grouping by exact values, you can bucket a numeric or date field into ranges with `facet.range=true`. Set `facet.range.field` to the field, and provide `facet.range.start` and `facet.range.end` (both required). The optional `facet.range.gap` sets the bucket size and defaults to `+1DAY` for dates. Range fields include `published_at`, `read_time`, `source.rank.opr`, `media.images.count`, `media.videos.count`, and the sentiment score fields (`sentiment.overall.score`, `sentiment.title.score`, `sentiment.body.score`). ``` curl "https://api.apitube.io/v1/news/everything?facet.range=true&facet.range.field=published_at&facet.range.start=2026-06-01&facet.range.end=2026-06-26&facet.range.gap=+1DAY&api_key=YOUR_API_KEY" ``` Range results arrive under a key named `<field>_ranges` (for example `published_at_ranges`), where each bucket is `{ range_start, range_end, count }`. This is the building block for a “articles per day” volume chart. # Common Questions[#](#common-questions) ## Which endpoints support faceting?[#](#which-endpoints-support-faceting) Faceting works on the article-search endpoints: `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. The parameters behave the same on each one. ## Can I get only the counts without the articles?[#](#can-i-get-only-the-counts-without-the-articles) The `facets` object is returned alongside the normal `results` array. To keep the response small while you build a dashboard, combine faceting with a tiny page (`per_page=1`) and field selection — see [returning only specific fields with fl](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields). The facet counts still cover the full matching set regardless of how small the page is. ## What errors can faceting return?[#](#what-errors-can-faceting-return) All faceting errors are `400` responses. `ER0310` is returned when `facet=true` but `facet.field` is missing. `ER0312` is returned when `facet.field` lists more than 5 fields. `ER0313` is returned when a field name is not supported, and the message lists every allowed field. For range faceting, `ER0332` is returned when `facet.range.start` or `facet.range.end` is missing. Check field names against the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) before sending the request. ## Why don’t my facet counts match the number of results?[#](#why-dont-my-facet-counts-match-the-number-of-results) They are measuring different things. The `results` array is limited by your `page` and `per_page` values, while facet counts are computed over every article that matches your filters. A request that returns 25 articles on the page can still report thousands across its facet values — that is expected. * * * ## Related Articles * [How to Filter News by Source or Domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How to Return Only Specific Fields with fl](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) --- ## How to Combine Multiple Filters in One Request URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters Combine APITube News API filters: separate parameters narrow with AND, comma lists inside one parameter mean OR, and sorting and pagination apply on top. # How to Combine Multiple Filters in One Request Stack language, category, date and source filters with AND logic on one call ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en&category_id=medtop%3A15000000&published_at_start=2026-06-01&sort_by=published_at&per_page=50) # How to combine multiple filters in one request[#](#how-to-combine-multiple-filters-in-one-request) Add as many filter parameters as you need to the same `/v1/news/everything` call: APITube applies every parameter to one query, so **different filters combine with AND logic** and each one you add narrows the results. Inside a single parameter, a comma-separated list uses OR. Sorting and [pagination](/en/articles/getting-started/glossary#pagination) then run on top of whatever the filters return. ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&category.id=medtop:15000000&published_at.start=2026-06-01&sort.by=published_at&per_page=50&api_key=YOUR_API_KEY" ``` That request returns English articles **and** in the Sport category **and** published since 1 June 2026, newest first, 50 per page. You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. ## How does APITube combine multiple filters?[#](#how-does-apitube-combine-multiple-filters) APITube builds one query and runs each filter parameter against it in turn, so the conditions add up: an article must satisfy **every** parameter to be returned (AND logic). Adding more filters always makes the result set smaller or equal, never larger. The two layers behave differently: * **Across different parameters** — AND. `language.code=en` and `category.id=medtop:15000000` together return only articles that are both English and Sport. * **Inside one parameter** — OR. A comma-separated list such as `category.id=medtop:15000000,medtop:04000000` returns articles matching either code. Most list parameters accept up to three values. So `language.code=en,fr&category.id=medtop:15000000` means “(English OR French) AND Sport”. ## How to combine filters in one request[#](#how-to-combine-filters-in-one-request) List each parameter with `&`. This call stacks four filters plus sorting and pagination: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=theguardian.com&language.code=en&category.id=medtop:15000000&sentiment.overall.polarity=positive&sort.by=relevance&per_page=25&api_key=YOUR_API_KEY" ``` It returns positive-[sentiment](/en/articles/getting-started/glossary#sentiment) Sport articles in English from theguardian.com, ranked by relevance, 25 per page. A few rules to keep in mind: * `per_page` defaults to 100 and maxes out at 250 (10 on Free, 50 on Starter, 200 on Basic) — a larger value returns HTTP 400 with error `ER0171`. Use `page` to walk through the rest; see [how to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). * `sort.by` and `sort.order` are not filters — they only reorder what the filters already selected. Without them, results come back sorted by `published_at` descending (newest first). * To restrict the time window, add `published_at.start` and `published_at.end` together; see [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## What happens if one filter in the request is invalid?[#](#what-happens-if-one-filter-in-the-request-is-invalid) If any single parameter is invalid, the **whole request fails** — the filter chain stops at the first problem and returns its error, so none of the other filters run. For example, an unknown `category.id` returns HTTP 400 with error `ER0206`, and an unknown `source.domain` returns `ER0214`. The fix is to validate values one parameter at a time before combining them. This also means a typo in one filter can make a multi-filter request look like it “returns nothing” when it actually returned an error. Check the HTTP status and error code first. ## How to exclude results while combining filters[#](#how-to-exclude-results-while-combining-filters) Every positive filter has an `ignore.` counterpart, and you can mix include and exclude filters in the same request. This call keeps English Sport articles but drops one publisher: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&category.id=medtop:15000000&ignore.source.domain=theguardian.com&api_key=YOUR_API_KEY" ``` `ignore.category.id`, `ignore.language.code` and `ignore.source.domain` follow the same comma rules as their positive versions and also abort the request on an unknown value (for example `ER0215` for an unknown ignored domain). For more on removing terms and publishers, see [how to exclude keywords or sources](/en/articles/searching-and-filtering/keyword-search/exclude-keywords-and-sources). ## Does the order of filters in the URL matter?[#](#does-the-order-of-filters-in-the-url-matter) No. The order you write parameters in the URL has no effect on the result. APITube runs filters in a fixed internal order optimised by cost — cheap indexed checks first, expensive lookups last — regardless of how you arranged them in the request. Write parameters in whatever order is clearest to read. # Common Questions[#](#common-questions) * [Do different filters use AND or OR?](#do-different-filters-use-and-or-or) * [How many values can I pass to one filter?](#how-many-values-can-i-pass-to-one-filter) * [Why does my multi-filter request return an error?](#why-does-my-multi-filter-request-return-an-error) * [Can I sort and paginate a filtered request?](#can-i-sort-and-paginate-a-filtered-request) ## Do different filters use AND or OR?[#](#do-different-filters-use-and-or-or) Different parameters use AND: an article must match all of them. A comma-separated list inside one parameter uses OR: the article must match at least one value in that list. So `language.code=en,fr` is OR within the language filter, while pairing it with `category.id=...` adds an AND condition. ## How many values can I pass to one filter?[#](#how-many-values-can-i-pass-to-one-filter) List parameters such as `language.code`, `category.id` and `source.domain` accept up to three comma-separated values; values beyond the third are dropped. To match more than three of something, run separate requests or use a broader filter. ## Why does my multi-filter request return an error?[#](#why-does-my-multi-filter-request-return-an-error) Because the filter chain stops on the first invalid parameter and returns that error instead of results — one bad `category.id` (`ER0206`) or unknown `source.domain` (`ER0214`) fails the entire call. Test each filter value on its own, then combine them once each one works. ## Can I sort and paginate a filtered request?[#](#can-i-sort-and-paginate-a-filtered-request) Yes. `sort.by`, `sort.order`, `page` and `per_page` apply on top of any combination of filters. The filters decide which articles match; sorting decides their order; pagination decides how many you get per call (default 100, maximum 250 — 50 on Starter, 10 on Free). * * * ## Related Articles * [How to Filter News by Language](/en/articles/searching-and-filtering/by-attribute/filter-by-language) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) * [How to Paginate Through Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## How to Highlight Matching Terms in Search Results URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/highlight-terms Use the APITube News API hl, hl.fl, hl.fragsize and hl.snippets parameters to return search snippets with matching terms wrapped in highlight tags like <em>. # How to Highlight Matching Terms in Search Results Use the hl parameters to get text snippets with your search terms wrapped in highlight tags, ready to render ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=bitcoin&hl=true) # How to highlight matching terms in search results[#](#how-to-highlight-matching-terms-in-search-results) The APITube News API `hl` parameter returns short text snippets with your search terms wrapped in highlight tags, so you can show users exactly why each article matched. Add `hl=true` to a keyword search and the response gains a `highlighting` object: each matching article gets arrays of snippets where every hit is surrounded by `<em>` and `</em>` by default. ``` curl "https://api.apitube.io/v1/news/everything?title=bitcoin&hl=true&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Highlighting reuses the terms from your search, so it only works when you actually searched for something — it has no terms to mark on an unfiltered request. ## How does highlighting work in the News API?[#](#how-does-highlighting-work-in-the-news-api) Highlighting is enabled with `hl=true` (or `hl=1`). The terms it marks come from your `title` (or `search`) keywords, so `title=bitcoin&hl=true` highlights “bitcoin” wherever it appears in the chosen fields. For each article that contains a match, the API extracts a snippet of surrounding text, wraps each hit in the highlight tags, and adds it to a top-level `highlighting` object keyed by article ID. ``` { "status": "ok", "results": [...], "highlighting": { "12345": { "title": [ "Breaking: <em>Bitcoin</em> reaches new all-time high" ], "description": [ "...The price of <em>Bitcoin</em> surged past $100,000 today..." ] } } } ``` Each field holds an array of snippets, and snippets taken from the middle of a longer text are wrapped with `...` on both sides to show they are an excerpt. If no article matches, the `highlighting` object is left out of the response entirely. ## Which fields can you highlight?[#](#which-fields-can-you-highlight) Use `hl.fl` to choose which fields are scanned for matches. It accepts a comma-separated list of up to 5 fields, and the allowed values are `title`, `description` and `body`. If you do not set `hl.fl`, the API highlights `title` and `description` by default. ``` curl "https://api.apitube.io/v1/news/everything?title=artificial intelligence&hl=true&hl.fl=title,description,body&api_key=YOUR_API_KEY" ``` Adding `body` is the most useful change: it surfaces snippets from deep inside the full article text, which is where the richest context usually lives. Naming a field that is not `title`, `description` or `body` returns `400` with error `ER0322`, and the message lists the allowed fields. ## How to control snippet size and count[#](#how-to-control-snippet-size-and-count) Two parameters shape the snippets themselves: * `hl.fragsize` — the maximum length of each snippet in characters. Default is `150`; values are clamped to the `50`–`500` range. * `hl.snippets` — the maximum number of snippets returned per field. Default is `3`; values are clamped to the `1`–`10` range. ``` curl "https://api.apitube.io/v1/news/everything?title=climate change&hl=true&hl.fragsize=300&hl.snippets=5&api_key=YOUR_API_KEY" ``` Larger `hl.fragsize` gives more surrounding context per match, while a higher `hl.snippets` returns more separate excerpts from the same field — handy when a term appears several times in a long `body`. ## How to change the highlight tags[#](#how-to-change-the-highlight-tags) By default matches are wrapped in `<em>` … `</em>`. Override both sides with `hl.tag.pre` and `hl.tag.post` to fit your front end — for example a styled `<mark>` element or a custom span. ``` curl "https://api.apitube.io/v1/news/everything?title=bitcoin&hl=true&hl.tag.pre=<mark>&hl.tag.post=</mark>&api_key=YOUR_API_KEY" ``` This lets you drop the snippets straight into your UI without a find-and-replace pass on the response. If you only set one of the two tags, the other keeps its default. ## Does highlighting match word variations?[#](#does-highlighting-match-word-variations) Yes. Before marking matches, the API expands each search term using its synonym and morphology dictionaries, so a search for “run” also highlights “running”, “runner” and “ran”. The expansion is language-aware, which means variations are caught across the languages APITube indexes — not just English. This is why a snippet can show highlighted words that are not letter-for-letter identical to what you typed. # Common Questions[#](#common-questions) ## Which endpoints support highlighting?[#](#which-endpoints-support-highlighting) Highlighting works on the search and listing endpoints: `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/story`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. The `hl` parameters behave the same on each one. Pair highlighting with [field selection](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) to keep responses lean while still returning the snippets you need. ## Why is the highlighting object empty or missing?[#](#why-is-the-highlighting-object-empty-or-missing) Highlighting needs search terms and at least one match. If you send `hl=true` without a `title` (or `search`) keyword, there is nothing to highlight and the `highlighting` object is omitted. The same happens when none of your results actually contain the term in the highlighted fields. Single-character terms are also skipped — a term must be at least two characters long to be highlighted. ## What errors can highlighting return?[#](#what-errors-can-highlighting-return) All highlighting errors are `400` responses. `ER0320` is returned when `hl.fl` is empty while `hl=true`, `ER0321` when `hl.fl` lists more than 5 fields, and `ER0322` when a field name is not `title`, `description` or `body`. Send a short, valid `hl.fl` list — or omit it to use the `title,description` default — and you will not hit any of them. The full parameter list is in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Does highlighting cost an extra request?[#](#does-highlighting-cost-an-extra-request) No. Highlighting is computed inside the same search call and returned in the same response, so it is billed as the one request you already made — there is no separate charge for adding `hl` parameters. It pairs naturally with [faceting](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets), which also rides along on the same request to enrich a single search response. * * * ## Related Articles * [How to Aggregate News Results with Facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) * [How to Return Only Specific Fields with fl](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) --- ## Sorting, Pagination & Shaping URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping Order APITube News API results with sort.by and sort.order, page through them, and shape what each request returns. # Sorting, Pagination & Shaping Order, page and shape your results. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) By Kent 1 author 8 articles * [How to Aggregate News Results with Facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) * [How to Combine Multiple Filters in One Request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) * [How to Highlight Matching Terms in Search Results](/en/articles/searching-and-filtering/sorting-and-shaping/highlight-terms) * [How to Paginate Through News API Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) * [How to Return Only Specific Fields with fl](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields) * [How to Sort News by Controversy, Trust and Social Shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) * [How to Sort News by Rank, Length and Sentiment](/en/articles/searching-and-filtering/sorting-and-shaping/sort-news) * [How to Sort News by Relevance, Date or Quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) --- ## How to Paginate Through News API Results URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results Paginate APITube News API results with page and per_page (250 per page, 50 on Starter, 10 on Free), follow the next_page URL, and stop when has_next_pages is… # How to Paginate Through News API Results Use page and per\_page to walk through every matching article, and read has\_next\_pages to know when to stop ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=50&page=1) # How to paginate through News API results[#](#how-to-paginate-through-news-api-results) To page through results in the APITube News API, use two parameters: `per_page` sets how many articles each request returns (default 100, maximum 250 — Starter caps both at 50, Free at 10), and `page` selects which slice you get (default 1). Each response tells you whether more pages exist through the `has_next_pages` flag and a ready-to-use `next_page` URL, so you keep requesting pages until `has_next_pages` is `false`. ``` curl "https://api.apitube.io/v1/news/everything?per_page=50&page=1&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter, and both parameters work the same way on a GET query string or in a POST JSON body. ## Which parameters control pagination?[#](#which-parameters-control-pagination) [Pagination](/en/articles/getting-started/glossary#pagination) on `/v1/news/everything` is offset-based and driven by exactly two parameters: * **`per_page`** — the number of articles in one response. The default is 100 and the hard maximum is 250 on Professional and up — **Basic** is capped at **200**, **Starter** at **50** and **Free** at **10**, and the default drops to the ceiling with it (a Free request without `per_page` returns 10 articles). Asking for more than your plan allows returns a `400` error with code `ER0171` (“Limit is out of range. Your plan allows up to N results per page.”), so cap your page size at the plan ceiling. * **`page`** — which page of results to return, starting at 1. The API skips `(page - 1) × per_page` articles before returning the next batch, so `page=3` with `per_page=50` starts at the 101st matching article. On the **Free plan**, paging stops after the first 5 pages: any `page` above 5 returns `400 ER0173` (“Free plan is limited to the first 5 pages.”). Upgrade to a paid plan to page further. Both parameters must be whole numbers. A non-integer `per_page` returns `400 ER0170` (“‘Per page’ is not a number.”), and a non-integer `page` returns `400 ER0172` (“Page is not a number.”). `per_page` must also be at least 1 — `per_page=0` or a negative value returns `400 ER0299` (“per\_page must be at least 1.”). A `page` below 1 is clamped to the first page rather than rejected. ## How do you move to the next page?[#](#how-do-you-move-to-the-next-page) Read the pagination fields the API returns alongside `results`. Every search response includes: * `page` — the page you just received. * `limit` — the `per_page` value in effect. * `has_next_pages` — `true` while another page may exist. * `next_page` — a complete URL for the following page (empty when there is none). * `has_previous_page` and `previous_page` — the same, going backwards. The simplest loop is to request page 1, then keep following `next_page` until `has_next_pages` is `false`. Because `has_next_pages` is set whenever the current batch comes back full (its length equals `per_page`), a final page that happens to be exactly full will report `has_next_pages: true`, and the next request will return an empty `results` array. Treat an empty `results` list as the real end of the data, even if the previous page hinted there was more. ## How do you get the total number of matches?[#](#how-do-you-get-the-total-number-of-matches) The `/v1/news/everything` response does not include a total count — it only tells you whether the next page exists. When you need the full number of matching articles up front (for example, to show “1 of N” or to decide how many pages to fetch), send the same filters to [the count endpoint](/en/articles/retrieval/count-articles), `/v1/news/count`. It runs the identical query and returns a single `count` value for one request, without downloading any article bodies. ``` curl "https://api.apitube.io/v1/news/count?title=tesla&language.code=en&api_key=YOUR_API_KEY" ``` # Common Questions[#](#common-questions) ## What is the maximum page size?[#](#what-is-the-maximum-page-size) The maximum `per_page` is 250 articles — 50 on Starter, 10 on Free. Requests above that limit are rejected with `400 ER0171` instead of being silently capped, so set `per_page` to your plan ceiling or lower. If you leave it out, the API uses 100 per page (50 on Starter). ## Why do articles shift between pages?[#](#why-do-articles-shift-between-pages) Pagination returns a slice of a sorted list, and the default sort is `published_at` in descending order (newest first). If you paginate a live search while new articles are being indexed, freshly added items can push everything down by one position, so an article from page 1 may reappear on page 2. To keep the order stable across pages, fix the ordering with the same [`sort.by` and `sort.order`](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) on every request, and narrow the window with a `published_at.end` boundary so the result set stops growing while you read it. ## Which errors can pagination return?[#](#which-errors-can-pagination-return) The pagination errors are all `400` responses: `ER0170` when `per_page` is not a number, `ER0171` when `per_page` exceeds your plan ceiling (250, 50 on Starter, 10 on Free), `ER0172` when `page` is not a number, and `ER0173` when a Free-plan key requests a `page` beyond 5. Send integers within range — and stay within the first 5 pages on the Free plan — and you will not hit any of them. For the full parameter reference, see the official [News API parameters documentation](https://docs.apitube.io/platform/news-api/everything). * * * ## Related Articles * [How to Count Matching Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Sort News by Controversy, Trust and Social Shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) --- ## How to Return Only Specific Fields with fl URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/select-fields Use the APITube News API fl parameter to return only the fields you need — id, title, source.domain and more — as a comma-separated list with dot notation. # How to Return Only Specific Fields with fl Use the fl parameter to trim each article down to just the fields you need, with dot notation for nested values ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson August 23, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=tesla&fl=id%2Ctitle%2Cpublished_at) # How to return only specific fields with fl[#](#how-to-return-only-specific-fields-with-fl) The APITube News API `fl` parameter returns only the fields you list instead of the full article object. Pass a comma-separated list — `fl=id,title,published_at` — and every item in the `results` array is trimmed to exactly those keys. Use dot notation such as `source.domain` to reach nested fields. This shrinks the response and speeds up parsing when you only need a few values per article — and the effect is large, because a full article object averages about 25 KB, most of it `body`, `body_html` and the `entities` array. Measured on `/v1/news/everything`: `per_page=10` returns ~250 KB, the same request with `fl=id,title,href` returns ~3 KB; at `per_page=100` it is 2 MB versus 21 KB. ``` curl "https://api.apitube.io/v1/news/everything?title=tesla&fl=id,title,published_at&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter, and `fl` works the same whether you put it on a GET query string or in a POST JSON body. ## How does the fl parameter work?[#](#how-does-the-fl-parameter-work) `fl` takes a comma-separated list of field names. The API formats each full article as usual, then keeps only the listed keys before sending the response. With `fl=id,title,published_at`, each object in `results` looks like this and nothing else: ``` { "id": 1234567, "title": "Tesla reports record quarterly deliveries", "published_at": "2026-06-26T08:15:00.000Z" } ``` The response wrapper does not change. The top-level fields — `status`, `page`, `limit`, `has_next_pages`, `next_page` and the `export` links — are always present. `fl` only shapes the article objects inside `results`, so your [pagination loop](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) keeps working exactly as before. ## How to select nested fields with dot notation[#](#how-to-select-nested-fields-with-dot-notation) Many article fields are nested objects — `source`, `sentiment`, `author`, `readability`. To pick a value inside one of them, write the path with a dot. The API rebuilds just that branch of the object and drops everything else. ``` curl "https://api.apitube.io/v1/news/everything?fl=id,source.domain,sentiment.overall.polarity&api_key=YOUR_API_KEY" ``` Each result then contains only the requested branches: ``` { "id": 1234567, "source": { "domain": "reuters.com" }, "sentiment": { "overall": { "polarity": "positive" } } } ``` You can mix flat and nested paths freely, for example `fl=title,author.name,source.bias`. To narrow results to one publisher first, combine `fl` with a [source filter](/en/articles/searching-and-filtering/by-attribute/filter-by-source). ## Which endpoints support fl?[#](#which-endpoints-support-fl) `fl` works on the article-returning endpoints, including `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/local`, `/v1/news/article`, `/v1/news/story/:id` and the `/v1/news/category` · `/topic` · `/industry` · `/entity` listings. Both real-time feeds honour it as well — `/v1/news/stream` and `/v1/news/ws` deliver only the fields you list, which is the cheapest way to shrink a busy stream. The behaviour is identical on each — list the fields you want and every returned article is trimmed to them. ``` curl "https://api.apitube.io/v1/news/top-headlines?fl=id,title,href,image&api_key=YOUR_API_KEY" ``` # Common Questions[#](#common-questions) ## What happens if I request a field that does not exist?[#](#what-happens-if-i-request-a-field-that-does-not-exist) Unknown field names are silently skipped — there is no error. If you ask for `fl=id,foobar`, each result returns just `{ "id": ... }` because `foobar` has no value to include. If none of the names you list exist, each item in `results` comes back as an empty object `{}`. Check field names against the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) so you do not accidentally drop the data you wanted. ## Does fl reduce how many requests I am charged?[#](#does-fl-reduce-how-many-requests-i-am-charged) No. Each call still counts as one request against your quota or balance, whether you return one field or the whole article. `fl` trims the payload to make responses smaller and faster to parse; it does not change billing. Use it to cut bandwidth and client-side work, not to save credits. ## Can I use fl with CSV, XLSX and other exports?[#](#can-i-use-fl-with-csv-xlsx-and-other-exports) Partly. The field selection is applied to the articles before the export file is generated, so the values you did not ask for are dropped — but the tabular formats (`csv`, `tsv`, `xlsx`, `parquet`) keep their **fixed 29-column layout**. A request with `fl=id,title` still returns all 29 headers; only the ID and Title cells carry data and the rest come back empty. The column set is the same for every export, which keeps files diff-able and importable, so treat `fl` here as a way to blank out content rather than to reshape the sheet. `xml` behaves the same way — the element list is fixed, so `fl=id,title` returns all 54 elements with 38 of them empty. Only the JSON response actually drops the keys you did not request. ## Which errors can fl return?[#](#which-errors-can-fl-return) Both `fl` errors are `400` responses. `ER0300` (“`fl` must be a string.”) is returned when the value is not a string, and `ER0301` (“`fl` cannot be empty.”) is returned when you send `fl` with no usable field names — for example `fl=` or `fl=,,`. Send a plain comma-separated list of names and you will not hit either one. * * * ## Related Articles * [How to Paginate Through News API Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) * [How to Sort News by Controversy, Trust and Social Shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) --- ## How to Sort News by Controversy, Trust and Social Shares URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes Use sort.by in the APITube News API to rank results by the engagement, controversy and trust composite scores, by media richness, or by Facebook, Twitter and… # How to Sort News by Controversy, Trust and Social Shares Rank News API results with the engagement, controversy and trust scores, media richness and share counts ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 26, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&sort_by=controversy&category_id=medtop%3A11000000) # How to sort news by controversy, trust and social shares[#](#how-to-sort-news-by-controversy-trust-and-social-shares) To rank results by something other than date, set `sort.by` to one of the composite scores — `engagement`, `controversy` or `trust` — or to a social-share key such as `shares.facebook.max`. By default the News API sorts by `published_at` in descending order, so newest first; the moment you pass a different `sort.by`, results are ranked by that signal instead. ``` curl "https://api.apitube.io/v1/news/everything?sort.by=controversy&category.id=medtop:11000000&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Composite scores are returned highest-first because the default `sort.order` is `desc` — you do not need to add `sort.order` to get the top-scoring articles at the top. ## What are the composite sort modes?[#](#what-are-the-composite-sort-modes) The News API ships three multifactor scores you can pass to `sort.by`. Each blends several article signals into a single number, so you pick the one that matches what “best” means for your use case: * **`engagement`** — viral potential for social feeds. It rewards breaking/important articles, the number of images and videos, positive [sentiment](/en/articles/getting-started/glossary#sentiment), and freshness (an article published within the last hour gets the biggest boost, within the last six hours a smaller one), plus the rank of the source. * **`controversy`** — polarization, for debates and hot topics. It rewards strong sentiment in either direction (intensity, not just positive), articles from left- or right-leaning sources (anything other than center), video content, and breaking news. * **`trust`** — credibility, for fact-checking and research. It rewards a high source rank, articles that are not duplicates, articles that are not paywalled, neutral sentiment, and articles that carry a named author. There are two more composite modes, `relevance` and `quality`, but the three above are the ones that change ranking by social and editorial signals. ## How to sort by engagement, controversy or trust[#](#how-to-sort-by-engagement-controversy-or-trust) Pass the mode name as `sort.by`. This returns the most trustworthy articles about a company first: ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&sort.by=trust&api_key=YOUR_API_KEY" ``` Because the three modes weight signals differently, the same query reordered by `engagement` versus `controversy` versus `trust` can surface very different articles. A practical pattern is a “what’s blowing up right now” feed — recent breaking coverage ranked by viral potential: ``` curl "https://api.apitube.io/v1/news/everything?is_breaking=1&sort.by=engagement&api_key=YOUR_API_KEY" ``` ## How to sort by social shares[#](#how-to-sort-by-social-shares) To rank by how widely an article was shared, use a share key: `shares.facebook.max`, `shares.twitter.max` or `shares.reddit.max`. Each maps to that platform’s share count, and with the default `sort.order=desc` the most-shared articles come first: ``` curl "https://api.apitube.io/v1/news/everything?title=climate&sort.by=shares.twitter.max&sort.order=desc&api_key=YOUR_API_KEY" ``` Keep one timing detail in mind: share counts are aggregated gradually over roughly two hours after an article is published. A story that went live a few minutes ago will show low share numbers that climb until they settle, so very fresh articles can rank lower than their eventual reach. ## How to sort by total media content[#](#how-to-sort-by-total-media-content) `media_richness` ranks articles by the total amount of media they carry — the image count plus the video count. It is the right choice for a visual feed where richer articles should win: ``` curl "https://api.apitube.io/v1/news/everything?has_image=1&sort.by=media_richness&api_key=YOUR_API_KEY" ``` For richer control over which images qualify before you sort, combine this with the media-quality filters described in [How to filter by media quality and social-ready images](/en/articles/searching-and-filtering/content-quality/filter-by-media-quality). ## How to flip the sort direction[#](#how-to-flip-the-sort-direction) `sort.order` takes two values, `asc` and `desc`, and defaults to `desc`. Add `sort.order=asc` when you want the lowest scores first — for example, the least controversial coverage of a topic: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:11000000&sort.by=controversy&sort.order=asc&api_key=YOUR_API_KEY" ``` A common pairing for trust-led research is to keep only non-duplicate, non-paywalled articles and then rank what is left by credibility — see [How to exclude paywalled or duplicate articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) for those filters. All sort options are listed in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Which endpoints support these sort modes?[#](#which-endpoints-support-these-sort-modes) Sorting works on the search and retrieval endpoints that return article lists: `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. Each accepts `sort.by` and `sort.order` on both `GET` (query string) and `POST` (request body). # Common Questions[#](#common-questions) * [What is the default sort order?](#what-is-the-default-sort-order) * [What happens if I pass an unknown sort.by value?](#what-happens-if-i-pass-an-unknown-sortby-value) * [Why do brand-new articles rank low when sorting by shares?](#why-do-brand-new-articles-rank-low-when-sorting-by-shares) * [What is the difference between engagement and controversy?](#what-is-the-difference-between-engagement-and-controversy) ## What is the default sort order?[#](#what-is-the-default-sort-order) If you do not pass `sort.by`, results are sorted by `published_at` (publication date), and the default `sort.order` is `desc`, so the newest articles come first. Every composite and share mode also defaults to `desc`, which means the highest score appears first unless you set `sort.order=asc`. ## What happens if I pass an unknown sort.by value?[#](#what-happens-if-i-pass-an-unknown-sortby-value) An unrecognized `sort.by` value does not raise an error — the request quietly falls back to sorting by `published_at`. So a typo such as `sort.by=trustt` will silently return date-sorted results instead of trust-ranked ones. Check the value against the supported list if a sort does not behave the way you expect. ## Why do brand-new articles rank low when sorting by shares?[#](#why-do-brand-new-articles-rank-low-when-sorting-by-shares) Social share counts are not final at publication. They are aggregated over roughly two hours after the article goes live, so a just-published story shows low Facebook, Twitter or Reddit numbers that rise over time. When you sort by `shares.*`, very recent articles can appear below older ones simply because their share totals have not caught up yet. ## What is the difference between engagement and controversy?[#](#what-is-the-difference-between-engagement-and-controversy) Both reward breaking news and video, but they treat sentiment and sources differently. `engagement` boosts positive sentiment, fresh timing and high-rank sources to predict viral reach. `controversy` boosts sentiment intensity in either direction and left- or right-leaning (non-center) sources to surface polarizing, debate-worthy coverage — so a calm, widely-shared article scores well on `engagement` but not on `controversy`. * * * ## Related Articles * [How to Filter by Media Quality and Social-Ready Images](/en/articles/searching-and-filtering/content-quality/filter-by-media-quality) * [How to Exclude Paywalled or Duplicate Articles](/en/articles/searching-and-filtering/content-quality/exclude-paywall-duplicates) --- ## How to Sort News by Relevance, Date or Quality URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes Use sort.by in the APITube News API to rank results by relevance, publication date or quality, switch to engagement for viral picks, and flip the order with… # How to Sort News by Relevance, Date or Quality Choose between newest-first, best-match and highest-quality results with sort.by and sort.order ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=electric+vehicles&sort_by=relevance) # How to sort news by relevance, date or quality[#](#how-to-sort-news-by-relevance-date-or-quality) Set `sort.by` to pick how the News API orders results: `published_at` for newest first (the default), `relevance` for the best match to your search, `quality` for the strongest articles, or `engagement` for the most viral. Pair it with `sort.order=asc` or `desc` to flip the direction. If you send no `sort.by`, results come back sorted by publication date, newest first. ``` curl "https://api.apitube.io/v1/news/everything?title=electric%20vehicles&sort.by=relevance&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter, and `sort.by` works on both `GET` (query string) and `POST` (request body). ## What is the default sort order?[#](#what-is-the-default-sort-order) By default the News API sorts by `published_at` (publication date) in descending order, so the newest articles appear first. You do not need to pass anything to get this — it is what every request returns when `sort.by` and `sort.order` are absent. To walk a feed from oldest to newest instead, keep the date sort and only change the direction: ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&sort.by=published_at&sort.order=asc&api_key=YOUR_API_KEY" ``` `published_at` is the right choice for a live news feed where recency is all that matters. For “most recently added to the system” rather than “most recently published,” use `created_at` (or its alias `new`); use `id` to sort by the article identifier. ## How to sort by relevance[#](#how-to-sort-by-relevance) `relevance` ranks results by how well they match your search, not by when they were published. It is built for keyword discovery, so it only does real matching when you also pass a `title` search term. With a query in place, `relevance` rewards an exact title match most heavily, then a title that starts with your term, then a term appearing anywhere in the title — and adds smaller boosts for higher source rank, recency and breaking news. ``` curl "https://api.apitube.io/v1/news/everything?title=interest%20rates&sort.by=relevance&api_key=YOUR_API_KEY" ``` One thing to know: if you set `sort.by=relevance` **without** a `title` term, there is nothing to match against, so the score falls back to a quality-style ranking (source rank, recency, breaking news, images and positive [sentiment](/en/articles/getting-started/glossary#sentiment)). Always combine `relevance` with a search term to get the behaviour you expect. ## How to sort by quality[#](#how-to-sort-by-quality) `quality` is the editorial-curation mode: it surfaces well-rounded articles regardless of how fresh or how viral they are. The score rewards a high source rank (Open Page Rank, [OPR](/en/articles/getting-started/glossary#opr-open-pagerank)), articles that carry images, articles that are **not** duplicates, positive overall sentiment, and articles that are not paywalled. Use it to build a “best of” list or a premium feed. ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sort.by=quality&api_key=YOUR_API_KEY" ``` For a quick comparison of the composite modes: `relevance` is for search, `quality` is for editorial picks (top score around 80 points), and `engagement` is for viral potential (top score around 139 points). ## How to sort by engagement and other modes[#](#how-to-sort-by-engagement-and-other-modes) `engagement` predicts viral reach for social feeds, rewarding breaking news, media, positive sentiment and freshness. It is one of a set of composite scores — alongside `controversy`, `trust`, `media_richness` and social-share counts — that rank by signals other than date or match quality: ``` curl "https://api.apitube.io/v1/news/everything?is_breaking=1&sort.by=engagement&api_key=YOUR_API_KEY" ``` These advanced modes have their own weighting rules, covered in detail in [How to sort news by controversy, trust and social shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes). The full list of `sort.by` values lives in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## How to flip the sort direction[#](#how-to-flip-the-sort-direction) `sort.order` takes `asc` or `desc` and defaults to `desc`. With the composite modes (`relevance`, `quality`, `engagement`) `desc` puts the highest score first, which is almost always what you want. Switch to `asc` only for the reverse — for example, the oldest matching coverage of a topic: ``` curl "https://api.apitube.io/v1/news/everything?title=olympics&sort.by=published_at&sort.order=asc&api_key=YOUR_API_KEY" ``` A misspelled or unsupported `sort.by` value does not raise an error. The request quietly falls back to sorting by `published_at`, so a typo like `sort.by=relevence` silently returns date-sorted results. Check the value against the supported list if a sort does not behave as expected. ## Which endpoints support sort.by and sort.order?[#](#which-endpoints-support-sortby-and-sortorder) Sorting works on the search and retrieval endpoints that return article lists: `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. Sorting changes only the order of results, not which articles match — so you can combine any `sort.by` with your filters and then [page through the ordered results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) with `page` and `per_page`. # Common Questions[#](#common-questions) * [What is the default sort.by value?](#what-is-the-default-sortby-value) * [Why does sort.by=relevance return odd results?](#why-does-sortbyrelevance-return-odd-results) * [What is the difference between published\_at and created\_at?](#what-is-the-difference-between-published_at-and-created_at) * [Does changing sort.by change which articles I get?](#does-changing-sortby-change-which-articles-i-get) ## What is the default sort.by value?[#](#what-is-the-default-sortby-value) If you do not pass `sort.by`, the News API sorts by `published_at` in descending order, so the newest articles come first. The default `sort.order` is also `desc`, which means every composite mode (relevance, quality, engagement) returns its highest scores first unless you add `sort.order=asc`. ## Why does sort.by=relevance return odd results?[#](#why-does-sortbyrelevance-return-odd-results) `relevance` needs something to match against. When you pass it together with a `title` search term it ranks by how well each article’s title matches that term. When you pass `relevance` with no `title`, there is no query to score, so it falls back to a quality-style ranking by source rank, recency and other signals. If relevance ordering looks like a generic quality list, add a `title` term. ## What is the difference between published\_at and created\_at?[#](#what-is-the-difference-between-published_at-and-created_at) `published_at` is when the article was published by its source; `created_at` (alias `new`) is when APITube added it to the system. They are usually close, but for back-filled or slowly-crawled articles they can differ. Sort by `published_at` for a reader-facing “latest news” feed and by `created_at` when you care about what is new in the index since your last poll. ## Does changing sort.by change which articles I get?[#](#does-changing-sortby-change-which-articles-i-get) No. `sort.by` and `sort.order` only reorder the articles that already match your filters — they never add or remove results. To change which articles come back, adjust your filters (title, language, category and so on); to change the order they arrive in, adjust `sort.by`. * * * ## Related Articles * [How to Sort News by Controversy, Trust and Social Shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) * [How to Paginate Through News API Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## How to Sort News by Rank, Length and Sentiment URL: https://support.apitube.io/en/articles/searching-and-filtering/sorting-and-shaping/sort-news Use sort.by in the APITube News API to order articles by source rank (OPR), read time, sentiment score or image count, and set the direction with sort.order. # How to Sort News by Rank, Length and Sentiment Order results by source rank, read time, sentiment score or media count with sort.by ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&category_id=medtop%3A04000000&sort_by=source.rank.opr&sort_order=desc) # How to sort news by rank, length and sentiment[#](#how-to-sort-news-by-rank-length-and-sentiment) Set `sort.by` to a field name to order results by a concrete article attribute instead of the publication date: `source.rank.opr` for the strongest sources first, `read_time` for the longest reads, `sentiment.overall.score` for the most positive coverage, or `media.images.count` for the most image-heavy articles. Pair it with `sort.order=asc` or `desc` to choose the direction. If you send no `sort.by`, results come back sorted by `published_at`, newest first. ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sort.by=source.rank.opr&sort.order=desc&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter, and `sort.by` works on both `GET` (query string) and `POST` (request body). Sorting only reorders the articles that already match your filters — it never changes which articles come back. ## How to sort news by source rank (OPR)[#](#how-to-sort-news-by-source-rank-opr) Set `sort.by=source.rank.opr` to put the highest-authority publishers first. This ranks articles by the source’s Open Page Rank ([OPR](/en/articles/getting-started/glossary#opr-open-pagerank)), a measure of the publisher’s authority, so a story from a top-ranked outlet appears above the same story from a low-ranked blog. It pairs well with a topic or category filter when you want the most credible coverage of a subject: ``` curl "https://api.apitube.io/v1/news/everything?title=inflation&sort.by=source.rank.opr&api_key=YOUR_API_KEY" ``` Use `sort.order=desc` (the default) for strongest sources first. To learn how the score itself is built, see [what the OPR source score means](/en/articles/trust-and-support/what-is-opr). ## How to sort news by length and read time[#](#how-to-sort-news-by-length-and-read-time) Length sorting runs on one field — `read_time`, the estimated reading time in minutes: * `read_time` — estimated reading time in minutes The article object also carries `characters_count`, `sentences_count`, `paragraphs_count` and `words_count`, but those live in the article document rather than in the search index, so they can be **read** from a result and not sorted on. Passing one of them as `sort.by` is ignored and the response comes back in the default `published_at` order. To rank by depth, use `read_time` or the [`is_long_read` / `is_deep_dive` flags](/en/articles/searching-and-filtering/content-quality/filter-by-readtime-readability). Sort descending to surface long-form, in-depth pieces first, or ascending for short news briefs: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&sort.by=read_time&sort.order=desc&api_key=YOUR_API_KEY" ``` This is handy for building a “long reads” feed or for filtering signal from short wire snippets without changing your search filters. ## How to sort news by sentiment score[#](#how-to-sort-news-by-sentiment-score) Three `sort.by` values order results by their [sentiment](/en/articles/getting-started/glossary#sentiment) score, from most negative to most positive: * `sentiment.overall.score` — sentiment of the whole article * `sentiment.title.score` — sentiment of the headline only * `sentiment.body.score` — sentiment of the body text ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&sort.by=sentiment.overall.score&sort.order=desc&api_key=YOUR_API_KEY" ``` With `sort.order=desc` the most positive coverage comes first; with `asc`, the most negative. Note that this only _orders_ results by their score — it does not drop neutral or mixed articles. To keep only positive or only negative stories, filter with `sentiment.overall.polarity` first, then sort within that set. ## How to sort news by media count and image size[#](#how-to-sort-news-by-media-count-and-image-size) You can order results by how much media each article carries: * `media.images.count` — number of images * `media.videos.count` — number of videos * `media.images.width.min` / `media.images.width.max` — smallest / largest image width * `media.images.height.min` / `media.images.height.max` — smallest / largest image height ``` curl "https://api.apitube.io/v1/news/everything?title=SpaceX&sort.by=media.images.count&sort.order=desc&api_key=YOUR_API_KEY" ``` Sorting by image dimensions is useful when you need large, display-quality artwork first — for example, when the article thumbnail has to fill a hero banner. ## How to set the sort direction[#](#how-to-set-the-sort-direction) `sort.order` takes `asc` or `desc` and defaults to `desc`. Descending puts the highest value first (biggest rank, longest read, most positive sentiment, most images); ascending flips it. There are also three simple recency fields you can use as the sort key: `published_at` (publication date, the default), `created_at` (when APITube added the article, with `new` as an alias), and `id` (the article identifier). An unsupported or misspelled `sort.by` value does not raise an error — the request quietly falls back to sorting by `published_at`. So a typo like `sort.by=read_tim` silently returns date-sorted results. Check the field name against the supported list if a sort does not behave as expected. ## Which endpoints support sort.by and sort.order?[#](#which-endpoints-support-sortby-and-sortorder) Field sorting works on the endpoints that return article lists: `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/category`, `/v1/news/topic`, `/v1/news/industry` and `/v1/news/entity`. Because `sort.by` only reorders matching articles, you can combine any sort field with your filters and then [page through the ordered results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) with `page` and `per_page`. The full list of `sort.by` values, including composite modes, lives in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [What fields can I sort news by?](#what-fields-can-i-sort-news-by) * [Does sorting by a field also filter out articles?](#does-sorting-by-a-field-also-filter-out-articles) * [How is field sorting different from relevance or quality sorting?](#how-is-field-sorting-different-from-relevance-or-quality-sorting) * [What happens if I use an invalid sort.by value?](#what-happens-if-i-use-an-invalid-sortby-value) ## What fields can I sort news by?[#](#what-fields-can-i-sort-news-by) You can sort by recency (`published_at`, `created_at`/`new`, `id`), source rank (`source.rank.opr`), length (`read_time`), sentiment (`sentiment.overall.score`, `sentiment.title.score`, `sentiment.body.score`) and media (`media.images.count`, `media.videos.count`, and image width/height min and max). Each is passed as the `sort.by` value together with `sort.order`. ## Does sorting by a field also filter out articles?[#](#does-sorting-by-a-field-also-filter-out-articles) No. `sort.by` and `sort.order` only reorder the articles that already match your filters — they never add or remove results. Sorting by `sentiment.overall.score`, for example, ranks every matching article by its score but keeps neutral and negative ones in the list. To change which articles come back, adjust your filters; to change the order, adjust `sort.by`. ## How is field sorting different from relevance or quality sorting?[#](#how-is-field-sorting-different-from-relevance-or-quality-sorting) Field sorting orders by a single stored attribute — the source rank, a length count, a sentiment score or a media count. Composite modes such as `relevance`, `quality` and `engagement` combine several signals into one calculated score. Use a field sort when you know the exact attribute you want to order by; use a composite mode for smart ranking, covered in [how to sort news by relevance, date or quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes). ## What happens if I use an invalid sort.by value?[#](#what-happens-if-i-use-an-invalid-sortby-value) An unrecognised `sort.by` value does not return an error. The request falls back to the default sort, `published_at` in descending order, so you get newest-first results even though your intended sort was ignored. Always check the spelling of the field name against the supported list if the ordering looks wrong. * * * ## Related Articles * [How to Sort News by Relevance, Date or Quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) * [How to Sort News by Controversy, Trust and Social Shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) * [How to Paginate Through News API Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## API key security best practices URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys/api-key-security Keep your APITube API key safe: send it in a header instead of the URL, never ship a live key in client code, restrict it by IP, scope and expiry, and rotate… # API key security best practices Send your key in a header, lock it down with IP, scope and expiry limits, and regenerate it the moment it leaks ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 28, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=10) # API key security best practices[#](#api-key-security-best-practices) Your APITube [API key](/en/articles/getting-started/glossary#api-key) is the single secret that authenticates every request, so treat it like a password: send it in a request header rather than the URL, never embed a [live key](/en/articles/getting-started/glossary#test-key-and-live-key) in browser or mobile code, restrict each key by IP, scope and expiry, and regenerate it immediately if it leaks. Each of these is enforced by the API or available on the **API Keys** page of your dashboard — this article shows how to combine them. ## Send your key in a header, not in the URL[#](#send-your-key-in-a-header-not-in-the-url) The News API accepts your key three ways and checks them in this order: an `Authorization: Bearer` token, an `X-API-Key` header, or an `api_key` query parameter. All three authenticate the call, but a query parameter travels inside the URL — and URLs routinely end up in browser history, server access logs, and proxy logs, where the secret can be read later. For anything beyond a one-off test, send the key in a header instead: ``` curl -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/everything?per_page=10" ``` For the full mechanics of each method, see [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests). ## Never expose a live key in client-side code[#](#never-expose-a-live-key-in-client-side-code) Anyone who can read your page source or a mobile app bundle can copy a key embedded in front-end JavaScript. Call the API from your own backend and keep the key server-side, where visitors can’t reach it. If you need to experiment from a browser, use a **test key** instead of a live one: test keys (prefix `api_test_`) return masked, truncated article content and never draw down your quota, so a leaked test key can’t run up your bill. Live keys (prefix `api_live_`) carry full access and full content — keep them off the client entirely. ## Lock each key down with IP, scope and expiry limits[#](#lock-each-key-down-with-ip-scope-and-expiry-limits) By default a key works from any IP, on any endpoint, with no end date. Tightening those three settings shrinks the damage a leaked key can do, and the API rejects any request that breaks a rule before doing any work: * **IP allowlist (CIDR).** Restrict a key to known server addresses or ranges (for example `10.0.0.0/24`). A request from a disallowed IP is refused with `403` `ER0601`. See [how to restrict an API key to specific IPs](/en/articles/account-and-dashboard/keys/key-ip-restriction). * **Endpoint scopes.** Limit a key to only the endpoints it needs. A key used on an endpoint outside its scopes is refused with `403` `ER0603`. See [how to limit an API key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes). * **Expiry date.** Give short-lived keys an end date; after it passes, the key returns `401` `ER0230`. See [how to set an expiry date on an API key](/en/articles/account-and-dashboard/keys/key-expiry). A refused request returns the standard error shape — a `status` of `not_ok`, your `request_id`, and an `errors` array with the `code` and `message` — so your code can detect exactly which rule blocked it. ![The API Key Restrictions card on the key detail page where allowed IPs and referrers are configured](/images/article/dashboard-key-restrictions-form.png) ## Use a separate key per app or environment[#](#use-a-separate-key-per-app-or-environment) You can hold up to **20 active keys per mode** (Test and Live counted separately) in a [workspace](/en/articles/getting-started/glossary#workspace), so give each application, script, server and environment its own named key. Because both rate limiting and access checks are keyed on the individual key, one key being throttled or revoked never affects the others — and when something breaks, a per-app key tells you exactly which integration is responsible. Create and name keys on the API Keys page: see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## Rotate or revoke a key the moment it leaks[#](#rotate-or-revoke-a-key-the-moment-it-leaks) If a key is exposed — committed to a repo, pasted in a ticket, shipped in a build — act immediately on the API Keys page: * **Regenerate** the key. This issues a brand-new secret in the same mode and invalidates the old value instantly; the next request that uses the old key is rejected with `401`. * **Revoke** any key you no longer use. Revocation is permanent for that key value: the API only authenticates keys that aren’t revoked, so a revoked key stops working on its next request. Rotating is safer than deleting and recreating because it keeps the same key record (and its name and restrictions) while swapping only the secret. # Common Questions[#](#common-questions) * [Is it safe to put my API key in the URL?](#is-it-safe-to-put-my-api-key-in-the-url) * [What happens to requests made with a key after I regenerate it?](#what-happens-to-requests-made-with-a-key-after-i-regenerate-it) * [Can my whole team share one API key?](#can-my-whole-team-share-one-api-key) * [Are test keys safer to expose than live keys?](#are-test-keys-safer-to-expose-than-live-keys) ## Is it safe to put my API key in the URL?[#](#is-it-safe-to-put-my-api-key-in-the-url) It works — the `api_key` query parameter is a supported way to authenticate — but it is the least private option. The key becomes part of the URL, which can be saved in browser history, server access logs, and proxy logs. Prefer the `Authorization: Bearer` token or the `X-API-Key` header, which are not stored as part of the address. Reserve the query parameter for quick manual tests. ## What happens to requests made with a key after I regenerate it?[#](#what-happens-to-requests-made-with-a-key-after-i-regenerate-it) The old secret stops authenticating immediately. Regenerating replaces the key value, so the next request carrying the old value finds no matching active key and is rejected with `401`. Update your applications with the new key before — or right after — you regenerate, and they resume working at once. ## Can my whole team share one API key?[#](#can-my-whole-team-share-one-api-key) You can, but separate keys are safer. With up to 20 active keys per mode, give each person, app or environment its own named key. If one leaks you can regenerate or revoke just that key without disrupting everyone else, and per-key usage and [rate limits](/en/articles/getting-started/glossary#rate-limit) make it clear which integration is doing what. ## Are test keys safer to expose than live keys?[#](#are-test-keys-safer-to-expose-than-live-keys) Lower risk, but still keep them private. Test keys return masked, truncated content and do not spend your quota, so a leaked test key can’t drain credits or expose full article bodies. Live keys carry full access, so a live key must never appear in client-side code, public repositories, or shared links. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to Restrict an API Key to Specific IPs](/en/articles/account-and-dashboard/keys/key-ip-restriction) --- ## How to authenticate your API requests URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests Authenticate APITube News API requests by sending your key three ways: an Authorization Bearer token, an X-API-Key header, or an api_key query parameter. # How to authenticate your API requests Send your API key with every request — as a Bearer token, an X-API-Key header, or an api\_key query parameter ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=10) # How to authenticate your API requests[#](#how-to-authenticate-your-api-requests) Every request to the APITube News API must carry your [API key](/en/articles/getting-started/glossary#api-key). You can send it three ways — as an `Authorization: Bearer` token, in an `X-API-Key` header, or as an `api_key` query parameter — and any one of them authenticates the call. The key is the only credential the API needs; there is no separate username, password or login step. ``` curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.apitube.io/v1/news/everything?per_page=10" ``` A valid key returns HTTP `200` and your results. If the key is missing or wrong, the API replies with a `401` before doing any work, so authentication is the first thing to get right. New to the API? Start with [how to run your first news search](/en/articles/getting-started/your-first-search), then come back here for every way to pass the key. The key itself is copied from the API Keys page of the dashboard: ![The keys table on the API Keys page of the dashboard with a copy control next to each masked key](/images/article/dashboard-api-keys-table.png) ## How do you send your API key?[#](#how-do-you-send-your-api-key) There are three accepted ways to attach your key to a request, and the API checks them in this order: 1. **Authorization header (Bearer)** — prefix the key with `Bearer`: ``` curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.apitube.io/v1/news/everything" ``` 2. **X-API-Key header** — send the raw key in a custom header: ``` curl -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/everything" ``` 3. **api\_key query parameter** — append the key to the URL: ``` curl "https://api.apitube.io/v1/news/everything?api_key=YOUR_API_KEY" ``` If a request includes more than one, the API uses the first it finds in that order: `Authorization` Bearer, then `X-API-Key`, then `api_key`. The same key works on `GET` and `POST` requests alike — put your filters in the query string for `GET` or in a JSON body for `POST`, and pass the key in a header either way. ## Which method should you use?[#](#which-method-should-you-use) Use a header — `Authorization: Bearer` or `X-API-Key` — for anything running against live data. The `api_key` query parameter is the quickest way to test from a browser or a one-line `curl`, but the key then sits in the URL, where proxies, server logs and browser history are likely to record it. For that reason the query-string method is not recommended for production. Pick a header for your servers, and reserve the query parameter for throwaway tests. The header name is case-insensitive, so `X-API-Key` and `x-api-key` are treated the same. ## What is the difference between live and test keys?[#](#what-is-the-difference-between-live-and-test-keys) Every account has two kinds of key, and the prefix is the only thing that tells them apart: * **[Live keys](/en/articles/getting-started/glossary#test-key-and-live-key)** start with `api_live_`. They return full article content and draw down your plan quota or [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance. * **Test keys** start with `api_test_`. They hit the same live endpoints and return the real response shape, but each article’s body is truncated and suffixed with `[Test mode — use a live key for full content]`, and **no quota or balance is spent**. Both kinds authenticate the same way — send them as a Bearer token, an `X-API-Key` header or an `api_key` parameter. Use a test key to wire up [pagination](/en/articles/getting-started/glossary#pagination), field selection and error handling for free, then switch to a live key on a paid plan for full content. If you see placeholder text where the article body should be, you are almost certainly using a test key — see [why your results are masked or placeholder text](/en/articles/troubleshooting/masked-results). ## What happens when authentication fails?[#](#what-happens-when-authentication-fails) A rejected key never spends a request — the API turns it away up front. Read the `error` code in the JSON response to know why: * **`401 ER0201`** — no key reached the server (missing header, empty `api_key=`, or a proxy stripped it). * **`401 ER0202`** — a key was sent but does not match an active key (a typo, extra whitespace, or the key was revoked). * **`401 ER0230`** — the key is valid but past its expiry date. * **`403 ER0601` / `ER0602` / `ER0603`** — the key works but is blocked by an IP allow-list, a domain restriction, or an endpoint scope. A `401` is always about the key itself; a `403` means the key is recognised but not permitted for this call. For the exact cause and fix of each one, see [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors). The full credential reference also lives on the official [authentication page on docs.apitube.io](https://docs.apitube.io/platform/news-api/authentication). # Common Questions[#](#common-questions) * [Do all endpoints require an API key?](#do-all-endpoints-require-an-api-key) * [Where do I find or create my API key?](#where-do-i-find-or-create-my-api-key) * [Can I send the key in a POST body?](#can-i-send-the-key-in-a-post-body) * [Is authentication different for streaming or webhooks?](#is-authentication-different-for-streaming-or-webhooks) ## Do all endpoints require an API key?[#](#do-all-endpoints-require-an-api-key) Almost all of them. Every News API endpoint authenticates the same way, with three exceptions that need no key: `/ping` (a health check), `/openapi.json` (the API schema) and `/robots.txt`. Anything that returns news data — search, retrieval, streaming and [webhooks](/en/articles/getting-started/glossary#webhook) — requires a valid key. ## Where do I find or create my API key?[#](#where-do-i-find-or-create-my-api-key) Your keys live on the **API Keys** page of your APITube dashboard. Create an account, open that page, and click **Create key**; the value starts with `api_live_` or `api_test_` depending on the mode you are in. You can hold several keys at once and revoke any of them — see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## Can I send the key in a POST body?[#](#can-i-send-the-key-in-a-post-body) No — the key travels in a header or the query string, not the JSON body. On a `POST` request you still put your search filters in the body, but the key goes in an `Authorization: Bearer` or `X-API-Key` header (or, for a quick test, the `api_key` query parameter on the URL). This keeps authentication identical across `GET` and `POST`. ## Is authentication different for streaming or webhooks?[#](#is-authentication-different-for-streaming-or-webhooks) No. The [SSE](/en/articles/getting-started/glossary#sse-stream) stream, the WebSocket feed and the webhook endpoints all accept the same key in the same three ways, because the key check runs on every request. One practical note: a browser `EventSource` cannot set custom headers, so for browser-side streaming you pass `?api_key=YOUR_API_KEY` on the URL — and because the key is then visible in the page, use a key you have restricted by IP, referrer or scope rather than a privileged one. * * * ## Related Articles * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## How to create an APITube account URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys/create-your-account Create an APITube account in seconds: click Sign Up on apitube.io, register with email and password (or Google/GitHub), and land on the free plan with a live… # How to create an APITube account Sign up with email and password — or Google or GitHub — and get a free plan and API key instantly ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 2, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=5) # How to create an APITube account[#](#how-to-create-an-apitube-account) To create an APITube account, open **apitube.io**, click **Sign Up**, and register with your email and a password — or with your Google or GitHub account. The moment you sign up you land on the **free plan** with a **live [API key](/en/articles/getting-started/glossary#api-key) already created**, and you are signed straight into your dashboard. There is no email-verification step to wait through, so you can make your first request right away. ## How to sign up with email and password[#](#how-to-sign-up-with-email-and-password) Clicking **Sign Up** on apitube.io opens the “Let’s create an account” dialog. To register with email: 1. Type your **email** address. 2. Type a **password**. 3. Click **Create account**. Your email has to be a valid address that is not already registered. If it is already in use, APITube shows the message **“User with this email already exists”** and you can switch to **Sign In** from the same dialog instead. A password is required — any value is accepted, but pick a strong one, because it is what guards access to your API keys and billing. Submitting the form signs you in immediately and takes you to your dashboard. ## Can you sign up with Google or GitHub?[#](#can-you-sign-up-with-google-or-github) Yes. Above the email form, the same dialog has **Create account with Google** and **Create account with GitHub** buttons. Pick one, authorize APITube on the provider’s consent screen, and you return already signed in — there is no separate password to set. Use this route if you would rather not manage another password. Whichever method you choose, signing up means you agree to APITube’s terms of service, which are linked at the bottom of the dialog. ## What do you get right after signing up?[#](#what-do-you-get-right-after-signing-up) Registration does more than create a login. As soon as your account exists, APITube sets you up so you can start calling the News API: * **The free plan.** Your account starts on the free tier with a request allowance you can use straight away. * **A live API key, created for you.** A key that starts with `api_live_` is generated automatically and attached to your account — you do not have to create one by hand first. * **You are signed in.** You are redirected to your dashboard with an active session, ready to explore. ![The dashboard home page of a fresh APITube account: your API key widget, a Quickstart snippet and the usage chart](/images/article/dashboard-home.png) Once you copy that key from the **API Keys** page, a first call looks like this: ``` curl -H "X-API-Key: api_live_YOUR_KEY" \ "https://api.apitube.io/v1/news/everything?per_page=5" ``` See [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) to grab the value, then walk through [how to run your first news search](/en/articles/getting-started/your-first-search) to confirm everything works. ## Do you need a credit card or email verification to sign up?[#](#do-you-need-a-credit-card-or-email-verification-to-sign-up) No. Creating an APITube account asks only for an email and a password — or a Google or GitHub login — and nothing more. There is no credit-card field on the sign-up form, and there is no confirmation email you must click before you can use the account: registration signs you in on the spot. That means the fastest path from landing on apitube.io to your first API response is just three clicks: **Sign Up**, fill in your details, **Create account**. For the full credential reference once you are in, see the official [authentication page on docs.apitube.io](https://docs.apitube.io/platform/news-api/authentication). # Common Questions[#](#common-questions) * [What if my email is already registered?](#what-if-my-email-is-already-registered) * [Do I need a credit card to create an account?](#do-i-need-a-credit-card-to-create-an-account) * [Is there an email-verification step?](#is-there-an-email-verification-step) * [Can I sign up with Google or GitHub instead?](#can-i-sign-up-with-google-or-github-instead) ## What if my email is already registered?[#](#what-if-my-email-is-already-registered) APITube will not create a second account on the same address. If you try to register with an email that already exists, the dialog returns **“User with this email already exists”**. Switch to **Sign In** from the same dialog and log in with that email instead, or use the forgot-password link if you cannot remember the password. ## Do I need a credit card to create an account?[#](#do-i-need-a-credit-card-to-create-an-account) No. The sign-up dialog only asks for an email and password (or a Google/GitHub login). Your new account starts on the free plan, so you can register and start making requests without entering any payment details. ## Is there an email-verification step?[#](#is-there-an-email-verification-step) No. Registration signs you straight in and sends you to your dashboard — there is no confirmation email you have to click before the account works. APITube does send a welcome email after you sign up, but you do not need to act on it to use the API. ## Can I sign up with Google or GitHub instead?[#](#can-i-sign-up-with-google-or-github-instead) Yes. The “Let’s create an account” dialog offers **Create account with Google** and **Create account with GitHub** buttons alongside the email form. Authorize APITube on the provider’s screen and you are signed in without setting a password. You get the same free plan and automatically created API key either way. * * * ## Related Articles * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [How to run your first news search](/en/articles/getting-started/your-first-search) * [Test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) --- ## How to make your first request with cURL URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys/first-request-with-curl Make your first APITube News API request with cURL: send your key to /v1/news/everything, URL-encode parameters, inspect the response with -i and jq, and fix… # How to make your first request with cURL Build, send and inspect a single curl call to /v1/news/everything — including how to encode parameters and read the JSON response ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to make your first request with cURL[#](#how-to-make-your-first-request-with-curl) To make your first APITube request with cURL, send a `GET` to `https://api.apitube.io/v1/news/everything` with your [API key](/en/articles/getting-started/glossary#api-key) in an `X-API-Key` header. A valid key returns HTTP `200` and a JSON object whose `results` field holds the articles. This one command is the whole round trip — copy it into a terminal, swap in your key, and you have live news back. ``` curl "https://api.apitube.io/v1/news/everything?per_page=3" \ -H "X-API-Key: YOUR_API_KEY" ``` cURL ships on macOS, Linux and Windows 10+, so this works without installing anything. Once this call succeeds, every filter — keywords, language, dates — is just another parameter on the same URL. ## How do you pass your API key in cURL?[#](#how-do-you-pass-your-api-key-in-curl) The API reads your key from one of three places, checked in this order: an `Authorization: Bearer` header, an `X-API-Key` header, then an `api_key` query parameter. Any one of them authenticates the call, so pick whichever is easiest: ``` # X-API-Key header (recommended for scripts) curl "https://api.apitube.io/v1/news/everything" -H "X-API-Key: YOUR_API_KEY" # Bearer token curl "https://api.apitube.io/v1/news/everything" -H "Authorization: Bearer YOUR_API_KEY" # api_key in the URL (quickest one-off test) curl "https://api.apitube.io/v1/news/everything?api_key=YOUR_API_KEY" ``` Use a header in anything you keep — the query-string form puts your key in shell history and server logs. For the full breakdown, see [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests). ## How do you add parameters and encode them correctly?[#](#how-do-you-add-parameters-and-encode-them-correctly) Filters are query parameters on the same endpoint. The catch with cURL is encoding: a value with a space (like a two-word title) or a symbol breaks a raw URL. The clean fix is `-G` plus `--data-urlencode`, which builds the query string and encodes each value for you: ``` curl -G "https://api.apitube.io/v1/news/everything" \ -H "X-API-Key: YOUR_API_KEY" \ --data-urlencode "title=electric vehicles" \ --data-urlencode "language.code=en" \ --data-urlencode "per_page=10" ``` Parameter names that contain a dot — `language.code`, `published_at.start` — are passed exactly as written; the dot needs no escaping. Only the **values** need encoding, and `--data-urlencode` handles that. Without `-G`, always wrap the whole URL in quotes: an unquoted `&` between parameters is read by your shell as “run in background”, which silently sends only the first parameter. The maximum `per_page` is **250**, or **50** on Starter and **10** on Free; ask for more and the API returns `400` with code `ER0171` (“Limit is out of range. Your plan allows up to N results per page.”). The complete parameter list lives in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## How do you read the cURL response?[#](#how-do-you-read-the-curl-response) A successful call returns a JSON envelope, not a bare list. The fields you reach for first are `status` (`"ok"`), `results` (the article array), `page` and `limit` (the current page and its size), `has_next_pages` and `next_page` (whether more exist, plus a ready-made URL), the `export` block (the same search as CSV, XLSX, RSS, XML, TSV, Parquet, JSON or JSONL), and `request_id` (quote it to support): ``` { "status": "ok", "limit": 3, "page": 1, "has_next_pages": true, "next_page": "https://api.apitube.io/v1/news/everything?per_page=3&page=2", "results": [ "… article objects …" ], "request_id": "…" } ``` To see the HTTP status line and headers as well as the body, add `-i`. To watch the whole exchange — request headers, TLS, redirects — use `-v`. To pretty-print only the parts you care about, pipe a quiet call into `jq`: ``` curl -s "https://api.apitube.io/v1/news/everything?api_key=YOUR_API_KEY&per_page=3" \ | jq '{status, page, count: (.results | length)}' ``` ## How do you send a POST request with a JSON body instead?[#](#how-do-you-send-a-post-request-with-a-json-body-instead) The same endpoint also accepts `POST`. Put your filters in a JSON body and set `Content-Type: application/json`; the API merges query-string and body parameters, so the key can still travel in a header. This is cleaner than `-G` when a query gets long: ``` curl -X POST "https://api.apitube.io/v1/news/everything" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"title": "electric vehicles", "language.code": "en", "per_page": 10}' ``` `GET` and `POST` return the identical envelope, so use whichever reads better. New to the endpoint itself? Start with [how to run your first news search](/en/articles/getting-started/your-first-search) for what each field means. # Common Questions[#](#common-questions) * [Why does cURL return a 401?](#why-does-curl-return-a-401) * [Why is only part of my query applied?](#why-is-only-part-of-my-query-applied) * [How do I see the exact HTTP status code?](#how-do-i-see-the-exact-http-status-code) * [Which endpoints work without a key?](#which-endpoints-work-without-a-key) ## Why does cURL return a 401?[#](#why-does-curl-return-a-401) A `401` means the key never reached the API or did not match. If no key was sent you get code `ER0201`; if a key was sent but is wrong, revoked or mistyped you get `ER0202`. Both arrive as a JSON envelope with `status: "not_ok"` and an `errors` array. The usual cURL cause is the header being dropped — check there is a space after the colon in `-H "X-API-Key: ..."` and that the key has no stray whitespace. See [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors). ## Why is only part of my query applied?[#](#why-is-only-part-of-my-query-applied) Almost always an unquoted URL. In a shell, `&` separates commands and `?`/spaces are special, so `curl https://...?a=1&b=2` sends `a=1` and backgrounds the rest. Wrap the entire URL in double quotes, or build the query with `-G --data-urlencode` so cURL assembles and encodes it for you. ## How do I see the exact HTTP status code?[#](#how-do-i-see-the-exact-http-status-code) Add `-i` to include the status line and response headers above the body, or `-w "%{http_code}\n"` to print just the numeric code. A working request shows `200`; an auth failure shows `401`; an out-of-range `per_page` shows `400`. ## Which endpoints work without a key?[#](#which-endpoints-work-without-a-key) Only three: `/ping` (a health check), `/openapi.json` (the schema) and `/robots.txt`. Every endpoint that returns news data requires a valid key, so your first real call always carries one. * * * ## Related Articles * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) --- ## Where to find and create your API key URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys/get-your-api-key Find and create your APITube API key on the API Keys page of your dashboard: click Create key, name it, and copy the value that starts with api_live_. # Where to find and create your API key Open the API Keys page in your dashboard, click Create key, and copy the value — it starts with api\_live\_ ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=10) # Where to find and create your API key[#](#where-to-find-and-create-your-api-key) Your APITube [API key](/en/articles/getting-started/glossary#api-key) lives on the **API Keys** page of your dashboard. Open that page, click **Create key**, give the key a name, and copy the value — it starts with `api_live_` (or `api_test_` when you are in Test mode). That single value is the only credential the News API needs; there is no separate username or password. ``` curl -H "X-API-Key: api_live_YOUR_KEY" \ "https://api.apitube.io/v1/news/everything?per_page=10" ``` If this is your very first request, run it once with the key you just copied and you should get HTTP `200` with results. New to the API entirely? Follow [how to run your first news search](/en/articles/getting-started/your-first-search) first, then come back to create and manage keys here. ## Where is your API key in the dashboard?[#](#where-is-your-api-key-in-the-dashboard) Open the **API Keys** page from the dashboard navigation. It lists every key on your account in a table with columns for **Name**, **Key**, **Usage points**, **Last used**, **Created**, a 7-day activity chart, and **Status**. Each row shows the key value truncated, with a copy icon next to it that copies the full secret to your clipboard at any time — APITube does not hide the value after creation, so you can grab it again whenever you need it. The first key you created is labelled **Default**, and any key made without a name shows as **Unnamed key**. The page header reminds you that an account can hold **up to 20 keys**, so you can keep separate keys for production, staging, and tests instead of reusing one everywhere. ![The keys table on the API Keys page: name, truncated key value with a copy icon, requests used and status](/images/article/dashboard-api-keys-table.png) ## How to create a new API key[#](#how-to-create-a-new-api-key) 1. On the **API Keys** page, click **Create key**. 2. Type a **name** in the “Create API key” dialog — this field is required, so pick something you will recognize later, like “Production server”. 3. Click **Create key** to confirm. The new key appears at the top of the table. Its value starts with `api_live_` for a [live key](/en/articles/getting-started/glossary#test-key-and-live-key) or `api_test_` for a test key — the prefix is the only thing that marks a key’s mode — followed by a long random string. Click the copy icon to grab the full secret and paste it into your app or a request: ``` curl "https://api.apitube.io/v1/news/everything?api_key=api_live_YOUR_KEY&per_page=5" ``` Keys are created in whichever mode (Test or Live) you currently have selected at the top of the dashboard, and the table shows only the keys for that mode. New accounts start in **Live** mode by default. For renaming, rotating, and revoking keys later, see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## Live key or test key — which one do you get?[#](#live-key-or-test-key--which-one-do-you-get) You can create two kinds of key, and the prefix tells them apart: * **Live keys** start with `api_live_`. They return full article content and draw down your plan quota or [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance. * **Test keys** start with `api_test_`. They call the same live endpoints and don’t consume your quota, but each article body is truncated and suffixed with `[Test mode — use a live key for full content]`. Switch the dashboard between Test and Live mode to create a key of either type. Use a test key to wire up your integration for free, then create a live key for real content. The difference is covered in full in [test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys). ## How do you use the key once you have it?[#](#how-do-you-use-the-key-once-you-have-it) Send the key with every request. The News API accepts it three ways, and checks them in this order: an `Authorization: Bearer` token, an `X-API-Key` header, or an `api_key` query parameter — any one of them authenticates the call. ``` # header (recommended for servers) curl -H "Authorization: Bearer api_live_YOUR_KEY" \ "https://api.apitube.io/v1/news/everything" # query parameter (handy for a quick browser test) curl "https://api.apitube.io/v1/news/everything?api_key=api_live_YOUR_KEY" ``` Prefer a header for anything running against live data — the query parameter leaves the key in URLs and logs. The full credential reference lives on the official [authentication page on docs.apitube.io](https://docs.apitube.io/platform/news-api/authentication), and every method is broken down in [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests). # Common Questions[#](#common-questions) * [Can I see the full key value again after creating it?](#can-i-see-the-full-key-value-again-after-creating-it) * [How many API keys can I create?](#how-many-api-keys-can-i-create) * [Does each key have its own quota?](#does-each-key-have-its-own-quota) * [Why is one of my keys called “Default”?](#why-is-one-of-my-keys-called-default) ## Can I see the full key value again after creating it?[#](#can-i-see-the-full-key-value-again-after-creating-it) Yes. The API Keys table shows every key with a copy icon that copies the complete secret at any time — there is no “you can only see it once” step. Still, treat the value like a password: store it in a secret manager and never embed a live key in browser or client-side code. ## How many API keys can I create?[#](#how-many-api-keys-can-i-create) You can hold up to **20 active keys**, counted within the current mode, so Test and Live each get their own allowance. Revoked keys don’t count toward the limit, so revoking an old key frees a slot. Trying to create one past the limit returns an error telling you the maximum has been reached. ## Does each key have its own quota?[#](#does-each-key-have-its-own-quota) No. Your request quota, balance, and subscription are shared at the account level, not per key. Creating several keys does not give you more requests — every key draws from the same pool. Use multiple keys to separate environments and to rotate or revoke one without disturbing the others. ## Why is one of my keys called “Default”?[#](#why-is-one-of-my-keys-called-default) The dashboard labels your first key **Default** so it is easy to spot in the table. Any key you create afterwards without typing a name shows as **Unnamed key**. The label is cosmetic — it doesn’t change how the key authenticates or what it can access. Give each key a clear name when you create it to make auditing and rotation easier later. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [Test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) --- ## Account & API Keys URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys Create your APITube account, find and create your API key, authenticate every request, and tell live keys from test keys. ![](/images/collections/user-management-security.png) # Account & API Keys Create an account and your first key. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Kent and 1 other 2 authors 6 articles * [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to create an APITube account](/en/articles/setup-and-installation/account-and-keys/create-your-account) * [How to make your first request with cURL](/en/articles/setup-and-installation/account-and-keys/first-request-with-curl) * [Test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) --- ## Test keys vs live keys URL: https://support.apitube.io/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys APITube test keys return the real response shape without spending quota but truncate content; live keys return full articles and draw down your plan. # Test keys vs live keys How APITube test keys and live keys differ — content, quota, rate limits — and when to use each ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&per_page=10) # Test keys vs live keys[#](#test-keys-vs-live-keys) Every APITube account has two kinds of [API key](/en/articles/getting-started/glossary#api-key). A **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** (prefix `api_test_`) calls the same live endpoints and returns the real response structure, but article content is truncated and **no quota or balance is spent**. A **live key** (prefix `api_live_`) returns full article content and draws down your plan quota or [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance. The prefix is the only difference the API looks at — there is no separate test environment or sandbox URL. ``` # Same endpoint, same shape — only the key's prefix changes the behaviour curl "https://api.apitube.io/v1/news/everything?per_page=10&api_key=api_test_YOUR_TEST_KEY" ``` Use a test key to build and verify an integration for free — [pagination](/en/articles/getting-started/glossary#pagination), [field selection](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields), filters and error handling all behave exactly as they will on a live key. Switch to a live key on a paid plan when you need the full article body. ## How do you tell a test key from a live key?[#](#how-do-you-tell-a-test-key-from-a-live-key) By the prefix, and nothing else. Keys are issued as a prefix plus a long random string: * **`api_live_…`** — a live key. * **`api_test_…`** — a test key. There is no `is_test` flag stored in the database; the API decides the mode purely by reading the start of the key value on every request. Both kinds authenticate the same three ways — an `Authorization: Bearer` token, an `X-API-Key` header, or an `api_key` query parameter (see [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests)). Every response also echoes the mode in a header so your client never has to parse the key: ``` x-apitube-mode: test x-apitube-mode: live ``` ## What does a test key return differently?[#](#what-does-a-test-key-return-differently) A test key hits the live API and gives you the genuine JSON structure — the same fields, the same arrays, the same error codes — so your parsing code is exercised for real. What changes is the **content** inside that structure. Test keys mask article data the same way the Free plan does: * The article **`body`** and **`description`** are cut to the first 200 characters, followed by a note of how many characters are hidden and the marker `[Test mode — use a live key for full content]`. * The **`href`** and **`image`** are truncated to a short stub plus that same marker. * The **source domain** is shortened too. Aggregate endpoints are limited in the same spirit so test keys can’t reveal the real archive volume: `/v1/news/count` returns a capped number (no more than 100), and `/v1/news/trends` returns the structure but hides the trending `value`. Streaming works as well — both the [SSE stream](/en/articles/delivery-and-export/streaming/stream-with-sse) and the [WebSocket](/en/articles/getting-started/glossary#websocket) feed deliver the real event flow with the body masked and no quota consumed. If you see placeholder text where the article body should be, you are using a test key — see [why your results are masked](/en/articles/troubleshooting/masked-results). ## Do test keys count against my quota or rate limit?[#](#do-test-keys-count-against-my-quota-or-rate-limit) Test keys never touch your quota. They do **not** decrement your plan requests, your streaming points or your pay-as-you-go balance, and they never hit the `402` “no points” wall — so you can hammer them during development without burning anything. They are, however, rate-limited more strictly than live keys, because the live endpoints they call are real: * **Test keys:** up to **15 requests per minute**. * **Live keys:** up to **50 requests per minute**. Both share the same abuse guard: after 30 violations the key is temporarily banned (HTTP `429`). Build your retry and back-off logic against a test key first, then it will already be correct when you move to live traffic. ## How do you create or switch between test and live keys?[#](#how-do-you-create-or-switch-between-test-and-live-keys) Both kinds are created in the [APITube dashboard](https://apitube.io). Flip the **Test mode** toggle at the bottom of the sidebar, then open **API Keys** and click **Create key** — a key made in test mode starts with `api_test_`, and a key made in live mode starts with `api_live_`. Test and live keys are listed separately per mode, so toggling the switch shows the set for whichever mode you are in. You can hold several of each and revoke any of them (see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys)). ![The Test mode toggle at the bottom of the dashboard sidebar](/images/article/dashboard-test-mode.png) The full credential reference also lives on the official [authentication page on docs.apitube.io](https://docs.apitube.io/platform/news-api/authentication). # Common Questions[#](#common-questions) * [Can I use a test key in production?](#can-i-use-a-test-key-in-production) * [Do test keys respect IP, referrer and scope restrictions?](#do-test-keys-respect-ip-referrer-and-scope-restrictions) * [Can a test key expire?](#can-a-test-key-expire) * [Does my code need to change when I switch from test to live?](#does-my-code-need-to-change-when-i-switch-from-test-to-live) ## Can I use a test key in production?[#](#can-i-use-a-test-key-in-production) No. A test key returns truncated article content, so the data is only useful for wiring up and validating an integration, not for serving real results. It is also rate-limited more tightly (15 requests per minute). For production traffic, create a live key on a paid plan to receive full content. ## Do test keys respect IP, referrer and scope restrictions?[#](#do-test-keys-respect-ip-referrer-and-scope-restrictions) Yes. The same access checks run on every request regardless of mode. If you add an IP allow-list, a domain (referrer) restriction or endpoint scopes to a test key, the API enforces them and returns `403` (`ER0601` for IP, `ER0602` for referrer, `ER0603` for scope) when a call falls outside them — exactly as it would for a live key. ## Can a test key expire?[#](#can-a-test-key-expire) Yes. If you set an expiry date on a key, it applies whether the key is test or live. Once the date passes, the API rejects the key with `401 ER0230` before doing any work. ## Does my code need to change when I switch from test to live?[#](#does-my-code-need-to-change-when-i-switch-from-test-to-live) No code changes — only the key value. Because a test key returns the same endpoints, parameters and response structure as a live key, swapping `api_test_…` for `api_live_…` is enough to start receiving full content. The only behavioural differences disappear automatically: content is no longer truncated, the [rate limit](/en/articles/getting-started/glossary#rate-limit) rises to 50 requests per minute, and requests begin drawing down your quota or balance. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [Why are my results masked or placeholder text?](/en/articles/troubleshooting/masked-results) * [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## Using APITube Agent Skills URL: https://support.apitube.io/en/articles/setup-and-installation/ai-and-mcp/agent-skills APITube Agent Skills are discoverable instruction files under /.well-known/ that teach an AI agent to authenticate and query the News API on its own. # Using APITube Agent Skills Discoverable instruction files APITube serves under /.well-known/ so AI agents can find, verify and use the News API on their own ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 # Using APITube Agent Skills[#](#using-apitube-agent-skills) APITube Agent Skills are small, discoverable instruction files that teach an AI agent how to authenticate, query and parse the News API — without a human wiring it up first. APITube publishes them under `/.well-known/`, following the [Agent Skills](https://agentskills.io/) standard, so a supporting agent can find them automatically and then call the News API correctly. There are two published skills today: `apitube-news-api`, for calling the API directly over HTTP, and `apitube-mcp`, for connecting through the hosted MCP server. You do not install or configure an Agent Skill yourself. It is a public instruction file the agent reads. Your only setup is having an [API key](/en/articles/getting-started/glossary#api-key) ready for the agent to authenticate with — see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). ## What are Agent Skills?[#](#what-are-agent-skills) Agent Skills are short instruction files that describe how to use a service, written for an AI agent rather than a person. Because APITube serves them from a `/.well-known/` path — a standard, predictable location — an agent that supports the Agent Skills discovery standard can fetch them on its own, with no manual setup. The skill tells the agent how to authenticate, which endpoints exist, which filters matter, and what the response looks like, so the agent builds valid requests instead of guessing. This is the discovery-and-instruction layer. It does not run your queries; it points the agent at the right way to run them — either the raw HTTP API or the hosted MCP server described below. ## Which skills does APITube publish?[#](#which-skills-does-apitube-publish) APITube publishes two Agent Skills, each aimed at a different way of reaching the News API: * **`apitube-news-api`** — how to call the News API directly over HTTP: authentication, the endpoints, the key `/news/everything` filters, the JSON response shape, and [rate limits](/en/articles/getting-started/glossary#rate-limit). Use this skill when the agent should build and send API requests itself against the base URL `https://api.apitube.io/v1`. * **`apitube-mcp`** — how to connect an assistant to the hosted MCP server at `https://mcp.apitube.io/` and search news in natural language, with no code and no install. This skill maps onto the [APITube MCP server](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server), whose `search_news` search tool and `suggest` ID-lookup tool the agent then drives. In short: pick `apitube-news-api` when the agent writes HTTP requests, and `apitube-mcp` when the agent talks to an assistant that speaks the Model Context Protocol. If you are configuring a client by hand instead, follow [how to use APITube in Cursor, Claude and VS Code](/en/articles/setup-and-installation/ai-and-mcp/use-in-ai-assistants). ## How does an agent discover the skills?[#](#how-does-an-agent-discover-the-skills) Every published skill is listed in one discovery index, which follows the Agent Skills Discovery RFC (schema version `0.2.0`): ``` https://docs.apitube.io/.well-known/agent-skills/index.json ``` The index is a plain JSON file the agent fetches first. Each entry gives the skill’s `name`, a `type` of `skill-md`, a one-line `description`, the `url` of the skill file, and a `digest` — a SHA-256 hash of the skill file’s raw bytes. You can read it with a single request: ``` curl https://docs.apitube.io/.well-known/agent-skills/index.json ``` A trimmed entry looks like this: ``` { "name": "apitube-mcp", "type": "skill-md", "description": "Connect an AI assistant to APITube News via the hosted MCP server...", "url": "/.well-known/agent-skills/apitube-mcp/SKILL.md", "digest": "sha256:b587a56b..." } ``` The `digest` matters: it is computed from the exact bytes of the served file, so an agent can hash the `SKILL.md` it downloads and confirm the file was not altered in transit or swapped out. If the hash matches the index, the instructions are authentic. Entries are sorted by name, and every skill is required to carry a `description`, so the index is always complete and predictable. ## What is inside each skill file?[#](#what-is-inside-each-skill-file) Each skill is a Markdown file at the `url` listed in the index. You can open either one in a browser or with `curl`: ``` https://docs.apitube.io/.well-known/agent-skills/apitube-news-api/SKILL.md https://docs.apitube.io/.well-known/agent-skills/apitube-mcp/SKILL.md ``` The **`apitube-news-api`** skill documents the direct HTTP path: the base URL, the three ways to pass your API key, an endpoint table (`/news/everything`, `/news/top-headlines`, `/news/article`, taxonomy and `/suggest` endpoints, `/balance`), the most-used `/news/everything` parameters, a sample JSON response, and rate limits. It is enough for an agent to authenticate and run a filtered search end to end. The **`apitube-mcp`** skill documents the hosted MCP path: the `https://mcp.apitube.io/` endpoint, the `search_news` search tool and the `suggest` ID-lookup tool, ready-made prompt templates, and how to add the server to an MCP client. MCP clients can also read the server’s capabilities from its **server card** at `https://docs.apitube.io/.well-known/mcp/server-card.json`, which lists the tools and prompts the server exposes. # Common Questions[#](#common-questions) * [Do I need to install or configure anything?](#do-i-need-to-install-or-configure-anything) * [Which API key do Agent Skills use?](#which-api-key-do-agent-skills-use) * [How does an agent know a skill file hasn’t changed?](#how-does-an-agent-know-a-skill-file-hasnt-changed) * [Can I read the skills myself?](#can-i-read-the-skills-myself) ## Do I need to install or configure anything?[#](#do-i-need-to-install-or-configure-anything) No. Agent Skills are public instruction files APITube hosts under `/.well-known/`, so there is nothing to install and nothing to set up in the skill itself. An agent that supports the Agent Skills discovery standard finds them automatically. The one thing you still provide is an API key, which the agent uses to authenticate its News API or MCP requests. ## Which API key do Agent Skills use?[#](#which-api-key-do-agent-skills-use) The same normal APITube API key you use everywhere else. The skills describe _how_ to authenticate — for example, passing the key in an `Authorization: Bearer` header — but they do not contain a key. Whether the agent takes the HTTP path (`apitube-news-api`) or the MCP path (`apitube-mcp`), it authenticates with your account key, so the usage draws on the same plan and quota as your direct requests. ## How does an agent know a skill file hasn’t changed?[#](#how-does-an-agent-know-a-skill-file-hasnt-changed) The discovery index stores a `sha256` digest of each skill file’s raw bytes. An agent can hash the `SKILL.md` it downloads and compare it to the digest in `index.json`. A match confirms the file is exactly what APITube published; a mismatch means the file was changed and should not be trusted. This is why the index is regenerated whenever a skill changes — the digest always reflects what is actually served. ## Can I read the skills myself?[#](#can-i-read-the-skills-myself) Yes. Everything is public and human-readable. Open the discovery index at `https://docs.apitube.io/.well-known/agent-skills/index.json` to see both skills, then open either `SKILL.md` at the `url` listed there. The `apitube-news-api` skill is a compact HTTP quick-start, and the `apitube-mcp` skill is a compact MCP quick-start — useful references even if you are wiring things up by hand rather than through an agent. For the official reference, see the [APITube Agent Skills documentation](https://docs.apitube.io/platform/news-api/ai/agent-skills). * * * ## Related Articles * [What is the APITube MCP server?](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) * [How to Use APITube in Cursor, Claude and VS Code](/en/articles/setup-and-installation/ai-and-mcp/use-in-ai-assistants) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) --- ## AI Assistants & MCP URL: https://support.apitube.io/en/articles/setup-and-installation/ai-and-mcp Connect APITube to AI assistants with the hosted MCP server: what it is, how to add it to Cursor or Claude, and how to search News API news in plain language. ![](/images/collections/ai.svg) # AI Assistants & MCP Connect Cursor and Claude via MCP. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Jacob 1 author 3 articles * [How to Use APITube in Cursor, Claude and VS Code](/en/articles/setup-and-installation/ai-and-mcp/use-in-ai-assistants) * [Using APITube Agent Skills](/en/articles/setup-and-installation/ai-and-mcp/agent-skills) * [What is the APITube MCP server?](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) --- ## How to Use APITube in Cursor, Claude and VS Code URL: https://support.apitube.io/en/articles/setup-and-installation/ai-and-mcp/use-in-ai-assistants Connect Cursor, Claude Code, Claude Desktop, VS Code or Windsurf to the hosted APITube MCP server with your API key and search news in plain language. # How to Use APITube in Cursor, Claude and VS Code Step-by-step MCP setup for Cursor, Claude Code, Claude Desktop, VS Code and Windsurf using the hosted server ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington August 22, 2026 # How to use APITube in Cursor, Claude and VS Code[#](#how-to-use-apitube-in-cursor-claude-and-vs-code) To use APITube inside an AI assistant, point the assistant at the hosted MCP server `https://mcp.apitube.io/` and add an `Authorization: Bearer YOUR_API_KEY` header in its MCP config, then restart the editor. The server is hosted, so there is nothing to install — you edit one config file (or run one command), and the assistant can search News API news in plain language. Cursor, Claude Code, Claude Desktop, VS Code (GitHub Copilot) and Windsurf are all supported. The setup is the same everywhere: the server URL is always `https://mcp.apitube.io/`, and your normal APITube [API key](/en/articles/getting-started/glossary#api-key) goes in the `Authorization: Bearer` header — it has to be a **paid-plan** key, because a free-plan key is refused with `403 ER0706`. Only the config file location and its exact shape differ per editor. Get a key first at [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key), then follow the block for your editor below. ## How to connect Cursor to APITube[#](#how-to-connect-cursor-to-apitube) Cursor supports remote MCP servers directly, so you only add the URL and header. Edit `~/.cursor/mcp.json` for all projects, or `.cursor/mcp.json` inside a single project: ``` { "mcpServers": { "apitube-news": { "url": "https://mcp.apitube.io/", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Save the file, restart Cursor, then open **Settings → MCP** and confirm `apitube-news` shows as connected. ## How to connect Claude Code to APITube[#](#how-to-connect-claude-code-to-apitube) Claude Code can add the server from the terminal in one command: ``` claude mcp add --transport http apitube-news https://mcp.apitube.io/ \ --header "Authorization: Bearer YOUR_API_KEY" ``` To commit the server to a repository instead, add an `.mcp.json` file to the repo root with `"type": "http"`, the same URL and the same `Authorization` header. Run `/mcp` inside Claude Code to check the connection. ## How to connect Claude Desktop to APITube[#](#how-to-connect-claude-desktop-to-apitube) Claude Desktop launches MCP servers as local processes and cannot call a remote server directly, so you bridge the hosted server with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote). Edit `claude_desktop_config.json` (in `~/Library/Application Support/Claude/` on macOS, or `%APPDATA%\Claude\` on Windows): ``` { "mcpServers": { "apitube-news": { "command": "npx", "args": [ "-y", "mcp-remote", "https://mcp.apitube.io/", "--header", "Authorization: Bearer YOUR_API_KEY" ] } } } ``` Restart Claude Desktop, and `apitube-news` appears under the tools (slider) icon. `npx` downloads the `mcp-remote` bridge on demand, so there is still nothing to install by hand. ## How to connect VS Code and Windsurf to APITube[#](#how-to-connect-vs-code-and-windsurf-to-apitube) **VS Code (GitHub Copilot)** reads `.vscode/mcp.json` per [workspace](/en/articles/getting-started/glossary#workspace). Use an input so the key is not stored in plain text, then open Copilot Chat in **Agent** mode and select the `apitube-news` tools: ``` { "inputs": [ { "type": "promptString", "id": "apitube-key", "description": "APITube API Key", "password": true } ], "servers": { "apitube-news": { "type": "http", "url": "https://mcp.apitube.io/", "headers": { "Authorization": "Bearer ${input:apitube-key}" } } } } ``` **Windsurf** uses `~/.codeium/windsurf/mcp_config.json` and the `serverUrl` key instead of `url`: ``` { "mcpServers": { "apitube-news": { "serverUrl": "https://mcp.apitube.io/", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Open **Windsurf Settings → Cascade → MCP Servers** and refresh. ## How do I verify the connection works?[#](#how-do-i-verify-the-connection-works) Once the editor restarts and shows `apitube-news` connected, ask a natural-language question and let the assistant call the tools for you: ``` Find positive breaking news about Tesla in English from the last week ``` The assistant calls the server’s `search_news` tool and returns matching articles. The server exposes two tools — `search_news` (search and filter) and `suggest` (resolve a name like “Tesla” to the exact `entity.id`, `category.id`, `topic.id` or `industry.id`) — plus four ready-made prompts surfaced as slash commands: `monitor_company`, `topic_sentiment`, `breaking_news` and `compare_coverage`. You never type a tool name yourself; you ask the question and the assistant picks the tool. For the concept behind all of this, see [what is the APITube MCP server](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server), and for the canonical per-editor reference see the official [code editors setup](https://docs.apitube.io/platform/news-api/ai/code-editors). # Common Questions[#](#common-questions) * [Which editors and assistants are supported?](#which-editors-and-assistants-are-supported) * [Why doesn’t the server show up after I add it?](#why-doesnt-the-server-show-up-after-i-add-it) * [Why does a search fail with 403 ER0603?](#why-does-a-search-fail-with-403-er0603) * [Which API key should I use here?](#which-api-key-should-i-use-here) ## Which editors and assistants are supported?[#](#which-editors-and-assistants-are-supported) The hosted APITube MCP server works with any MCP-compatible client. The step-by-step configs above cover Cursor, Claude Code, Claude Desktop, VS Code (through GitHub Copilot) and Windsurf. Clients that support remote servers natively — Cursor, Claude Code, VS Code and Windsurf — take the URL and header directly; clients that only launch local processes, such as Claude Desktop, use the `mcp-remote` bridge to reach the same hosted URL. ## Why doesn’t the server show up after I add it?[#](#why-doesnt-the-server-show-up-after-i-add-it) Almost always because the editor was not restarted, or the config file is in the wrong place. Save the config, fully restart the editor, and confirm you used that editor’s exact file — `~/.cursor/mcp.json` for Cursor, `.vscode/mcp.json` for VS Code, `claude_desktop_config.json` for Claude Desktop, and so on. Also check the header is spelled `Authorization: Bearer YOUR_API_KEY`; if that header never reaches the server, tool calls fail even though the server is listed. ## Why does a search fail with 403 ER0603?[#](#why-does-a-search-fail-with-403-er0603) A `403` with code `ER0706` means the key is on the free plan — the MCP server needs Starter or above. A `403` with code `ER0603` means your API key is not permitted to call the MCP tools (`search_news` and `suggest`). Grant the key the matching endpoint permissions in its settings, or use a key with full access. Treat the key like a password and never commit it in plain text — see [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security). ## Which API key should I use here?[#](#which-api-key-should-i-use-here) Your normal APITube API key — the same one you use on the News API. The MCP server validates it against your account on every tool call, so usage from your editor draws on the same key, plan and quota as your direct API requests. Get or create one on the [API key page](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). * * * ## Related Articles * [What is the APITube MCP server?](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security) --- ## What is the APITube MCP server? URL: https://support.apitube.io/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server The APITube MCP server is a hosted Model Context Protocol endpoint that lets AI assistants like Cursor and Claude search News API news in plain language. # What is the APITube MCP server? Connect Cursor, Claude and other AI assistants to the News API in plain language — hosted, no install, just your API key ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington August 22, 2026 # What is the APITube MCP server?[#](#what-is-the-apitube-mcp-server) The APITube MCP server is a **hosted Model Context Protocol (MCP) server** that connects AI assistants — like Cursor, Claude Desktop, VS Code and Windsurf — directly to the APITube News API. Instead of writing HTTP requests, you ask for news in plain language and the assistant turns your question into a News API call and reads back the results. The server lives at `https://mcp.apitube.io/`, needs no installation, and you authenticate with your normal APITube [API key](/en/articles/getting-started/glossary#api-key). It is a **paid-plan feature**: a free-plan key is refused with `403 ER0706` (`MCP server is not available on the free plan.`), so connect it with a Starter key or above. ## What is the Model Context Protocol (MCP)?[#](#what-is-the-model-context-protocol-mcp) The Model Context Protocol is an open standard that lets an AI assistant call external tools on your behalf. APITube runs the server side of that standard for you: a single hosted endpoint that exposes the News API as MCP **tools** the assistant can call. Because APITube hosts the server, there is nothing to install, run or keep updated — you point your assistant at the URL, add your API key, and it is ready. The server identifies itself as **“APITube News MCP-Server”**, version `1.0.0`. It speaks the latest MCP protocol version and negotiates down to whatever version your client asks for, so both current and older assistants can connect. ## What can you do with the APITube MCP server?[#](#what-can-you-do-with-the-apitube-mcp-server) Once connected, you search and filter global news from inside your assistant without leaving it. The APITube MCP server exposes two tools: * A **news-search tool** that runs a full News API query — filtering by title and keywords, language, [sentiment](/en/articles/getting-started/glossary#sentiment), [entities](/en/articles/getting-started/glossary#entity) (people, organizations, locations, brands, events), categories, topics, industries, media (images and videos), source quality and political bias, date ranges and breaking-news status, with sorting by relevance, date, engagement or quality. * A **`suggest` tool** that resolves a name or prefix — say “Tesla” or “spo” — to the exact APITube ID (entity, category, topic or industry) the search filters need. The assistant calls `suggest` first when it needs a precise ID, then feeds that ID into the search. You normally never type a tool name yourself: you ask a question and the assistant picks the tool. The server also ships four ready-made **prompts**, surfaced as slash commands in MCP clients — `monitor_company`, `topic_sentiment`, `breaking_news` and `compare_coverage`. Typical things you can ask: ``` Find positive breaking news about Tesla in English from the last week Show me long-form articles about SpaceX with images Compare the volume and sentiment of coverage for Apple vs Google ``` ## How do you connect and authenticate the MCP server?[#](#how-do-you-connect-and-authenticate-the-mcp-server) The hosted server speaks HTTP JSON-RPC, so you pass your key in the `Authorization: Bearer` header. Listing the available tools is open, but every actual search is authenticated: the server validates your key against your APITube account — the same key that works on the News API — before running the query. Get a key first (see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key)), and the [same authentication rules](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) apply. For clients with native remote-server support (Cursor, VS Code, Windsurf), add the URL and header to the MCP config: ``` { "mcpServers": { "apitube-news": { "url": "https://mcp.apitube.io/", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Claude Desktop launches MCP servers as local processes, so bridge the hosted server with `mcp-remote`: ``` { "mcpServers": { "apitube-news": { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.apitube.io/", "--header", "Authorization: Bearer YOUR_API_KEY"] } } } ``` Restart the assistant after saving the config. Treat the key like a password — see [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security). ## Can you use the MCP server without an AI assistant?[#](#can-you-use-the-mcp-server-without-an-ai-assistant) Yes. The MCP server is also a plain JSON-RPC API over `POST https://mcp.apitube.io/`, so you can call it with `curl` or any HTTP client. A quick reachability check is the `initialize` method, which needs no key: ``` curl -X POST https://mcp.apitube.io/ \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' ``` A healthy server replies with `serverInfo.name` set to “APITube News MCP-Server”. For the full request and response payloads, see the official [MCP Server reference](https://docs.apitube.io/platform/news-api/ai/mcp-server). # Common Questions[#](#common-questions) * [Do I need to install anything?](#do-i-need-to-install-anything) * [Which API key does the MCP server use?](#which-api-key-does-the-mcp-server-use) * [Why does a request fail with 401 ER0230 or 403 ER0603?](#why-does-a-request-fail-with-401-er0230-or-403-er0603) * [How is the MCP server different from the REST News API?](#how-is-the-mcp-server-different-from-the-rest-news-api) ## Do I need to install anything?[#](#do-i-need-to-install-anything) No. The APITube MCP server is hosted at `https://mcp.apitube.io/` with no install, no local process to run and no maintenance. You only edit your assistant’s MCP config to add the URL and your API key. Clients that cannot talk to a remote server directly (such as Claude Desktop) use the `mcp-remote` bridge, which `npx` downloads on demand. ## Which API key does the MCP server use?[#](#which-api-key-does-the-mcp-server-use) Your normal APITube API key — the same one you use on the News API. Pass it in the `Authorization: Bearer YOUR_API_KEY` header (or `X-API-Key`). The server validates it against your account on every tool call, so MCP usage draws on the same key, plan and quota as your direct API requests. ## Why does a request fail with 401 ER0230 or 403 ER0603?[#](#why-does-a-request-fail-with-401-er0230-or-403-er0603) A `401` with code `ER0230` means the API key has expired — renew or extend its expiry date. A `403` with code `ER0603` means the key is not permitted to call the MCP tools; grant the key the matching endpoint permissions (scopes), or use a key with full access. A `401` with code `ER0201` means no key reached the server — the `Authorization: Bearer` (or `X-API-Key`) header is missing, so check your config; a `401` with code `ER0202` means the key itself is invalid or revoked. ## How is the MCP server different from the REST News API?[#](#how-is-the-mcp-server-different-from-the-rest-news-api) They return the same news data from the same News API. The MCP server is a natural-language front end for AI assistants, while the REST News API is for code you write yourself. Use the MCP server to research and prototype inside Cursor or Claude; use the REST API when you build an application. Both authenticate with the same key. * * * ## Related Articles * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) --- ## Setup & Installation URL: https://support.apitube.io/en/articles/setup-and-installation Get your API key, authenticate every request, and connect APITube to SDKs, no-code tools and AI assistants. ![](/images/collections/company-settings.png) # Setup & Installation Get your key and connect SDKs, no-code and AI. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Jacob and 2 others 3 authors 19 articles Everything you need to get the APITube News API wired into your stack: creating an account and API keys, official SDKs for Node.js, PHP and Python, ready-made tools like the Postman collection, no-code integrations (n8n, Make, Zapier), and AI setups via MCP for Claude and Cursor. If you have not created a key yet, start with the [account and keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) guides — the difference between test and live keys trips up more new users than anything else in setup. ## [Account & API Keys](/en/articles/setup-and-installation/account-and-keys) * * * * [API key security best practices](/en/articles/setup-and-installation/account-and-keys/api-key-security) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to create an APITube account](/en/articles/setup-and-installation/account-and-keys/create-your-account) * [How to make your first request with cURL](/en/articles/setup-and-installation/account-and-keys/first-request-with-curl) * [Test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) ## [AI Assistants & MCP](/en/articles/setup-and-installation/ai-and-mcp) * * * * [How to Use APITube in Cursor, Claude and VS Code](/en/articles/setup-and-installation/ai-and-mcp/use-in-ai-assistants) * [Using APITube Agent Skills](/en/articles/setup-and-installation/ai-and-mcp/agent-skills) * [What is the APITube MCP server?](/en/articles/setup-and-installation/ai-and-mcp/what-is-mcp-server) ## [Built-in Tools](/en/articles/setup-and-installation/tools) * * * * [How to test requests in the API Playground](/en/articles/setup-and-installation/tools/test-in-playground) * [How to Use the APITube Postman Collection](/en/articles/setup-and-installation/tools/use-postman-collection) * [How to use the Query Builder](/en/articles/setup-and-installation/tools/using-query-builder) ## [No-code & Automation](/en/articles/setup-and-installation/no-code) * * * * [How to connect APITube to Make.com](/en/articles/setup-and-installation/no-code/connect-with-make) * [How to connect APITube to n8n](/en/articles/setup-and-installation/no-code/connect-with-n8n) * [How to connect APITube to Zapier](/en/articles/setup-and-installation/no-code/connect-with-zapier) ## [SDKs & Client Libraries](/en/articles/setup-and-installation/sdks) * * * * [How to call the News API from Python, Java, Go and more](/en/articles/setup-and-installation/sdks/call-from-any-language) * [How to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk) * [How to install and use the PHP SDK](/en/articles/setup-and-installation/sdks/install-php-sdk) * [Official APITube News API SDKs: Node, PHP, Python](/en/articles/setup-and-installation/sdks/official-sdks-overview) --- ## How to connect APITube to Make.com URL: https://support.apitube.io/en/articles/setup-and-installation/no-code/connect-with-make Connect APITube to Make.com with the HTTP 'Make a request' module: use GET, add an X-API-Key header, call /v1/news/everything, and iterate the results array. # How to connect APITube to Make.com Call the News API from Make's HTTP module — GET the endpoint, send an X-API-Key header, then iterate the results array into any downstream app ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to connect APITube to Make.com[#](#how-to-connect-apitube-to-makecom) To connect APITube to Make.com, use the **HTTP → Make a request** module: Make has no dedicated APITube app, so you call the News API over plain HTTP. Set the module’s **Method** to `GET`, add an **`X-API-Key`** header with your key, point the **URL** at an endpoint such as `https://api.apitube.io/v1/news/everything`, and enable **Parse response** so Make reads the JSON back as structured data. That one module pulls live news into any Make scenario, and an **Iterator** module then splits the returned articles so you can send each one to Slack, Google Sheets, a datastore, or an AI module — no code required. You need a [Make account](https://www.make.com) and an APITube [API key](/en/articles/getting-started/glossary#api-key) from your dashboard — see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). Everything below builds on one HTTP module. ## Why do you use the HTTP module instead of an APITube app?[#](#why-do-you-use-the-http-module-instead-of-an-apitube-app) There is no dedicated APITube app in Make, so you call the REST API directly. Make’s generic **HTTP → Make a request** module sends arbitrary HTTP calls, which is all APITube needs — every News API endpoint is a normal `GET` URL. The API also accepts `POST` on its search endpoints, but `GET` is the simpler fit for a Make scenario. Add an **HTTP** module as the first step after your scenario trigger, choose **Make a request**, and set **Method** to `GET`. Paste an APITube endpoint into the **URL** field, and turn on **Parse response** so downstream modules can map individual fields instead of a raw string. ## How do you authenticate the Make request?[#](#how-do-you-authenticate-the-make-request) APITube reads your key from any of three places, so pick whichever the HTTP module makes easiest: * **`X-API-Key` header** (recommended) — in the HTTP module’s **Headers** section, add a header named `X-API-Key` with your key as the value. * **`Authorization` header** — send the value `Bearer YOUR_API_KEY` instead. * **`api_key` query parameter** — append `api_key=YOUR_API_KEY` to the URL. This works, but a key in the URL lands in scenario logs, so prefer a header. ``` Header name: X-API-Key Header value: YOUR_API_KEY ``` If a request comes back with HTTP `401`, the key never reached APITube or did not match — recheck the header name and value. For every authentication option, see [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests). ## Which APITube endpoint should the HTTP module call?[#](#which-apitube-endpoint-should-the-http-module-call) The base URL is `https://api.apitube.io`. The endpoints you will reach for most from Make are: Endpoint What it returns `/v1/news/everything` Search all articles with the full set of filters `/v1/news/top-headlines` Top news from authoritative sources `/v1/news/article` A single article by ID `/v1/news/story/:articleId` Every article covering the same story `/v1/news/trends` Trending topics and aggregations Filters are query parameters on the same URL. A monitoring call — keywords in the title, English only, newest first — looks like this: ``` https://api.apitube.io/v1/news/everything?title=artificial+intelligence&language.code=en&per_page=50&sort.by=published_at&sort.order=desc ``` Change `title` to track different keywords, add `source.country.code=us` (a two-letter country code) to limit by country, or add `published_at.start` to set a date floor. The `sort.by` parameter also accepts `relevance`, `engagement`, `quality`, `controversy` and `trust`; `sort.order` is `asc` or `desc`. The complete list is in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## How do you iterate over the returned articles?[#](#how-do-you-iterate-over-the-returned-articles) The HTTP module returns a JSON envelope, and the articles live in the **`results`** array — the envelope wraps it with `status`, `page` and `limit`. Add an **Iterator** module after the HTTP module and set the array to `results`. Make then emits one bundle per article, and the modules after the Iterator run once for each one. The field names matter, because they are not the generic ones: * **Article link** is `href` — there is no top-level `url` field, so mapping `url` returns nothing. * **Source** is `source.domain` (for example `reuters.com`) — the `source` object has no `name` field. * **Headline** is `title`, and **publish time** is `published_at` (ISO 8601, UTC). * **[Sentiment](/en/articles/getting-started/glossary#sentiment) label** is `sentiment.overall.polarity` (`positive`, `neutral` or `negative`). Mapping the real paths — `href` and `source.domain` rather than `url` and `source.name` — is the difference between a full record and an empty one. See [how to run your first news search](/en/articles/getting-started/your-first-search) for what each field means. ## How do you build a scheduled news scenario?[#](#how-do-you-build-a-scheduled-news-scenario) A common recipe collects matching articles on a schedule and drops them into a destination. It chains four modules: 1. **Schedule the scenario** — open the scenario’s clock settings and set it to run every 15 minutes so it polls on its own. 2. **HTTP → Make a request** — a `GET` to your `/v1/news/everything` URL with the `X-API-Key` header and **Parse response** on. 3. **Iterator** — set the array to `results` so each article flows through separately. 4. **Destination module** — for example **Slack** (create a message), **Google Sheets** (add a row), or a **Data store** module, mapping each article’s fields into the output. Add a **Filter** between the Iterator and the destination that only passes when the article count is greater than `0`, so an empty poll never posts a blank alert. To summarize each article, insert an AI module and feed it the `title` and `body` fields. ## How do you avoid duplicates and rate-limit errors?[#](#how-do-you-avoid-duplicates-and-rate-limit-errors) Two settings keep a scheduled scenario clean. First, add `published_at.start` with a rolling cutoff so each poll only asks for articles published since the last run — that stops the same story arriving on every cycle. Second, respect the limits: APITube allows **50 requests per minute** on a [live key](/en/articles/getting-started/glossary#test-key-and-live-key), and repeatedly exceeding the limit temporarily bans the key after 30 violations, so keep the scenario interval sensible (every 15–30 minutes is plenty). Request at most `per_page=250` articles per call, and page through larger result sets with the `page` parameter — see [how to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). Encode spaces in query values as `+` or `%20` (for example `title=climate+change`). # Common Questions[#](#common-questions) * [Does Make have an official APITube app?](#does-make-have-an-official-apitube-app) * [Where do I put my API key in Make?](#where-do-i-put-my-api-key-in-make) * [Which field holds the article link?](#which-field-holds-the-article-link) * [Why is the article body cut short in Make?](#why-is-the-article-body-cut-short-in-make) ## Does Make have an official APITube app?[#](#does-make-have-an-official-apitube-app) No. There is no dedicated APITube app in Make, so you use the **HTTP → Make a request** module to call the News API over HTTP. That module can hit any APITube endpoint with a `GET` request, which covers search, top headlines, single articles, stories and trends — everything a no-code scenario needs. The same plain-HTTP approach works in [Zapier](/en/articles/setup-and-installation/no-code/connect-with-zapier) and other automation tools. ## Where do I put my API key in Make?[#](#where-do-i-put-my-api-key-in-make) In the **HTTP → Make a request** module, open the **Headers** section and add `X-API-Key` with your key as the value. This keeps the key out of the URL. You can pass `api_key=YOUR_API_KEY` in the URL instead, but that leaks the key into your scenario’s execution log, so the header is safer for anything you keep running. ## Which field holds the article link?[#](#which-field-holds-the-article-link) The canonical link to the original article is the `href` field on each object in the `results` array — not `url`. Likewise, the publisher is `source.domain`, not `source.name`. Map those exact paths after your Iterator module to fill a Slack message, spreadsheet row or data store correctly. ## Why is the article body cut short in Make?[#](#why-is-the-article-body-cut-short-in-make) Because the key is on the free plan or is a test key. In those two cases APITube trims `body`, `description` and the URL fields to a short preview and appends a marker — `...[Upgrade subscription plan]` on the free plan, or `...[Test mode — use a live key for full content]` on a test key. It is not a Make or mapping problem — switching to a live key on a paid plan returns full content. This is covered in detail in [why are my results masked or placeholder text](/en/articles/troubleshooting/masked-results). * * * ## Related Articles * [How to connect APITube to Zapier](/en/articles/setup-and-installation/no-code/connect-with-zapier) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to run your first news search](/en/articles/getting-started/your-first-search) --- ## How to connect APITube to n8n URL: https://support.apitube.io/en/articles/setup-and-installation/no-code/connect-with-n8n Connect APITube to n8n with an HTTP Request node: add a Header Auth credential named X-API-Key, then GET https://api.apitube.io/v1/news/everything on a… # How to connect APITube to n8n Use n8n's HTTP Request node with a Header Auth credential to poll the News API on a schedule — no code required ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to connect APITube to n8n[#](#how-to-connect-apitube-to-n8n) To connect APITube to [n8n](https://n8n.io), add a **Header Auth** credential that sends your [API key](/en/articles/getting-started/glossary#api-key) in the `X-API-Key` header, then use an **HTTP Request** node to `GET https://api.apitube.io/v1/news/everything`. APITube has no dedicated n8n node — you call the plain News API over HTTPS, so any n8n workflow can pull articles on a schedule and route them wherever you like. There is nothing else to install. The News API returns JSON, n8n reads JSON, and a **Schedule Trigger** decides how often to poll. Once the HTTP Request node works, you can hang a Slack, Telegram, Google Sheets, email, or AI node off the end. ## How do you set up the APITube credential in n8n?[#](#how-do-you-set-up-the-apitube-credential-in-n8n) APITube authenticates every request by an API key. In n8n, store the key once as a credential so you never paste it into a node: 1. Open **Credentials → Add credential** and pick **Header Auth**. 2. Set **Name** to `X-API-Key`. 3. Set **Value** to your live API key from the dashboard. 4. Save it as `APITube API`. The API key is read from the `X-API-Key` request header (the `api_key` query parameter also works, but a header keeps the key out of logs and URLs). Grab your key from [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key), and see [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) for the full auth options. ## How do you configure the HTTP Request node?[#](#how-do-you-configure-the-http-request-node) Add an **HTTP Request** node after your trigger and point it at the News API. In the node, set **Authentication** to **Generic Credential Type**, choose **Header Auth**, and select your `APITube API` credential. Then set the method to `GET`, the URL to the endpoint, turn on **Send Query Parameters**, and add each News API filter as a name/value row. A minimal monitoring node looks like this: ``` { "url": "https://api.apitube.io/v1/news/everything", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "title", "value": "artificial intelligence" }, { "name": "language.code", "value": "en" }, { "name": "source.domain", "value": "bbc.com" }, { "name": "published_at.start", "value": "={{ $now.minus(15, 'minutes').toISO() }}" }, { "name": "per_page", "value": "50" }, { "name": "sort.by", "value": "published_at" }, { "name": "sort.order", "value": "desc" } ] } } ``` Every name here is a real News API parameter: `title` searches article titles, `language.code` takes a two-letter code such as `en`, `source.domain` limits results to one publisher, and `published_at.start` sets the earliest publish time. `sort.by` accepts `published_at` (the default) or `relevance`, and `sort.order` accepts `asc` or `desc`. Add any other filter — country, category, [sentiment](/en/articles/getting-started/glossary#sentiment) — the same way; see [how to combine multiple filters in one request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) for stacking them. ## How do you loop over the returned articles?[#](#how-do-you-loop-over-the-returned-articles) The News API wraps articles in a `results` array alongside [pagination](/en/articles/getting-started/glossary#pagination) fields like `page`, `limit`, `has_next_pages`, and `next_page`. Add a **Split Out** node after the HTTP Request and set **Field To Split Out** to `results` — each article then flows through the rest of the workflow one item at a time. Read fields off each item with the exact names the API returns. The article link is `href` (not `url`), the publisher label is `source.domain` (there is no `source.name`), and the overall tone is `sentiment.overall.score`. A Slack or Telegram message might use `title`, `href`, `source.domain`, and `published_at`. **Field names matter.** In n8n expressions, use `{{ $json.href }}` for the article link and `{{ $json.source.domain }}` for the source. The object has `href` and `source.domain` — not `url` or `source.name` — so referencing the wrong name returns an empty value with no error. ## What can you build once the connection works?[#](#what-can-you-build-once-the-connection-works) With one HTTP Request node in place, common n8n workflows are: * **News monitoring:** a Schedule Trigger every 15 minutes → HTTP Request → an **IF** node that keeps only items where `sentiment.overall.score` is above a threshold → append to Google Sheets. * **Team alerts:** Schedule Trigger → HTTP Request → Split Out → a Slack or Telegram node that posts `title`, `source.domain`, and `href`. * **AI digest:** a daily Schedule Trigger → HTTP Request to `/v1/news/top-headlines` → a Code node that formats the list → an LLM node that summarizes → an email node. # Common Questions[#](#common-questions) * [Does APITube have an official n8n node?](#does-apitube-have-an-official-n8n-node) * [How do I avoid fetching the same article twice?](#how-do-i-avoid-fetching-the-same-article-twice) * [How often can n8n poll the API?](#how-often-can-n8n-poll-the-api) * [Can I pull more than 250 articles per run?](#can-i-pull-more-than-250-articles-per-run) ## Does APITube have an official n8n node?[#](#does-apitube-have-an-official-n8n-node) No. There is no dedicated APITube node in n8n. You use the generic **HTTP Request** node against the REST API, which is why the same setup works in Make, Zapier, or any tool with an HTTP step. This is the same plain-HTTPS contract described in [how to call the News API from Python, Java, Go and more](/en/articles/setup-and-installation/sdks/call-from-any-language) — n8n is just one more client. ## How do I avoid fetching the same article twice?[#](#how-do-i-avoid-fetching-the-same-article-twice) Two ways, used together. Set `published_at.start` to the time of your last poll — the n8n expression `={{ $now.minus(15, 'minutes').toISO() }}` fetches only articles published since the previous run. As a safety net, add n8n’s built-in **Remove Duplicates** node and key it on `href`, which is unique per article. ## How often can n8n poll the API?[#](#how-often-can-n8n-poll-the-api) The [rate limit](/en/articles/getting-started/glossary#rate-limit) is **50 requests per minute on paid plans** (the Free plan is capped at **10 per minute**, and [test keys](/en/articles/getting-started/glossary#test-key-and-live-key) at 15). A Schedule Trigger that runs every few minutes stays well under it; if you fan out many HTTP Request nodes in one run, space them out. See [understanding rate limits](/en/articles/billing/credits/rate-limits) for what happens when you exceed the limit. ## Can I pull more than 250 articles per run?[#](#can-i-pull-more-than-250-articles-per-run) `per_page` maxes out at **250**, or **50** on Starter and **10** on Free — a larger value returns a `400` error, not a silent trim. To page further, add the `page` parameter and increment it (the response includes `has_next_pages` and a ready-built `next_page` URL). For a bulk export instead of item-by-item processing, add `export=csv` or `export=xlsx` to the request and n8n receives a file rather than JSON. * * * ## Related Articles * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to call the News API from Python, Java, Go and more](/en/articles/setup-and-installation/sdks/call-from-any-language) --- ## How to connect APITube to Zapier URL: https://support.apitube.io/en/articles/setup-and-installation/no-code/connect-with-zapier Connect APITube to Zapier with the Webhooks by Zapier app: set the request method to GET, add your X-API-Key header, and call /v1/news/everything — no code… # How to connect APITube to Zapier Pull live news into any Zap with the Webhooks by Zapier app — set the method to GET, add your X-API-Key header, and call the News API ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to connect APITube to Zapier[#](#how-to-connect-apitube-to-zapier) To connect APITube to Zapier, use the **[Webhooks](/en/articles/getting-started/glossary#webhook) by Zapier** app: Zapier has no built-in APITube integration, so you make a plain HTTP call to the News API instead. Set the request **Method** to `GET`, add an **`X-API-Key`** header with your key, and point the **URL** at an APITube endpoint such as `https://api.apitube.io/v1/news/everything`. That single Webhooks step pulls live news into any Zap, so you can push matching articles to Google Sheets, Slack, email, or an AI summarizer without writing code. You need a [Zapier account](https://zapier.com) (free or paid) and an APITube [API key](/en/articles/getting-started/glossary#api-key) from your [dashboard](https://dashboard.apitube.io). Everything below builds on that one Webhooks step. ## Why do you use “Webhooks by Zapier” instead of an APITube app?[#](#why-do-you-use-webhooks-by-zapier-instead-of-an-apitube-app) There is no dedicated APITube app in the Zapier directory, so you call the REST API directly. Zapier’s own **Webhooks by Zapier** app makes arbitrary HTTP requests, which is all APITube needs — every News API endpoint is a normal `GET` URL. Inside a Zap, add an action step, choose **Webhooks by Zapier**, and pick the **Custom Request** event. Set **Method** to `GET` and paste an APITube endpoint as the **URL**. This same step works for any endpoint, so once one Zap is running, the rest are just different URLs. ## How do you authenticate the Zapier request?[#](#how-do-you-authenticate-the-zapier-request) APITube reads your key from one of three places, so pick whichever the Webhooks step makes easiest. In the Webhooks step’s **Headers** section, add a header named `X-API-Key` with your key as the value — this is the recommended way. You can instead append `api_key=YOUR_API_KEY` to the URL, but a key in the URL ends up in logs, so prefer the header. A third option is an `Authorization` header with the value `Bearer YOUR_API_KEY`. ``` Header name: X-API-Key Header value: YOUR_API_KEY ``` If a request comes back with HTTP `401`, the key never reached APITube or did not match — recheck the header name and value. For the full breakdown, see [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests). ## Which APITube endpoint should the Webhooks step call?[#](#which-apitube-endpoint-should-the-webhooks-step-call) The base URL is `https://api.apitube.io`. The endpoints you will reach for most from Zapier are: Endpoint What it returns `/v1/news/everything` Search all articles with the full set of filters `/v1/news/top-headlines` Top news from authoritative sources `/v1/news/article` A single article by ID `/v1/news/story/:articleId` Every article covering the same story `/v1/news/trends` Trending topics and aggregations Filters are query parameters on the same URL. A monitoring call looks like this — keywords in the title, English only, newest first: ``` https://api.apitube.io/v1/news/everything?title=artificial+intelligence&language.code=en&per_page=50&sort.by=published_at&sort.order=desc ``` Change `title` to track different keywords, add `source.country.code=us` (a two-letter country code) to limit by country, or add `published_at.start` to set a date floor. The complete list is in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## How do you build a news-monitoring Zap step by step?[#](#how-do-you-build-a-news-monitoring-zap-step-by-step) A common recipe collects matching articles into a spreadsheet on a schedule. It chains four steps, each a built-in Zapier app: 1. **Schedule by Zapier** (trigger) — set it to run **Every 15 Minutes** so the Zap polls on its own. 2. **Webhooks by Zapier** — a `GET` **Custom Request** to your `/v1/news/everything` URL with the `X-API-Key` header, as above. 3. **Looping by Zapier** — **Create Loop From Line Items**, with the articles array from the Webhooks step as the values to loop. 4. **Google Sheets** — **Create Spreadsheet Row**, mapping each article’s fields into columns. Swap Google Sheets for **Slack** (Send Channel Message) or **Gmail** (Send Email) to get alerts instead of rows, and add a **Filter by Zapier** step that only continues when the article count is greater than `0` so you never send an empty notification. ## How do you map article fields correctly?[#](#how-do-you-map-article-fields-correctly) The Webhooks step returns a JSON envelope, and the articles live in the **`results`** array — that is what you point **Looping by Zapier** at. Each item in `results` is one article, and the field names you map matter: * **Article link** is `href` — there is no top-level `url` field, so mapping `url` returns nothing. * **Source** is `source.domain` (for example `reuters.com`) — the source object has no `name` field. * **Headline** is `title`, and **publish time** is `published_at` (ISO 8601, UTC). * **[Sentiment](/en/articles/getting-started/glossary#sentiment) label** is `sentiment.overall.polarity` (`positive`, `neutral` or `negative`). Using the real field names — `href` and `source.domain` rather than `url` and `source.name` — is the difference between a row full of data and a row full of blanks. See [how to run your first news search](/en/articles/getting-started/your-first-search) for what each field means. ## How do you avoid duplicates and rate-limit errors?[#](#how-do-you-avoid-duplicates-and-rate-limit-errors) Two settings keep a scheduled Zap clean. First, add `published_at.start` with a rolling cutoff so each poll only asks for articles published since the last run — that stops the same story arriving on every cycle. Second, respect the limits: APITube allows **50 requests per minute** on a [live key](/en/articles/getting-started/glossary#test-key-and-live-key), and repeatedly exceeding the limit gets the key temporarily banned after 30 violations, so keep the Schedule interval sensible (every 15–30 minutes is plenty). Ask for at most `per_page=250` articles per call, and encode spaces in query values as `+` or `%20` (for example `title=climate+change`). To page through more results, increment the `page` parameter — see [how to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). # Common Questions[#](#common-questions) * [Does Zapier have an official APITube app?](#does-zapier-have-an-official-apitube-app) * [Where do I put my API key in a Zap?](#where-do-i-put-my-api-key-in-a-zap) * [Which field holds the article link?](#which-field-holds-the-article-link) * [How many articles can one Webhooks step return?](#how-many-articles-can-one-webhooks-step-return) ## Does Zapier have an official APITube app?[#](#does-zapier-have-an-official-apitube-app) No. There is no dedicated APITube app in the Zapier directory, so you use **Webhooks by Zapier** to call the News API over HTTP. That app can hit any APITube endpoint with a `GET` request, which covers search, top headlines, single articles, stories and trends — everything a no-code workflow needs. ## Where do I put my API key in a Zap?[#](#where-do-i-put-my-api-key-in-a-zap) In the **Webhooks by Zapier** step, open the **Headers** section and add `X-API-Key` with your key as the value. This keeps the key out of the URL. You can pass `api_key=YOUR_API_KEY` in the URL instead, but that leaks the key into logs, so the header is safer for anything you keep running. ## Which field holds the article link?[#](#which-field-holds-the-article-link) The canonical link to the original article is the `href` field on each object in the `results` array — not `url`. Likewise, the publisher is `source.domain`, not `source.name`. Map those exact paths in your Zapier field mapper to fill your spreadsheet, Slack message or email correctly. ## How many articles can one Webhooks step return?[#](#how-many-articles-can-one-webhooks-step-return) Up to `per_page=250` in a single call. Ask for more and the request is rejected, so page through larger result sets with the `page` parameter across multiple calls. For frequent polling, pair `per_page` with a `published_at.start` cutoff so each run only pulls what is new. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## No-code & Automation URL: https://support.apitube.io/en/articles/setup-and-installation/no-code Connect APITube to no-code automation tools like Zapier, Make and n8n using their HTTP or Webhooks step — call the News API and route articles anywhere without writing code. ![](/images/collections/consolidate-benchmark.png) # No-code & Automation Zapier, Make and n8n without code. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Jacob 1 author 3 articles * [How to connect APITube to Make.com](/en/articles/setup-and-installation/no-code/connect-with-make) * [How to connect APITube to n8n](/en/articles/setup-and-installation/no-code/connect-with-n8n) * [How to connect APITube to Zapier](/en/articles/setup-and-installation/no-code/connect-with-zapier) --- ## How to call the News API from Python, Java, Go and more URL: https://support.apitube.io/en/articles/setup-and-installation/sdks/call-from-any-language Call the APITube News API from Python, Java, Go, Ruby, C# and PHP: send an HTTPS GET to /v1/news/everything with your key in the X-API-Key header — no SDK… # How to call the News API from Python, Java, Go and more No SDK required — any language that can make an HTTPS request can query the News API with your key in a header or the api\_key query parameter ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 2, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to call the News API from Python, Java, Go and more[#](#how-to-call-the-news-api-from-python-java-go-and-more) The APITube News API is plain HTTPS plus JSON, so **any language that can send an HTTPS request can call it** — no SDK required. Send a `GET` (or `POST`) to `https://api.apitube.io/v1/news/everything`, put your key in the `X-API-Key` header, and read the JSON back. The example below is the whole contract; every language snippet further down is the same request in different syntax. ``` curl -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/everything?language.code=en&per_page=5" ``` ## What do you need to call the News API from any language?[#](#what-do-you-need-to-call-the-news-api-from-any-language) Three things, and nothing else: * **Base URL + endpoint:** `https://api.apitube.io/v1/news/everything` — the main search endpoint that returns articles from all sources. * **Your [API key](/en/articles/getting-started/glossary#api-key):** sent either as an `X-API-Key` request header (recommended) or as an `api_key` query parameter in the URL. An `Authorization: Bearer YOUR_API_KEY` header also works. If no key is present, the API replies `401` with error code `ER0201`. * **Query parameters:** plain URL query values such as `language.code=en`, `title=climate change` and `per_page=5`. Dotted names like `language.code` are passed literally. The response is JSON with a `status` field (`"ok"` on success), [pagination](/en/articles/getting-started/glossary#pagination) fields (`page`, `has_next_pages`), a `request_id` for support, and a `results` array. Each item in `results` holds fields like `id`, `title`, `href`, `published_at` and `language`. ## How do you call the News API from Python?[#](#how-do-you-call-the-news-api-from-python) Use the standard `requests` library — send the key as a header and pass filters through `params`: ``` import requests resp = requests.get( "https://api.apitube.io/v1/news/everything", headers={"X-API-Key": "YOUR_API_KEY"}, params={"language.code": "en", "per_page": 5}, ) data = resp.json() for article in data["results"]: print(article["title"], article["href"]) ``` ## How do you call it from Java, Go, Ruby and C#?[#](#how-do-you-call-it-from-java-go-ruby-and-c) The pattern is identical everywhere: build the URL, set the `X-API-Key` header, read `results` from the JSON. **Java** (built-in `java.net.http`, Java 11+): ``` HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.apitube.io/v1/news/everything?language.code=en&per_page=5")) .header("X-API-Key", "YOUR_API_KEY") .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); ``` **Go** (standard `net/http`): ``` req, _ := http.NewRequest("GET", "https://api.apitube.io/v1/news/everything?language.code=en&per_page=5", nil) req.Header.Set("X-API-Key", "YOUR_API_KEY") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Println(string(body)) ``` **Ruby** (standard `net/http`): ``` require "net/http" require "json" uri = URI("https://api.apitube.io/v1/news/everything?language.code=en&per_page=5") req = Net::HTTP::Get.new(uri) req["X-API-Key"] = "YOUR_API_KEY" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } JSON.parse(res.body)["results"].each { |a| puts a["title"] } ``` **C# / .NET** (`HttpClient`): ``` using var client = new HttpClient(); client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY"); var url = "https://api.apitube.io/v1/news/everything?language.code=en&per_page=5"; var json = await client.GetStringAsync(url); Console.WriteLine(json); ``` ## How do you call it from PHP without the SDK?[#](#how-do-you-call-it-from-php-without-the-sdk) If you would rather not add the SDK, `curl` from PHP core does the job: ``` $ch = curl_init("https://api.apitube.io/v1/news/everything?language.code=en&per_page=5"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-Key: YOUR_API_KEY"]); $response = json_decode(curl_exec($ch), true); foreach ($response["results"] as $article) { echo $article["title"] . "\n"; } ``` ## Do you need an official SDK?[#](#do-you-need-an-official-sdk) No — every example above uses only your language’s standard HTTP tools. Official SDKs exist for three languages and save you the URL-building and JSON parsing: **Node.js** (`npm install @apitube/news-api`), **PHP** (`composer require apitube/news-api`) and **Python** (`pip install apitube`). For those three, prefer the SDK; see [how to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk). For Java, Go, Ruby, C# and any other language, the plain HTTP request is the supported path — there is nothing extra to install. For the full parameter list, see the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Where do I put the API key — header or URL?](#where-do-i-put-the-api-key--header-or-url) * [Which endpoints can I call this way?](#which-endpoints-can-i-call-this-way) * [How many results can I get per request?](#how-many-results-can-i-get-per-request) * [What rate limit applies?](#what-rate-limit-applies) ## Where do I put the API key — header or URL?[#](#where-do-i-put-the-api-key--header-or-url) Either works. The `X-API-Key` request header is recommended because it keeps the key out of logs and URLs. As an alternative you can append `api_key=YOUR_API_KEY` to the query string, which is handy for quick tests but riskier since URLs get logged. An `Authorization: Bearer YOUR_API_KEY` header is also accepted. See [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) for the details. ## Which endpoints can I call this way?[#](#which-endpoints-can-i-call-this-way) All of them. The same header-plus-URL pattern works for every `/v1/...` endpoint — `/v1/news/everything`, `/v1/news/top-headlines`, `/v1/news/article`, `/v1/news/count` and the rest. Only the path and the query parameters change; the authentication stays the same. ## How many results can I get per request?[#](#how-many-results-can-i-get-per-request) Set `per_page` to control page size. The default is **100** and the maximum is **250** — on Starter both drop to **50**, on Free to **10**; ask for more and the API returns `400` with error code `ER0171` (“Limit is out of range. Your plan allows up to N results per page.”). Use `page` together with `per_page` to walk through more results, and check `has_next_pages` in the response to know when to stop. ## What rate limit applies?[#](#what-rate-limit-applies) [Live keys](/en/articles/getting-started/glossary#test-key-and-live-key) are limited to **50 requests per minute**. Space your calls out and reuse one HTTP client instead of opening a new connection per request. If you exceed the limit you receive a `429` response — see how to handle [rate-limit](/en/articles/getting-started/glossary#rate-limit) errors before adding retry logic. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk) * [How to make your first request with cURL](/en/articles/setup-and-installation/account-and-keys/first-request-with-curl) --- ## SDKs & Client Libraries URL: https://support.apitube.io/en/articles/setup-and-installation/sdks Official APITube SDKs for Node.js, PHP and Python — install a client, authenticate with your API key, and call the News API in a few typed lines. ![](/images/collections/analysis-tools.png) # SDKs & Client Libraries Node.js, PHP and Python clients. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Jacob 1 author 4 articles * [How to call the News API from Python, Java, Go and more](/en/articles/setup-and-installation/sdks/call-from-any-language) * [How to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk) * [How to install and use the PHP SDK](/en/articles/setup-and-installation/sdks/install-php-sdk) * [Official APITube News API SDKs: Node, PHP, Python](/en/articles/setup-and-installation/sdks/official-sdks-overview) --- ## How to install and use the Node.js SDK URL: https://support.apitube.io/en/articles/setup-and-installation/sdks/install-nodejs-sdk Install the official @apitube/news-api Node.js SDK: add it with npm, create a Client with your API key, and search, count and fetch news in a few typed lines. # How to install and use the Node.js SDK Add the official @apitube/news-api package, create a typed Client with your API key, and search, count and read news in a few lines ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 2, 2026 # How to install and use the Node.js SDK[#](#how-to-install-and-use-the-nodejs-sdk) Install the official SDK with `npm install @apitube/news-api`, import `Client`, and create it with your [API key](/en/articles/getting-started/glossary#api-key). From there, `client.news('everything', {...})` sends the request and hands you back parsed articles — no manual URL building or JSON wrangling. The package needs **Node.js 18+**, ships both ESM and CommonJS builds, and includes TypeScript types, so it works the same in a plain Node script or a typed project. ``` import { Client } from '@apitube/news-api'; const client = new Client({ apiKey: 'your-api-key' }); const response = await client.news('everything', { title: 'artificial intelligence', 'language.code': 'en', per_page: 5, }); for (const article of response.articles) { console.log(article.title, article.url); } ``` ## How do you install the Node.js SDK?[#](#how-do-you-install-the-nodejs-sdk) The SDK is published on npm as `@apitube/news-api`. Add it to any Node project: ``` npm install @apitube/news-api ``` It requires **Node.js 18 or newer** and depends on `axios` for HTTP. The package exposes both an ESM entry (`import`) and a CommonJS entry (`require`), so `import { Client } from '@apitube/news-api'` and `const { Client } = require('@apitube/news-api')` both work. TypeScript declarations are bundled — you get autocomplete and type checking without installing a separate `@types` package. The library is MIT-licensed. ## How do you create the client and authenticate?[#](#how-do-you-create-the-client-and-authenticate) Create one `Client` and reuse it. The only required option is `apiKey`; `baseUrl` defaults to `https://api.apitube.io`, so you normally leave it out: ``` import { Client } from '@apitube/news-api'; const client = new Client({ apiKey: process.env.APITUBE_API_KEY, // keep the key out of source }); ``` Under the hood the SDK sends your key in an `X-API-Key` header on every request, so you never build that header yourself. Need a custom timeout or interceptor? Pass your own `axios` instance as `httpClient`: ``` import axios from 'axios'; import { Client } from '@apitube/news-api'; const httpClient = axios.create({ timeout: 30_000 }); const client = new Client({ apiKey: process.env.APITUBE_API_KEY, httpClient }); ``` Grab a key from your dashboard first — see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) and [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) for the header details. ## How do you search for news articles?[#](#how-do-you-search-for-news-articles) `client.news(endpoint, params)` is the main method. The first argument picks the endpoint — `'everything'`, `'top-headlines'`, `'story'`, `'article'` or `'raw'` — and the second is a plain object of filter parameters. Parameter names are passed exactly as the API expects them, including dotted names like `language.code` and `sort.by`: ``` const response = await client.news('everything', { title: 'climate change', 'language.code': 'en', 'sort.by': 'published_at', 'sort.order': 'desc', per_page: 10, }); console.log(`Page: ${response.page}`); console.log(`Has next page: ${response.hasNextPages ? 'yes' : 'no'}`); for (const article of response.articles) { console.log(article.title); console.log(`Source: ${article.source?.domain}`); console.log(`Published: ${article.publishedAt}`); console.log(`Sentiment: ${article.sentiment?.overall?.polarity}`); } ``` The call returns an `ArticleList` whose `articles` array holds parsed article objects, plus [pagination](/en/articles/getting-started/glossary#pagination) fields `page`, `limit`, `hasNextPages` and `nextPage`. The `'story'` endpoint needs an `id` in the params (`client.news('story', { id: 'story-id' })`); the SDK throws if it is missing. Every method accepts an optional third argument for the API version, which defaults to `'v1'`. For the full parameter list, see the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## How do you count, autocomplete and read reference data?[#](#how-do-you-count-autocomplete-and-read-reference-data) Beyond search, the client wraps the helper endpoints: * **Count** — `await client.count({ title: 'artificial intelligence', 'language.code': 'en' })` returns a plain number of matching articles, using the same filters as `everything`. * **Autocomplete** — `await client.suggest('categories', 'spo')` returns suggestion items; supported types are `categories`, `topics`, `industries` and `entities`. * **Reference lists and profiles** — `client.people(params)`, `client.companies(params)` and `client.journalists(params)` return a paginated list in `.results`; each has a by-ID profile method (`client.person(id)`, `client.company(id)`, `client.journalist(id)`). * **Balance** — `await client.balance()` returns your `plan` and remaining `points`. * **Ping** — `await client.ping()` returns `true` if the API is reachable, `false` otherwise. ## How do you handle errors and rate limits?[#](#how-do-you-handle-errors-and-rate-limits) Failed requests throw typed exceptions you can catch by class. `AuthenticationException` covers a `401` (missing or wrong key), `RateLimitException` covers a `429` and exposes `retryAfter` in seconds, and `ApiException` is the base for any other API error, carrying `statusCode` and `requestId`: ``` import { ApiException, AuthenticationException, RateLimitException, } from '@apitube/news-api'; try { const response = await client.news('everything', { title: 'node' }); } catch (e) { if (e instanceof AuthenticationException) { console.log(`Auth error: ${e.message}`); } else if (e instanceof RateLimitException) { console.log(`Rate limited. Retry after ${e.retryAfter}s`); } else if (e instanceof ApiException) { console.log(`API error (${e.statusCode}): ${e.message}, request ${e.requestId}`); } } ``` Quote the `requestId` when you contact support. For what triggers a `429` and how to back off, see [how to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). # Common Questions[#](#common-questions) * [Which Node.js versions are supported?](#which-nodejs-versions-are-supported) * [Does the SDK support TypeScript?](#does-the-sdk-support-typescript) * [Which endpoints can I call from the SDK?](#which-endpoints-can-i-call-from-the-sdk) * [Can I use my own HTTP client?](#can-i-use-my-own-http-client) ## Which Node.js versions are supported?[#](#which-nodejs-versions-are-supported) The package declares `engines.node >= 18`, so use **Node.js 18 or newer**. It ships both an ESM build and a CommonJS build, so it drops into modern `import`\-based projects and older `require`\-based ones alike. ## Does the SDK support TypeScript?[#](#does-the-sdk-support-typescript) Yes. Type declarations (`.d.ts`) are bundled with the package, so `Client`, its option and endpoint types (`ClientOptions`, `NewsEndpoint`, `SuggestType`), the response classes and the exception classes are all fully typed. You get autocomplete and compile-time checks with no extra `@types` install. ## Which endpoints can I call from the SDK?[#](#which-endpoints-can-i-call-from-the-sdk) `client.news(...)` covers `everything`, `top-headlines`, `story`, `article` and `raw`. Separate methods cover `count`, `suggest`, the `people`/`companies`/`journalists` lists and profiles, `balance` and `ping`. Each maps to the matching `/v1/...` REST endpoint. ## Can I use my own HTTP client?[#](#can-i-use-my-own-http-client) Yes. Pass an `axios` instance as the `httpClient` option when constructing the `Client`. This lets you set a global timeout, add interceptors, or route requests through a proxy while the SDK still handles auth headers, JSON parsing and error mapping. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to run your first news search](/en/articles/getting-started/your-first-search) * [How to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors) --- ## How to install and use the PHP SDK URL: https://support.apitube.io/en/articles/setup-and-installation/sdks/install-php-sdk Install the official apitube/news-api PHP SDK: add it with Composer, create a Client with your API key, and search, count and read news in a few lines. # How to install and use the PHP SDK Add the official apitube/news-api Composer package, create a Client with your API key, and search, count and read news in a few lines ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 2, 2026 # How to install and use the PHP SDK[#](#how-to-install-and-use-the-php-sdk) Install the official SDK with `composer require apitube/news-api`, then create `APITube\Client` with your [API key](/en/articles/getting-started/glossary#api-key). From there, `$client->news('everything', [...])` sends the request and hands you back parsed article objects — no manual URL building or JSON decoding. The package needs **PHP 8.1+** and a PSR-18 HTTP client such as Guzzle, and is published on Packagist as `apitube/news-api` under the MIT license. ``` use APITube\Client; $client = new Client(apiKey: 'your-api-key'); $response = $client->news('everything', [ 'title' => 'artificial intelligence', 'language.code' => 'en', 'per_page' => 5, ]); foreach ($response->articles as $article) { echo $article->title . "\n"; echo $article->url . "\n\n"; } ``` ## How do you install the PHP SDK?[#](#how-do-you-install-the-php-sdk) The SDK is published on Packagist as `apitube/news-api`. Add it to any Composer project: ``` composer require apitube/news-api ``` It requires **PHP 8.1 or newer** and a PSR-18 HTTP client plus a PSR-17 HTTP factory. If you do not already have one installed, add Guzzle: ``` composer require guzzlehttp/guzzle ``` The client library autoloads under the `APITube\` namespace (PSR-4), so once Composer’s autoloader is included, `use APITube\Client;` is all you need. When you construct the client without passing an HTTP client, the SDK auto-discovers an installed PSR-18 implementation, which is why Guzzle (or any compatible client) has to be present in your project. ## How do you create the client and authenticate?[#](#how-do-you-create-the-client-and-authenticate) Create one `Client` and reuse it. The only required argument is `apiKey`; `baseUrl` defaults to `https://api.apitube.io`, so you normally leave it out: ``` use APITube\Client; $client = new Client( apiKey: getenv('APITUBE_API_KEY'), // keep the key out of source ); ``` Under the hood the SDK sends your key in an `X-API-Key` header on every request, so you never build that header yourself. Need a custom timeout? Pass your own PSR-18 client as the third argument: ``` $client = new Client( apiKey: getenv('APITUBE_API_KEY'), httpClient: new \GuzzleHttp\Client(['timeout' => 30]), ); ``` Grab a key from your dashboard first — see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) and [how to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) for the header details. ## How do you search for news articles?[#](#how-do-you-search-for-news-articles) `$client->news($endpoint, $params)` is the main method. The first argument picks the endpoint — `'everything'`, `'top-headlines'`, `'story'`, `'article'` or `'raw'` — and the second is a plain array of filter parameters. Parameter names are passed exactly as the API expects them, including dotted keys like `language.code` and `sort.by`: ``` $response = $client->news('everything', [ 'title' => 'climate change', 'language.code' => 'en', 'sort.by' => 'published_at', 'sort.order' => 'desc', 'per_page' => 10, ]); echo "Page: {$response->page}\n"; echo "Has next page: " . ($response->hasNextPages ? 'yes' : 'no') . "\n"; foreach ($response->articles as $article) { echo "{$article->title}\n"; echo "Source: {$article->source?->domain}\n"; echo "Published: {$article->publishedAt}\n"; echo "Sentiment: {$article->sentiment?->overall?->polarity}\n"; } ``` The call returns an `ArticleList` whose `articles` array holds parsed article objects, plus [pagination](/en/articles/getting-started/glossary#pagination) fields `page`, `limit`, `hasNextPages` and `nextPage`. The `'story'` endpoint needs an `id` in the params (`$client->news('story', ['id' => 'story-id'])`); the SDK throws an `InvalidArgumentException` if it is missing. Every method takes an optional third `version` argument that defaults to `'v1'`. For the full parameter list, see the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). ## How do you count, autocomplete and read reference data?[#](#how-do-you-count-autocomplete-and-read-reference-data) Beyond search, the client wraps the helper endpoints: * **Count** — `$client->count(['title' => 'artificial intelligence', 'language.code' => 'en'])` returns a plain integer of matching articles, using the same filters as `everything`. * **Autocomplete** — `$client->suggest('categories', 'spo')` returns suggestion items; supported types are `categories`, `topics`, `industries` and `entities`. * **Reference lists and profiles** — `$client->people($params)`, `$client->companies($params)` and `$client->journalists($params)` return a paginated list in `->results`; each has a by-ID profile method (`$client->person($id)`, `$client->company($id)`, `$client->journalist($id)`) that returns the raw profile array. * **Balance** — `$client->balance()` returns a `BalanceResponse` with your `plan` and remaining `points`. * **Ping** — `$client->ping()` returns `true` if the API is reachable, `false` otherwise. ## How do you handle errors and rate limits?[#](#how-do-you-handle-errors-and-rate-limits) Failed requests throw typed exceptions you can catch by class. `AuthenticationException` covers a `401` (missing or wrong key), `RateLimitException` covers a `429` and exposes `retryAfter` in seconds, and `ApiException` is the base for any other API error, carrying `requestId` and the HTTP status via `getCode()`: ``` use APITube\Exceptions\ApiException; use APITube\Exceptions\AuthenticationException; use APITube\Exceptions\RateLimitException; try { $response = $client->news('everything', ['title' => 'php']); } catch (AuthenticationException $e) { echo "Auth error: {$e->getMessage()}\n"; } catch (RateLimitException $e) { echo "Rate limited. Retry after {$e->retryAfter}s\n"; } catch (ApiException $e) { echo "API error ({$e->getCode()}): {$e->getMessage()}, request {$e->requestId}\n"; } ``` Quote the `requestId` when you contact support. For what triggers a `429` and how to back off, see [how to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). Prefer Node? The same client design ships as the [Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk). # Common Questions[#](#common-questions) * [Which PHP versions are supported?](#which-php-versions-are-supported) * [Do I need Guzzle specifically?](#do-i-need-guzzle-specifically) * [Which endpoints can I call from the SDK?](#which-endpoints-can-i-call-from-the-sdk) * [Can I use my own HTTP client?](#can-i-use-my-own-http-client) ## Which PHP versions are supported?[#](#which-php-versions-are-supported) The package declares `"php": "^8.1"` in its `composer.json`, so use **PHP 8.1 or newer**. The client relies on constructor property promotion and named arguments, both PHP 8.1 features, so older runtimes are not supported. ## Do I need Guzzle specifically?[#](#do-i-need-guzzle-specifically) No. The SDK depends on the PSR-18 and PSR-17 interfaces, not on one library. Guzzle is the simplest option and is used in the examples, but any PSR-18 client works. If none is installed, `php-http/discovery` auto-discovers the one it finds, so the client can be created without passing an HTTP client explicitly. ## Which endpoints can I call from the SDK?[#](#which-endpoints-can-i-call-from-the-sdk) `$client->news(...)` covers `everything`, `top-headlines`, `story`, `article` and `raw`. Separate methods cover `count`, `suggest`, the `people`/`companies`/`journalists` lists and profiles, `balance` and `ping`. Each maps to the matching `/v1/...` REST endpoint. ## Can I use my own HTTP client?[#](#can-i-use-my-own-http-client) Yes. Pass any PSR-18 client as the `httpClient` argument when constructing the `Client`. This lets you set a global timeout, add middleware, or route requests through a proxy while the SDK still adds the `X-API-Key` header, decodes JSON and maps errors to typed exceptions. * * * ## Related Articles * [How to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk) * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [How to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors) --- ## Official APITube News API SDKs: Node, PHP, Python URL: https://support.apitube.io/en/articles/setup-and-installation/sdks/official-sdks-overview APITube ships official News API SDKs for Node.js, PHP and Python. Install them with npm, Composer or pip, add your API key, and query news in a few typed lines. # Official APITube News API SDKs: Node, PHP, Python Compare the three official clients — install commands, language requirements, and what each one wraps ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 3, 2026 # Official APITube News API SDKs[#](#official-apitube-news-api-sdks) APITube maintains three official SDKs for the News API — **Node.js**, **PHP** and **Python**. Each one wraps the REST API behind a small typed `Client`: you install the package, create the client with your [API key](/en/articles/getting-started/glossary#api-key), and call `news('everything', {...})` to get parsed articles back, so you skip manual URL building and JSON decoding. Install them from the standard registry for your language: ``` npm install @apitube/news-api # Node.js composer require apitube/news-api # PHP pip install apitube # Python ``` If your language is not one of the three, you do **not** need an SDK — the API is plain HTTPS and JSON, so any language that can make a web request can call it. See [how to call the News API from Python, Java, Go and more](/en/articles/setup-and-installation/sdks/call-from-any-language). ## Which official SDKs does APITube offer?[#](#which-official-sdks-does-apitube-offer) There are three, one per language, published on each ecosystem’s main package registry: Language Package Install with Requires Node.js `@apitube/news-api` (npm) `npm install @apitube/news-api` Node.js 18+, TypeScript 5+ optional PHP `apitube/news-api` (Packagist) `composer require apitube/news-api` PHP 8.1+, a PSR-18 HTTP client Python `apitube` (PyPI) `pip install apitube` Python 3.7+ The Node.js package is fully typed — TypeScript declarations ship inside it, so you get autocomplete and compile-time checks with no extra `@types` install. The PHP package needs a PSR-18 HTTP client and PSR-17 factory (Guzzle is the common choice) and is MIT-licensed. All three default their `baseUrl` to `https://api.apitube.io`, so you normally only pass your API key. ## How do you use each SDK?[#](#how-do-you-use-each-sdk) The shape is the same in every language: create a `Client` with your key, then call `news(endpoint, params)`. You pass parameter names exactly as the API expects them, including dotted names like `language.code`. The client attaches your API key to every request for you, so you never build the auth header by hand. ``` // Node.js import { Client } from '@apitube/news-api'; const client = new Client({ apiKey: 'your-api-key' }); const response = await client.news('everything', { title: 'artificial intelligence', 'language.code': 'en', per_page: 5 }); for (const article of response.articles) console.log(article.title, article.url); ``` ``` // PHP use APITube\Client; $client = new Client(apiKey: 'your-api-key'); $response = $client->news('everything', ['title' => 'artificial intelligence', 'language.code' => 'en', 'per_page' => 5]); foreach ($response->articles as $article) { echo $article->title . "\n"; } ``` ``` # Python from apitube import Client client = Client(api_key="your-api-key") response = client.news("everything", {"title": "artificial intelligence", "language.code": "en", "per_page": 5}) for article in response.articles: print(article.title, article.url) ``` The first argument to `news()` picks the endpoint — `everything` for search, plus `top-headlines`, `story` and `article` (the Node.js and PHP clients also accept `raw`) — and the second holds your filter parameters. For the full parameter list, see the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## What is the difference between the SDKs?[#](#what-is-the-difference-between-the-sdks) They cover the same core, but not the exact same surface. All three expose `news()` for articles, `balance()` to check your plan and remaining points, and `ping()` to test connectivity. The **Node.js and PHP** SDKs go further and also wrap the helper endpoints: `count()` for a match count, `suggest()` for autocomplete, and the directory and profile methods `people()`, `companies()` and `journalists()`. The **Python** SDK currently focuses on `news()`, `balance()` and `ping()`. So if you need count, autocomplete or the people/company/journalist directories with a typed method, reach for the Node.js or PHP client. From Python you can still hit those endpoints — just call them over plain HTTPS, exactly like any other REST request. ## Which SDK should you pick?[#](#which-sdk-should-you-pick) Pick the SDK that matches your stack — there is no “best” one, they all talk to the same News API: * **Node.js / TypeScript projects** → `@apitube/news-api`. Fully typed, ships both ESM and CommonJS builds. See [how to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk). * **PHP / Laravel / Symfony apps** → `apitube/news-api`. Bring-your-own PSR-18 client. See [how to install and use the PHP SDK](/en/articles/setup-and-installation/sdks/install-php-sdk). * **Python scripts, data and ML work** → `apitube`. Small client for search, balance and health checks. * **Any other language** → no SDK; call the HTTPS endpoint directly. Ready-to-copy request snippets cover Java, Go, Ruby and C#. # Common Questions[#](#common-questions) * [Are the APITube SDKs free and open source?](#are-the-apitube-sdks-free-and-open-source) * [Do I need an SDK to use the News API?](#do-i-need-an-sdk-to-use-the-news-api) * [Which SDK has the most features?](#which-sdk-has-the-most-features) * [How do I authenticate with an SDK?](#how-do-i-authenticate-with-an-sdk) ## Are the APITube SDKs free and open source?[#](#are-the-apitube-sdks-free-and-open-source) Yes. All three official SDKs are open-source and MIT-licensed, published on their language’s standard registry — `@apitube/news-api` on npm, `apitube/news-api` on Packagist, and `apitube` on PyPI. You install them with the normal package manager (`npm`, `composer`, `pip`) and you still need an APITube API key to make requests. ## Do I need an SDK to use the News API?[#](#do-i-need-an-sdk-to-use-the-news-api) No. The SDKs are a convenience — they build URLs, attach your key and parse JSON for you. The News API itself is plain HTTPS plus JSON, so any language or tool that can send an HTTP request can call it directly. If there is no SDK for your language, send the request yourself and read the JSON back; [calling the News API from any language](/en/articles/setup-and-installation/sdks/call-from-any-language) shows the exact request. ## Which SDK has the most features?[#](#which-sdk-has-the-most-features) The Node.js and PHP SDKs currently wrap the widest surface: `news()`, `count()`, `suggest()`, the `people()`/`companies()`/`journalists()` directories, `balance()` and `ping()`. The Python SDK wraps `news()`, `balance()` and `ping()`. Every endpoint the SDKs don’t wrap is still reachable over plain HTTPS from any of these languages. ## How do I authenticate with an SDK?[#](#how-do-i-authenticate-with-an-sdk) You pass your API key when you construct the client — `new Client({ apiKey })` in Node.js, `new Client(apiKey: ...)` in PHP, `Client(api_key=...)` in Python — and the SDK attaches it to every request automatically. Keep the key out of source control by reading it from an environment variable. Grab a key from your dashboard first; see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). * * * ## Related Articles * [How to install and use the Node.js SDK](/en/articles/setup-and-installation/sdks/install-nodejs-sdk) * [How to install and use the PHP SDK](/en/articles/setup-and-installation/sdks/install-php-sdk) * [How to call the News API from Python, Java, Go and more](/en/articles/setup-and-installation/sdks/call-from-any-language) --- ## Built-in Tools URL: https://support.apitube.io/en/articles/setup-and-installation/tools Try the News API without writing code: build and run requests in the API Playground, copy ready-made snippets, and replay logged calls. ![](/images/collections/insights-dashboard.svg) # Built-in Tools Playground, snippets and request replay. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Jacob 1 author 3 articles * [How to test requests in the API Playground](/en/articles/setup-and-installation/tools/test-in-playground) * [How to Use the APITube Postman Collection](/en/articles/setup-and-installation/tools/use-postman-collection) * [How to use the Query Builder](/en/articles/setup-and-installation/tools/using-query-builder) --- ## How to test requests in the API Playground URL: https://support.apitube.io/en/articles/setup-and-installation/tools/test-in-playground The API Playground lets you build a News API request from dropdowns, run it with your own key, and see the real JSON response — no code required. # How to test requests in the API Playground Build a News API request in the dashboard, run it with your own key, and read the live response ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 3, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en&per_page=10) # How to test requests in the API Playground[#](#how-to-test-requests-in-the-api-playground) The API [Playground](/en/articles/getting-started/glossary#playground) is a page in the APITube dashboard, at **/playground**, where you build a News API request from dropdowns and fields, run it with one of your own [API keys](/en/articles/getting-started/glossary#api-key), and read the real JSON response — no code required. It sends a genuine call to the live News API, so the results, the quota it draws down, and the [rate limits](/en/articles/getting-started/glossary#rate-limit) it hits are exactly what your own integration will get. Open it from the **API Playground** item in the dashboard sidebar. The page has three things to set before you run: the **Endpoint**, the **API key**, and the **Query parameters**. ![The API playground: endpoint and API key selectors, preset searches, and the live request preview with code samples](/images/article/dashboard-playground.png) ## How do you run your first request in the Playground?[#](#how-do-you-run-your-first-request-in-the-playground) Four steps get you a live response: 1. **Pick an endpoint.** It defaults to **Everything** (`/v1/news/everything`), the general search endpoint. 2. **Pick an API key.** The selector lists the keys in your [workspace](/en/articles/getting-started/glossary#workspace) for the current Test/Live mode. If you have none yet, the Playground shows _No API keys yet_ and a **Create a key** link — see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). 3. **Set query parameters.** For example, set **Language** to `en` and **Per page** to `10`. 4. **Click Execute search** (or press **⌘/Ctrl + Enter**). The response appears on the right. That request is the equivalent of `GET https://api.apitube.io/v1/news/everything?language.code=en&per_page=10`, but you never type the URL — the Playground assembles it from the fields. ## Which endpoints and filters can you try?[#](#which-endpoints-and-filters-can-you-try) The endpoint dropdown covers the main read endpoints: **Everything**, **Top headlines**, **Raw**, **Local**, **Count**, **Trends**, **Article**, **Story**, **Category**, **Topic**, **Industry**, **[Entity](/en/articles/getting-started/glossary#entity)**, and **Fact Check**. Endpoints that need a path value (Story, Category, Topic, Industry, Entity) show an extra field for it. The essential parameters are always visible as their own fields: **Title**, **Language**, **Category**, **Country**, **Source domain**, **Published date**, **[Sentiment](/en/articles/getting-started/glossary#sentiment)**, **Sort by**, **Order**, **Per page** and **Page**. Everything else lives in the **Advanced filters** accordion, grouped by area — Sources, Entities & people, Media, Content & quality, Readability, Sentiment, Faceting, Highlighting and Trends. Every filter carries a small mono tag showing its exact API parameter name (for example `source.bias`, `is_breaking`, `media.images.count.min`), so what you build in the form maps one-to-one onto a request you can send yourself. If you want a starting point, the **Presets** are ready-made scenarios grouped into Brand Monitoring, Curated Topics, Investment Intelligence and Risk Intelligence — pick one to fill the form, then tweak. ## Does the Playground use my quota?[#](#does-the-playground-use-my-quota) Yes, when you run with a live key. The Playground runs the request with the key you selected, so it **counts against your account quota** and draws down the same request pool your production traffic uses. A **test key** (prefix `api_test_`) never spends quota — it returns the real response shape with article content truncated, which makes it ideal for exploring the Playground for free. See [test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) for the full difference. Because the call is real, the News API enforces everything it would enforce on your own request: quota, endpoint scopes, and rate limits all apply. If a request comes back with an error instead of articles — for example `402` when you are out of requests, `403` (`ER0603`) when the key lacks that endpoint’s scope, or `429` when you exceed the rate limit — the Playground shows that error response as the result rather than hiding it. ## How do you turn a Playground request into code?[#](#how-do-you-turn-a-playground-request-into-code) Below the form, the **Source code example** panel renders the exact request as a copyable snippet in **cURL, JavaScript, Python, PHP, Go, Ruby** and **Java**. Switch tabs to get the language you use. Each snippet sends your key in the `X-API-Key` header and shows a `YOUR_API_KEY` placeholder — the key is deliberately kept out of the URL so it can’t leak into server logs or referrers. The panel also shows the plain **Request URL**, so you can paste the whole thing into another tool if you prefer. ## How do you read the response?[#](#how-do-you-read-the-response) The response area has three tabs. **JSON** shows the raw body with **Copy** and **Download** buttons for the full payload (the on-screen view is capped to a few KB so a large response can’t freeze the page — Copy and Download always give you everything). **Visual** renders the articles as cards with Previous/Next paging. **Headers** shows the response headers the API returned. Above the tabs you get the HTTP status and the round-trip latency, so you can see both what came back and how fast. # Common Questions[#](#common-questions) * [Can I replay a request from my API logs?](#can-i-replay-a-request-from-my-api-logs) * [Can I share a Playground request with a teammate?](#can-i-share-a-playground-request-with-a-teammate) * [Do test keys work in the Playground?](#do-test-keys-work-in-the-playground) * [Why did my request return an error instead of articles?](#why-did-my-request-return-an-error-instead-of-articles) ## Can I replay a request from my API logs?[#](#can-i-replay-a-request-from-my-api-logs) Yes. In your [request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs), open a log entry and click **Open in Playground**. That rebuilds the exact endpoint and parameters of the logged call in the Playground, so you can inspect what was sent and re-run or adjust it. The button only appears for endpoints the Playground supports. ## Can I share a Playground request with a teammate?[#](#can-i-share-a-playground-request-with-a-teammate) Yes. The full state of the form — endpoint, key selection and every parameter — is encoded in the page URL, and the **Share request** button copies that URL to your clipboard. Anyone on your team who opens it lands on the same pre-filled request (they still choose their own key to run it). ## Do test keys work in the Playground?[#](#do-test-keys-work-in-the-playground) Yes. A test key runs in the Playground exactly like a live key and returns the same response structure, but the article content is truncated and **no quota is spent**. Use a test key while you are learning the parameters, then switch to a live key for full content. The key selector follows the dashboard’s Test/Live mode, so it only lists keys for the mode you are currently in. ## Why did my request return an error instead of articles?[#](#why-did-my-request-return-an-error-instead-of-articles) The Playground shows the real API response, including errors. A `402` means the account is out of requests, a `403` with `ER0603` means the selected key is not scoped to that endpoint, and a `429` means you hit the rate limit. A `4xx` with a validation code usually means a filter value is malformed. Read the status and body in the JSON tab, fix the offending field, and run again. * * * ## Related Articles * [Test keys vs live keys](/en/articles/setup-and-installation/account-and-keys/test-vs-live-keys) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) --- ## How to Use the APITube Postman Collection URL: https://support.apitube.io/en/articles/setup-and-installation/tools/use-postman-collection Import the APITube Postman collection, set the api_key variable once, and run 140+ ready-made News API requests without writing any code. # How to Use the APITube Postman Collection Import the ready-made News API collection, set your api\_key once, and run every endpoint without writing code ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to use the APITube Postman collection[#](#how-to-use-the-apitube-postman-collection) The APITube Postman collection is a ready-made set of News API requests you import into Postman, point at your own key, and run — no code required. Open the public collection at **[postman.com/apitube/apitube](https://www.postman.com/apitube/apitube/overview)**, add it to your [workspace](/en/articles/getting-started/glossary#workspace), set one `api_key` variable, and every request is ready to send against `https://api.apitube.io`. It bundles **142 ready-to-run requests**: the core endpoints at the top level plus an `Examples` folder of themed filter recipes. Because each request is pre-built with the right URL and parameters, it is the fastest way to learn the API surface hands-on before you write a single line of client code. ## How do you import the APITube Postman collection?[#](#how-do-you-import-the-apitube-postman-collection) The collection is published to the public APITube Postman workspace. Open **[postman.com/apitube/apitube/overview](https://www.postman.com/apitube/apitube/overview)** and use Postman’s **Fork** or **Import** action to copy it into your own workspace. Once it lands in your sidebar, you will see the collection named **“APITube - News API”** with every request grouped and ready. Every request already targets the live base URL, so there is nothing to configure except your key: ``` https://api.apitube.io/v1/news/everything?api_key={{api_key}} ``` ## How do you set your API key in Postman?[#](#how-do-you-set-your-api-key-in-postman) Every request in the collection reads a Postman variable called `api_key` and appends it as the `api_key` query parameter (`?api_key={{api_key}}`). Set that variable **once** — as a collection variable or an environment variable — to your own key, and all 142 requests inherit it. 1. Grab your key from the dashboard — see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). 2. In Postman, open the collection’s **Variables** tab (or create an environment), add `api_key`, and paste your key as the value. 3. Send any request — for example **Check balance** (`GET /v1/balance`) — to confirm the key resolves. If you prefer sending the key as a header instead of a query parameter, the API also accepts an `X-API-Key` header. A missing key returns `401 ER0201` (“[API key](/en/articles/getting-started/glossary#api-key) is required”), and an invalid one returns `401 ER0202`. ## What requests are included in the collection?[#](#what-requests-are-included-in-the-collection) The top level of the collection covers the main endpoints, each pre-filled and ready to send: * **Everything** — the main search endpoint (`POST /v1/news/everything`, sent as JSON). Its optional filters (`title`, `language.code`, `category.id`, `topic.id` and many more) ship **pre-filled but disabled** — flip the toggle next to any parameter to activate it. * **Top headlines**, and browse-by requests: **Get news by category / topic / industry / [entity](/en/articles/getting-started/glossary#entity)**. * **Get article by ID** and **Get story by ID** to fetch a single article or a whole [story cluster](/en/articles/getting-started/glossary#story). * **Get trends**, plus **Trends with trending score**, **Trends with period comparison** and **Trends by time bucket**. * **Suggest entities** for autocomplete (a `prefix` such as `Apple`, an optional `type` like `organization`, and a `limit`). * **Check balance** to read your remaining quota. ## How do you use the Examples folder?[#](#how-do-you-use-the-examples-folder) The `Examples` folder is where the collection earns its keep: **16 themed sub-folders** of copy-and-run filter recipes, so you can see the exact parameter syntax for each feature. The sub-folders are **Filters, Sorting, Geolocation, Readability, Read Time, Faceting, Highlighting, Disasters & Events, Clickbait Detection, Breaking News, [Export Formats](/en/articles/getting-started/glossary#export-format), [Pagination](/en/articles/getting-started/glossary#pagination), Persons, Organizations, Brands** and **Field Selection**. Each example is a real, working request. A few to try: ``` # Geolocation → Search by bounding box GET /v1/news/everything?api_key={{api_key}}&location.bbox=34.0,-118.5,34.3,-118.1 # Clickbait Detection → Detect clickbait articles GET /v1/news/everything?api_key={{api_key}}&is_clickbait=1 # Export Formats → Export as CSV GET /v1/news/everything?api_key={{api_key}}&export=csv # Field Selection → Minimal response GET /v1/news/everything?api_key={{api_key}}&fl=id,title,href ``` Trim the response to only the fields you need with `fl` — see [how to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields). The full parameter list behind every example lives in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Where do I download the APITube Postman collection?](#where-do-i-download-the-apitube-postman-collection) * [Why do my requests return a 401 error in Postman?](#why-do-my-requests-return-a-401-error-in-postman) * [Do I have to enable each parameter by hand?](#do-i-have-to-enable-each-parameter-by-hand) * [Can I use the collection without writing code?](#can-i-use-the-collection-without-writing-code) ## Where do I download the APITube Postman collection?[#](#where-do-i-download-the-apitube-postman-collection) The collection is hosted on the public APITube Postman workspace at [postman.com/apitube/apitube/overview](https://www.postman.com/apitube/apitube/overview). Fork or import it from there into your own workspace. The same link is listed as “Postman Collection” in the APITube docs, so you always land on the current version. ## Why do my requests return a 401 error in Postman?[#](#why-do-my-requests-return-a-401-error-in-postman) A `401` means the API did not receive a valid key. If you see `ER0201`, the `api_key` variable is empty or unresolved — set it in the collection’s **Variables** tab or in an active environment. If you see `ER0202`, the key value is wrong or revoked; copy a fresh key from your dashboard. Confirm the fix by sending the **Check balance** request. ## Do I have to enable each parameter by hand?[#](#do-i-have-to-enable-each-parameter-by-hand) For the **Everything** request, yes — its many optional filters are included but disabled so the base request stays clean. Tick the checkbox next to any parameter in the query editor to activate it. The requests inside the `Examples` folder are different: each already has its parameters enabled, so you can send them as-is and then tweak the values. ## Can I use the collection without writing code?[#](#can-i-use-the-collection-without-writing-code) Yes. Postman runs every request for you and shows the live JSON response, so the collection is a full no-code way to explore the News API. If you would rather build requests inside the APITube dashboard, the [API Playground](/en/articles/setup-and-installation/tools/test-in-playground) offers the same run-with-your-key experience without leaving your account. * * * ## Related Articles * [How to authenticate your API requests](/en/articles/setup-and-installation/account-and-keys/authenticate-your-requests) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [How to test requests in the API Playground](/en/articles/setup-and-installation/tools/test-in-playground) --- ## How to use the Query Builder URL: https://support.apitube.io/en/articles/setup-and-installation/tools/using-query-builder Use the APITube Query Builder to assemble a News API request from dropdowns and fields, then copy the generated URL or cURL command — no query syntax to… # How to use the Query Builder Build a News API request from form fields on docs.apitube.io and copy the ready URL or cURL command ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 4, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=AI&sentiment_polarity=positive) # How to use the Query Builder[#](#how-to-use-the-query-builder) The APITube Query Builder is an interactive form on the documentation site at **[docs.apitube.io/platform/news-api/query-builder](https://docs.apitube.io/platform/news-api/query-builder)**. You pick an endpoint, fill in filter fields, and it writes the matching request URL and a ready-to-run cURL command for you — so you never have to hand-type parameter names or remember the dot-notation syntax. Fill a field, and the generated request updates instantly below the form. It is the fastest way to turn “I want English articles about AI with positive [sentiment](/en/articles/getting-started/glossary#sentiment)” into a working request. You leave with a URL you can paste into code and a cURL command you can run in a terminal. ## How do you build a request with the Query Builder?[#](#how-do-you-build-a-request-with-the-query-builder) Start at the top of the form and work down. There are three things that matter most: 1. **Pick the endpoint.** The endpoint dropdown defaults to **Everything** (`/v1/news/everything`), the general search endpoint, and also offers Top Headlines, Story, Category, Topic, Industry, [Entity](/en/articles/getting-started/glossary#entity), Trends and Single Article. 2. **Fill in filter fields.** Type your title terms, choose a language, set a sentiment polarity, and so on. Empty fields are ignored — only the fields you fill become part of the request. 3. **Read the generated request.** As you edit, the builder rewrites the request URL and cURL command underneath. For example, setting **Title** to `AI` and **Sentiment Polarity** to `positive` produces: ``` https://api.apitube.io/v1/news/everything?title=AI&sentiment.overall.polarity=positive&api_key=YOUR_API_KEY ``` Notice the form uses friendly labels but the URL uses the real API parameter names — the builder maps each field to its dot-notation parameter, so **Sentiment Polarity** becomes `sentiment.overall.polarity`, **Language Code** becomes `language.code`, and **Source Rank Min** becomes `source.rank.opr.min`. That mapping is the whole point: you learn the API by watching the URL build itself. ## Which endpoints and filters can you use?[#](#which-endpoints-and-filters-can-you-use) The endpoint dropdown covers nine read endpoints: **Everything, Top Headlines, Story, Category, Topic, Industry, Entity, Trends** and **Single Article**. The filter fields are grouped into logical sections — Endpoint, Title, Language, Categories, Topics, Industries, Entities, Persons, Locations, Organizations, Brands, Authors, Sentiment, Media, Source, Date Range, Sorting, [Pagination](/en/articles/getting-started/glossary#pagination), other filters, and Export — so a parameter is easy to find by area. A few input conventions carry straight through to the URL: * **Multiple values** go in one field separated by commas, e.g. `language.code=en,fr,de` or `title=Bitcoin,Ethereum,Cryptocurrency`. * **Exact phrases** use quotes, e.g. `title="Breaking News"`. * The **title pattern** field is a case-insensitive substring (`LIKE`) match, not a regular expression — characters like `^`, `.` and `*` are treated as literal text. * **Sorting** fields fill `sort.by` and `sort.order`; if you leave them blank the API sorts by `published_at` in `desc` order (newest first). For the full meaning of every field, the builder links to the [Parameters Reference](https://docs.apitube.io/platform/news-api/everything), which stays the canonical source for parameter syntax. ## How do you copy the URL or cURL command?[#](#how-do-you-copy-the-url-or-curl-command) Below the form the builder shows two outputs with copy buttons: **Copy URL** puts the full request URL on your clipboard, and **Copy cURL** copies a `curl -X GET "…"` command wrapping that same URL. Paste the URL into your code (a `fetch`, a `requests.get`, an SDK call) or run the cURL command straight in a terminal. If you have not entered a key, the builder inserts the placeholder `YOUR_API_KEY` in the copied request, so you can safely share or paste it and swap the key in later. Enter a real key only to use the **Test Query** button — it opens the request URL, with your key attached, in a new browser tab so you can see the raw JSON response. Because Test Query fires a genuine call to the News API, a [live key](/en/articles/getting-started/glossary#test-key-and-live-key) spends quota just like any other request (see [how to combine multiple filters in one request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) for building the filters, and [where to find your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key)). # Common Questions[#](#common-questions) * [Where does the Query Builder live?](#where-does-the-query-builder-live) * [Is the Query Builder the same as the Playground?](#is-the-query-builder-the-same-as-the-playground) * [Is my API key safe in the Query Builder?](#is-my-api-key-safe-in-the-query-builder) * [Do I need an API key to build a request?](#do-i-need-an-api-key-to-build-a-request) ## Where does the Query Builder live?[#](#where-does-the-query-builder-live) The Query Builder is a page in the APITube documentation, at `docs.apitube.io/platform/news-api/query-builder` — not inside the dashboard. It needs no login: anyone can open it, build a request, and copy the URL or cURL. That makes it handy for drafting a request while you read the docs, then dropping the result into your own code. ## Is the Query Builder the same as the Playground?[#](#is-the-query-builder-the-same-as-the-playground) No — they are two different tools for two moments. The **Query Builder** (in the docs) assembles a request and hands you the URL and cURL; its Test Query button opens the raw response in a new tab. The **[API Playground](/en/articles/setup-and-installation/tools/test-in-playground)** (in your dashboard) runs the request with one of your [workspace](/en/articles/getting-started/glossary#workspace) keys and renders the JSON response inline, with visual cards and headers. Use the Query Builder to draft and copy a request quickly; use the [Playground](/en/articles/getting-started/glossary#playground) to run and inspect responses against your account. ## Is my API key safe in the Query Builder?[#](#is-my-api-key-safe-in-the-query-builder) The key you type stays in your browser — it is only used to assemble the request and to open the Test Query tab, and it is not sent to the documentation server. One thing to watch: once you enter a real key, the generated URL and cURL contain it, so if you then click **Copy URL** or **Copy cURL** the copied text includes your key. Don’t paste a copied request that contains your live key into a public place — clear the key field first, or rely on the `YOUR_API_KEY` placeholder. ## Do I need an API key to build a request?[#](#do-i-need-an-api-key-to-build-a-request) No. You can pick an endpoint, fill every filter, and copy a complete URL or cURL without ever entering a key — the builder simply writes `YOUR_API_KEY` where the key goes. A key is required only for the **Test Query** button, which needs a real key to make the live call. This lets you design and share a request first, then add authentication when you are ready to send it. * * * ## Related Articles * [How to test requests in the API Playground](/en/articles/setup-and-installation/tools/test-in-playground) * [Where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key) * [How to combine multiple filters in one request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) --- ## How to review the workspace audit log URL: https://support.apitube.io/en/articles/teams-and-workspaces/audit-log Review your APITube workspace audit log to see who changed keys, invited or removed members, and managed the team. Owners and admins can filter by actor,… # How to review the workspace audit log See who changed API keys, invited or removed teammates, and managed your APITube workspace — and filter the history by person, action or date ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 2, 2026 Updated July 21, 2026 # How to review the workspace audit log[#](#how-to-review-the-workspace-audit-log) The **Audit log** in your APITube dashboard records the team actions taken in a [workspace](/en/articles/getting-started/glossary#workspace) — who changed an [API key](/en/articles/getting-started/glossary#api-key), who invited or removed a teammate, who renamed or deleted the workspace — each stamped with the person, the exact action, the target, the time and the IP address. It is visible to the workspace **owner and admins** under the **Audit log** page in the dashboard. Members and viewers do not see it. Use it to answer “who did this, and when?” without guessing. The audit log is scoped to the **current workspace**, so switch to the workspace you want to inspect first, then open its Audit log. ## Who can view the workspace audit log?[#](#who-can-view-the-workspace-audit-log) Only the **owner** and **admins** of a workspace can open the Audit log. Members and viewers have no access: the `/audit-log` page returns “not found” for them and the underlying request is rejected, so the action history stays with the people who manage the team. This mirrors the rest of team management — inviting, re-roling and removing teammates is owner-and-admin work too, and the audit log is where those actions are recorded. If you own several workspaces, each has its own separate audit log. Even a **personal** workspace has one, visible to you as its owner. For the full breakdown of what each role can do, see [workspace roles: owner, admin, member and viewer](/en/articles/teams-and-workspaces/workspace-roles). ## What actions does the audit log record?[#](#what-actions-does-the-audit-log-record) The audit log captures **team and workspace changes**, not read-only browsing. Recorded actions include: * **API keys** — created, renamed, revoked, regenerated, and updates to a key’s permissions (scopes), IP restrictions and expiry date. * **[Webhooks](/en/articles/getting-started/glossary#webhook)** — created, updated, deleted, a delivery resent, and a test event sent. * **Members and invites** — a member invited, an invite revoked, a teammate joining, a role changed, a member removed, and a member leaving. * **Workspace** — the workspace created, renamed or deleted. * **Billing limit** — the monthly spending limit updated (owner only). * **Data** — request logs exported. Each of these shows in the log with a plain-language label such as “Created API key”, “Changed member role” or “Removed member”, so you read the history without decoding internal codes. Managing keys is one of the most common things you will see here — see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## What does each audit log entry show?[#](#what-does-each-audit-log-entry-show) Every entry is one row with these columns: * **Time** — when the action happened. * **Actor** — the teammate who did it, shown by email (and name when available). The email is captured at the moment of the action, so the record stays accurate even if that person later changes their address or leaves the team. * **Action** — the plain-language action label, for example “Revoked API key”. * **Target** — what the action affected: an API key, a member, a webhook or the workspace itself. * **Details** — opens a side panel with the **IP address** the action came from and any extra context for that change, such as the old and new value of a setting. Because the actor and target are recorded on every row, you can trace a specific change back to a specific person and a specific object. ![The workspace audit log: rows with time, actor, action and target, such as member invites and key changes](/images/article/dashboard-audit-log.png) ## How to filter the audit log[#](#how-to-filter-the-audit-log) The Audit log page has three filters so you can narrow a long history fast: * **Actor** — pick a teammate to see only their actions (the “All actors” dropdown lists everyone who has ever acted in the workspace). * **Action** — pick an action type, for example only “Revoked API key” or only member changes. * **Date range** — bound the history to a start and end date. Combine them to answer targeted questions — “what did this admin change last week?” — and page through the results, 50 entries at a time. The audit log is **read-only**: there is no way to edit or delete an entry, which is what makes it a trustworthy record. ## What the audit log does not track[#](#what-the-audit-log-does-not-track) The audit log is a **team** record, so it deliberately leaves out personal account settings. Changing your own email, password, avatar, dashboard language or theme is **not** written to the workspace audit log, because those are your private profile actions, not workspace management. It is also different from your **API request logs**. The audit log answers “who managed the team and the keys?”; the request logs answer “what API traffic went through my keys?” — status codes, latency, endpoints. For that live API usage history, see [how to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs). # Common Questions[#](#common-questions) * [Can members or viewers see the audit log?](#can-members-or-viewers-see-the-audit-log) * [Does the audit log record my email or password changes?](#does-the-audit-log-record-my-email-or-password-changes) * [Does the audit log show the IP address of each action?](#does-the-audit-log-show-the-ip-address-of-each-action) * [Is the audit log per workspace or account-wide?](#is-the-audit-log-per-workspace-or-account-wide) ## Can members or viewers see the audit log?[#](#can-members-or-viewers-see-the-audit-log) No. The Audit log is limited to the workspace **owner and admins**. Members and viewers cannot open it — the page returns “not found” for them. If a teammate needs to review the workspace’s action history, promote them to **admin**; that grants audit-log access along with team and key management, without touching billing. ## Does the audit log record my email or password changes?[#](#does-the-audit-log-record-my-email-or-password-changes) No. Personal account settings — your email, password, avatar, language and theme — are **not** written to the workspace audit log. The log is intentionally a record of team and workspace actions (keys, members, webhooks, workspace changes and the spending limit), not private profile changes. ## Does the audit log show the IP address of each action?[#](#does-the-audit-log-show-the-ip-address-of-each-action) Yes. Open the **Details** panel on any entry to see the IP address the action came from, along with any extra context for that change. The actor’s email and the timestamp are on the row itself, and the IP is captured on a best-effort basis from the request. ## Is the audit log per workspace or account-wide?[#](#is-the-audit-log-per-workspace-or-account-wide) Per workspace. Each workspace keeps its own separate audit log scoped to that workspace’s actions, so switch to the workspace you want to inspect before opening its Audit log. If you own multiple workspaces, reviewing one does not show the actions of another. * * * ## Related Articles * [Workspace roles: owner, admin, member and viewer](/en/articles/teams-and-workspaces/workspace-roles) * [How to invite team members](/en/articles/teams-and-workspaces/invite-members) * [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) * [How to view and search your request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs) --- ## How to Create and Switch Workspaces URL: https://support.apitube.io/en/articles/teams-and-workspaces/create-switch-workspaces Create a new APITube workspace from the switcher in the dashboard, give it a name, and switch between workspaces at any time. You can own up to 10 workspaces. # How to Create and Switch Workspaces Add a new workspace from the switcher, name it, and move between your workspaces in the APITube dashboard ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 3, 2026 Updated July 21, 2026 # How to create and switch workspaces[#](#how-to-create-and-switch-workspaces) To create a [workspace](/en/articles/getting-started/glossary#workspace), open the **workspace switcher** in the dashboard sidebar, choose **Create workspace**, type a name, and confirm — the new workspace opens right away. To switch, open the same switcher and pick any workspace from the list. Your choice is remembered, so the next time you sign in you land back in the same workspace. You can own **up to 10 workspaces**, and every account already has one **Personal** workspace to start from. ## How do I create a new workspace?[#](#how-do-i-create-a-new-workspace) Creating a workspace takes a few seconds and does not require any billing setup: 1. Open the **workspace switcher** at the top of the dashboard sidebar (it shows your current workspace name). 2. Click **Create workspace**. 3. Enter a **name** — a name is required, and it can be up to 255 characters. Use something you will recognize later, such as a client, project or team name. 4. Confirm. APITube creates the workspace and **switches you into it automatically**, so you can start making [API keys](/en/articles/getting-started/glossary#api-key) there immediately. The new workspace begins empty: it has its own API keys and its own member list, separate from every other workspace. Because [API keys are scoped to each workspace](/en/articles/account-and-dashboard/keys/manage-keys), any keys you had before stay in the workspace where you made them. ![The workspace switcher dropdown listing the Personal and team workspaces with the Create workspace action](/images/article/dashboard-workspace-switcher.png) ## How do I switch between workspaces?[#](#how-do-i-switch-between-workspaces) Open the **workspace switcher** and select the workspace you want. The switcher lists two groups: the workspaces **you own**, and any workspaces **shared with you** — ones owned by other people where you are an active member. Each row shows your **role** in that workspace (owner, admin, member or viewer), and a check mark marks the workspace you are currently in. Switching changes your active context across the whole dashboard at once: the **API keys, request logs, usage and audit log** you see all follow the workspace you selected. APITube refreshes this data immediately after you switch, so you are never looking at another workspace’s keys by mistake. Billing, quota and balance are the exception — they belong to the owner’s account and stay the same across all of that owner’s workspaces. You can also switch from the **Workspaces** overview page (linked at the bottom of the switcher). That page lists every workspace with its role and API key count; the menu on each row lets you **Switch to** it, open its **Settings** (for workspaces you own), or **Leave** it (for workspaces shared with you). Your active workspace is saved to your account, not just your browser tab. If a workspace you had selected is later deleted, or your membership in someone else's workspace is removed, APITube quietly falls back to your **Personal** workspace so you always have a valid context. ## How many workspaces can I have?[#](#how-many-workspaces-can-i-have) You can **own up to 10 workspaces**. Once you reach that limit, the **Create workspace** button is disabled and the dashboard shows a note that the limit is reached. This ceiling counts only the workspaces you own — workspaces that other people have shared with you do **not** count toward your 10. There is also always your **Personal** workspace: APITube creates it for you automatically the first time you sign in, and it is your default. You cannot delete the Personal workspace, since it is the one that always holds your keys. If you delete a different workspace you own, its API keys are moved back into your Personal workspace rather than lost. ## Who can create workspaces and invite people?[#](#who-can-create-workspaces-and-invite-people) Any signed-in user can create their **own** workspaces — creating one makes you its owner. Inviting teammates into a workspace is separate and more restricted: only the **owner or an admin** of a workspace can invite members. If you want to build a team inside a workspace, see [how to invite team members](/en/articles/teams-and-workspaces/invite-members). For a deeper look at what a workspace is and what is shared versus scoped, read [what are workspaces and when to use them](/en/articles/teams-and-workspaces/what-are-workspaces). # Common Questions[#](#common-questions) * [Does creating a workspace start a new bill?](#does-creating-a-workspace-start-a-new-bill) * [Will switching workspaces log me out or change my settings?](#will-switching-workspaces-log-me-out-or-change-my-settings) * [Do shared workspaces count toward my limit?](#do-shared-workspaces-count-toward-my-limit) ## Does creating a workspace start a new bill?[#](#does-creating-a-workspace-start-a-new-bill) No. A new workspace organizes keys and members; it does not create a separate bill or a second quota. Billing, plan, quota and balance belong to the owner’s account and are shared across every workspace that owner has. Creating a workspace only gives you a fresh container for API keys and teammates. ## Will switching workspaces log me out or change my settings?[#](#will-switching-workspaces-log-me-out-or-change-my-settings) No. Switching only changes which workspace’s keys, logs, usage and members you see. You stay signed in, and personal settings such as your language, theme and profile follow you as an individual — they are not tied to the workspace. Your active workspace is remembered, so you return to it on your next visit. ## Do shared workspaces count toward my limit?[#](#do-shared-workspaces-count-toward-my-limit) No. The 10-workspace limit counts only the workspaces you own. Workspaces that other people own and have shared with you appear in your switcher and let you work inside them, but they never use up one of your own 10 slots. * * * ## Related Articles * [What are workspaces and when to use them](/en/articles/teams-and-workspaces/what-are-workspaces) * [How to invite team members to a workspace](/en/articles/teams-and-workspaces/invite-members) * [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## Teams & Workspaces URL: https://support.apitube.io/en/articles/teams-and-workspaces Work together in APITube: create workspaces, invite teammates, assign owner, admin, member and viewer roles, and share one owner's billing across the team. ![](/images/collections/user-management-security.png) # Teams & Workspaces Workspaces, roles and shared billing. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) By Brian and 1 other 2 authors 8 articles Workspaces let a team share one APITube account without sharing credentials: each workspace has its own API keys and members, while billing stays with the workspace owner. These articles cover creating and switching workspaces, inviting members, assigning roles, and how shared billing works. If you are setting up a team for the first time, read [what are workspaces](/en/articles/teams-and-workspaces/what-are-workspaces) and then [invite members](/en/articles/teams-and-workspaces/invite-members) — the two together take about five minutes to act on. * [How Billing and Usage Are Shared in a Workspace](/en/articles/teams-and-workspaces/shared-billing) * [How to Change a Member's Role or Remove Them](/en/articles/teams-and-workspaces/manage-members) * [How to Create and Switch Workspaces](/en/articles/teams-and-workspaces/create-switch-workspaces) * [How to Invite Team Members to a Workspace](/en/articles/teams-and-workspaces/invite-members) * [How to Rename or Delete a Workspace](/en/articles/teams-and-workspaces/rename-or-delete-workspace) * [How to review the workspace audit log](/en/articles/teams-and-workspaces/audit-log) * [What Are Workspaces and When to Use Them](/en/articles/teams-and-workspaces/what-are-workspaces) * [Workspace Roles: Owner, Admin, Member, Viewer](/en/articles/teams-and-workspaces/workspace-roles) --- ## How to Invite Team Members to a Workspace URL: https://support.apitube.io/en/articles/teams-and-workspaces/invite-members Only a workspace owner or admin can invite teammates in APITube. Open Workspaces → Team, pick a role (admin, member or viewer), and share the invite link. # How to Invite Team Members to a Workspace Generate an invite link, pick a role, and add admins, members or viewers to your APITube workspace ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 2, 2026 Updated July 21, 2026 # How to invite team members[#](#how-to-invite-team-members) In APITube, a [workspace](/en/articles/getting-started/glossary#workspace) **owner or admin** invites a teammate from the dashboard: open **Workspaces → Team**, click **Invite**, choose a role (admin, member or viewer), and share the generated invite link. Every invite is a link of the form `/invite/<token>`, so the person you add just needs an APITube account to accept it. Members and viewers cannot invite anyone — the Team page is hidden from them. ## Who can invite people to a workspace?[#](#who-can-invite-people-to-a-workspace) Only the **owner and admin** can invite. When an admin or owner opens the dashboard, the sidebar shows a **Workspaces → Team** item; members and viewers do not see it, and the team page returns “not found” if they try to open it directly. This matches the permission model, where inviting, changing roles and removing people are admin-and-owner actions. See [workspace roles: owner, admin, member and viewer](/en/articles/teams-and-workspaces/workspace-roles) for the full breakdown of what each role can do. ## How to send an invite step by step[#](#how-to-send-an-invite-step-by-step) Follow these steps in the dashboard: 1. In the sidebar, open **Workspaces → Team** (the page at `/workspaces/members`). 2. Click **Invite** to open the “Invite a teammate” dialog. 3. **Email is optional.** Leave it blank to create a link anyone with an APITube account can accept, or enter an address to lock the invite so **only that email** can accept it. 4. Pick a **role** — Admin, Member or Viewer. Member is the default. 5. Click **Create invite link**. APITube creates a _pending_ invite and shows the link. 6. **Copy the link and share it.** If you entered an email, APITube also emails the link to that address on a best-effort basis; if sending fails, the dialog tells you to copy the link and send it yourself. The invite you just created appears in the team list with a **Pending** badge until the person accepts it. ![The invite dialog with an optional email field and a role selector before creating the invite link](/images/article/dashboard-invite-dialog.png) ## Which role should you give a teammate?[#](#which-role-should-you-give-a-teammate) You choose one of three roles when inviting — **owner is never an option**, so you can promote someone up to admin but never hand out ownership: * **Admin** — manages the team and the workspace’s [API keys](/en/articles/getting-started/glossary#api-key) and [webhooks](/en/articles/getting-started/glossary#webhook). An admin cannot touch billing, the plan, or the owner’s account. * **Member** — creates and uses API keys and webhooks and views usage and logs, but cannot invite, re-role or remove people. * **Viewer** — read-only access to the workspace’s data. Keys and members are scoped to the workspace, but quota, balance and billing are **shared and belong to the owner**, so any key a teammate creates spends the owner’s quota. To manage those keys, see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## What happens when someone accepts the invite?[#](#what-happens-when-someone-accepts-the-invite) The teammate opens the invite link, signs in to their **APITube account**, and clicks **Accept invitation**. On success they are added to the workspace and switched straight into it. If you locked the invite to an email, only the account with that exact address can accept — anyone else gets an error. A link-only invite can be accepted by any signed-in APITube user, but only once: after that the invite is used. Nobody can accept an invite into a workspace they already own. ## How to change a teammate’s role or remove them[#](#how-to-change-a-teammates-role-or-remove-them) On the **Team** page, each **active** member shows a role dropdown — change Admin / Member / Viewer inline (owner and admin only). **Revoke** cuts a person’s access to the workspace immediately, and revoked people disappear from the list. The same **Revoke** action cancels a **pending** invite before it is accepted, so you can withdraw a link you shared by mistake. # Common Questions[#](#common-questions) * [Can a member invite other people?](#can-a-member-invite-other-people) * [Can I invite someone as the owner of the workspace?](#can-i-invite-someone-as-the-owner-of-the-workspace) * [Do teammates share my quota and billing?](#do-teammates-share-my-quota-and-billing) * [My teammate didn’t get the invite email — what now?](#my-teammate-didnt-get-the-invite-email--what-now) ## Can a member invite other people?[#](#can-a-member-invite-other-people) No. Inviting is limited to the **owner and admin**. A member can create and use API keys and set up webhooks, but the Team page and the Invite button are not available to them. If you want a teammate to manage the team as well, give them the **Admin** role. ## Can I invite someone as the owner of the workspace?[#](#can-i-invite-someone-as-the-owner-of-the-workspace) No. The three invitable roles are **Admin, Member and Viewer** only — owner is never offered. The owner is fixed to the account that created the workspace, and there is no “transfer ownership” action. To let someone run the team day to day, make them an admin, which grants full member and key management without billing or account access. ## Do teammates share my quota and billing?[#](#do-teammates-share-my-quota-and-billing) Yes. A workspace’s API keys and members are its own, but quota, balance and billing are **shared and belong to the owner**. Every request a teammate’s key makes counts against the owner’s quota, and only the owner sees billing and can change the plan. Admins and members create and use keys, but the checkout and subscription screens stay with the owner. ## My teammate didn’t get the invite email — what now?[#](#my-teammate-didnt-get-the-invite-email--what-now) The email is a convenience, not the invite itself — the invite **is the link**. If you entered an email and it didn’t arrive, open the **Team** page, create the invite again (or reuse the link shown at creation), and send the `/invite/<token>` link directly. A link-only invite (no email) never depends on email delivery at all; you just copy the link and share it. * * * ## Related Articles * [Workspace roles: owner, admin, member, viewer](/en/articles/teams-and-workspaces/workspace-roles) * [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## How to Change a Member's Role or Remove Them URL: https://support.apitube.io/en/articles/teams-and-workspaces/manage-members Only a workspace owner or admin can change a teammate's role or remove them in APITube. Open Workspaces → Team, use the role dropdown, or click Revoke. # How to Change a Member's Role or Remove Them Re-role or revoke a teammate on the APITube Workspaces → Team page, and let members leave on their own ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 2, 2026 Updated July 21, 2026 # How to change a member’s role or remove them[#](#how-to-change-a-members-role-or-remove-them) In APITube, a [workspace](/en/articles/getting-started/glossary#workspace) **owner or admin** manages existing teammates on the **Team** page — open **Workspaces → Team** (the page at `/workspaces/members`). To change what someone can do, pick a new role from the inline dropdown (**Admin**, **Member** or **Viewer**). To take away access, click **Revoke**. Members and viewers cannot manage the team, and the workspace **owner** can never be re-roled or removed — ownership is fixed to the account that created the workspace. ## Who can change roles and remove members?[#](#who-can-change-roles-and-remove-members) Only the **owner and admin** can re-role or remove teammates. When an admin or owner opens the dashboard, the sidebar shows a **Workspaces → Team** item; members and viewers do not see it, and the Team page returns “not found” if they open the URL directly. This follows the role model: inviting, changing roles and removing people are all admin-and-owner actions, while a **member** can only create and use keys and [webhooks](/en/articles/getting-started/glossary#webhook), and a **viewer** has read-only access. For the full capability breakdown, see [what each workspace role can do](/en/articles/teams-and-workspaces/workspace-roles). ## How to change a member’s role[#](#how-to-change-a-members-role) On the **Team** page, every **active** member shows a role dropdown next to their name. Change it inline: 1. Open **Workspaces → Team**. 2. Find the member and click the role dropdown in their row. 3. Choose **Admin**, **Member** or **Viewer**. The change applies immediately. ![The Members tab of a workspace: the owner row, a pending invite, and active members with inline role dropdowns and Revoke actions](/images/article/dashboard-team-members.png) A few things to know about role changes: * **Owner is never an option.** You can promote a teammate up to Admin, but you cannot hand out ownership — there is no “transfer ownership” action anywhere in the dashboard. * **Pending invites can’t be re-roled.** A teammate who has not accepted their invite yet shows a plain **Pending** badge and no dropdown. To change the role you offered them, revoke the pending invite and send a new one with the role you want. * **Admin still can’t touch billing.** Promoting someone to Admin gives them team and key management, but not billing, the plan, or the owner’s account settings. ## How to remove a member from a workspace[#](#how-to-remove-a-member-from-a-workspace) To remove a teammate, click the **Revoke** button in their row on the **Team** page. APITube asks you to confirm, then cuts that person’s access to the workspace right away and drops them from the member list. The same **Revoke** button also cancels a **Pending** invite before it is accepted, so you can withdraw a link you shared by mistake. Revoking a teammate is a “soft” removal: it ends their membership but keeps a record, which is why the person disappears from the list rather than being erased. If you need to bring them back later, you send a **fresh invite** — a revoked membership cannot be flipped back on in place. See [how to invite team members](/en/articles/teams-and-workspaces/invite-members) for the invite flow. ## What happens to a removed member’s access and API keys?[#](#what-happens-to-a-removed-members-access-and-api-keys) Removing a teammate ends their access to the workspace immediately: on their next visit the workspace disappears from their switcher and they fall back to their own **personal** workspace. Removing a person does **not** delete the [API keys](/en/articles/getting-started/glossary#api-key) they created, however. Keys belong to the **workspace**, not to the individual, so any key a removed teammate made stays active and keeps spending the owner’s shared quota. If you want those keys gone, revoke them yourself on the API Keys page — see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## How can a teammate remove themselves?[#](#how-can-a-teammate-remove-themselves) A member, admin or viewer can leave a workspace they were invited to without waiting for an admin. On the **Workspaces** page (`/workspaces`), open the **⋯** menu on the row for that workspace and choose **Leave**, then confirm. Leaving revokes your own membership and drops you back into your personal workspace. The one exception: the **owner cannot leave their own workspace** — a workspace you own is removed by deleting it, not by leaving. ## Why can’t I remove or replace the workspace owner?[#](#why-cant-i-remove-or-replace-the-workspace-owner) The **owner** is the account that created the workspace, and APITube treats ownership as fixed. The owner never appears in the member list, so there is no Revoke button or role dropdown for them, and no role change can demote them. There is also no way to transfer ownership to another account. This keeps billing unambiguous: quota, balance and the subscription are **shared and belong to the owner**, so the owner is always the single account responsible for the workspace. To let a teammate run day-to-day team management instead, make them an **Admin**. # Common Questions[#](#common-questions) * [Can a member change roles or remove people?](#can-a-member-change-roles-or-remove-people) * [Does removing someone delete the keys they created?](#does-removing-someone-delete-the-keys-they-created) * [Can I get a removed teammate back?](#can-i-get-a-removed-teammate-back) * [Where can I see who changed a role or removed a member?](#where-can-i-see-who-changed-a-role-or-removed-a-member) ## Can a member change roles or remove people?[#](#can-a-member-change-roles-or-remove-people) No. Changing roles and removing teammates are limited to the **owner and admin**. A member can create and use API keys and webhooks and view usage, but the Team page is hidden from them and returns “not found” if opened directly. If you want a teammate to manage the team as well, give them the **Admin** role. ## Does removing someone delete the keys they created?[#](#does-removing-someone-delete-the-keys-they-created) No. Revoking a teammate ends their access but leaves the workspace’s API keys untouched, because keys are owned by the workspace, not by the person who made them. Those keys stay active and keep drawing on the owner’s shared quota until you revoke each one on the API Keys page. ## Can I get a removed teammate back?[#](#can-i-get-a-removed-teammate-back) Yes, by inviting them again. A revoked membership cannot be re-enabled in place, so you open **Workspaces → Team**, create a new invite for that person, and pick the role you want. Once they accept the new invite, they rejoin the workspace. ## Where can I see who changed a role or removed a member?[#](#where-can-i-see-who-changed-a-role-or-removed-a-member) Every role change and removal is recorded in the workspace **audit log**, which the owner and admins can review. It shows who made the change, what the change was, and when — useful for keeping track of team access over time. See [how to review the workspace audit log](/en/articles/teams-and-workspaces/audit-log). * * * ## Related Articles * [Workspace roles: owner, admin, member, viewer](/en/articles/teams-and-workspaces/workspace-roles) * [How to review the workspace audit log](/en/articles/teams-and-workspaces/audit-log) --- ## How to Rename or Delete a Workspace URL: https://support.apitube.io/en/articles/teams-and-workspaces/rename-or-delete-workspace Rename or delete an APITube workspace from its Settings page. Only the owner can do either; deletion moves the workspace's API keys back to the owner's… # How to Rename or Delete a Workspace Owner-only maintenance from the workspace Settings page — and exactly what happens to keys and members on deletion ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 6, 2026 Updated July 21, 2026 # How to rename or delete a workspace[#](#how-to-rename-or-delete-a-workspace) Both actions live on the [workspace](/en/articles/getting-started/glossary#workspace)’s **Settings** page and both belong to the **owner alone**: open **Workspaces** in the dashboard, find the row of a workspace you own, and choose **Settings** from its **⋯** menu. Renaming is a simple field-and-save; deleting asks you to type the workspace name to confirm and then removes the workspace and its memberships — while the [API keys](/en/articles/getting-started/glossary#api-key) survive by moving back to your personal workspace. ## How to rename a workspace[#](#how-to-rename-a-workspace) On the Settings page, edit the name field and save (the dialog is titled **Rename workspace**). The change is cosmetic — nothing about keys, members, quota or billing is affected, and members simply see the new name in their workspace switcher. Renaming is recorded in the workspace [audit log](/en/articles/teams-and-workspaces/audit-log) as a “Renamed workspace” event, so the team can see who changed it. Admins cannot rename the workspace: even though admins manage keys and members, the workspace object itself — its name and its existence — is reserved for the owner. If you administer a workspace and need it renamed, ask the person who created it. ![The General tab of a workspace's settings with the name field, the workspace ID and its creation date](/images/article/dashboard-workspace-general.png) ## How to delete a workspace[#](#how-to-delete-a-workspace) In the danger section of the same Settings page, press **Delete this workspace**. The confirmation dialog requires you to **type the workspace name exactly** before the destructive button activates — a safeguard against deleting the wrong workspace from a list of similar names. The same checks run on the server, so the confirmation cannot be skipped. ![The Danger zone tab of a workspace's settings with the Delete this workspace action](/images/article/dashboard-workspace-danger.png) Deletion is immediate and cannot be undone. Three things happen at once: 1. **API keys move, they are not destroyed.** Every key that belonged to the workspace is reassigned to your **personal** workspace and keeps working. If some of those keys should die with the workspace, revoke them afterwards on the API Keys page. 2. **Memberships are removed.** Teammates lose access instantly; on their next visit the workspace is gone from their switcher and they fall back to their own personal workspace. 3. **The workspace itself disappears**, freeing one slot of your workspace allowance (you can own up to **10** workspaces at a time). If the deleted workspace happened to be your active one, the dashboard quietly switches you back to **Personal**, so you are never left without a working context. ## Which workspaces cannot be deleted?[#](#which-workspaces-cannot-be-deleted) Your **Personal** workspace is permanent: it is created automatically on first sign-in and is the fallback that always holds your keys, so the Settings page will tell you it can’t be deleted rather than offer the button. Workspaces you are only a **member** of are also off-limits — you can [leave them](/en/articles/teams-and-workspaces/manage-members), but only their owner can delete them. And since ownership of a workspace can never be transferred to someone else, “the owner left the company” is a case for deleting the workspace and recreating it under a new account, not for handing it over. # Common Questions[#](#common-questions) * [Do the moved API keys keep their limits and usage history?](#do-the-moved-api-keys-keep-their-limits-and-usage-history) * [Can an admin delete a workspace?](#can-an-admin-delete-a-workspace) * [Is there any way to restore a deleted workspace?](#is-there-any-way-to-restore-a-deleted-workspace) ## Do the moved API keys keep their limits and usage history?[#](#do-the-moved-api-keys-keep-their-limits-and-usage-history) Yes. Deletion changes only which workspace a key belongs to — the key string, its name, scopes, restrictions and accumulated usage stay as they were, and integrations using the key keep working without interruption. The keys are simply listed under your personal workspace from then on. ## Can an admin delete a workspace?[#](#can-an-admin-delete-a-workspace) No. Admins manage day-to-day contents — API keys, [webhooks](/en/articles/getting-started/glossary#webhook), members — but renaming and deleting the workspace are owner-only, and the server rejects the attempt regardless of what the UI shows. The full permission matrix is in [workspace roles](/en/articles/teams-and-workspaces/workspace-roles). ## Is there any way to restore a deleted workspace?[#](#is-there-any-way-to-restore-a-deleted-workspace) No. There is no trash bin or undo for workspaces — the type-to-confirm dialog is the last stop. What survives is deliberate: the API keys (moved to your personal workspace) keep serving traffic, so deleting a workspace never takes production integrations down by itself. If you deleted by mistake, recreate the workspace and re-invite the team; the keys can then be created fresh in the new workspace. * * * ## Related Articles * [How to Create and Switch Workspaces](/en/articles/teams-and-workspaces/create-switch-workspaces) * [Workspace Roles: Owner, Admin, Member, Viewer](/en/articles/teams-and-workspaces/workspace-roles) * [How to Change a Member's Role or Remove Them](/en/articles/teams-and-workspaces/manage-members) --- ## How Billing and Usage Are Shared in a Workspace URL: https://support.apitube.io/en/articles/teams-and-workspaces/shared-billing The workspace owner holds the plan, quota and pay-as-you-go balance in APITube; every workspace they own shares those pools. Only the owner changes the plan. # How Billing and Usage Are Shared in a Workspace One owner pays and holds the quota; every workspace they own draws from the same shared pools, while API keys stay per-workspace ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis August 11, 2026 Updated July 12, 2026 # How billing and usage are shared in a workspace[#](#how-billing-and-usage-are-shared-in-a-workspace) In an APITube [workspace](/en/articles/getting-started/glossary#workspace), the **plan, quota and balance belong to the workspace owner**, and every workspace that owner creates draws from the same shared pools. [API keys](/en/articles/getting-started/glossary#api-key) are the only thing kept separate per workspace. So if the owner is on a plan with 150,000 requests, all of the owner’s workspaces and teammates share that one 150,000-request pool — usage anywhere counts against it. Only the owner can change the plan, top up, or see invoices. This split lets a team spread work across several workspaces without paying several times: one subscription funds them all. ## What is shared across the whole account?[#](#what-is-shared-across-the-whole-account) These belong to the **owner** and are shared by every workspace the owner runs and every teammate in them: * **The subscription plan** — Free, Starter, Basic, Professional or Corporate. * **The monthly request quota** — the plan’s request allowance (its _points_): 100 per day on Free, 10,000 on Starter, 50,000 on Basic, 150,000 on Professional, 300,000 on Corporate. * **The [SSE](/en/articles/getting-started/glossary#sse-stream) streaming quota** — a separate streaming pool (1,000 Free / 3,000 Starter / 5,000 Basic / 15,000 Professional / 40,000 Corporate). * **The [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance** — the money that covers overflow at **$0.01 per request** once the plan pool is empty. * **The [webhook](/en/articles/getting-started/glossary#webhook) limit** — how many webhooks the account may run (1 Free / 5 Starter / 5 Basic / 20 Professional / 100 Corporate), counted across all of the owner’s workspaces. Because these are account-level, a request sent with a key from _any_ of the owner’s workspaces draws from the same quota. Splitting into more workspaces organises keys and people — it does **not** give you more quota. ## What is kept separate per workspace?[#](#what-is-kept-separate-per-workspace) **API keys are scoped to a single workspace.** Each workspace has its own set of keys, and a key you create in one workspace is not visible in another. This is how a team isolates a project or client: give each its own keys, revoke them independently, and read each workspace’s own request logs — while the spend still lands on the one shared quota. Your personal dashboard settings — language, theme, avatar and date formatting — belong to **you** (the logged-in user), not to the workspace, so they follow you as you switch between workspaces. ## Who can manage billing and see invoices?[#](#who-can-manage-billing-and-see-invoices) **Only the owner.** Billing is the one area admins do not control. The four workspace roles line up like this: * **Owner** — changes the plan, tops up the balance, cancels, and sees billing history. * **Admin** — manages members, keys and webhooks, but **cannot** touch billing. * **Member** — creates and uses keys, and sees usage; no billing, no member management. * **Viewer** — read-only. When a non-owner opens the **Subscription** page, they see the current plan but a note that it is **managed by the owner** — no upgrade, cancel or top-up buttons, and no billing history. Finances are never shown to teammates. For the full permission grid, see [workspace roles: owner, admin, member, viewer](/en/articles/teams-and-workspaces/workspace-roles). Billing actions (change plan, manage, cancel, top up) open the APITube billing pages, which run on **LemonSqueezy**. They work off the owner's own login, which is exactly why only the owner sees them — a teammate clicking them would land on their own account, not the owner's. ## How is usage counted and shown?[#](#how-is-usage-counted-and-shown) Every billed call spends one request from the shared pool, no matter which workspace or which key it came from. The dashboard **overview** shows the owner’s remaining request quota and SSE quota for the account as a whole, plus the plan and when the quota resets (Free resets daily; a paid plan resets on its renewal date). Request **logs**, on the other hand, are shown **per workspace**: the overview and the Logs page filter the owner’s usage history down to the keys in the workspace you are currently viewing. That way each workspace sees its own traffic, even though the quota being consumed is the single shared account pool. To understand what one request costs and how the separate request, SSE and pay-as-you-go pools work, read [how requests and credits work](/en/articles/billing/credits/how-credits-work). ![The Usage by workspace block on the Workspaces page breaking the shared account quota down per workspace](/images/article/dashboard-workspaces.png) # Common Questions[#](#common-questions) * [Do more workspaces give me more quota?](#do-more-workspaces-give-me-more-quota) * [Can a teammate upgrade the plan or top up?](#can-a-teammate-upgrade-the-plan-or-top-up) * [Whose quota do my API keys spend?](#whose-quota-do-my-api-keys-spend) * [Can I see how much each workspace is spending?](#can-i-see-how-much-each-workspace-is-spending) ## Do more workspaces give me more quota?[#](#do-more-workspaces-give-me-more-quota) No. Quota is tied to the owner’s plan, not to the number of workspaces. Creating a second or third workspace organises keys and teammates separately, but every one of them draws from the same request and streaming pools. To raise your limits you change the plan or add pay-as-you-go — not add workspaces. ## Can a teammate upgrade the plan or top up?[#](#can-a-teammate-upgrade-the-plan-or-top-up) No. Only the workspace owner can change the plan, top up the balance or cancel. Admins manage members and keys but have no billing access, and members and viewers have none either. A non-owner sees the current plan marked as _managed by the owner_ with no billing controls. If you need to change the plan, ask the owner or become the owner of your own workspace. ## Whose quota do my API keys spend?[#](#whose-quota-do-my-api-keys-spend) The owner’s. A key lives in a specific workspace, but the request it sends is charged to the owner’s shared quota pool. This is true for every key in every workspace the owner runs, so a member using a key in a team workspace spends the same pool as the owner’s Personal workspace. ## Can I see how much each workspace is spending?[#](#can-i-see-how-much-each-workspace-is-spending) Yes, per workspace. The Logs page shows the request history filtered to the current workspace’s keys, so you can compare traffic across the workspaces you belong to. The headline quota figure, though, is the shared account total — it does not split into a separate allowance per workspace, because there is only one pool. * * * ## Related Articles * [What are workspaces and when to use them](/en/articles/teams-and-workspaces/what-are-workspaces) * [Workspace roles: owner, admin, member, viewer](/en/articles/teams-and-workspaces/workspace-roles) * [How do requests and credits work?](/en/articles/billing/credits/how-credits-work) --- ## What Are Workspaces and When to Use Them URL: https://support.apitube.io/en/articles/teams-and-workspaces/what-are-workspaces A workspace is a separate space in APITube with its own API keys and members. Everyone gets a Personal workspace; billing and quota stay shared across all of… # What Are Workspaces and When to Use Them How APITube workspaces separate API keys and teammates while one owner keeps a single shared bill ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 2, 2026 Updated July 21, 2026 # What are workspaces and when to use them[#](#what-are-workspaces-and-when-to-use-them) A **[workspace](/en/articles/getting-started/glossary#workspace)** in APITube is a separate space that holds its own set of [API keys](/en/articles/getting-started/glossary#api-key) and its own list of teammates. Every account starts with one **Personal** workspace, and you can create more from the workspace switcher — one per project, client or team — while everything you build stays under a single account. The key rule to understand up front: **API keys and members are scoped to each workspace, but billing, quota and balance belong to the owner and are shared across all of that owner’s workspaces.** A new workspace organizes access; it does not create a separate bill. ## What is a workspace in APITube?[#](#what-is-a-workspace-in-apitube) A workspace is the container your API keys and teammates live in. When you sign in for the first time, APITube creates a **Personal** workspace for you automatically (it is your default workspace), so you always have somewhere to make keys without any setup. From there you can add more workspaces — for example a “Client A” workspace and a “Internal tools” workspace — and each one keeps its own keys and its own member list, fully separate from the others. Because keys are scoped to a workspace, a key you create in one workspace is not visible in another. Switching workspaces changes which keys you see and manage, which makes workspaces a clean way to keep unrelated projects from mixing. ![The Workspaces page listing a Personal and a team workspace with roles, key counts and usage by workspace](/images/article/dashboard-workspaces.png) ## What is scoped to a workspace, and what is shared?[#](#what-is-scoped-to-a-workspace-and-what-is-shared) This is the most important distinction, because it decides what a new workspace does and does not change: * **Scoped to each workspace:** your **API keys** and your **members** (the teammates and their roles). Each workspace has its own. * **Shared across all of the owner’s workspaces:** **billing, plan, quota, balance, subscription and notifications.** These belong to the owner’s account, so every workspace the owner has draws from the same request quota and the same wallet. * **Per-teammate:** personal settings such as language, theme and profile follow the individual signed-in person, not the workspace. In practice this means any key a teammate creates in any of your workspaces spends **your** quota, and there is no separate invoice per workspace. Usage logs are still shown per workspace — filtered to the keys in the workspace you are viewing — so you can see how much each workspace is spending even though the quota pool is one. Creating a second workspace does **not** give you a second free quota or a separate bill. Quota, balance and billing are the owner's and are shared across every workspace they own. Use workspaces to organize keys and access, not to split billing. ## How do I create and switch workspaces?[#](#how-do-i-create-and-switch-workspaces) Use the **workspace switcher** in the dashboard. It lists the workspaces you own plus any workspaces owned by other people where you are an active member, and it has a **Create workspace** option to add a new one. Selecting a workspace switches your active context, and APITube remembers your choice — the next time you sign in you land in the same workspace. If a workspace you had selected is later deleted, or your membership in someone else’s workspace is removed, APITube quietly falls back to your Personal workspace, so you are never left without a valid context. Note that only the **owner or admin** of a workspace can invite people into it — see [how to invite team members](/en/articles/teams-and-workspaces/invite-members) for that flow. ## When should I use more than one workspace?[#](#when-should-i-use-more-than-one-workspace) Create a separate workspace when you want to isolate **keys and people** without splitting your account. Common cases: * **Per client or per project** — keep each client’s keys and (optionally) their team apart, while you keep one bill. * **Separate a team from your solo keys** — invite teammates into a shared workspace and keep your personal experiments in your Personal workspace. * **Join someone else’s team** — accept an invite to work inside another owner’s workspace as an admin, member or viewer; there the _owner_ pays, not you. If instead you only need to control what different people can do, you may not need a new workspace at all — assign [workspace roles](/en/articles/teams-and-workspaces/workspace-roles) within one workspace. And if you later delete a workspace you own, its keys are moved back into your Personal workspace so nothing is lost. # Common Questions[#](#common-questions) * [Does each workspace get its own quota or bill?](#does-each-workspace-get-its-own-quota-or-bill) * [Do I have to create a workspace to use the API?](#do-i-have-to-create-a-workspace-to-use-the-api) * [What happens to my keys if I delete a workspace?](#what-happens-to-my-keys-if-i-delete-a-workspace) ## Does each workspace get its own quota or bill?[#](#does-each-workspace-get-its-own-quota-or-bill) No. Quota, balance, plan and billing belong to the owner’s account and are shared across every workspace that owner has. A key created in any of your workspaces spends the same quota, and you receive one bill regardless of how many workspaces you run. Workspaces separate **keys and members**, not money — though usage logs are shown per workspace so you can still see each one’s spend. ## Do I have to create a workspace to use the API?[#](#do-i-have-to-create-a-workspace-to-use-the-api) No. APITube gives every account a **Personal** workspace automatically the first time you sign in, and you can create and use API keys there right away. You only add more workspaces when you want to keep separate sets of keys or teammates — for a client, a project or a team. ## What happens to my keys if I delete a workspace?[#](#what-happens-to-my-keys-if-i-delete-a-workspace) When you delete a workspace you own, its API keys are moved back into your **Personal** workspace rather than destroyed, and the workspace’s memberships are removed. You cannot delete your Personal workspace, since it is the default that always holds your keys. * * * ## Related Articles * [Workspace roles: owner, admin, member, viewer](/en/articles/teams-and-workspaces/workspace-roles) * [How to invite team members to a workspace](/en/articles/teams-and-workspaces/invite-members) * [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) --- ## Workspace Roles: Owner, Admin, Member, Viewer URL: https://support.apitube.io/en/articles/teams-and-workspaces/workspace-roles APITube workspaces have four roles: owner does everything, admin manages members and keys, member creates and uses keys, viewer is read-only. Here is the exact… # Workspace Roles: Owner, Admin, Member, Viewer What each APITube workspace role can and cannot do — access to keys, webhooks, members, billing and the audit log ![Brian Hollis](/images/authors/brian-hollis-apitube-io-128.jpg) Written by Brian Hollis July 2, 2026 Updated July 21, 2026 # Workspace roles: owner, admin, member and viewer[#](#workspace-roles-owner-admin-member-and-viewer) An APITube [workspace](/en/articles/getting-started/glossary#workspace) has four roles, each a fixed set of permissions checked on every action: **owner** can do everything, **admin** manages members and [API keys](/en/articles/getting-started/glossary#api-key), **member** creates and uses keys, and **viewer** has read-only access. Billing, plan changes and account settings stay with the owner no matter how many admins a workspace has. Every teammate you invite gets one of the three invitable roles — admin, member or viewer — because the owner role is never handed out. ## What are the four workspace roles?[#](#what-are-the-four-workspace-roles) Each role is a distinct level of access, from full control down to look-but-don’t-touch: * **Owner** — the account that created the workspace. The owner is implicit (there is no member row for them) and can do everything, including billing, plan changes and account settings that no other role can touch. * **Admin** — manages the team and the workspace’s API keys and [webhooks](/en/articles/getting-started/glossary#webhook), and can read the audit log. An admin cannot change billing, the plan, or the owner’s account settings. * **Member** — a working teammate: creates and uses API keys, sets up webhooks, and views usage and logs. A member cannot invite, remove or re-role other people. * **Viewer** — read-only. A viewer can see the workspace’s data but cannot create keys, change anything, or manage members. ## What can each role do?[#](#what-can-each-role-do) Permissions are grouped by area. This is the full list of what admin, member and viewer are allowed to do (owner is allowed all of it): * **API keys** — create, revoke, regenerate, rename, and set restrictions, expiry and endpoint [scopes](/en/articles/account-and-dashboard/keys/key-scopes). Allowed for **member and admin**, not viewer. * **Webhooks** — create, update (including re-sending a delivery) and delete. Allowed for **member and admin**, not viewer. See [what webhooks are and how they work](/en/articles/delivery-and-export/webhooks/what-are-webhooks). * **Members** — invite people, change a teammate’s role, and remove a teammate. Allowed for **admin only** (and owner). * **Audit log** — view the workspace’s action history. Allowed for **admin only** (and owner). * **Billing, plan and account settings** — **owner only.** No admin, member or viewer can start a checkout, change the plan, or edit the owner’s account. So a viewer has no write actions at all, a member is limited to keys and webhooks, and an admin adds team management and the audit log on top. ![A workspace member list showing an Owner, a pending Viewer invite, and Member and Admin roles selectable per row](/images/article/dashboard-team-members.png) ## Who can invite people and change roles?[#](#who-can-invite-people-and-change-roles) Only the **owner and admin** can open the team page (in the dashboard under **Workspaces → members**), invite people, and change roles. Members and viewers do not see that page at all. When you invite or re-role someone, the role you pick is **admin, member or viewer** — those are the only three options, so you can promote a teammate up to admin but never to owner. Inviting a teammate creates a pending invite and gives you an `/invite/<token>` link to share; you do not have to enter an email address for the link to work. Removing a teammate is a soft revoke, so their access is cut immediately. ## Can I transfer ownership of a workspace?[#](#can-i-transfer-ownership-of-a-workspace) No. There is no “transfer ownership” action in APITube. The owner is fixed to the account that created the workspace, and the only roles you can assign are admin, member and viewer — none of which is owner. For the same reason, an owner cannot _leave_ their own workspace: leaving is for teammates in someone else’s workspace, and an owner who wants to shut a workspace down deletes it instead. If you need someone else to run the team day to day, make them an **admin** — that grants full member and key management without touching billing or the owner’s account. ## How do roles work across multiple workspaces?[#](#how-do-roles-work-across-multiple-workspaces) Roles are scoped to a single workspace. You can own several workspaces and also be an admin, member or viewer in workspaces owned by other people, and your permissions are decided per workspace. An admin in one workspace has no power in another — role checks always run against the current workspace, so admins only manage the members and keys of the workspace they are actually in. # Common Questions[#](#common-questions) * [Can a member see billing or change the plan?](#can-a-member-see-billing-or-change-the-plan) * [Can a viewer create an API key?](#can-a-viewer-create-an-api-key) * [Can an admin remove or replace the owner?](#can-an-admin-remove-or-replace-the-owner) * [Who can see the workspace audit log?](#who-can-see-the-workspace-audit-log) ## Can a member see billing or change the plan?[#](#can-a-member-see-billing-or-change-the-plan) No. Billing, plan changes and account settings are **owner-only**. A member can create and use API keys and set up webhooks, and can view usage and logs, but the checkout, subscription and account screens belong to the owner. Admins are in the same position here — team management does not include billing. ## Can a viewer create an API key?[#](#can-a-viewer-create-an-api-key) No. A viewer is read-only: they can look at the workspace’s data but cannot create, revoke or rename keys, cannot manage webhooks, and cannot invite or remove people. To let someone create and use keys, give them the **member** role. To manage keys, see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys). ## Can an admin remove or replace the owner?[#](#can-an-admin-remove-or-replace-the-owner) No. An admin can invite, re-role and remove other admins, members and viewers, but the owner is not a member row and cannot be removed or demoted. There is also no way to promote anyone to owner, because the assignable roles are admin, member and viewer only. ## Who can see the workspace audit log?[#](#who-can-see-the-workspace-audit-log) The audit log — the record of key, webhook and member actions in a workspace — is visible to the **owner and admins**. Members and viewers do not have access to it. This keeps the workspace’s action history in the hands of the people who can manage the team. * * * ## Related Articles * [How to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) * [What are webhooks and how do they work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) * [How to limit a key to specific endpoints (scopes)](/en/articles/account-and-dashboard/keys/key-scopes) --- ## How to Debug Your API Requests URL: https://support.apitube.io/en/articles/troubleshooting/debug-requests Debug APITube News API requests step by step: read the status and error envelope, check x- response headers, replay calls in the Playground, inspect request… # How to Debug Your API Requests A step-by-step way to find why an APITube request fails: status, headers, Playground and logs ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 28, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en&per_page=5) # How to debug your API requests[#](#how-to-debug-your-api-requests) When an APITube News API request fails or returns something unexpected, debug it in four moves: read the **HTTP status** and the `ERxxxx` code in the error envelope, check the `x-` **response headers** for your account state, **reproduce** the call in the dashboard **API [Playground](/en/articles/getting-started/glossary#playground)**, and **inspect** the exact request in your **API Logs**. Most problems are visible at one of these steps without contacting support. The key idea is to separate the three things that can be wrong: your request (a bad parameter), your key (auth, mode, restrictions), or your account state (out of credits, rate-limited). Each step below points at one of them. ## Start with the HTTP status and error code[#](#start-with-the-http-status-and-error-code) Every failed REST request returns the same JSON envelope: a top-level `status` of `not_ok`, a `request_id`, and an `errors` array. Read `errors[0].code` (an `ERxxxx` value) together with `errors[0].message`, and branch your handling on the **HTTP status first**. For a `400`, the `message` names the exact parameter at fault — for example `"is_paywall must be 0 or 1."` — which is usually the whole fix. The full map of statuses and codes is in [understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes). A quick way to see both at once with cURL is to print the status line and body: ``` curl -i -H "X-API-Key: api_live_YOUR_KEY" \ "https://api.apitube.io/v1/news/everything?language.code=en&per_page=5" ``` ## Read the response headers[#](#read-the-response-headers) Even a successful response carries headers that explain your account state, so add `-i` (or `-D -`) to your cURL call to see them. The ones worth reading when debugging: * **`X-Request-ID`** — a unique id for the call, identical to `request_id` in the error body. Quote it when you contact support so the exact request can be traced. * **`x-apitube-mode`** — `test` or `live`. This instantly confirms whether the key you sent is a [Test key](/en/articles/getting-started/glossary#test-key-and-live-key), which is the cause of many “the data looks wrong” reports. * **`x-points-remaining`** and **`x-balance-remaining`** — plan credits and [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) cents left, so you can see a `402` coming before it happens. * **`x-subscription-plan`** — the plan the key resolves to, and **`x-budget-remaining`** when you have set a monthly pay-as-you-go limit. ## Reproduce the call in the API Playground[#](#reproduce-the-call-in-the-api-playground) The dashboard **API Playground** runs a real request for you: you pick one of your keys, fill in the endpoint and parameters, and it sends the call and shows the same JSON response your own code would get. Because it uses a real key, your quota, endpoint scopes and key restrictions apply exactly as they do in production — nothing is bypassed. This isolates the bug. If the Playground returns what you expect but your own code does not, the difference is in how your code builds the request — usually the authentication header, the key mode, or a mistyped parameter — not in the API. ## Inspect the request in your API Logs[#](#inspect-the-request-in-your-api-logs) The dashboard **API Logs** page records every call your keys make, including failed and empty ones. Each row shows the **Time**, **Type**, **Status**, **Latency**, **[API key](/en/articles/getting-started/glossary#api-key)**, **Cost** and **Endpoint**, and opening a row reveals the **query parameters** that were sent and the calling **IP address**. Filter **Status** to **Errors**, then narrow by key and date to find the failing call quickly. Because the log captures the parameters and status the server actually saw, it is the source of truth for “what did my code really send?” — far more reliable than re-reading your own code. ![The API logs page with per-request rows and error-rate and latency stats used to find a failing call](/images/article/dashboard-logs.png) ## Common gotchas to check first[#](#common-gotchas-to-check-first) Before deep debugging, rule out the frequent causes: * **Placeholder or masked text in the body** → you are using a **Test** key, which truncates article content. See [why results are masked or placeholder text](/en/articles/troubleshooting/masked-results). * **`401`** → the key is missing, invalid or expired. See [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors). * **`403`** → the key is blocked by an IP allow-list or endpoint scope. See [why a request is blocked by IP or scope](/en/articles/troubleshooting/ip-scope-blocked). * **`429`** → you passed your per-minute [rate limit](/en/articles/getting-started/glossary#rate-limit); wait and retry. See [how to fix rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). * **An empty result set with HTTP `200`** → this is not an error; your filters are too narrow. See [why a search returns no results](/en/articles/troubleshooting/no-results). # Common Questions[#](#common-questions) * [Why does the same request work in the Playground but not in my code?](#why-does-the-same-request-work-in-the-playground-but-not-in-my-code) * [How do I send enough detail for support?](#how-do-i-send-enough-detail-for-support) * [Can I see the exact request my code sent?](#can-i-see-the-exact-request-my-code-sent) ## Why does the same request work in the Playground but not in my code?[#](#why-does-the-same-request-work-in-the-playground-but-not-in-my-code) When the **API Playground** succeeds but your own request fails, the request itself is fine, so check how your client builds it. Confirm you send the key as the `X-API-Key` header (or the `api_key` query parameter), that it is a **Live** key if you expect full content — read the `x-apitube-mode` header to be sure — and that every parameter name matches exactly. URL-encoding of values like dates and quoted phrases is a common culprit. ## How do I send enough detail for support?[#](#how-do-i-send-enough-detail-for-support) Include the `request_id` (also returned as the **`X-Request-ID`** header), the full error envelope, the endpoint and HTTP method you called, and the timestamp. The `request_id` lets support trace the exact call, which resolves issues far faster than describing the symptom. ## Can I see the exact request my code sent?[#](#can-i-see-the-exact-request-my-code-sent) Yes. Open the failing call in the dashboard **API Logs** and expand it: the detail panel shows the **query parameters** the server received and the **endpoint**, alongside the status, latency and IP. Comparing that to what you intended to send usually reveals a missing or mistyped parameter immediately. * * * ## Related Articles * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [Why Is My Search Returning No Results?](/en/articles/troubleshooting/no-results) * [Why Are My Results Masked or Placeholder Text?](/en/articles/troubleshooting/masked-results) --- ## Understanding API Error Codes and HTTP Responses URL: https://support.apitube.io/en/articles/troubleshooting/error-codes Read APITube News API errors: every failure returns a JSON envelope with an HTTP status, an ERxxxx code and a message. Learn the 400, 401, 402, 403 and 429… # Understanding API Error Codes and HTTP Responses How to read the APITube error envelope and what each HTTP status and ERxxxx code means ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated August 16, 2026 # Understanding API error codes and HTTP responses[#](#understanding-api-error-codes-and-http-responses) When a request to the APITube News API fails, the response carries two things you need to read together: an **HTTP status code** (the family of problem) and an **ERxxxx error code** plus a human-readable `message` (the exact cause). Every error uses the same JSON envelope, so one parser handles them all: ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 401, "code": "ER0202", "message": "Invalid API key.", "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }, "timestamp": "…" } ] } ``` The top-level `status` is `ok` or `not_ok`, `request_id` identifies the call for support, and `errors` is an array — read `errors[0].code` and `errors[0].message` first. The `links.about` field points to the official reference. ## What do the HTTP status codes mean?[#](#what-do-the-http-status-codes-mean) The HTTP status tells you the category of failure before you even look at the code. APITube uses conventional families: `2xx` success, `4xx` a problem with your request, `5xx` a problem on the server. * **200** — success. * **400** — the request is malformed or a parameter value is invalid. * **401** — the [API key](/en/articles/getting-started/glossary#api-key) is missing, invalid, or expired (authentication). * **402** — the account has no points or credits left to serve the request. * **403** — the key is recognized but not allowed for this request (authorization). * **429** — you exceeded your per-minute [rate limit](/en/articles/getting-started/glossary#rate-limit). * **500** — an unexpected server error; usually transient, so retry shortly. ## Which error codes are most common?[#](#which-error-codes-are-most-common) The `code` field pinpoints the cause within its HTTP status. Read it alongside the `message`, which names the exact parameter or reason. The codes you are most likely to see: * **400 — parameter validation.** A specific filter value is out of range or the wrong type. The `message` names the parameter, for example `"language.code must be between 1 and 2 characters."` or `"is_paywall must be 0 or 1."` Fix the value the message points to — the patterns are broken down in [how to fix 400 Bad Request errors](/en/articles/troubleshooting/fix-400-errors). * **401 — `ER0201`** (no key was sent), **`ER0202`** (key is invalid or was revoked), **`ER0230`** (key has expired). See [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors). * **402 — `ER0176`** (`"You have no points on your account."`) and **`ER0177`** (`"Monthly pay-as-you-go spending limit reached."`). Top up or wait for your plan credits to renew. * **403 — `ER0601`** (your IP is not on the key’s allow-list), **`ER0602`** (the request domain is not allowed), **`ER0603`** (the key’s scopes do not include this endpoint), **`ER0706`** (the plan does not include the feature you called — Fact Check on Free, or the `prompt` parameter on Free and Starter). * **429 — `ER0203`** (rate limit exceeded — 50 requests/minute on paid plans, 10 on the free plan, 15 on [test keys](/en/articles/getting-started/glossary#test-key-and-live-key), 10 on fact-check) and **`ER0204`** (a temporary ban after repeated violations). See [how to fix rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). * **500 — `ER0183`** (`"Something went wrong."`). Retry; if it persists, contact support with the `request_id`. * **502 — `ER0801`** (`"Prompt understanding service is temporarily unavailable."`). Only reaches you on a request that used the `prompt` parameter; see the next section. ## What are the 502 and prompt-specific errors?[#](#what-are-the-502-and-prompt-specific-errors) The `prompt` parameter has its own block of codes, returned while your sentence is being translated into filters — before the search itself runs. It is also the only place a `502` appears. * **`ER0706`** (HTTP 403) — `prompt` is not included in your plan. It requires Basic or above; Free and Starter keys are refused before the translation runs and are not charged. * **`ER0800`** (HTTP 400) — the prompt is shorter than 3 or longer than 500 characters. * **`ER0801`** (HTTP 502) — the translation service was unavailable. Nothing is charged, so retry. This is the one `5xx` you can safely retry immediately. * **`ER0802`** (HTTP 400) — nothing usable came out of the prompt: either no filter was found in the sentence, or everything it produced was overridden by parameters you sent explicitly, or unsupported on that endpoint. `ER0706` carries three different meanings depending on the request: `403` on `/v1/fact-check` means Fact Check is not on the Free plan, `403` on a request that sent `prompt` means the plan is below Basic, and `400` on a request that sent the boolean `query` parameter means a range was used on a field that has no range support. Branch on the HTTP status and the message, never on the code by itself. Your plan and your quota are both checked **before** the translation runs, so an exhausted account gets the usual `402 ER0176` instead of `ER0801`, and is not billed for a translation it never received. On the [WebSocket](/en/articles/getting-started/glossary#websocket) stream these arrive as an error frame followed by close code `4001`. Details in [how to search news in plain English](/en/articles/searching-and-filtering/keyword-search/natural-language-search). ## How can I see my remaining quota before a 402?[#](#how-can-i-see-my-remaining-quota-before-a-402) Every successful response includes headers that report your account state, so you can back off before you ever hit a `402`. Read `x-points-remaining` (plan credits left), `x-balance-remaining` ([pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) cents), `x-subscription-plan`, and `x-apitube-mode` (`test` or `live`). If you set a monthly pay-as-you-go limit, `x-budget-remaining` shows how much of it is left. Every response also returns `X-Request-ID`, the same value as `request_id` in the error body — quote it when you contact support so the exact call can be traced. ## Can a successful response still carry an error code?[#](#can-a-successful-response-still-carry-an-error-code) Yes — APITube also returns **warnings**, which use the same `ERxxxx` scheme but arrive with HTTP `200` in a `meta.warnings` array next to your results. A warning means the request succeeded but was adjusted, so read it if the result set looks smaller than expected. The one warning in use today is **`ER0366`**: a headline search (`title`, `title_starts_with`, `title_ends_with`, `title_pattern` or `query`) arrived without `published_at.start` and `published_at.end`, so the API searched the **last 31 days** by default. The same fact is repeated in the `x-query-window-clamped: 31` response header, which is how [export formats](/en/articles/getting-started/glossary#export-format) such as CSV and XLSX surface it — they have no JSON body to carry `meta`. ``` { "status": "ok", "results": [], "meta": { "warnings": [{ "code": "ER0366", "message": "published_at window defaulted to the last 31 days for title search. …" }] } } ``` Its error counterpart is **`ER0110`** (HTTP 400): the same headline search with an explicit `published_at` range **wider** than 31 days. Both are covered in [how to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title). ## How are streaming errors different?[#](#how-are-streaming-errors-different) Real-time connections do not return an HTTP error body once the stream is open — they deliver errors **in-band**. An [SSE stream](/en/articles/delivery-and-export/streaming/stream-with-sse) sends an `error` event with a `code` and `message`, and a [WebSocket](/en/articles/delivery-and-export/streaming/stream-with-websocket) sends an `{"type":"error","code":...,"message":...}` message followed by a WebSocket close code. The codes still follow the same ERxxxx scheme, so your error handling logic can be shared between REST and streaming. # Common Questions[#](#common-questions) * [Is each error code globally unique?](#is-each-error-code-globally-unique) * [Does a 4xx error mean I should retry?](#does-a-4xx-error-mean-i-should-retry) * [How do I report an error to support?](#how-do-i-report-an-error-to-support) ## Is each error code globally unique?[#](#is-each-error-code-globally-unique) Treat the `code` as meaningful **within the HTTP status it arrives with**, not as a global key, and always read it together with the `message`. The `message` is the authoritative, human-readable explanation — for `400` errors it names the exact parameter at fault, which is the fastest path to a fix. Branch your code on the HTTP status first, then on `code` and `message` for the precise cause. ## Does a 4xx error mean I should retry?[#](#does-a-4xx-error-mean-i-should-retry) Not blindly. A `4xx` is a problem with the request, so retrying the same call unchanged returns the same error — fix the cause first (correct the parameter for `400`, the key for `401`, the restriction for `403`). The exceptions are `402` (retry after topping up or when credits renew) and `429`, which you should retry after waiting the period the message reports. A `500` is server-side and safe to retry after a short delay. ## How do I report an error to support?[#](#how-do-i-report-an-error-to-support) Include the `request_id` (also returned as the `X-Request-ID` header), the full error envelope, the endpoint and HTTP method you called, and the timestamp. The `request_id` lets support trace the exact request, which is far faster than describing the symptom. For authentication and rate-limit issues, the dedicated guides above resolve most cases without contacting support at all. * * * ## Related Articles * [How to Fix Authentication (401) Errors](/en/articles/troubleshooting/fix-auth-errors) * [How to Fix Rate-Limit (429) Errors](/en/articles/troubleshooting/rate-limit-errors) * [How to Check Your Balance via the API](/en/articles/retrieval/check-balance-api) --- ## How to Fix 400 Bad Request Errors URL: https://support.apitube.io/en/articles/troubleshooting/fix-400-errors Fix APITube News API 400 errors: the message names the parameter at fault — a value out of range, a wrong type, per_page over your plan ceiling, or an unknown… # How to Fix 400 Bad Request Errors What the ERxxxx validation codes mean, why a lookup filter can return 400, and how to correct the parameter the message names ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn August 22, 2026 Updated July 29, 2026 # How to fix 400 Bad Request errors[#](#how-to-fix-400-bad-request-errors) A **400 Bad Request** from the APITube News API means one specific parameter in your request failed validation, and the error message names it. Read `errors[0].message` in the response body — it tells you which parameter to fix and what the accepted values are, so the fastest fix is always to correct exactly what the message says, not to guess. The envelope looks like this: ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 400, "code": "ER0171", "message": "Limit is out of range. Your plan allows up to 250 results per page." } ] } ``` ## What are the most common 400 validation errors?[#](#what-are-the-most-common-400-validation-errors) Validation messages follow a few repeating patterns, each pointing at a different kind of mistake: * **`Invalid <parameter> value.`** — the value has the wrong type or format for that filter, for example a word where a number is expected. * **`<parameter> must be 0 or 1.`** — boolean-style flags such as `is_duplicate` or `is_paywall` accept only the literal digits `0` and `1`, not `true`/`false`. * **`<parameter> must be between 1 and N characters.`** — a length bound. For example `title` accepts 1 to 100 characters and `language.code` accepts 1 to 2 characters. * **`<parameter> must be greater than or equal to 0.`** — numeric filters such as `media.images.count.min` reject negative numbers. ## Why do pagination parameters return 400?[#](#why-do-pagination-parameters-return-400) [Pagination](/en/articles/getting-started/glossary#pagination) has its own set of codes: * **ER0170** — `'Per page' is not a number.` `per_page` must be an integer. * **ER0171** — `Limit is out of range. Your plan allows up to N results per page.` `per_page` is capped at **250** on Basic and up, **50** on **Starter** and **10** on **Free** (the default is 100, clamped down to the plan ceiling). Request no more than your plan allows. * **ER0172** — `Page is not a number.` `page` must be an integer. * **ER0173** — the free plan is limited to the **first 5 pages**. Deep pagination needs a paid plan; until then, narrow the query with filters instead of paging past results. ## Why does a name filter return 400 instead of empty results?[#](#why-does-a-name-filter-return-400-instead-of-empty-results) Lookup filters resolve a name against APITube’s [entity](/en/articles/getting-started/glossary#entity) index **before** the search runs. If the name is unknown, the API rejects the request with a 400 rather than silently returning zero articles: * **ER0204** — `author with name '…' not found.` * **ER0214** — `source domain name '…' not found.` * **ER0216** — `entity person name '…' not found.` (the `person.name` filter) * **ER0220** — `entity organization name '…' not found.` (the `organization.name` filter) This is deliberate: a typo like `organization.name=Aple` fails loudly instead of looking like “no news about Apple today”. Entity filters match the tracked entity name **exactly**, so a plausible-looking value can still fail — `Nike` and `Disney` are not in the directory, while `Coca-Cola` and `The Walt Disney Company` are. The reliable fix is to resolve the spelling first: call `/v1/suggest/entities?prefix=disney` and use the `name` it returns, checking that `type` matches the filter you need. You can also search the text with `title` instead of an entity filter. If the request is accepted but still returns nothing, that is a different problem — see [why does my query return no results](/en/articles/troubleshooting/no-results). Suggest endpoints add one more: **ER0346** — `` `Prefix` in query required. `` — the autocomplete endpoints need a non-empty prefix to complete. ## Why does a headline search with old dates return 400?[#](#why-does-a-headline-search-with-old-dates-return-400) **ER0110** — `Date range exceeds the maximum of 31 days for title search.` A search that matches on article headlines may cover at most 31 days of publish dates per request. It fires in two situations: * `published_at.start` and `published_at.end` are more than 31 days apart, for example a whole quarter. * `published_at.start` is older than 31 days and there is **no** `published_at.end`, so the window silently runs all the way to now. This is the case people hit most often, because the request looks narrow. The message reports both the limit and the width of the range you asked for, so the gap is visible at a glance. The rule covers `title`, `title_starts_with`, `title_ends_with`, `title_pattern` and the Boolean `query`, on every plan and every endpoint. Fix it by adding an end date inside the same month, or by selecting the articles without a headline filter — `category.id`, `entity.id` and `source.domain` carry no range limit. To cover a longer period, loop over month-sized windows; the pattern is in [how to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title). Dropping the dates entirely is not an error: the request then runs against the last 31 days and returns HTTP 200 with an `ER0366` warning in `meta.warnings`. ## How should my code handle a 400?[#](#how-should-my-code-handle-a-400) Do not retry a 400 unchanged — the same request produces the same error. Branch on the HTTP status, log `code` and `message`, and surface the message to whoever built the query, since it already contains the fix. The full envelope format and the other status codes (401, 402, 403, 429) are covered in [understanding API error codes](/en/articles/troubleshooting/error-codes). # Common Questions[#](#common-questions) ## Does a 400 consume quota?[#](#does-a-400-consume-quota) No. Validation happens before the search executes, so a rejected request does not draw down your plan credits. ## Can one request produce several 400 errors?[#](#can-one-request-produce-several-400-errors) `errors` is an array, but validation stops at the first failing parameter group in most cases — fix what is reported, re-send, and repeat if another parameter is also wrong. Fixing parameters one message at a time converges in a couple of attempts. ## The message names a parameter I did not send — why?[#](#the-message-names-a-parameter-i-did-not-send--why) Check for a typo in a parameter _name_. An unrecognised name can make its value land in the wrong place, and the validator then reports the canonical parameter. Compare your request against the [parameter reference](https://docs.apitube.io/platform/news-api/everything) and the walkthrough in [how to debug failed API requests](/en/articles/troubleshooting/debug-requests). * * * ## Related Articles * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [Why does my query return no results?](/en/articles/troubleshooting/no-results) * [How to debug failed API requests](/en/articles/troubleshooting/debug-requests) --- ## How to fix authentication (401) errors URL: https://support.apitube.io/en/articles/troubleshooting/fix-auth-errors Fix 401 errors from the APITube News API: ER0201 (missing key), ER0202 (invalid or revoked key) and ER0230 (expired key), with the exact cause and remedy for… # How to fix authentication (401) errors Resolve ER0201, ER0202 and ER0230 when the API rejects your key ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to fix authentication (401) errors[#](#how-to-fix-authentication-401-errors) A `401` response means the APITube News API could not authenticate your request. There are three distinct causes, each with its own error code: **ER0201** (no key was sent), **ER0202** (the key is invalid or was revoked), and **ER0230** (the key has expired). The fix depends on which code you get, so read the `error` field in the JSON response first. ``` curl "https://api.apitube.io/v1/news/everything?api_key=YOUR_API_KEY" ``` Every endpoint requires a key except `/ping`, `/openapi.json` and `/robots.txt`. You can pass the key either as an `X-API-Key` request header or as an `api_key` query parameter — both work, so pick whichever suits your client. ## How to fix ER0201 — API key is required[#](#how-to-fix-er0201--api-key-is-required) `ER0201` means no key reached the server at all. The message is _“[API key](/en/articles/getting-started/glossary#api-key) is required. Provide it via X-API-Key header or api\_key query parameter.”_ This usually happens when the header name is misspelled, the `api_key` query parameter is empty, or a proxy stripped the header. Send the key one of these two ways: ``` # As a header curl -H "X-API-Key: YOUR_API_KEY" "https://api.apitube.io/v1/news/everything" # As a query parameter curl "https://api.apitube.io/v1/news/everything?api_key=YOUR_API_KEY" ``` The header name is case-insensitive, so `X-API-Key` and `x-api-key` are equivalent. Make sure the value is not blank — an empty `api_key=` still counts as missing and returns `ER0201`. ## How to fix ER0202 — invalid API key[#](#how-to-fix-er0202--invalid-api-key) `ER0202` means a key was sent, but it does not match an active key on your account. Two situations produce it: the key string is wrong (a typo, a truncated copy-paste, or extra whitespace), or the key was **revoked** in the dashboard. A revoked key is treated by the API as if it no longer exists, so the fix is to use a different active key or create a new one. To resolve `ER0202`: * Copy the key again from the dashboard, with no leading or trailing spaces. * Confirm you are using the right environment: [live keys](/en/articles/getting-started/glossary#test-key-and-live-key) start with `api_live_` and test keys start with `api_test_`. * If the key was revoked, generate a fresh key and update your application. ![The keys table on the API Keys page where each key's Status column shows Active, Revoked or Expired](/images/article/dashboard-api-keys-table.png) ## How to fix ER0230 — API key has expired[#](#how-to-fix-er0230--api-key-has-expired) `ER0230` means the key itself is valid but has passed its expiry date. Keys can be created with an `expires_at` date for time-boxed access, and once that moment passes every request returns `401` with `ER0230`. The fix is to either remove or extend the expiry on that key in the dashboard, or issue a new key without an expiry. There is no way to revive an expired key on the fly — the date is enforced on every request. ## Is a 403 the same as a 401?[#](#is-a-403-the-same-as-a-401) No. A `401` is always an authentication problem (no key, wrong key, expired key). A `403` is an **authorization** problem: the key is recognized but not allowed for this request. The News API returns `ER0601` when your IP address is not on the key’s allow-list, `ER0602` when the request’s domain is not allowed, and `ER0603` when the key’s scopes do not include the endpoint you called. If you see a `403`, the key works — the restriction on it does not match where or how you are calling from. # Common Questions[#](#common-questions) ## Why does my key work in one request but fail in another?[#](#why-does-my-key-work-in-one-request-but-fail-in-another) Check that both requests target the same environment and send the key the same way. A common cause is a test key (`api_test_…`) used where a live key (`api_live_…`) is expected, or a header that one client sends and another drops. Authentication is identical across endpoints, so a key that authenticates on `/v1/news/everything` will authenticate everywhere — if one call fails with `401`, the key or its transport differs between the two calls. ## Is a 401 the same as running out of credits?[#](#is-a-401-the-same-as-running-out-of-credits) No. A `401` is about the key being missing, invalid or expired. Running out of requests is a separate `402` response, not a `401`. If your key authenticates but you are blocked by quota, check your remaining balance instead — see [how to check your balance via the API](/en/articles/retrieval/check-balance-api). For request throttling, which returns `429`, see [how to handle rate-limit errors](/en/articles/troubleshooting/rate-limit-errors). ## Should I put my API key in the URL or a header?[#](#should-i-put-my-api-key-in-the-url-or-a-header) Both are supported, but the `X-API-Key` header is safer for production because query strings are more likely to be logged by proxies and servers. Use the `api_key` query parameter for quick tests and the header for anything that runs against live data. * * * ## Related Articles * [How to Handle Rate-Limit (429) Errors](/en/articles/troubleshooting/rate-limit-errors) * [How to Check Your Balance via the API](/en/articles/retrieval/check-balance-api) --- ## News API Frequently Asked Questions URL: https://support.apitube.io/en/articles/troubleshooting/general-faqs Frequently asked questions about the APITube News API: the base URL, how to authenticate, what counts as a request, default sorting, per_page and rate limits,… # News API Frequently Asked Questions Quick answers to the most common questions about authentication, usage, sorting, limits and errors ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson June 28, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en) # Frequently asked questions[#](#frequently-asked-questions) This page gives the short answer to the questions people ask most often when they start with the APITube News API — the base URL, how to authenticate, what a request costs, how results are ordered and limited, and how to read an error. Each answer links to the full guide when there is more to know. ## What is the base URL and main endpoint?[#](#what-is-the-base-url-and-main-endpoint) The News API lives at `https://api.apitube.io`, and the primary search endpoint is `/v1/news/everything`. It accepts both `GET` (parameters in the query string) and `POST` (parameters in the JSON body), so a minimal call looks like this: ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&api_key=YOUR_API_KEY" ``` Other endpoints sit under the same `/v1/` prefix — for example `/v1/news/count` to count matches and `/v1/balance` to read your credit balance. ## How do I authenticate my requests?[#](#how-do-i-authenticate-my-requests) Send your [API key](/en/articles/getting-started/glossary#api-key) in the `X-API-Key` request header, or as the `api_key` query parameter (an `Authorization: Bearer <key>` header also works). If no key is sent the API returns `401` with code `ER0201`; an invalid or revoked key returns `ER0202`, and an expired key returns `ER0230`. If you are getting `401` responses, see [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors). ## What counts as one request, and when am I charged?[#](#what-counts-as-one-request-and-when-am-i-charged) A successful search costs **one request** (one credit), and you are charged **only when the response returns at least one article**. A query that matches nothing returns an empty list and does not decrement your quota, so you can tune filters and re-run a search that comes back empty without spending credits. To see how many articles a filter combination matches before you fetch them, send the same parameters to [the count endpoint](/en/articles/retrieval/count-articles), and to read your remaining credits call [the balance endpoint](/en/articles/retrieval/check-balance-api). ## Why is article content shortened or showing placeholder text?[#](#why-is-article-content-shortened-or-showing-placeholder-text) You are using a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** or a **free plan**, both of which return matching articles but truncate the body to a preview. A test key marks the cut text `[Test mode — use a live key for full content]` and a free plan marks it `[Upgrade subscription plan]`. This is content masking, not an error and not an empty result — the articles matched and were returned. Use a live key on a paid plan for full bodies. See [why results are masked or placeholder text](/en/articles/troubleshooting/masked-results). ## What is the default sort order, and how many results can I get per page?[#](#what-is-the-default-sort-order-and-how-many-results-can-i-get-per-page) By default the News API sorts by `published_at` in descending order, so the newest articles come first. You can change this with `sort.by` and `sort.order` — see [how to sort news by relevance, date or quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes). Page size is controlled by `per_page`, which defaults to 100 and has a maximum of **250** — **50** on Starter, **10** on Free — and asking for more than your plan allows returns a `400` error (`ER0171`). Walk through large result sets with the `page` parameter, as described in [how to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). ## Why does my search return no results?[#](#why-does-my-search-return-no-results) An empty search is `HTTP 200` with `status: "ok"` and an empty `results` array — a successful request that matched nothing, not an error. The usual cause is filters that are too narrow: different filters combine with AND, so each one you add can only shrink the result set. Remove filters one at a time until results come back to find the one that emptied the response. See [why is my search returning no results](/en/articles/troubleshooting/no-results) for the full checklist. ## What are the rate limits?[#](#what-are-the-rate-limits) The per-minute ceiling is **50 requests on paid plans, 10 on the free plan, 15 on test keys, and 10 on fact-check**. Exceeding it returns `429` with code `ER0203`, whose `message` tells you how long to wait; repeated violations trigger a temporary ban (`ER0204`) after 30 offenses. Add a short delay and retry — see [how to fix rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors). ## What export formats are available?[#](#what-export-formats-are-available) A search can return more than JSON. Add the `export` parameter to get the same results as `csv`, `tsv`, `xml`, `rss`, `xlsx`, `parquet` or `jsonl` — for example `?export=csv`. The default, with no `export` parameter, is JSON. # Common Questions[#](#common-questions) * [How do I read an API error?](#how-do-i-read-an-api-error) * [Does the API return cached data?](#does-the-api-return-cached-data) ## How do I read an API error?[#](#how-do-i-read-an-api-error) Every failed request returns the same JSON envelope: a top-level `status` of `not_ok`, a `request_id`, and an `errors` array. Read `errors[0].code` (an `ERxxxx` value) together with `errors[0].message` — for a `400`, the message names the exact parameter at fault. The same `request_id` is also returned as the `X-Request-ID` header; quote it when you contact support. The full map of statuses and codes is in [understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes). ## Does the API return cached data?[#](#does-the-api-return-cached-data) No. Responses are sent with `Cache-Control: no-store`, because news changes by the minute and a stale cached copy would show outdated articles. If the same request returns different results on a later call, that is fresh data, not a caching bug. * * * ## Related Articles * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [Why Is My Search Returning No Results?](/en/articles/troubleshooting/no-results) * [How to Check Your Balance via the API](/en/articles/retrieval/check-balance-api) --- ## Troubleshooting & Errors URL: https://support.apitube.io/en/articles/troubleshooting Diagnose and fix APITube News API problems: authentication failures, rate-limit (429) errors, empty results and other HTTP error codes. ![](/images/collections/faqs.png) # Troubleshooting & Errors Fix common errors and failed requests. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) By Erick and 1 other 2 authors 11 articles When a request misbehaves, start here. These guides cover the most common failure modes: queries that return no results, authentication errors, rate-limit (429) responses, masked or truncated results, and a general debugging walkthrough that narrows any problem down step by step. Most issues resolve to one of three causes — a filter that is stricter than intended, a key used in the wrong mode, or an exhausted quota. [Debug requests](/en/articles/troubleshooting/debug-requests) shows how to tell them apart quickly. * [How to Debug Your API Requests](/en/articles/troubleshooting/debug-requests) * [How to Fix 400 Bad Request Errors](/en/articles/troubleshooting/fix-400-errors) * [How to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) * [How to Fix Rate-Limit (429) Errors](/en/articles/troubleshooting/rate-limit-errors) * [How to Fix SSE Stream Problems (ER0360, Disconnects)](/en/articles/troubleshooting/sse-stream-issues) * [News API Frequently Asked Questions](/en/articles/troubleshooting/general-faqs) * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [Why Are My Results Masked or Placeholder Text?](/en/articles/troubleshooting/masked-results) * [Why is my request blocked by IP or scope?](/en/articles/troubleshooting/ip-scope-blocked) * [Why Is My Search Returning No Results?](/en/articles/troubleshooting/no-results) * [Why Is My Webhook Not Receiving Events?](/en/articles/troubleshooting/webhook-not-receiving-events) --- ## Why is my request blocked by IP or scope? URL: https://support.apitube.io/en/articles/troubleshooting/ip-scope-blocked A 403 ER0601 means your IP is not on the key's allow-list; ER0603 means the key's scopes don't cover that endpoint. Here is the exact cause and fix for each. # Why is my request blocked by IP or scope? Fix 403 ER0601 (IP not allowed) and ER0603 (scope not authorized) on your API key ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 21, 2026 # Why is my request blocked by IP or scope?[#](#why-is-my-request-blocked-by-ip-or-scope) A `403` from the APITube News API means your key is recognized but **not allowed** for this request. Two restrictions on the key cause it: **ER0601** when your IP address is not on the key’s allow-list, and **ER0603** when the key’s scopes do not include the endpoint you called. Read the `code` field in the JSON body to know which one you hit, then fix the matching setting on the key in the dashboard. ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 403, "code": "ER0601", "message": "Access denied: your IP address is not allowed for this API key.", "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }, "timestamp": "2026-06-27T12:00:00.000Z" } ] } ``` A `403` is different from a `401`. A `401` means the key is missing, invalid or expired; a `403` means the key works but a restriction on it does not match where or how you are calling from. See [how to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) if you are getting `401` instead. ## What does ER0601 (IP address not allowed) mean?[#](#what-does-er0601-ip-address-not-allowed-mean) `ER0601` means the key has an **IP allow-list**, and the public IP the API saw for your request is not on it. The API runs behind a proxy with forwarding trusted, so the address it checks is the **public egress IP** of whatever made the call — your server’s outbound IP, your office gateway, or your proxy — not the private LAN address of your machine. If that IP changed (a new server, a dynamic ISP address, a different cloud region), a previously working key starts returning `ER0601`. An empty allow-list means **no IP restriction** — every address is allowed. So `ER0601` only appears when at least one entry is set on the key. ## How to fix an ER0601 IP block[#](#how-to-fix-an-er0601-ip-block) Add the IP the API actually sees to the key’s allow-list: 1. Find the public IP of the machine making the request (its outbound/egress IP, e.g. via any “what is my IP” service run from that machine — not your laptop if a server sends the calls). 2. Open the key in the dashboard under **[API Keys](/en/articles/getting-started/glossary#api-key) → your key → API Key Restrictions**. 3. Add the address to **Allowed IP Addresses**, one entry per line (up to 50 entries). Each line can be one of four forms: * An exact address — `203.0.113.7` or an IPv6 address. * A CIDR range — `203.0.113.0/24` (IPv4 prefixes `/0`–`/32`, IPv6 `/0`–`/128`). * A prefix wildcard — `203.0.113.*` matches every address starting with `203.0.113.`. * `*` — allow any IP (same effect as leaving the list empty). To remove the restriction entirely, clear the list and save. The API applies whatever the list contains on the very next request — there is nothing to deploy on your side. ![The API Key Restrictions card where allowed IP addresses are entered one per line and saved](/images/article/dashboard-key-restrictions-form.png) ## What does ER0603 (scope not authorized) mean?[#](#what-does-er0603-scope-not-authorized-mean) `ER0603` means the key has **scopes** set, and the endpoint you called is outside them. The message names the scope it needed, for example _“Access denied: this API key is not authorized for this endpoint. Required scope: everything.”_ A scope maps one-to-one to an endpoint’s request type: `/v1/news/everything` requires `everything`, `/v1/news/top-headlines` requires `top_headlines`, `/v1/news/raw` requires `news_raw`, `/v1/balance` requires `balance`, and so on. [Webhooks](/en/articles/getting-started/glossary#webhook) split by method: reading a webhook (`GET`) needs `webhooks:read`, while creating, editing or deleting one needs `webhooks:write`. A key with **no scopes set has full access** to every endpoint, so `ER0603` only appears on keys you deliberately restricted. ## How to fix an ER0603 scope block[#](#how-to-fix-an-er0603-scope-block) Either call an endpoint the key is allowed to use, or widen the key’s scopes: 1. Read the `Required scope` value from the `403` message — that is the exact endpoint the call needs. 2. Open the key in the dashboard under **API Keys → your key → Permissions**. 3. Either tick that endpoint’s scope, or choose **Full access** to clear the restriction. Leaving the Permissions selection empty (or selecting every endpoint) means full access — the key behaves as if no scope filter exists. Keep scopes narrow when a key only powers one feature; widen them when one key serves several endpoints. ## Is ER0602 (domain not allowed) related?[#](#is-er0602-domain-not-allowed-related) Yes. `ER0602` is the third member of the same family: it fires when the key has an **HTTP referrer allow-list** and the request’s `Referer`/`Origin` domain is not on it. You set it right next to the IP list, under **Allowed HTTP Referrers** on the same restrictions panel. The full list of restriction codes lives in [understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes). # Common Questions[#](#common-questions) ## The API saw a different IP than the one I expected — why?[#](#the-api-saw-a-different-ip-than-the-one-i-expected--why) Because the allow-list checks the **public** address the request arrives from, not your local one. If your app runs on a server, the relevant IP is that server’s outbound IP; if traffic goes through a load balancer, NAT gateway or proxy, it is that hop’s public IP. Browsers and serverless platforms often use rotating egress IPs, which makes a fixed allow-list brittle — prefer a CIDR range or a stable proxy for those. ## In what order are these checks run?[#](#in-what-order-are-these-checks-run) The API checks the key in a fixed order: expiry first (a `401 ER0230` for an expired key), then IP (`ER0601`), then referrer (`ER0602`), then scope (`ER0603`). The first failing check wins, so an expired key always returns `401` before any `403` restriction is even evaluated. Fix `401` problems first. ## I have both an IP allow-list and scopes — does a request need to pass both?[#](#i-have-both-an-ip-allow-list-and-scopes--does-a-request-need-to-pass-both) Yes. The restrictions are independent gates, all applied on every request. A call only succeeds when the IP is allowed **and** the endpoint’s scope is granted (and the referrer, if a referrer list is set). Loosen whichever gate returned the `403` — the `code` field tells you which one. * * * ## Related Articles * [How to fix authentication (401) errors](/en/articles/troubleshooting/fix-auth-errors) * [Understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes) --- ## Why Are My Results Masked or Placeholder Text? URL: https://support.apitube.io/en/articles/troubleshooting/masked-results APITube masks only the article body with an '[Upgrade subscription plan]' marker on free plans and test keys; a live key on a paid plan returns the full text. # Why Are My Results Masked or Placeholder Text? An '\[Upgrade subscription plan\]' or test-mode marker in the body means a free plan or a test key, not a bug ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn August 23, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=Apple) # Why are my results masked or placeholder text?[#](#why-are-my-results-masked-or-placeholder-text) Masked content is expected behaviour on a free plan or a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) — it is not an error. When the article `body` comes back cut short and ends with `...[Upgrade subscription plan]` or `...[Test mode — use a live key for full content]`, the API matched real articles and returned them, but trimmed the article text to a preview. Everything else — the link, image, description, source and all enrichment — is returned in full. The fix is to use a **live key** (prefix `api_live_`) on a **paid plan**; that returns the full body. Your request still succeeded — the `HTTP` status is `200`, only the article text is shortened. ``` { "title": "Apple reports record quarterly revenue", "description": "Apple posted its strongest December quarter to date, driven by...[Upgrade subscription plan]", "body": "Apple Inc. said on Thursday that revenue rose across every product...(+1962 chars hidden)...[Upgrade subscription plan]", "href": "https://ww...(+41 chars hidden)...[Upgrade subscription plan]" } ``` ## What triggers content masking?[#](#what-triggers-content-masking) Two conditions trigger masking, and only these two: your key belongs to the **free** subscription plan, or your key is a **test key**. A live key on any paid plan returns full content. The server applies the exact same trimming in both cases — the only difference is the marker text it leaves behind. * **Free plan** — content is trimmed and tagged with `[Upgrade subscription plan]`. * **Test key** — the same trim, tagged with `[Test mode — use a live key for full content]`. A test key is recognised purely by its prefix: anything starting with `api_test_` is a test key. Test keys are deliberately useful for wiring up integrations — they do not consume your request quota and never hit the out-of-credits error — but they always preview the content. A live key starts with `api_live_`. ## Which fields are masked and which stay full?[#](#which-fields-are-masked-and-which-stay-full) Only the article text is previewed. Everything else — including the fields you would show in a UI and all the enrichment you filter on — is returned in full, even on a free plan or test key. **Trimmed to a preview:** * `body` and `body_html` — cut to the first 200 characters, then the marker is appended. **Returned in full (never masked):** * `title` and `description` — the headline and summary are complete. * `href`, `image`, `links[].url` and `media[].url` — real, working URLs. * `source` — `domain`, `home_page_url` and `favicon`. * `translations.en.title` and `translations.en.description`. * `entities` (people, companies, locations), `categories`, `topics` and `industries`. * `sentiment` scores, `readability`, `published_at`, language, country and the rest of the structured fields. That split is why a masked response still looks normal: the article is readable and linkable, the [entity](/en/articles/getting-started/glossary#entity) and [sentiment](/en/articles/getting-started/glossary#sentiment) data are real, and only the full text is held back. Two aggregate endpoints behave differently with a **test key**, and it is easy to mistake for broken data: `/v1/news/count` caps the answer at **100** (a filter matching millions still returns `100`), and `/v1/news/trends` returns real counts but replaces each entry’s `value` — the category, entity or source — with `[Upgrade subscription plan]`. Neither is a masking bug; both disappear on a live key. ## How do I confirm it’s a key issue and not bad data?[#](#how-do-i-confirm-its-a-key-issue-and-not-bad-data) Read the response headers — the API tells you the key mode directly, so you do not have to guess from the body text. Every response includes: * `x-apitube-mode` — `test` for a test key, `live` for a live key. * `x-subscription-plan` — your plan, for example `free` or a paid tier. * `x-points-remaining` — your remaining request quota. If `x-apitube-mode` is `test`, you are using a test key; if `x-subscription-plan` is `free`, you are on the free plan. Either one explains the marker. You can see them with a verbose request: ``` curl -i "https://api.apitube.io/v1/news/everything?title=Apple&api_key=YOUR_API_KEY" ``` The `-i` flag prints the headers. Check `x-apitube-mode` and `x-subscription-plan` at the top before you read the body. ## How do I get the full, unmasked content?[#](#how-do-i-get-the-full-unmasked-content) Use a live key on a paid plan. Generate or copy your live key (it starts with `api_live_`) from the dashboard — see [how to create, rename and revoke API keys](/en/articles/account-and-dashboard/keys/manage-keys) — and send that key instead of the test key. On a paid plan the `body`, `body_html`, `description` and URLs come back complete, with no marker appended. ``` curl "https://api.apitube.io/v1/news/everything?title=Apple&api_key=api_live_YOUR_LIVE_KEY" ``` Masking is applied the same way across every delivery method, so switching to a live key fixes it everywhere: search endpoints, single-article lookups, exports, and the real-time [SSE](/en/articles/getting-started/glossary#sse-stream) and [WebSocket](/en/articles/getting-started/glossary#websocket) streams all preview the article body on a free plan or test key and return the full text on a paid live key. # Common Questions[#](#common-questions) * [Is a masked result the same as an empty result?](#is-a-masked-result-the-same-as-an-empty-result) * [Do test keys cost a request or a credit?](#do-test-keys-cost-a-request-or-a-credit) * [Why is the headline full but the body cut off?](#why-is-the-headline-full-but-the-body-cut-off) * [Does masking affect the streaming endpoints too?](#does-masking-affect-the-streaming-endpoints-too) ## Is a masked result the same as an empty result?[#](#is-a-masked-result-the-same-as-an-empty-result) No. A masked result still contains real articles — the `results` array is populated, the headline and metadata are present, and only the long text fields are previewed. An empty result is `results: []` with no articles at all, which is a filter problem rather than a key problem. If you are unsure which one you are looking at, see [why is my search returning no results](/en/articles/troubleshooting/no-results). ## Do test keys cost a request or a credit?[#](#do-test-keys-cost-a-request-or-a-credit) No. A test key does not consume your request quota and never triggers the out-of-credits error, which is exactly why it is meant for development and wiring up integrations. The trade-off is that test keys always preview the content. When you need full article text, switch to a live key on a paid plan. ## Why is the headline full but the body cut off?[#](#why-is-the-headline-full-but-the-body-cut-off) Because only `body` and `body_html` are trimmed to a preview — the `title`, `description` and every URL come back complete. So a masked article shows a full headline, summary and link alongside a shortened body that ends with the upgrade or test-mode marker. That is normal masking behaviour, not a partial or corrupted record. ## Does masking affect the streaming endpoints too?[#](#does-masking-affect-the-streaming-endpoints-too) Yes. The same preview applies to the real-time SSE stream and the WebSocket stream when you connect with a free plan or a test key — each delivered article has its body trimmed and tagged with the marker, while the link, description and enrichment stay complete. Connecting with a live key on a paid plan streams full content. * * * ## Related Articles * [Why Is My Search Returning No Results?](/en/articles/troubleshooting/no-results) * [How to Create, Rename and Revoke API Keys](/en/articles/account-and-dashboard/keys/manage-keys) * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) --- ## Why Is My Search Returning No Results? URL: https://support.apitube.io/en/articles/troubleshooting/no-results An empty APITube News API search returns HTTP 200 with an empty results array. Loosen AND-combined filters, check that title matches the headline, and verify… # Why Is My Search Returning No Results? An empty results array is HTTP 200, not an error — how to loosen filters, fix keyword search and check entity IDs ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn June 27, 2026 Updated July 29, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&language_code=en&category_id=medtop%3A04000000) # Why is my search returning no results?[#](#why-is-my-search-returning-no-results) An empty search is almost always a filter problem, not a bug. The APITube News API returns `HTTP 200` with `status: "ok"` and an empty `results` array when your query is valid but nothing matches it. The usual causes are filters that are too narrow (every filter you add is combined with AND), a keyword search that only looks at the headline, or an `entity.id` that matches nothing. Remove filters one at a time until results come back, then add them back to find the one that emptied the response. ``` { "status": "ok", "limit": 25, "page": 1, "has_next_pages": false, "results": [] } ``` A clean empty result like this means the request succeeded and simply found no articles — and because the News API only charges a request when at least one article is returned, an empty search does not cost a credit. ## Is an empty result an error?[#](#is-an-empty-result-an-error) No. An empty result is `HTTP 200` with `status: "ok"` and `results: []`, which is a successful response that happened to match nothing. That is different from an error, which returns a `4xx` status and an error code: a bad parameter returns `400`, an authentication problem returns `401`, and too many requests returns `429`. If you are getting a status code other than `200`, you are looking at an error, not an empty search — see [understanding API error codes](/en/articles/troubleshooting/error-codes) for the full map. So the first debugging step is to read the HTTP status: a `200` with an empty `results` array tells you the query ran and the filters excluded everything. ## Why does adding more filters return nothing?[#](#why-does-adding-more-filters-return-nothing) Different filter parameters combine with AND, so each one you add narrows the result set, and a few specific filters together can reduce it to zero. For example `title=earnings&language.code=ja&source.domain=bbc.com&published_at.start=NOW-1DAYS` requires all four conditions at once — a Japanese-language BBC article with “earnings” in the headline from the last 24 hours — which may genuinely not exist. ``` curl "https://api.apitube.io/v1/news/everything?language.code=en&category.id=medtop:04000000&api_key=YOUR_API_KEY" ``` To find the filter that empties your response, drop them one at a time and re-run the search until results appear. The filter you removed last is the one that excluded everything. For the rules on how filters stack, see [how to combine multiple filters in one request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters). ## Why doesn’t my keyword search find articles I know exist?[#](#why-doesnt-my-keyword-search-find-articles-i-know-exist) The `title` parameter matches words in the article **headline only**, not the body. If your keyword appears in the article text but not the title, the article will not match. Two more rules narrow it further: when you pass several words, they are combined with AND (every word must be in the headline), and matching is by whole token, so `ai` does not match `Jamaica` and a partial word does not match a longer one. ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&api_key=YOUR_API_KEY" ``` If a multi-word `title` returns nothing, try fewer words, or wrap an exact phrase in quotes only when you really need it (`title="climate change"`) — a quoted phrase is the strictest match of all. The `title` value must be 2 to 100 characters or the request fails with `ER0007`. When you are searching for coverage about a person or company rather than a literal headline word, filter by the [entity](/en/articles/getting-started/glossary#entity) instead — `person.name`, `organization.name` or `entity.id` — which matches the article wherever the entity is mentioned. See [how to search news by title](/en/articles/searching-and-filtering/keyword-search/search-by-title) for the keyword rules. ## Why does an entity or name filter come back empty?[#](#why-does-an-entity-or-name-filter-come-back-empty) Name filters and ID filters fail differently, and knowing which you used explains the empty response. A name that APITube does not recognize fails **loudly**: an unknown `person.name` returns `400` with `ER0216`, and an unknown `organization.name` returns `ER0220`. So if a name filter returned a clean empty list instead of an error, the name resolved correctly and there is simply no recent coverage. A numeric `entity.id` is the opposite — it is not checked against the directory, so an ID that matches no entity **silently** returns no articles rather than failing. If you filtered by `entity.id` and got nothing, confirm the ID is correct: read it from the `entities` array of a known article, or look it up in the directory. See [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) for the difference between name and ID matching. ## Why does my date filter return nothing?[#](#why-does-my-date-filter-return-nothing) A date window that is too tight, or pointed at the future, excludes everything. `published_at.start` and `published_at.end` are the bounds, and a relative value like `published_at.start=NOW-7DAYS` means “the last seven days”. A common mistake is setting `published_at.start` to a time later than `published_at.end`, or to a moment in the future, which leaves no valid range: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Tim Cook&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" ``` Widen the window first (drop `published_at.start` entirely to confirm the rest of the query works), then tighten it. An unparseable date value is rejected with `ER0104` for `published_at.start` rather than returning an empty list, so a clean empty response means the dates parsed but matched nothing. One caveat when the query also searches headlines: dropping the dates does **not** widen a `title` search to the whole archive. Headline searches are capped at a 31-day window, so removing the dates falls back to the last 31 days and the response says so with an `ER0366` warning in `meta.warnings`. If you check `meta.warnings` and see that code, the empty list means “nothing in the last month”, not “nothing ever” — pick an explicit month with `published_at.start` and `published_at.end` to look further back. Asking for a wider range in one go returns `ER0110` instead of an empty list; the details are in [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## How do I debug an empty search?[#](#how-do-i-debug-an-empty-search) Add `debug=1` (or `debug=true`) to the request. The response then includes a `user_input` object that echoes exactly how the server parsed your parameters — with the [API key](/en/articles/getting-started/glossary#api-key) removed — which quickly reveals a misspelled parameter name or a value that was not applied the way you expected. ``` curl "https://api.apitube.io/v1/news/everything?title=Tesla&debug=1&api_key=YOUR_API_KEY" ``` Then strip the query down to a single filter, confirm it returns articles, and add the others back one by one. To check how many articles a query matches before fetching any, use [the count endpoint](/en/articles/retrieval/count-articles) (`/v1/news/count`). One more thing to rule out: a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) or a free plan still returns matching articles, but the body is truncated to a preview — that is masked content, not an empty result, so check whether `results` is actually empty or just shortened. # Common Questions[#](#common-questions) * [Does an empty search cost a request or credit?](#does-an-empty-search-cost-a-request-or-credit) * [My results have placeholder or shortened text — is that the same as no results?](#my-results-have-placeholder-or-shortened-text--is-that-the-same-as-no-results) * [Why did a misspelled name return an error instead of an empty list?](#why-did-a-misspelled-name-return-an-error-instead-of-an-empty-list) * [How do I check how many articles match before fetching them?](#how-do-i-check-how-many-articles-match-before-fetching-them) ## Does an empty search cost a request or credit?[#](#does-an-empty-search-cost-a-request-or-credit) No. The News API only charges a request when at least one article is returned. A query that resolves to an empty `results` array does not decrement your request quota, so you can safely tune filters and re-run a search that returns nothing without spending credits. ## My results have placeholder or shortened text — is that the same as no results?[#](#my-results-have-placeholder-or-shortened-text--is-that-the-same-as-no-results) No. Shortened or preview body text means your articles matched and were returned, but the content was masked because you used a test key or a free plan. That is a content-masking behavior, not an empty search — `results` still contains articles. An empty search is specifically `results: []` with no articles at all. ## Why did a misspelled name return an error instead of an empty list?[#](#why-did-a-misspelled-name-return-an-error-instead-of-an-empty-list) Because name filters validate against the entities APITube tracks. An unknown `person.name` returns `ER0216` and an unknown `organization.name` returns `ER0220`, both `HTTP 400`, and the request stops rather than returning an empty list. This is intentional: it tells you the name itself is wrong instead of silently matching nothing. Fix the spelling, or switch to a numeric `entity.id`, which never triggers these errors. ## How do I check how many articles match before fetching them?[#](#how-do-i-check-how-many-articles-match-before-fetching-them) Send the same filters to `/v1/news/count` instead of `/v1/news/everything`. It returns the number of matching articles without downloading them, which is the fastest way to confirm whether a filter combination matches zero, a few, or millions of articles. See [how to count matching articles](/en/articles/retrieval/count-articles) for details. * * * ## Related Articles * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [How to Combine Multiple Filters in One Request](/en/articles/searching-and-filtering/sorting-and-shaping/combine-filters) * [How to Count Matching Articles](/en/articles/retrieval/count-articles) --- ## How to Fix Rate-Limit (429) Errors URL: https://support.apitube.io/en/articles/troubleshooting/rate-limit-errors Fix APITube News API 429 errors: paid plans allow 50 requests per minute (Corporate 200, free plan 10), ER0203 means slow down, ER0204 means a temporary ban.… # How to Fix Rate-Limit (429) Errors Why the News API returns 429, what ER0203 and ER0204 mean, and how to stay under the per-minute limit ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn August 22, 2026 # How to fix rate-limit (429) errors[#](#how-to-fix-rate-limit-429-errors) A `429 Too Many Requests` response means you sent more requests than your per-minute limit allows. On Starter, Basic and Professional that limit is **50 requests per minute**, on Corporate **200 requests per minute**, and on the free plan **10 requests per minute**: slow down, wait the amount of time the error reports, and retry. The cap is counted per **account**, so every [live key](/en/articles/getting-started/glossary#test-key-and-live-key) you own shares it — one busy key does eat into the budget of the others. A blocked request returns this body: ``` { "status": "not_ok", "request_id": "…", "errors": [ { "status": 429, "code": "ER0203", "message": "Rate limit exceeded. You can make 50 requests per minute. Try again in 1 minute.", "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }, "timestamp": "…" } ] } ``` ## What are the request limits?[#](#what-are-the-request-limits) APITube applies a one-minute window, and the ceiling depends on your plan and key type: * **Paid plans** (Starter, Basic, Professional) — 50 requests per minute. **Corporate** — 200 requests per minute. * **Free plan** — 10 requests per minute. * **Test keys** — 15 requests per minute. Test data does not draw down your quota, so the [rate limit](/en/articles/getting-started/glossary#rate-limit) is the only backstop and is set lower. * **Fact-check** (`/v1/fact-check`) — 10 requests per minute, on its own counter separate from the plan pool, because each call runs a language model. The counter is keyed on the **account**, not on the individual key: every live key you own draws from the same per-minute budget, so issuing more keys does not raise your ceiling. Test keys (`api_test_`) keep a separate counter with their own 15/min limit, and your IP address is used only as a fallback when no key is present. ## What does a 429 response look like?[#](#what-does-a-429-response-look-like) Exceeding the limit returns HTTP `429` with error code `ER0203`. The JSON body follows the standard APITube error shape shown above: a `status` of `not_ok`, your `request_id`, and an `errors` array. The message states both your ceiling and how long to wait — for example, _“You can make 50 requests per minute. Try again in 1 minute.”_ Read that wait time and hold further calls until it passes instead of retrying immediately. ## Why am I temporarily banned (ER0204)?[#](#why-am-i-temporarily-banned-er0204) If you keep sending requests after hitting the limit — 30 over-limit responses — the key is temporarily banned. A ban returns HTTP `429` with code `ER0204` and the message _“You have been temporarily banned for exceeding rate limits. Try again in …”_. The ban is temporary and clears after the stated interval. The fix is the same as for `ER0203`, but more urgent: stop sending requests and back off, rather than retrying in a tight loop that keeps the ban alive. ## What is ER0184, and how is it different?[#](#what-is-er0184-and-how-is-it-different) `ER0184` is also HTTP `429`, but it is a **concurrency** limit rather than a rate limit: it caps how many queries your account may run _at the same moment_ — 1 on Free, 2 on Starter and Basic, 3 on Professional, 4 on Corporate. Requests above the cap wait briefly in a queue, so you only see `ER0184` when that queue is full or a queued request timed out. The response includes a `Retry-After` header. The fix is different too: reduce how many calls you fire in parallel (a smaller worker pool), not how often you call. Streaming endpoints are exempt — `/v1/news/stream` and `/v1/news/ws` never return `ER0184`. ## How do I avoid hitting the limit?[#](#how-do-i-avoid-hitting-the-limit) Treat the 50-per-minute cap as a budget and shape traffic to stay under it: * **Back off on 429.** When you get `ER0203`, pause for the time the message reports — or use exponential backoff — before retrying. Never retry in a tight loop, or you risk the `ER0204` ban. * **Fetch more per call.** Raise `per_page` up to its maximum of `250` — `50` on Starter, `10` on Free — so one request returns more articles; going over the ceiling is rejected with `ER0171`. Fewer, larger pages mean fewer requests. See [How to paginate through results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results). * **Count before you download.** Use `/v1/news/count` to learn how many articles match a filter without pulling them — a cheap way to size a job before paging through it. See [How to count matching articles](/en/articles/retrieval/count-articles). * **Do not expect extra keys to help.** The budget is shared across every live key on the account, so splitting a workload over several keys gives no extra throughput — pace the calls instead. Separate keys are still worth having for attribution and for scoping permissions. A rejected request is cheap in one way: the rate-limit check runs _before_ the request is processed, so a `429` does not consume a request from your quota. Only processed, delivered responses are billed. # Common Questions[#](#common-questions) * [Is the rate limit per API key, per account or per IP address?](#is-the-rate-limit-per-api-key-per-account-or-per-ip-address) * [Do test keys and fact-check share the 50-per-minute limit?](#do-test-keys-and-fact-check-share-the-50-per-minute-limit) * [How long does an ER0204 ban last?](#how-long-does-an-er0204-ban-last) * [Does a 429 error use up one of my requests?](#does-a-429-error-use-up-one-of-my-requests) ## Is the rate limit per API key, per account or per IP address?[#](#is-the-rate-limit-per-api-key-per-account-or-per-ip-address) Per account. The counter is keyed on the account behind the request, so all of your live keys share one 50-requests-per-minute budget (200 on Corporate, 10 on Free) — issuing more keys does not raise it. Test keys (`api_test_`) are counted separately, with their own 15-per-minute budget. The IP address is used only as a fallback when a request arrives without a key, and unauthenticated requests are rejected at authentication first. ## Do test keys and fact-check share the 50-per-minute limit?[#](#do-test-keys-and-fact-check-share-the-50-per-minute-limit) No. A Starter, Basic or Professional key gets 50 requests per minute, Corporate gets 200, the free plan gets 10, a test key gets 15 per minute, and the `/v1/fact-check` endpoint has its own 10-per-minute limit counted separately from your general request pool. Hitting the fact-check limit does not block your other News API calls, and the reverse is true as well. ## How long does an ER0204 ban last?[#](#how-long-does-an-er0204-ban-last) The ban is temporary. The `ER0204` message includes a “Try again in …” interval — wait until it elapses, then resume at a slower pace. Continuing to send requests during the ban only keeps it active, so stop and back off. ## Does a 429 error use up one of my requests?[#](#does-a-429-error-use-up-one-of-my-requests) No. Rate limiting happens before the request is processed and billed, so a `429` (either `ER0203` or `ER0204`) does not deduct from your request quota. Only requests that are actually processed and returned count against your plan. * * * ## Related Articles * [How to Paginate Through Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) * [How to Count Matching Articles](/en/articles/retrieval/count-articles) --- ## How to Fix SSE Stream Problems (ER0360, Disconnects) URL: https://support.apitube.io/en/articles/troubleshooting/sse-stream-issues Fix APITube SSE stream problems: a connected but silent stream, ER0360 connection limits you can clear with DELETE /v1/news/stream/sessions, and planned… # How to Fix SSE Stream Problems (ER0360, Disconnects) A silent stream, a connection limit that will not clear, ordering surprises and expected disconnects — with the exact error codes ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=acme&language_code=en) # How to fix SSE stream problems (ER0360, disconnects)[#](#how-to-fix-sse-stream-problems-er0360-disconnects) Most [SSE](/en/articles/getting-started/glossary#sse-stream) stream problems fall into three buckets, each with a fast fix: a stream that connects but stays silent (usually filters that match nothing new), a `429` with code `ER0360` because your plan’s connection slots are taken — clearable with `DELETE /v1/news/stream/sessions` — and disconnects that are actually by design, like the 6-hour session limit (`ER0362`). This guide walks each bucket with the exact behaviour of `/v1/news/stream`, so you fix the real cause instead of blindly reconnecting. ## Why is my stream connected but silent?[#](#why-is-my-stream-connected-but-silent) A connected stream that sends nothing is usually working exactly as designed. The stream delivers **new** articles only: on connect it anchors to the latest matching article and pushes what is indexed after that moment. It checks for new matches about every **30 seconds** and sends up to 50 articles per cycle — so with narrow filters, minutes of silence are normal. The `: heartbeat` lines you see every ~30 seconds are comments keeping the connection alive, not events, and they cost nothing. To confirm the filters are the issue, run them against the search endpoint — the stream accepts the same dot-notation parameters as `/v1/news/everything`: ``` curl "https://api.apitube.io/v1/news/everything?title=acme&language.code=en&api_key=YOUR_API_KEY" ``` Few or zero results there means few or zero stream events. Widen one filter at a time, as in [debugging an empty search](/en/articles/troubleshooting/no-results). Also check which key you connected with: a [test key](/en/articles/getting-started/glossary#test-key-and-live-key) streams events with **masked** content — if you filter on the masked text downstream, everything looks empty. ## How do I fix “Maximum SSE connections” (ER0360)?[#](#how-do-i-fix-maximum-sse-connections-er0360) HTTP `429` with `ER0360` means every simultaneous-connection slot your plan allows is occupied. Slots are counted per account owner: Starter allows **2**, Basic **2**, Professional **10**, Corporate **50**, and the Free plan allows **1**. A cleanly closed stream frees its slot immediately — but a client that crashed or lost network without closing the socket can leave the slot occupied until the server notices the dead connection, which can take a few minutes. You do not have to wait. Two management endpoints exist exactly for this, and neither costs credits: ``` # See which sessions are holding your slots curl "https://api.apitube.io/v1/news/stream/sessions" -H "X-API-Key: YOUR_API_KEY" # Free them all (or one: ?session_id=..., or per key: ?api_key_id=...) curl -X DELETE "https://api.apitube.io/v1/news/stream/sessions" -H "X-API-Key: YOUR_API_KEY" ``` `GET` lists each active session’s `session_id`, `api_key_id` and `started_at` — a session that started hours ago from a process you already killed is your zombie. `DELETE` force-closes the sessions (the closed streams receive an `error` event with code `ER0364`), and the slots are free for your next connect. Calling `DELETE` before a planned restart of your consumer is the clean way to avoid `ER0360` entirely. ## Why did my stream disconnect?[#](#why-did-my-stream-disconnect) Some disconnects are planned, and the error code tells you which one you got: * **`ER0362`** — a single session may live at most **6 hours**; the server asks you to reconnect. Reconnect with the `Last-Event-Id` header set to the last article id you received and you miss nothing. * **`ER0301`** — your balance ran out mid-stream. Top up or wait for plan credits to renew, then reconnect. * **`ER0361`** — the [API key](/en/articles/getting-started/glossary#api-key) was revoked while streaming; the session ends immediately. * **`ER0364`** — the session was terminated via `DELETE /v1/news/stream/sessions` (see above). A drop with no error event is plain network trouble. The browser `EventSource` reconnects and replays `Last-Event-Id` automatically; a custom client should do the same — the resume recipe is in [how to stream news with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## Why do articles arrive late or out of order?[#](#why-do-articles-arrive-late-or-out-of-order) The stream follows the **indexing order**, not the publication order: its cursor moves over article ids, and each batch is sorted by `published_at` before it is written to you. An article published an hour ago but crawled just now still arrives — with its original `published_at` in the payload. So “real time” means _as articles enter the index_, which is worth knowing before you alert on timestamps; [how fresh the data is](/en/articles/getting-started/how-fresh-is-the-data) covers the pipeline latency itself. If stale-looking articles are noise for your use case, cut them at the server with `stream.max_age` — the maximum age, in minutes, an article’s publication date may have to be delivered: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?language.code=en&stream.max_age=60" ``` `stream.max_age` must be a positive whole number of minutes; anything else is rejected with `400` and code `ER0363`. ## Do parallel streams multiply my bill?[#](#do-parallel-streams-multiply-my-bill) Yes. Each connection is billed independently, one credit per article it delivers — three identical streams receiving the same article spend three credits. Slots and billing are separate concerns: even within your slot limit, duplicate streams are pure overhead. Run **one** stream per filter set and fan the events out to consumers inside your own infrastructure; if different teams need different filters, narrow each stream so their results do not overlap. # Common Questions[#](#common-questions) * [Do heartbeats or the open connection cost credits?](#do-heartbeats-or-the-open-connection-cost-credits) * [Can I resume after the 6-hour disconnect without losing articles?](#can-i-resume-after-the-6-hour-disconnect-without-losing-articles) * [Does closing a stream free the slot instantly?](#does-closing-a-stream-free-the-slot-instantly) * [Why was my connection rejected with ER0176?](#why-was-my-connection-rejected-with-er0176) ## Do heartbeats or the open connection cost credits?[#](#do-heartbeats-or-the-open-connection-cost-credits) No. You pay one credit per article actually delivered, drawn from the streaming credit pool. Heartbeat comments, the idle connection, and the `GET`/`DELETE` session-management endpoints are all free. ## Can I resume after the 6-hour disconnect without losing articles?[#](#can-i-resume-after-the-6-hour-disconnect-without-losing-articles) Yes. Keep the `id:` of the last `article` event you processed and send it as the `Last-Event-Id` header on reconnect — APITube delivers everything that matched after that id, then continues live. The 6-hour limit (`ER0362`) costs you a reconnect, never data. ## Does closing a stream free the slot instantly?[#](#does-closing-a-stream-free-the-slot-instantly) A clean close does — the moment the socket closes, the slot is back. Only an unclean drop (crash, dead network path) leaves a slot occupied until the server detects the dead socket. If you hit `ER0360` after a crash, clear the zombie with `DELETE /v1/news/stream/sessions` instead of waiting. ## Why was my connection rejected with ER0176?[#](#why-was-my-connection-rejected-with-er0176) `402` with `ER0176` means the account has no streaming credits and no positive [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance — the connection is refused before it opens. This is different from `ER0301`, which ends a stream that ran out of balance mid-flight. Check the streaming pool on your dashboard’s usage page and see [what counts as a request](/en/articles/billing/credits/what-counts-as-request) for how the pools are spent. * * * ## Related Articles * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [SSE vs WebSocket vs Webhooks: Which to Choose](/en/articles/delivery-and-export/streaming/choose-realtime-method) * [Why Is My Search Returning No Results?](/en/articles/troubleshooting/no-results) --- ## Why Is My Webhook Not Receiving Events? URL: https://support.apitube.io/en/articles/troubleshooting/webhook-not-receiving-events A webhook that stopped delivering usually has a disabled status, filters that match nothing, or an endpoint that fails to answer 2xx within 30 seconds. # Why Is My Webhook Not Receiving Events? A debugging checklist: status, filters, endpoint response, blocked URLs, quota — in the order that finds the culprit fastest ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 6, 2026 Updated July 21, 2026 # Why is my webhook not receiving events?[#](#why-is-my-webhook-not-receiving-events) A [webhook](/en/articles/getting-started/glossary#webhook) that receives nothing almost always has one of five causes, and they are quick to tell apart: the webhook’s status is not `active` (paused, or auto-disabled after failures), its saved-search filters match no new articles, your endpoint does not answer `2xx` within 30 seconds, the endpoint URL is blocked by APITube’s safety checks, or the account has no webhook quota left. Walk the checklist below in order — each step takes a minute and rules out one cause. ## Is the webhook status still “active”?[#](#is-the-webhook-status-still-active) Only an `active` webhook receives deliveries. Check the status on the webhook’s detail page in the [dashboard](https://dashboard.apitube.io) or over the API: ``` curl "https://api.apitube.io/v1/webhooks" -H "X-API-Key: YOUR_API_KEY" ``` Two non-active states look similar but mean different things. `paused` means someone paused it deliberately. `disabled` means APITube switched it off automatically after **3 consecutive failed deliveries** — the most common reason a webhook “suddenly” goes quiet after a deploy that briefly broke your endpoint. Either way, the fix is the same: set the status back to `active` in the dashboard or with `PATCH /v1/webhooks/:id` and body `{"status":"active"}`. The auto-disable rule itself is explained in [webhook retries and delivery history](/en/articles/delivery-and-export/webhooks/webhook-retries-history). ![The webhook Delivery log showing a failed delivery with its HTTP status and full request and response details](/images/article/dashboard-webhook-deliveries.png) ## Do your filters actually match any new articles?[#](#do-your-filters-actually-match-any-new-articles) A webhook only fires for articles that match its [saved search](/en/articles/getting-started/glossary#saved-search), and a saved search that is too narrow fires never. Test the exact same filters against the search endpoint — a webhook’s filters are the same dot-notation parameters `/v1/news/everything` accepts: ``` curl "https://api.apitube.io/v1/news/everything?title=acme&language.code=en&source.domain=reuters.com&api_key=YOUR_API_KEY" ``` If this search returns an empty `results` array, the webhook is working correctly — there is simply nothing to deliver. Loosen one filter at a time (drop `source.domain` first, it is usually the tightest) until articles appear, then update the webhook’s filters to the widest version that still matches what you want. The technique is the same as debugging [a search that returns no results](/en/articles/troubleshooting/no-results), and every accepted filter is listed in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Does your endpoint answer 2xx within 30 seconds?[#](#does-your-endpoint-answer-2xx-within-30-seconds) APITube counts a delivery as successful **only** when your endpoint replies with an HTTP `2xx` status within **30 seconds**. Everything else is a failure: a `4xx` or `5xx`, a `3xx` redirect (redirects are not followed), a connection error, or a handler that takes longer than 30 seconds. Three failures in a row and the webhook is disabled. The robust pattern is acknowledge-then-process: store the payload, return `200` immediately, and do slow work (parsing, enrichment, database writes) asynchronously. Retries resend the same batch with the same `X-Webhook-Delivery-Id` header, so an endpoint that already processed a delivery ID should ignore the repeat and still answer `2xx`. ## Is the endpoint URL reachable from the public internet?[#](#is-the-endpoint-url-reachable-from-the-public-internet) Before every send, APITube resolves your URL’s DNS and refuses to deliver to addresses that could be used to probe internal infrastructure. Blocked destinations include `localhost` and `*.localhost`, loopback (`127.0.0.0/8`), private ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), link-local (`169.254.0.0/16`), carrier-grade NAT (`100.64.0.0/10`), and their IPv6 equivalents. A hostname whose DNS fails to resolve is also treated as blocked. This is why a webhook pointed at a development machine, an internal hostname, or a VPN-only address never receives anything: the delivery is rejected before it is sent, and the delivery history shows a failure with no HTTP status code. Use a public HTTPS endpoint, or a tunnel (ngrok and similar) while developing. ## Do you still have webhook quota?[#](#do-you-still-have-webhook-quota) Webhook deliveries bill per delivered article from your webhook credits, falling back to a positive [pay-as-you-go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) balance on paid plans. When both are at zero, deliveries stop until credits renew or you top up. Check the balances on the dashboard’s usage page, and see [what counts as a request](/en/articles/billing/credits/what-counts-as-request) for how each pool is spent. Failed deliveries are never charged. ## Still stuck? Send a test event[#](#still-stuck-send-a-test-event) The **Send test event** button on the webhook’s detail page delivers a signed sample payload to your endpoint immediately, bypassing the delivery worker and your billing. It works even while the webhook is paused or disabled, and the result — HTTP status, request and response bodies — lands in the delivery history. If the test event arrives but real deliveries do not, the problem is filters or quota; if the test event fails too, the problem is your endpoint or the URL. Verifying the signature on that test payload is covered in [how to verify webhook signatures](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures). # Common Questions[#](#common-questions) * [How quickly should a new article arrive?](#how-quickly-should-a-new-article-arrive) * [Are failed deliveries retried?](#are-failed-deliveries-retried) * [Am I charged while the webhook delivers nothing?](#am-i-charged-while-the-webhook-delivers-nothing) * [Why did my webhook go quiet right after a deploy?](#why-did-my-webhook-go-quiet-right-after-a-deploy) ## How quickly should a new article arrive?[#](#how-quickly-should-a-new-article-arrive) The delivery worker scans for new matching articles roughly every 10 seconds and sends up to 100 articles per delivery. If a matching article was indexed and your webhook is `active`, expect the POST within seconds — a delay of minutes points at retries in progress or at your endpoint responding slowly. ## Are failed deliveries retried?[#](#are-failed-deliveries-retried) Yes — each delivery is attempted up to 5 times in total, with gaps of about 1 minute, 5 minutes, 30 minutes and 2 hours between attempts. Every attempt appears in the delivery history with the returned status code. The full schedule and the auto-disable rule are in [webhook retries and delivery history](/en/articles/delivery-and-export/webhooks/webhook-retries-history). ## Am I charged while the webhook delivers nothing?[#](#am-i-charged-while-the-webhook-delivers-nothing) No. Billing happens per successfully delivered article — a webhook that matches nothing, is paused, or fails to deliver costs zero. You only spend quota when your endpoint actually returns `2xx` for a batch of articles. ## Why did my webhook go quiet right after a deploy?[#](#why-did-my-webhook-go-quiet-right-after-a-deploy) If the deploy made your endpoint return errors for a few deliveries in a row, APITube disabled the webhook after 3 consecutive failures. Fix the endpoint, then set the webhook’s status back to `active` — deliveries resume from there. To avoid a repeat, keep the acknowledge-then-process pattern from above: a fast `2xx` survives slow downstream code, and the delivery history shows you the first failure the moment it happens. * * * ## Related Articles * [How to Set Up a Webhook for a Saved Search](/en/articles/delivery-and-export/webhooks/set-up-webhook) * [Understanding Webhook Retries and Delivery History](/en/articles/delivery-and-export/webhooks/webhook-retries-history) * [How to Verify Webhook Signatures (HMAC)](/en/articles/delivery-and-export/webhooks/verify-webhook-signatures) --- ## Where to Check APITube API Status and Uptime URL: https://support.apitube.io/en/articles/trust-and-support/api-status Check APITube API status at status.apitube.io, ping the /ping health endpoint, and read the HTTP error code to tell a real outage from a key, quota or… # Where to Check APITube API Status and Uptime Find the status page, run the /ping health check, and read error codes to tell an outage from a problem on your side ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 4, 2026 # Where to check APITube API status and uptime[#](#where-to-check-apitube-api-status-and-uptime) The official APITube status page is **[status.apitube.io](https://status.apitube.io)** — that is where you confirm whether the platform is operational and review past incidents. But before you assume an outage, do a two-step check: first read the HTTP status code your request returned, because most “the API is broken” reports are actually a `401`, `402`, `403`, or `429` on your side. If your calls fail with a `500`, that points at the API itself — then the status page is the right place to look. For a fast machine check, the API also exposes an unauthenticated health endpoint at `/ping` that returns `pong` when the service is up. ## Where is the APITube status page?[#](#where-is-the-apitube-status-page) The status page lives at **[https://status.apitube.io](https://status.apitube.io)**. It is the single source of truth for whether the News API is currently operational and for the history of past incidents, so it is the first link to open when several requests fail at once or latency spikes across every endpoint. The same link is published in the APITube site footer and in the documentation, so you can always reach it without a login. Open the status page when the failure is **broad** — every endpoint failing, or plain `500` responses. If only one specific request fails while others succeed, it is far more likely a parameter or account issue than a platform outage. ## Is the APITube API down, or is it a problem on my side?[#](#is-the-apitube-api-down-or-is-it-a-problem-on-my-side) Read the HTTP status code first. APITube returns a specific code and an `ER…` error identifier for client-side problems, and reserves `500` for a genuine server-side fault. This is the fastest way to tell an outage from a configuration or quota issue: * **`401` (ER0201 / ER0202 / ER0230)** — authentication. The key is missing, invalid, or expired. Fix the key, not the platform. * **`402` (ER0176 / ER0177)** — billing. You have no requests left (`ER0176`) or hit your monthly [Pay As You Go](/en/articles/getting-started/glossary#balance-and-pay-as-you-go-payg) spending limit (`ER0177`). * **`403` (ER0601 / ER0602 / ER0603)** — access rules on the key: a blocked IP, a disallowed domain, or an endpoint outside the key’s scopes. * **`429` (ER0203 / ER0204)** — rate limiting. You sent too many requests per minute (`ER0203`), or you were temporarily banned after repeated violations (`ER0204`). * **`500` (ER0183)** — a server-side error (`"Something went wrong."`). This is the one code that suggests the problem is on APITube’s side. If you see it repeatedly, check the status page. So a `429` or a `402` is never an outage — it means your requests or your quota need attention, covered in [handling rate-limit errors](/en/articles/troubleshooting/rate-limit-errors) and the full [error-code reference](/en/articles/troubleshooting/error-codes). ## How do I health-check the API without a key?[#](#how-do-i-health-check-the-api-without-a-key) Send a `GET` request to `/ping`. It skips authentication and returns the plain string `pong`, so it is a lightweight way to confirm the API is reachable from your network — for example, in an uptime monitor or a deploy smoke test: ``` curl "https://api.apitube.io/ping" ``` A `pong` response means the API is up and answering. If `/ping` times out or returns a `500`, the problem is not your [API key](/en/articles/getting-started/glossary#api-key) (this endpoint needs none) — check the status page next. Because `/ping` needs no authentication, it does not touch your quota or count as a billed request. ## How do I check my own account status?[#](#how-do-i-check-my-own-account-status) Many “errors” are simply an empty balance. Before blaming an outage, confirm your account still has requests to spend by calling the authenticated balance endpoint: ``` curl "https://api.apitube.io/v1/balance?api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If this returns your balance normally but your data calls still fail with `402`, you are out of requests; if it fails with `401`, the key itself is the problem. See [how to check your balance via the API](/en/articles/retrieval/check-balance-api) for the full response shape. A `429` and a `500` look similar — both interrupt a working integration — but they mean opposite things. `429` (ER0203/ER0204) is **your** request rate and clears on its own once you slow down; `500` (ER0183) is a fault on the API side and is the code worth checking against the status page. # Common Questions[#](#common-questions) * [Is the APITube API down right now?](#is-the-apitube-api-down-right-now) * [How do I tell a rate-limit ban from a real outage?](#how-do-i-tell-a-rate-limit-ban-from-a-real-outage) * [Can I monitor APITube uptime automatically?](#can-i-monitor-apitube-uptime-automatically) ## Is the APITube API down right now?[#](#is-the-apitube-api-down-right-now) Check two things. Open **[https://status.apitube.io](https://status.apitube.io)** for the current operational status and any active incidents, and call `GET /ping` to see whether the API answers with `pong` from your own network. If `/ping` succeeds but a specific request fails, the problem is that request — read its HTTP code (`401`, `402`, `403`, or `429`), not a platform outage. ## How do I tell a rate-limit ban from a real outage?[#](#how-do-i-tell-a-rate-limit-ban-from-a-real-outage) By the error code. A [rate-limit](/en/articles/getting-started/glossary#rate-limit) ban returns `429` with `ER0204` and a “temporarily banned” message after repeated limit violations; it lifts automatically once you back off. A real outage shows up as `500` (`ER0183`, “Something went wrong.”) across many requests, and is what the status page reports. A `429` is never an outage — it is a signal to reduce your request rate. ## Can I monitor APITube uptime automatically?[#](#can-i-monitor-apitube-uptime-automatically) Yes. Point an uptime monitor at `https://api.apitube.io/ping` and treat any non-`pong` response — a timeout or a `5xx` — as down. Because `/ping` needs no API key and does not consume quota, it is safe to poll on a schedule. For overall status and incident history, watch the status page at **[https://status.apitube.io](https://status.apitube.io)**. * * * ## Related Articles * [Understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes) * [How to check your balance via the API](/en/articles/retrieval/check-balance-api) * [How to handle rate-limit (429) errors](/en/articles/troubleshooting/rate-limit-errors) --- ## Where to Find APITube Product Updates and Changelog URL: https://support.apitube.io/en/articles/trust-and-support/changelog Find the APITube changelog at docs.apitube.io/platform/changelog and in your dashboard under Changelog: versioned, dated release notes for every platform… # Where to Find APITube Product Updates and Changelog Find the public changelog and the in-dashboard release notes, and read how each versioned, dated entry is organized ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 4, 2026 Updated July 21, 2026 # Where to find APITube product updates and changelog[#](#where-to-find-apitube-product-updates-and-changelog) APITube publishes every platform change in one public **changelog** at **[docs.apitube.io/platform/changelog](https://docs.apitube.io/platform/changelog)**, and the exact same log is built into your dashboard under **Changelog**. Each release is versioned and dated with the newest entry at the top, so you can see precisely what shipped, when it shipped, and which part of the platform it touched. There are two places to read it, and they never disagree because the in-dashboard page renders the same underlying file as the public docs page. Use the public page when you have no login open; use the dashboard page when you are already signed in and want updates next to your keys and usage. ## Where is the APITube changelog?[#](#where-is-the-apitube-changelog) There are two official surfaces for product updates: * **Public docs:** [docs.apitube.io/platform/changelog](https://docs.apitube.io/platform/changelog) — open to everyone, no login required. It is linked from the main site’s top navigation (under the “Changelog” item) and again in the site footer, so you can always reach it. * **In your dashboard:** open **Changelog** from the sidebar at `dashboard.apitube.io/changelog`. This page reads the same source as the public docs changelog, so the release notes you see there are identical to the public ones — just placed inside your account. Because both surfaces come from a single source, you never have to reconcile two versions of “what changed.” Pick whichever is closer to hand. ![The Changelog page inside the dashboard rendering the same release notes as the public docs](/images/article/dashboard-changelog.png) ## What does the APITube changelog include?[#](#what-does-the-apitube-changelog-include) The changelog lists new features, improvements, and bug fixes made to the platform — that is its whole job, as the note at the top of the page states. Each entry is tagged to show the area it affects (for example `[News API]`), and when an entry introduces a feature, it links straight to that feature’s documentation page. Recent additions read as a timeline of what the News API has gained. For instance, the log records the **Fact Check** endpoint, **[entity](/en/articles/getting-started/glossary#entity)\-level [sentiment](/en/articles/getting-started/glossary#sentiment)** filters, **[Webhooks](/en/articles/getting-started/glossary#webhook)** push delivery, the **Local News** endpoint, and the **People / Companies / Journalists** reference endpoints — each with the version and date it landed. So the changelog doubles as a quick map of newer capabilities: if you are unsure whether a feature exists yet, its presence (and date) in the log is the answer. To go deeper on any of these, follow the in-entry link — for example the [webhooks overview](/en/articles/delivery-and-export/webhooks/what-are-webhooks). ## How is the APITube changelog organized?[#](#how-is-the-apitube-changelog-organized) Every release is a heading in the form `version — date`, newest first. A real header looks like: ``` ## 1.0.46 — July 3, 2026 ``` Under each version header is a bullet list of the changes in that release. The history runs all the way back to version **1.0.1 (December 12, 2024)**, so the changelog is a complete record of the platform’s releases, not just the latest few. Reading top-to-bottom gives you the most recent work; scrolling down walks backward through every prior version. ## How do I find when a feature was added?[#](#how-do-i-find-when-a-feature-was-added) Open the changelog and search the page with your browser’s find (`Ctrl+F` / `Cmd+F`) for the feature’s name — a parameter, an endpoint, an error code. The nearest `version — date` header above the match tells you the release it shipped in and the date it went live. Because entries also carry documentation links, you can jump from the changelog straight to the full reference for that feature. The **changelog** and the **status page** answer different questions. The changelog is the historical record of _what changed_ in the platform (features, fixes, new endpoints). The status page at `status.apitube.io` is about _live health_ — whether the API is up right now and its incident history. If an integration suddenly breaks, check the status page; if you want to know what a new field or endpoint is, check the changelog. # Common Questions[#](#common-questions) * [Is the dashboard changelog different from the public one?](#is-the-dashboard-changelog-different-from-the-public-one) * [How far back does the changelog go?](#how-far-back-does-the-changelog-go) * [Where do I report a bug or request a feature?](#where-do-i-report-a-bug-or-request-a-feature) * [Do the changelog entries link anywhere?](#do-the-changelog-entries-link-anywhere) ## Is the dashboard changelog different from the public one?[#](#is-the-dashboard-changelog-different-from-the-public-one) No. The **Changelog** page in your dashboard renders the same source file as the public [docs.apitube.io/platform/changelog](https://docs.apitube.io/platform/changelog) page, so the two show identical release notes. The only difference is context: the public page needs no login, while the dashboard page sits inside your account next to keys, usage, and billing. ## How far back does the changelog go?[#](#how-far-back-does-the-changelog-go) All the way back to the first release. The oldest entry in the log is version **1.0.1, dated December 12, 2024**, and every release since then is listed above it in order. That makes the changelog a full history of the platform rather than a rolling “recent changes” snippet. ## Where do I report a bug or request a feature?[#](#where-do-i-report-a-bug-or-request-a-feature) The changelog is read-only — it records what has already shipped, not requests. To flag a problem or suggest something new, follow [how to report a bug or request a feature](/en/articles/trust-and-support/report-bug-request-feature). New work, once released, then shows up in the changelog with its version and date. ## Do the changelog entries link anywhere?[#](#do-the-changelog-entries-link-anywhere) Yes. When a changelog entry introduces a feature, it links to that feature’s documentation page (for example a new endpoint links to its reference). Following the link takes you from the one-line summary in the changelog to the full parameters and examples in the docs, so you can go from “this exists now” to “here is how to call it” in one click. * * * ## Related Articles * [Where to Check APITube API Status and Uptime](/en/articles/trust-and-support/api-status) * [How to Report a Bug or Request a Feature](/en/articles/trust-and-support/report-bug-request-feature) * [What Are Webhooks and How Do They Work?](/en/articles/delivery-and-export/webhooks/what-are-webhooks) --- ## How to Contact APITube Support URL: https://support.apitube.io/en/articles/trust-and-support/contact-support Contact APITube support by live chat on any Help Center page or email support@apitube.io. Send bug reports and feature requests to hello@apitube.io. # How to Contact APITube Support The channels for reaching the APITube team — live chat, email, the contact form, and the right address for bugs and feature requests ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 4, 2026 # How to contact APITube support[#](#how-to-contact-apitube-support) The two fastest ways to reach APITube support are the **live chat widget** on any Help Center page and email at **[support@apitube.io](mailto:support@apitube.io)**. The chat opens a conversation where you can send the team a message; the email address is the general contact for your account and anything not covered elsewhere. Product feedback has its own address — send **bug reports and feature requests to [hello@apitube.io](mailto:hello@apitube.io)** — and platform-wide problems are tracked on the status page at **status.apitube.io**. Which channel to use depends on what you need: a quick question, a billing or key problem, a bug, a feature idea, or a check on whether the API itself is down. This article maps each situation to the right channel so your message reaches the correct place the first time. ## What are the ways to contact APITube support?[#](#what-are-the-ways-to-contact-apitube-support) APITube gives you several channels, and picking the matching one gets you a faster answer: * **Live chat** — every Help Center page shows a chat widget in the corner. Open it to send the team a message directly from the page you are reading, without switching to email. * **Email `support@apitube.io`** — the general support address for account questions, billing, [API keys](/en/articles/getting-started/glossary#api-key), and anything not covered by a more specific channel. It is listed as the official Contact on the APITube About page. * **Email `hello@apitube.io`** — the address for product feedback: bug reports, feature requests, and requests to add a new news source. * **Contact form** — the `/contact` page on apitube.io takes your name, email, and message and sends it to the team, which is handy when you do not want to open your mail client. * **Status page** — [status.apitube.io](https://status.apitube.io) shows whether the platform is operational and lists past incidents, so you can tell a real outage from a problem on your side. ## Which email should I use, support@ or hello@?[#](#which-email-should-i-use-support-or-hello) APITube runs two contact addresses, and using the right one routes your message correctly: * **`support@apitube.io`** — the general contact for your **account and everything else**: login trouble, billing, subscriptions, API keys, quota, and usage questions. This is the address published as the official Contact on the company’s About page and referenced as the “support service” in the documentation. * **`hello@apitube.io`** — **product feedback**: reporting a bug, requesting a new feature, or asking to add a news website. If your message is “here’s something that’s broken” or “here’s something I wish the API did,” `hello@apitube.io` is the right address. When you are unsure, `support@apitube.io` is the safe default — the team can route it internally. For adding a publication specifically, see [how to request a new news source](/en/articles/trust-and-support/request-news-source), which walks through checking coverage before you write. ## How do I get help fastest?[#](#how-do-i-get-help-fastest) Two habits make support faster. First, **read the HTTP error code** your request returned before you write in — many “the API is broken” reports are a `401`, `402`, `403`, or `429` on the caller’s side, each with a specific `ER…` identifier you can fix yourself. The full map is in [understanding API error codes](/en/articles/troubleshooting/error-codes). Second, if calls are failing broadly, **check [status.apitube.io](https://status.apitube.io)** first — a live outage is reported there, and there is nothing support can add beyond the incident update. See [where to check API status and uptime](/en/articles/trust-and-support/api-status) for how to tell an outage from a key or quota issue. When you do write, include the concrete details: the endpoint you called, the exact error code and message, and a request example with your key redacted. That turns a back-and-forth into a single reply. ## Where do I report a bug or request a feature?[#](#where-do-i-report-a-bug-or-request-a-feature) Send both to **`hello@apitube.io`**. For a **bug**, describe what you called, what you expected, and what happened instead — the endpoint, parameters, and the error code make it reproducible. For a **feature request**, describe the outcome you need; feedback feeds into what the team prioritizes. The same address also handles requests to add a new news source, so any “please change or add this” message belongs there. To see what has already shipped before you ask, the public **changelog** at [docs.apitube.io/platform/changelog](https://docs.apitube.io/platform/changelog) lists product updates — your requested feature may already be live. Before emailing about a failing request, read its HTTP status code. A `429` is a rate limit and a `402` is an empty balance — both are on your side and clear without support. Reserve `support@apitube.io` for genuine account issues and a `500` that persists after the status page shows all-clear. # Common Questions[#](#common-questions) * [What is the APITube support email?](#what-is-the-apitube-support-email) * [Is there a live chat for support?](#is-there-a-live-chat-for-support) * [How do I report an API bug?](#how-do-i-report-an-api-bug) * [How do I know if the problem is an outage?](#how-do-i-know-if-the-problem-is-an-outage) ## What is the APITube support email?[#](#what-is-the-apitube-support-email) The general support email is **[support@apitube.io](mailto:support@apitube.io)** — the official Contact address for account, billing, API-key, and usage questions, listed on the APITube About page. Product feedback (bugs, feature requests, and new-source requests) goes to **[hello@apitube.io](mailto:hello@apitube.io)** instead. If you are not sure which fits, use `support@apitube.io` and the team will route it. ## Is there a live chat for support?[#](#is-there-a-live-chat-for-support) Yes. Every Help Center page shows a live chat widget in the corner. Opening it lets you send the APITube team a message right from the page you are on, so you do not have to switch to email for a quick question. There is no published response time, so treat the reply — by chat or email — as the confirmation. ## How do I report an API bug?[#](#how-do-i-report-an-api-bug) Email **[hello@apitube.io](mailto:hello@apitube.io)** with the details that make the bug reproducible: the endpoint you called, the parameters, the HTTP status and `ER…` error code you received, and what you expected instead. A concrete request example (with your API key redacted) is the single most useful thing to include. The same address takes feature requests and requests to add a news source. ## How do I know if the problem is an outage?[#](#how-do-i-know-if-the-problem-is-an-outage) Read the error code and check the status page. A `401`, `402`, `403`, or `429` is on your side — a key, billing, access, or [rate-limit](/en/articles/getting-started/glossary#rate-limit) issue you can fix without contacting anyone. A `500` (`ER0183`) across many requests points at the platform, and that is what [status.apitube.io](https://status.apitube.io) reports. See [where to check API status and uptime](/en/articles/trust-and-support/api-status) for the full outage-vs-your-side checklist. * * * ## Related Articles * [Where to Check APITube API Status and Uptime](/en/articles/trust-and-support/api-status) * [How to Request a New News Source](/en/articles/trust-and-support/request-news-source) * [Understanding API error codes and HTTP responses](/en/articles/troubleshooting/error-codes) --- ## Trust, Coverage & Support URL: https://support.apitube.io/en/articles/trust-and-support How APITube scores source authority, how wide the coverage is, and how to reach support — including the OPR (Open PageRank) score used across the News API. ![](/images/collections/user-management-security.png) # Trust, Coverage & Support Source authority, coverage and support. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) By Beatrice and 2 others 3 authors 7 articles How to reach us and what we publish about the platform: contact channels for account and technical questions, the product changelog, how source coverage is measured, what the OPR source-quality score means, plus how to request a new news source or report a bug. The short version on contact: account and billing questions go to [support@apitube.io](mailto:support@apitube.io), bug reports and feature or source requests go to [hello@apitube.io](mailto:hello@apitube.io), and the in-page chat answers quick questions fastest. [Contact support](/en/articles/trust-and-support/contact-support) lists every channel with response expectations. * [How many websites does APITube aggregate?](/en/articles/trust-and-support/source-coverage) * [How to Contact APITube Support](/en/articles/trust-and-support/contact-support) * [How to Report a Bug or Request a Feature](/en/articles/trust-and-support/report-bug-request-feature) * [How to Request a New News Source](/en/articles/trust-and-support/request-news-source) * [What is the OPR (Open PageRank) score?](/en/articles/trust-and-support/what-is-opr) * [Where to Check APITube API Status and Uptime](/en/articles/trust-and-support/api-status) * [Where to Find APITube Product Updates and Changelog](/en/articles/trust-and-support/changelog) --- ## How to Report a Bug or Request a Feature URL: https://support.apitube.io/en/articles/trust-and-support/report-bug-request-feature To report an APITube bug, email hello@apitube.io or use the live chat with your request URL, HTTP status and ER error code. Feature requests go to… # How to Report a Bug or Request a Feature Where to send an APITube bug report, what to put in it, and how to suggest a new feature ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 5, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=election&debug=1) # How to report a bug or request a feature[#](#how-to-report-a-bug-or-request-a-feature) To report a bug in the APITube News API, email **[hello@apitube.io](mailto:hello@apitube.io)** or open the **live chat** on this help center, and include the request that failed: the endpoint URL (with your key removed), the HTTP status code, and the `ER…` error identifier from the response. To request a feature, email **[hello@apitube.io](mailto:hello@apitube.io)** and describe what you want to do. There is no separate bug-tracker form or dashboard button — reports go to a person, so a clear, reproducible example gets you a faster answer. Before you file a bug, it is worth a quick check that the failure is really a bug and not a key, quota, or [rate-limit](/en/articles/getting-started/glossary#rate-limit) issue on your side — those are the most common “the API is broken” reports, and they have their own fixes. ## How do you report a bug in the APITube API?[#](#how-do-you-report-a-bug-in-the-apitube-api) Send a bug report to **[hello@apitube.io](mailto:hello@apitube.io)**, the address for bug reports, feature requests, and new-source requests, or use the **live chat** widget available on this help center for a faster back-and-forth. There is no self-serve form: each report is read by the team, so the more precisely you describe the failing request, the quicker they can reproduce and fix it. The single most useful thing you can attach is the exact request that failed, with the [API key](/en/articles/getting-started/glossary#api-key) stripped out. Never paste a working key into an email or chat — replace it with `YOUR_API_KEY`. A report the team can copy, run, and see fail is worth far more than a description of the symptom. ## What should you include in a bug report?[#](#what-should-you-include-in-a-bug-report) Give the team everything needed to reproduce the failure in one message: * **The endpoint and full request** — for example `GET /v1/news/everything?title=election&language.code=en`, with the key masked. * **The HTTP status code and `ER…` identifier** — APITube returns a specific code (like `ER0214` or `ER0057`) for client-side problems; the identifier tells the team exactly which check failed. See the [full error-code reference](/en/articles/troubleshooting/error-codes). * **What you expected versus what you got** — the actual response body, or the part of it that looks wrong. * **When it happened** — an approximate timestamp helps correlate with logs. You can copy the failing call straight from your [dashboard request logs](/en/articles/account-and-dashboard/usage-and-logs/view-logs). * **Whether it is reproducible** — does it fail every time, or only sometimes? A powerful debugging aid to run _before_ reporting is the `debug` parameter. Set `debug=1` and the response includes a `user_input` object that shows every parameter exactly as the API parsed it — the fastest way to catch a misspelled parameter or a URL-encoding problem that looks like an API bug: ``` curl "https://api.apitube.io/v1/news/everything?title=election&debug=1&api_key=YOUR_API_KEY" ``` Use `debug=1` only while investigating, not in production. If the `user_input` object shows your parameter parsed differently than you intended, the fix is in your request, not the API. For more, see [how to debug your API requests](/en/articles/troubleshooting/debug-requests) and the canonical [debugging guide](https://docs.apitube.io/platform/news-api/debugging). ## How do you request a new feature?[#](#how-do-you-request-a-new-feature) Feature requests and product suggestions go to **[hello@apitube.io](mailto:hello@apitube.io)** — the same address that handles new-source requests. Describe the outcome you are after, not just the parameter you wish existed: what are you trying to build, and what is blocking you today? A concrete use case (“I need to filter articles by X so I can do Y”) gives the team the context to weigh it against their roadmap. There is no published turnaround, so treat the reply as the confirmation. If your request is specifically to add a publication to the index, follow the dedicated flow in [how to request a new news source](/en/articles/trust-and-support/request-news-source). ## Is it actually a bug? Check these first[#](#is-it-actually-a-bug-check-these-first) Most reported “bugs” are configuration or account issues that resolve without a fix. Read the HTTP status code first — a `401`, `402`, `403`, or `429` is on your side, not a platform fault, and each has a specific cause listed in the [error-code reference](/en/articles/troubleshooting/error-codes). Three cases in particular are not bugs: * **Masked or placeholder article text.** That is the [test key](/en/articles/getting-started/glossary#test-key-and-live-key) or the Free plan truncating content for preview, working as designed — see [why results are masked](/en/articles/troubleshooting/masked-results). * **A broad outage or `500` responses.** Check the status page at **status.apitube.io** and ping the unauthenticated health endpoint (`GET /ping`, which answers `pong`) before reporting — a platform incident is already known, not something to file. * **A missing news source.** If a domain returns `ER0214`, the site simply is not indexed yet; that is a source request to `hello@apitube.io`, not a bug. # Common Questions[#](#common-questions) * [Where do I report a bug versus a feature?](#where-do-i-report-a-bug-versus-a-feature) * [Where do I report a bug in an APITube SDK?](#where-do-i-report-a-bug-in-an-apitube-sdk) * [Is there a bug-tracker or feature-request board?](#is-there-a-bug-tracker-or-feature-request-board) * [How do I know if it is a real bug before reporting?](#how-do-i-know-if-it-is-a-real-bug-before-reporting) ## Where do I report a bug versus a feature?[#](#where-do-i-report-a-bug-versus-a-feature) Report a **bug** — something returning the wrong result or failing when it should work — to **[hello@apitube.io](mailto:hello@apitube.io)** or the live chat, with the failing request attached. Send a **feature request** or product suggestion to the same address, **[hello@apitube.io](mailto:hello@apitube.io)**, describing your use case. Both are handled by the team directly; there is no form to fill in. ## Where do I report a bug in an APITube SDK?[#](#where-do-i-report-a-bug-in-an-apitube-sdk) APITube publishes its open-source SDKs and examples on GitHub at **github.com/apitube** (for example the Node.js and PHP News API clients). If the bug is in a client library rather than the API itself, opening an issue on the relevant repository is the most direct route, because it reaches the code the team maintains. For a bug in the API’s behavior or data, email **[hello@apitube.io](mailto:hello@apitube.io)** instead. ## Is there a bug-tracker or feature-request board?[#](#is-there-a-bug-tracker-or-feature-request-board) No public bug-tracker or feature-voting board is exposed. Bug reports and feature requests are both handled over email at **[hello@apitube.io](mailto:hello@apitube.io)** and through live chat, and library-specific issues go to the GitHub repositories. This is the same person-reviewed model APITube uses for adding new sources. ## How do I know if it is a real bug before reporting?[#](#how-do-i-know-if-it-is-a-real-bug-before-reporting) Read the response. A `4xx` status with an `ER…` code is a client-side problem — a key, quota, scope, or parameter issue — and the [error-code reference](/en/articles/troubleshooting/error-codes) tells you which. Masked content means a test or Free-plan key, not a bug. A `500` across many requests points at the platform, so check **status.apitube.io** and `GET /ping` first. If the request is well-formed, returns a `500` on its own, or produces data that is clearly wrong, that is a genuine bug worth reporting. * * * ## Related Articles * [How to Debug Your API Requests](/en/articles/troubleshooting/debug-requests) * [Understanding API Error Codes and HTTP Responses](/en/articles/troubleshooting/error-codes) * [How to Request a New News Source](/en/articles/trust-and-support/request-news-source) --- ## How to Request a New News Source URL: https://support.apitube.io/en/articles/trust-and-support/request-news-source To request a new news source, email hello@apitube.io with the website — after checking coverage with the source.domain filter first. # How to Request a New News Source Check whether APITube already covers a site, then email the team to add it ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 4, 2026 Updated July 7, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_domain=example-news.com) # How to request a new news source[#](#how-to-request-a-new-news-source) To request a new news source, email the APITube team at **[hello@apitube.io](mailto:hello@apitube.io)** with the website you would like added. APITube reviews the site and replies with the next steps — sources are added per request, so there is no self-serve form to fill in. Before you write, it is worth checking whether the site is already indexed, because APITube already aggregates from a large pool of sources and yours may be covered. This article shows both halves: how to confirm coverage with the API, and how to send the request if the source is genuinely missing. ## How do you request a new source?[#](#how-do-you-request-a-new-source) Send a short email to **[hello@apitube.io](mailto:hello@apitube.io)** naming the website you want indexed. The team reviews the site and gets back to you with the next steps — that review step is why a request is a message to a person, not an instant API call. If you are not sure which address to use, `hello@apitube.io` is the right one for source requests; `support@apitube.io` is the general contact for the account and everything else. Include the site’s homepage URL so the reviewer can find it quickly. There is no published turnaround time, so treat the reply as the confirmation that the source is (or is not) being added. ## How do you check whether APITube already covers a source?[#](#how-do-you-check-whether-apitube-already-covers-a-source) Before requesting, test the domain against the live index with the `source.domain` filter on `/v1/news/everything`. If the domain is indexed you get matching articles back; if it is **not** indexed, the request fails with HTTP 400 and error `ER0214` (`source domain name '…' not found`). That error is the clearest signal that a site is missing and worth requesting: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=example-news.com&api_key=YOUR_API_KEY" ``` `source.domain` accepts up to three comma-separated domains, each 1 to 255 characters (a value outside that range returns `ER0057`). The mirror parameter `ignore.source.domain` excludes a domain instead (`ER0059` for a bad length). See [how to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) for the full filter. ## How do you check whether a source is already indexed?[#](#how-do-you-check-whether-a-source-is-already-indexed) There is no name-based source directory, so check a publication by its exact website domain. Query the domain with the `source.domain` filter on `/v1/news/everything`: an indexed domain returns articles, while a domain APITube does not track returns HTTP 400 with error `ER0214`. ``` curl "https://api.apitube.io/v1/news/everything?source.domain=reuters.com&api_key=YOUR_API_KEY" ``` An empty article list, or an `ER0214` error, tells you the source is not yet covered and is a good candidate to request. ## Why might a source not be indexed yet?[#](#why-might-a-source-not-be-indexed-yet) APITube does not index every website automatically; sources are curated, and coverage is built out over time and by request. If a site returns `ER0214`, it simply has not been added yet — requesting it is exactly how new publications enter the pipeline. To understand how APITube selects and vets the sources it does carry, see [how APITube ensures data quality](/en/articles/news-data/data-quality). For the full list of source-related parameters, the official [parameters reference](https://docs.apitube.io/platform/news-api/everything) is the canonical source. # Common Questions[#](#common-questions) * [Which email should I use to request a source?](#which-email-should-i-use-to-request-a-source) * [How do I confirm a source is missing before requesting it?](#how-do-i-confirm-a-source-is-missing-before-requesting-it) * [Is there a form or dashboard button to add a source?](#is-there-a-form-or-dashboard-button-to-add-a-source) * [Can I request a feature the same way?](#can-i-request-a-feature-the-same-way) ## Which email should I use to request a source?[#](#which-email-should-i-use-to-request-a-source) Use **[hello@apitube.io](mailto:hello@apitube.io)** to request a new news source, and include the website you want added. APITube reviews the site and replies with the next steps. The general account contact is **[support@apitube.io](mailto:support@apitube.io)**, but for adding a publication `hello@apitube.io` is the address that goes to the right place. ## How do I confirm a source is missing before requesting it?[#](#how-do-i-confirm-a-source-is-missing-before-requesting-it) Query the domain with `source.domain` on `/v1/news/everything`. Indexed domains return articles; a domain that is not indexed returns HTTP 400 with error `ER0214`. An empty article list or that error confirms the site is a valid candidate to request. ## Is there a form or dashboard button to add a source?[#](#is-there-a-form-or-dashboard-button-to-add-a-source) No. New sources are added per request by the APITube team, so the process is an email to **[hello@apitube.io](mailto:hello@apitube.io)** rather than a self-serve form. The team reviews each requested website before it is added to the index. ## Can I request a feature the same way?[#](#can-i-request-a-feature-the-same-way) Yes. Feature requests and suggestions also go to **[hello@apitube.io](mailto:hello@apitube.io)** — the same address handles both new-source requests and product feedback. Describe what you need and the team will factor it into their planning. * * * ## Related Articles * [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [How does APITube ensure data quality?](/en/articles/news-data/data-quality) * [What is the OPR (Open PageRank) score?](/en/articles/trust-and-support/what-is-opr) --- ## How many websites does APITube aggregate? URL: https://support.apitube.io/en/articles/trust-and-support/source-coverage APITube covers a broad, curated pool of news sources across 59 languages and 177 countries. There's no total-count endpoint — check coverage with source.domain. # How many websites does APITube aggregate? APITube covers a broad, curated pool of news sources — and how to measure that coverage for your own topics and regions ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 4, 2026 Updated July 7, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_domain=example-news.com) # How many websites does APITube aggregate?[#](#how-many-websites-does-apitube-aggregate) APITube aggregates a **broad, curated pool** of news sources across **59 languages and 177 countries**, but the API does not publish a single fixed “N websites” number, and there is no endpoint that lists every publisher. Coverage is curated and added over time, so the reliable way to answer “is my source in here?” is to test the specific sites, topics, and regions you care about — the API gives you three tools to measure that directly. Instead of trusting one headline figure, you check coverage against the live index: confirm a domain with the `source.domain` filter and size a topic or region with `/v1/news/count`. This article shows each check, so you can judge coverage for exactly the slice of news you need. ## Does APITube publish a total source count?[#](#does-apitube-publish-a-total-source-count) No. There is no directory endpoint that returns the full list of publishers or a grand total — the source directory routes are intentionally not exposed by the API. That is a deliberate design choice, the same one APITube makes for archive depth: rather than a marketing number that can drift out of date, the API lets you measure the real, current coverage for your own filters. What you _can_ rely on is the enrichment attached to every article. Each result carries a `source` object with the publisher’s `domain`, country, political `bias`, and an **[OPR](/en/articles/getting-started/glossary#opr-open-pagerank) (Open PageRank) authority score from 0 to 10** under `source.rankings.opr`. Because sources range from unranked domains up to top-tier publishers, sampling that field across your results tells you the _quality spread_ of the coverage you are getting, not just its size. See [what is the OPR score](/en/articles/trust-and-support/what-is-opr) for the scale. ## How do I check whether a specific website is covered?[#](#how-do-i-check-whether-a-specific-website-is-covered) Test the domain against the live index with the `source.domain` filter on `/v1/news/everything`. If the domain is indexed you get matching articles back; if it is not, the request fails with `400` and error `ER0214` (`source domain name '…' not found`). That error is the clearest yes/no signal for a single site: ``` curl "https://api.apitube.io/v1/news/everything?source.domain=example-news.com&api_key=YOUR_API_KEY" ``` `source.domain` accepts up to **three** comma-separated domains, each 1 to 255 characters (a value outside that range returns `ER0057`). There is no name-based source directory, so check each publication by its exact website domain. An empty autocomplete result, like an `ER0214`, tells you the source is not yet indexed. For the full filter, see [how to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source). ## How do I gauge coverage for my topic or region?[#](#how-do-i-gauge-coverage-for-my-topic-or-region) Use `/v1/news/count` to measure how much of a topic, language, or country APITube actually holds — it returns the number of matching articles without downloading them, so it is cheap to run across many slices. Because it accepts the same filter chain as search, you can profile coverage by any dimension: ``` curl "https://api.apitube.io/v1/news/count?language.code=de&source.country.code=de&api_key=YOUR_API_KEY" ``` Coverage spans **59 languages and 177 countries** — filter by an article’s language with `language.code` and by the publisher’s country with `source.country.code`, then compare the counts to see where coverage is deep and where it is thin. The authoritative code lists live in the official [parameters reference](https://docs.apitube.io/platform/news-api/everything); for how the two filters differ, see [which languages and countries are supported](/en/articles/getting-started/supported-languages-and-countries). Article volume varies a lot by language and region, so a per-slice count is far more useful than any global number. ## Where do the sources come from?[#](#where-do-the-sources-come-from) APITube continuously discovers news from publishers across the web — through their RSS feeds, Google News, and XML sitemaps — then fetches, cleans, and enriches each article before indexing it. The pool is **curated**, not scraped indiscriminately: sources are vetted and added over time, and you can ask for a specific one to be included. If a site you need returns `ER0214` or no autocomplete match, email the team at **[hello@apitube.io](mailto:hello@apitube.io)** to request it — see [how to request a new news source](/en/articles/trust-and-support/request-news-source). # Common Questions[#](#common-questions) * [Is there an endpoint that lists every source?](#is-there-an-endpoint-that-lists-every-source) * [Why doesn’t APITube give one headline number?](#why-doesnt-apitube-give-one-headline-number) * [How do I estimate the number of sources in my results?](#how-do-i-estimate-the-number-of-sources-in-my-results) * [What if the source I need isn’t covered?](#what-if-the-source-i-need-isnt-covered) ## Is there an endpoint that lists every source?[#](#is-there-an-endpoint-that-lists-every-source) No. APITube exposes the `source.domain` filter for checking a specific domain, but there is no public directory or name-lookup endpoint that returns the complete list of publishers or a total count. You confirm coverage per source or per query, not by pulling one master list. ## Why doesn’t APITube give one headline number?[#](#why-doesnt-apitube-give-one-headline-number) Because a fixed number would be misleading. Coverage is curated and grows over time, and what matters is depth for _your_ filters, not a global figure — a feed that indexes many low-authority domains is not better than one with fewer, higher-OPR publishers. Measuring with `source.domain` and `/v1/news/count` gives you the real, current answer for the sources you actually rely on. ## How do I estimate the number of sources in my results?[#](#how-do-i-estimate-the-number-of-sources-in-my-results) Read the `source.domain` field on the articles a query returns and collect the distinct values. Running a search over your topic and counting the unique domains in the response is the practical way to see how many publishers cover that subject in the index — a targeted estimate that a single global count could never give you. ## What if the source I need isn’t covered?[#](#what-if-the-source-i-need-isnt-covered) Request it. If a domain returns `ER0214`, the site simply has not been added yet. Email **[hello@apitube.io](mailto:hello@apitube.io)** with the homepage URL, and APITube reviews the site and replies with next steps — requesting a source is exactly how new publications enter the pipeline. * * * ## Related Articles * [How to Request a New News Source](/en/articles/trust-and-support/request-news-source) * [How to filter news by source or domain](/en/articles/searching-and-filtering/by-attribute/filter-by-source) * [Which languages and countries are supported?](/en/articles/getting-started/supported-languages-and-countries) --- ## What is the OPR (Open PageRank) score? URL: https://support.apitube.io/en/articles/trust-and-support/what-is-opr OPR (Open PageRank) is APITube's 0–10 authority score for a news source. Read it from source.rankings.opr and filter with source.rank.opr.min and .max. # What is the OPR (Open PageRank) score? The 0–10 authority score APITube attaches to every news source ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 2, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&source_rank_min=7) # What is the OPR (Open PageRank) score?[#](#what-is-the-opr-open-pagerank-score) [OPR](/en/articles/getting-started/glossary#opr-open-pagerank) (Open PageRank) is an authority score from **0 to 10** that APITube attaches to every news source — the publishing domain, not the individual article. A higher number means a more established, higher-authority publisher. Every article returned by the News API carries the score of its source under `source.rankings.opr`, and you can filter results by it with `source.rank.opr.min` and `source.rank.opr.max`. Because OPR describes the **source**, every article from the same domain shares the same OPR value. It measures how authoritative the publisher is — not whether a specific story is accurate, positive, or breaking. For those, APITube has separate fields such as `sentiment` and `is_breaking`. ## Where do I find the OPR score in a response?[#](#where-do-i-find-the-opr-score-in-a-response) Every article includes its source’s OPR under `source.rankings.opr` as a whole number from 0 to 10: ``` { "source": { "domain": "example-news.com", "rankings": { "opr": 8 } } } ``` You do not need a special parameter to get it — the value is part of the standard `source` object on each article, the same object that also holds the publisher’s `domain`, `bias`, and `location`. For the full list of fields on an article, see [what’s inside a news article](/en/articles/getting-started/understanding-article-data). ## What does the OPR score mean, from 0 to 10?[#](#what-does-the-opr-score-mean-from-0-to-10) OPR is scored on a **0 to 10 integer scale**, where 0 is an unranked or unknown domain and 10 is the strongest authority. APITube treats **OPR 5** as its own bar for a well-ranked publisher: that is the floor used by top headlines and by the built-in quality flags described below. As a rough guide for setting your own floor: * **OPR 5 and above** — established, well-ranked publishers. APITube’s default authority bar. * **OPR 6 and above** — the top tier, used by the premium-source flag. * **Below 5** — smaller, newer, or niche domains. Useful for wide coverage, weaker as an authority signal. OPR rates the domain’s standing, so it is a signal of publisher reputation, not a fact-check of the article. ## How do I filter news by OPR score?[#](#how-do-i-filter-news-by-opr-score) Use `source.rank.opr.min` to set a floor and `source.rank.opr.max` to set a ceiling. Pass a **whole number** between 0 and 10 — the value is read as an integer, so a floor of 7 keeps only publishers ranked 7 or higher: ``` curl "https://api.apitube.io/v1/news/everything?source.rank.opr.min=7&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. If the value is not a number the request returns HTTP 400 with error `ER0044`; a negative value returns `ER0045`; a value whose length is outside 1–10 characters returns `ER0046`. The matching `source.rank.opr.max` errors are `ER0047`, `ER0048`, and `ER0049`. Combine the two to keep a band, for example mid-tier publishers only: ``` curl "https://api.apitube.io/v1/news/everything?source.rank.opr.min=4&source.rank.opr.max=7&api_key=YOUR_API_KEY" ``` ## Which built-in filters already use the OPR score?[#](#which-built-in-filters-already-use-the-opr-score) Several ready-made switches are built on the OPR-5 bar, so you do not have to set the floor by hand: * **Top headlines** — `/v1/news/top-headlines` only returns articles from high-authority sources with OPR 5 or higher. See [how to get top headlines](/en/articles/retrieval/get-top-headlines). * **`is_high_quality=1`** — keeps articles from an OPR-5+ publisher that are not duplicates, carry an image, and have a named author. * **`is_verified_source=1`** — keeps OPR 5+ publishers and drops duplicates. * **`is_premium_source=1`** — keeps only the top tier at OPR 6 or higher. For a full walkthrough of these flags and when to pick each one, see [how to filter for high-quality, verified sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources). ## Does OPR affect how local news is ranked?[#](#does-opr-affect-how-local-news-is-ranked) Yes. On `/v1/news/local`, OPR is one of the weights that decides ordering. The `authority` ranking preset leans most heavily on it, blending source authority with distance, recency, and importance, so higher-OPR publishers surface first when you ask for authoritative local coverage. # Common Questions[#](#common-questions) * [Does a higher OPR mean the article is true?](#does-a-higher-opr-mean-the-article-is-true) * [Is OPR set per article or per source?](#is-opr-set-per-article-or-per-source) * [Can I pass a decimal like 0.6 to the OPR filter?](#can-i-pass-a-decimal-like-06-to-the-opr-filter) ## Does a higher OPR mean the article is true?[#](#does-a-higher-opr-mean-the-article-is-true) No. OPR measures the **publisher’s authority**, not the accuracy of any single story. A high-OPR domain is more established, but the score does not verify claims. Treat OPR as a reputation signal and pair it with your own checks when accuracy matters. ## Is OPR set per article or per source?[#](#is-opr-set-per-article-or-per-source) Per source. OPR belongs to the publishing domain, so every article from the same source reports the same `source.rankings.opr` value. Filtering on `source.rank.opr.min` therefore keeps or drops whole publishers, not individual stories. ## Can I pass a decimal like 0.6 to the OPR filter?[#](#can-i-pass-a-decimal-like-06-to-the-opr-filter) Use a whole number. `source.rank.opr.min` and `source.rank.opr.max` are read as integers on a 0–10 scale, so pass values like `5`, `6`, or `7` rather than a decimal. Whole numbers match the same scale you see in `source.rankings.opr`. * * * ## Related Articles * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [How to get top headlines](/en/articles/retrieval/get-top-headlines) * [What's inside a news article?](/en/articles/getting-started/understanding-article-data) --- ## How to Monitor Your Brand Reputation URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/brand-reputation-monitoring Monitor your brand reputation with APITube: pull every mention, measure the tone toward your brand with entity.sentiment, track volume over time, and get live… # How to Monitor Your Brand Reputation Track every mention of your brand, measure the tone directed at it, watch volume shift over time, and get alerted the moment coverage lands ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Tesla&language_code=en) # How to monitor your brand reputation[#](#how-to-monitor-your-brand-reputation) Brand reputation monitoring on APITube is four moves against `/v1/news/everything` and its siblings: pull every article that names your brand, measure the tone directed at your brand with `entity.sentiment`, count how that volume shifts over time with `/v1/news/count`, and stream new coverage live so nothing surprises you. Start with one mention query and layer the rest on top of the same filters. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&language.code=en&api_key=YOUR_API_KEY" ``` Send the key as a header (`X-API-Key: YOUR_API_KEY`) if you prefer not to put it in the query string. Results come back newest-first, because the default `sort.by` is `published_at` and the default `sort.order` is `desc` — so the freshest mention is already at the top without adding a sort. ## How do I pull every article that mentions my brand?[#](#how-do-i-pull-every-article-that-mentions-my-brand) Add one [entity](/en/articles/getting-started/glossary#entity) filter to `/v1/news/everything`: `organization.name` for a company, or `brand.name` for a consumer brand. APITube resolves the name against the entities it tracks and returns only articles that mention it. Each filter accepts up to three comma-separated values, so you can watch a company and its product lines in a single request. If a name is not tracked or is misspelled you get a “not found” error — switch to the numeric `entity.id`, which is stable for a given brand and never changes. ``` curl "https://api.apitube.io/v1/news/everything?brand.name=Coca-Cola,Samsung Galaxy&language.code=en&per_page=100&api_key=YOUR_API_KEY" ``` `per_page` goes up to 250 (10 on Free, 50 on Starter, 200 on Basic), so a wide sweep of recent coverage fits in one call. To find the right `entity.id` for a brand, query the [entity autocomplete](/en/articles/searching-and-filtering/entities/entity-autocomplete) endpoint (`/v1/suggest/entities`) and reuse the identifier it returns. ## How do I measure whether coverage is positive or negative?[#](#how-do-i-measure-whether-coverage-is-positive-or-negative) Reputation is about the tone aimed _at you_, not the average mood of the article. That is what `entity.sentiment.polarity` gives you: paired with `organization.name` or `brand.name`, it keeps only articles where the [sentiment](/en/articles/getting-started/glossary#sentiment) measured toward your specific brand matches `positive`, `negative`, or `neutral`. To size the split, run the same filters through `/v1/news/count` twice — once for each polarity — and compare the two counts. ``` curl "https://api.apitube.io/v1/news/count?organization.name=Tesla&entity.sentiment.polarity=positive&published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` The count endpoint returns `{ "status": "ok", "count": 128, "request_id": "..." }` and costs one request, so a positive-versus-negative comparison for the last week is two cheap calls. In the full article response, every item in the `entities` array carries its own `sentiment` block with a `score`, a `polarity`, and a `mentions` breakdown counting `positive`, `neutral`, and `negative` references — the raw signal behind the filter. For a stricter cut, `entity.sentiment.score.min` and `entity.sentiment.score.max` (each from `-1` to `1`) let you keep only strongly-toned coverage and drop the borderline middle. ## How do I track mention volume over time?[#](#how-do-i-track-mention-volume-over-time) To see whether you are being talked about more or less, hold the brand filter fixed and move the date window with `published_at.start` and `published_at.end`. Both accept absolute timestamps and relative shortcuts such as `NOW-7DAYS`, `NOW-24HOURS`, or `NOW-1WEEK`. Counting each window with `/v1/news/count` builds a volume series without downloading a single article. ``` curl "https://api.apitube.io/v1/news/count?brand.name=Coca-Cola&published_at.start=NOW-24HOURS&api_key=YOUR_API_KEY" ``` For a bucketed view in one call, `/v1/news/trends` accepts the same brand filter plus `field=source.id` (or `field=entity.id`) and `time_bucket=day`, returning counts grouped per day. Add `compare=true` with a `compare_window` such as `7DAYS` to get the change versus the previous period. The trends endpoint looks back a maximum of 30 days per request, so use it for recent momentum and the count series for longer stretches. ## Which outlets are shaping my reputation?[#](#which-outlets-are-shaping-my-reputation) Not every mention carries the same weight. To see who is driving your coverage, send your brand filter to `/v1/news/trends` with `field=source.id` — the response ranks the outlets publishing about you by article count, so you learn where the conversation is concentrated. To focus on authoritative publishers, add `source.rank.opr.min` to require a minimum Open Page Rank, or `is_verified_source=1` to keep only higher-ranked, non-duplicate sources. When you already know the outlet, `source.domain` narrows any query to a single publisher. ``` curl "https://api.apitube.io/v1/news/trends?field=source.id&organization.name=Tesla&is_verified_source=1&api_key=YOUR_API_KEY" ``` ## How do I get alerted to new coverage instantly?[#](#how-do-i-get-alerted-to-new-coverage-instantly) Re-running a search on a timer wastes requests and adds lag. The `/v1/news/stream` endpoint accepts the exact same brand and sentiment filters and pushes each new matching article over [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) (SSE) shortly after it is indexed, sending only articles newer than the ones you have already seen. That turns your reputation watch into a live feed instead of a poll. ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?organization.name=Tesla&language.code=en" ``` For a hands-off alert that calls your own server, set up a [webhook](/en/articles/getting-started/glossary#webhook) on a [saved search](/en/articles/getting-started/glossary#saved-search) from the dashboard — webhooks are created in the dashboard, not through an API call. Pair the stream with `entity.sentiment.polarity=negative` when you want the fastest possible warning on a reputation risk, as covered in [detect negative mentions quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions). # Common Questions[#](#common-questions) * [Why use entity sentiment instead of overall sentiment?](#why-use-entity-sentiment-instead-of-overall-sentiment) * [How do I monitor several brands at once?](#how-do-i-monitor-several-brands-at-once) * [Does counting or trends download the article bodies?](#does-counting-or-trends-download-the-article-bodies) ## Why use entity sentiment instead of overall sentiment?[#](#why-use-entity-sentiment-instead-of-overall-sentiment) `sentiment.overall.polarity` scores the tone of the whole article, so a piece that mentions ten companies can read as “neutral” while still being harsh about you. `entity.sentiment.polarity` scores the tone toward your brand specifically, which is what reputation work needs. The [entity-level sentiment](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) guide breaks down the difference and the `mentions` counts in full. ## How do I monitor several brands at once?[#](#how-do-i-monitor-several-brands-at-once) Entity name filters such as `organization.name` and `brand.name` accept up to three comma-separated values per request, and `entity.id` accepts up to three IDs. Put your brand and its sub-brands in one call, then reuse that same filter set across `/v1/news/count`, `/v1/news/trends`, and `/v1/news/stream` so every view of your reputation stays aligned. ## Does counting or trends download the article bodies?[#](#does-counting-or-trends-download-the-article-bodies) No. `/v1/news/count` returns only a number, and `/v1/news/trends` returns aggregated counts per source or entity — neither returns article bodies. Each costs one request, which makes them the cheap way to measure volume and momentum before you spend a heavier call fetching the actual coverage from `/v1/news/everything`. * * * ## Related Articles * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to Detect Negative Mentions Quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions) * [How to Get Sentiment Toward a Specific Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) --- ## How to curate a newsletter with a news API URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/curate-newsletter Curate a newsletter with the APITube News API: one saved query with topic, date-window and quality filters returns each issue's candidate articles as JSON or… # How to curate a newsletter with a news API Build a repeatable pipeline that selects fresh, high-quality articles on your topic and hands them to your newsletter tool ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything) # How to curate a newsletter with a news API[#](#how-to-curate-a-newsletter-with-a-news-api) To curate a newsletter, run one saved APITube query per issue: scope it to your topic, limit it to the days since the last issue with `published_at.start`, and gate quality with `source.rank.opr.min`. The response is the issue’s candidate list — every article with its title, link, summary and source — ready for a human pick or an automated template. The same query, re-run weekly, is the entire pipeline. ``` curl -G "https://api.apitube.io/v1/news/everything" \ --data-urlencode "topic.id=industry.crypto_news" \ --data-urlencode "published_at.start=NOW-7DAYS" \ --data-urlencode "source.rank.opr.min=6" \ --data-urlencode "language.code=en" \ --data-urlencode "per_page=25" \ --data-urlencode "api_key=YOUR_API_KEY" ``` `NOW-7DAYS` is the relative date syntax, so the window slides automatically — no date arithmetic in your scheduler. ## How do you scope the query to your newsletter’s topic?[#](#how-do-you-scope-the-query-to-your-newsletters-topic) Pick the narrowest filter that matches how your topic is defined: * **A subject area** — `topic.id` (like `industry.crypto_news` above) or an IPTC category via `category.id`; see [how to filter by topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic). * **A keyword in the headline** — `title=electric vehicles`; multi-word values need every word to appear. * **A company or person beat** — `organization.name` / `person.name` matches detected [entities](/en/articles/getting-started/glossary#entity) rather than raw text, so a “Nvidia this week” section doesn’t miss articles that say “the chipmaker” in the headline. Filters combine with AND, so `topic.id` + `title` gives you “this subject, but only stories about X” — a natural fit for newsletter sections. Run one query per section rather than one broad query you re-sort by hand. ## How do you keep the issue high-quality?[#](#how-do-you-keep-the-issue-high-quality) Reader trust dies on link rot and content farms, so push quality into the query instead of eyeballing every candidate: * `source.rank.opr.min=6` sets an authority floor ([OPR](/en/articles/getting-started/glossary#opr-open-pagerank) is 0–10; raise it for a stricter list) — or use the stricter composite flag described in [filtering to trusted, high-quality sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources). * `ignore.source.domain=example-tabloid.com` drops up to three publishers your readers dislike, comma-separated. * Wire reprints cluster around one event; fetch the [story cluster](/en/articles/retrieval/get-story-cluster) for a headline you picked and feature the strongest version instead of three copies of the same news. ## How do you hand the result to your newsletter tool?[#](#how-do-you-hand-the-result-to-your-newsletter-tool) Three integration shapes, cheapest first: * **RSS:** append `export=rss` and paste the URL into any tool that ingests feeds (most email platforms do) — the API returns the same search as an RSS 2.0 document. See [how to export search results as RSS](/en/articles/delivery-and-export/export/export-rss). * **JSON:** call the API from your build script and render candidates into your template — each article carries `title`, `href`, `description`, `published_at` and `source`, which is everything an issue block needs. * **Spreadsheet triage:** the response’s `export` block includes ready CSV/XLSX URLs, so an editor can pick winners in a sheet before layout. The full list of filters you can bake into the saved query is in the official [News API parameter reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [How do I avoid repeating an article across two issues?](#how-do-i-avoid-repeating-an-article-across-two-issues) * [How many requests does a weekly newsletter cost?](#how-many-requests-does-a-weekly-newsletter-cost) * [Can I get article summaries for the issue blurbs?](#can-i-get-article-summaries-for-the-issue-blurbs) ## How do I avoid repeating an article across two issues?[#](#how-do-i-avoid-repeating-an-article-across-two-issues) Anchor the window to your publishing cadence: a weekly issue queries `published_at.start=NOW-7DAYS` at the same hour each week, so consecutive windows touch without overlapping. If your schedule slips, store the `published_at` of the newest article you featured and pass it as the exact `published_at.start` of the next run. ## How many requests does a weekly newsletter cost?[#](#how-many-requests-does-a-weekly-newsletter-cost) One search that returns articles counts as one request against your quota, so a five-section weekly newsletter costs about five requests per issue — around twenty per month, which fits comfortably in any plan. Requests that return zero articles are not charged. See [what counts as a request](/en/articles/billing/credits/what-counts-as-request). ## Can I get article summaries for the issue blurbs?[#](#can-i-get-article-summaries-for-the-issue-blurbs) Yes — each article object already includes a `summary` produced during processing, alongside `description`. Render it as the blurb draft and edit by hand where it matters; for tighter payloads, request only the fields you use with the `fl` parameter — see [how to select specific response fields](/en/articles/searching-and-filtering/sorting-and-shaping/select-fields). * * * ## Related Articles * [How to export search results as an RSS feed](/en/articles/delivery-and-export/export/export-rss) * [How to filter news to trusted, high-quality sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [How to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Detect Negative Mentions Quickly URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/detect-negative-mentions Detect negative news about your brand fast: filter with sentiment.overall.polarity=negative, target your entity with entity.sentiment.polarity, and stream new… # How to Detect Negative Mentions Quickly Catch negative coverage of your brand early with sentiment.overall.polarity, entity.sentiment.polarity and the live SSE stream ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Tesla&sentiment_polarity=negative) # How to detect negative mentions quickly[#](#how-to-detect-negative-mentions-quickly) To catch negative mentions fast, combine one [entity](/en/articles/getting-started/glossary#entity) filter with one negative-[sentiment](/en/articles/getting-started/glossary#sentiment) filter on `/v1/news/everything`: for example `organization.name=Tesla&sentiment.overall.polarity=negative`. APITube returns only negative articles that mention your company, newest-first by default, so the first result is the freshest problem. To be alerted the moment a negative story is indexed, run the same filters on the live [SSE](/en/articles/getting-started/glossary#sse-stream) stream instead of polling. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&sentiment.overall.polarity=negative&api_key=YOUR_API_KEY" ``` Send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter if you prefer. Because the default sort is `published_at` descending, you do not need a `sort` parameter — the newest negative mention is already at the top. ## How do I find only negative articles about my brand?[#](#how-do-i-find-only-negative-articles-about-my-brand) Add `sentiment.overall.polarity=negative` to any search. This keeps articles whose overall tone is negative and drops positive and neutral coverage. Pair it with an entity filter so you only see stories about you: use `organization.name` for a company or `brand.name` for a consumer brand. APITube resolves the name against the entities it tracks; if the name is not tracked you get a “not found” error, so keep an eye on the exact spelling or use the stable numeric `entity.id` instead. ``` curl "https://api.apitube.io/v1/news/everything?brand.name=Coca-Cola&sentiment.overall.polarity=negative&language.code=en&api_key=YOUR_API_KEY" ``` Each returned article carries a `sentiment` object with `overall`, `title` and `body`, and each has a `score` (from `-1` to `1`) and a `polarity` string. The headline is often the sharpest early signal, so `sentiment.title.polarity=negative` surfaces stories with a negative headline even when the full body reads more neutral. ## How do I catch negativity aimed at my brand inside a mixed article?[#](#how-do-i-catch-negativity-aimed-at-my-brand-inside-a-mixed-article) Overall polarity looks at the whole article, so a long piece that mentions ten companies can read as “neutral” while still being harsh about you specifically. To isolate negativity directed at your entity, add `entity.sentiment.polarity=negative` next to your `organization.name` or `brand.name`. APITube then keeps only articles where the sentiment measured toward that exact company or brand is negative — not the article’s average mood. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&entity.sentiment.polarity=negative&api_key=YOUR_API_KEY" ``` In the response, every item in the article’s `entities` array has its own `sentiment` block with a `score`, a `polarity`, and a `mentions` breakdown counting `positive`, `neutral` and `negative` references. That per-entity view is what powers `entity.sentiment.polarity`, and it is the difference between “this article is negative” and “this article is negative about us.” ## How do I keep only the strongly negative coverage?[#](#how-do-i-keep-only-the-strongly-negative-coverage) Polarity is a coarse three-way label; the numeric score lets you set a threshold so mildly critical pieces do not drown out real crises. Use `sentiment.overall.score.max` to cap the score — for example `sentiment.overall.score.max=-0.3` keeps only clearly negative articles and hides borderline ones. Combine it with a recency window using `published_at.start` and a relative date such as `NOW-24HOURS` to review just the last day. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&sentiment.overall.score.max=-0.3&published_at.start=NOW-24HOURS&api_key=YOUR_API_KEY" ``` Lower the cap (closer to `-1`) to see only the most damaging stories; raise it (toward `0`) to widen the net. The score always ranges from `-1` (most negative) to `1` (most positive). ## How do I get negative mentions the moment they publish?[#](#how-do-i-get-negative-mentions-the-moment-they-publish) Re-running a search on a timer wastes requests and adds lag. The `/v1/news/stream` endpoint accepts the same filters and pushes each new matching article over Server-Sent Events (SSE) shortly after it is indexed, so a negative story reaches you in near real time instead of on your next poll. ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?organization.name=Tesla&sentiment.overall.polarity=negative" ``` The stream only sends articles newer than the ones you have already seen, so you get a clean feed of fresh negative mentions rather than a repeat of your backlog. For a fully hands-off alert that calls your own server, set up a [webhook](/en/articles/getting-started/glossary#webhook) from the dashboard on a [saved search](/en/articles/getting-started/glossary#saved-search) — webhooks are created in the dashboard, not through an API call. # Common Questions[#](#common-questions) * [What is the difference between overall and entity sentiment?](#what-is-the-difference-between-overall-and-entity-sentiment) * [My brand name returns an error. What now?](#my-brand-name-returns-an-error-what-now) * [Can I watch several brands at once?](#can-i-watch-several-brands-at-once) ## What is the difference between overall and entity sentiment?[#](#what-is-the-difference-between-overall-and-entity-sentiment) `sentiment.overall.polarity` describes the tone of the whole article; `entity.sentiment.polarity` describes the tone toward one specific company, brand or person named in it. For reputation work you usually want the entity-level filter, because it catches articles that are critical of you even when the overall piece is balanced. See [entity-level sentiment](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) for the full breakdown. ## My brand name returns an error. What now?[#](#my-brand-name-returns-an-error-what-now) Name filters resolve against the entities APITube tracks, so an untracked or misspelled name returns a “not found” error. Switch to the numeric `entity.id`, which never changes for a given company or brand, or look up the right identifier first. The [monitor a company or brand](/en/articles/searching-and-filtering/entities/monitor-company-news) guide shows how to find and use an `entity.id`. ## Can I watch several brands at once?[#](#can-i-watch-several-brands-at-once) Yes. Entity name filters such as `organization.name` and `brand.name` accept up to three comma-separated values in one request, and `entity.id` accepts up to three IDs. Add the same `sentiment.overall.polarity=negative` or `entity.sentiment.polarity=negative` filter to keep the whole request focused on negative coverage across all of them. * * * ## Related Articles * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Get Sentiment Toward a Specific Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Find Journalists for PR Outreach URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/find-journalists-pr Build a targeted press list with APITube: find reporters on your beat, qualify them with /v1/journalists stats, and research every byline before pitching. # How to Find Journalists for PR Outreach Discover reporters who cover your beat from the articles they write, qualify them by coverage, activity and tone, then research their back-catalogue before you pitch ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=fintech&published_at_start=NOW-30DAY&per_page=100) # How to find journalists for PR outreach[#](#how-to-find-journalists-for-pr-outreach) To build a PR list, search recent articles about your beat with `GET /v1/news/everything` and read the `author` field on each result to see who actually covers the topic, then qualify each reporter with `GET /v1/journalists/:id` for their beat, activity and tone, and pull their full back-catalogue with the `author.id` filter before you pitch. There is no “search journalists by topic” call — the directory searches by name only, so the reporters you want are discovered from the coverage they produce. ``` curl "https://api.apitube.io/v1/news/everything?title=fintech&published_at.start=NOW-30DAY&per_page=100" \ -H "X-API-Key: YOUR_API_KEY" ``` You can send the key as the `X-API-Key` header or the `api_key` query parameter. Every article APITube returns includes an `author` object with an `id` and `name`, so one search over your beat hands you a raw list of the journalists writing about it right now. ## Who covers your beat? Start from the articles, not the directory[#](#who-covers-your-beat-start-from-the-articles-not-the-directory) The `/v1/journalists` directory only accepts a `name` filter, so you cannot ask it “which reporters cover fintech?” directly. The reliable way to find journalists on a beat is to search the beat and collect the bylines. Scope a search to your topic and a recent window, then read `author.id` and `author.name` off each article: ``` # Reporters writing about your beat in the last 30 days curl "https://api.apitube.io/v1/news/everything?title=cybersecurity&published_at.start=NOW-30DAY&per_page=100" \ -H "X-API-Key: YOUR_API_KEY" ``` `title` does a keyword match on the headline (2–100 characters). `published_at.start` accepts relative values such as `NOW-30DAY`, `NOW-1WEEK` or `NOW-1MONTH`, so you keep the list to reporters who are active on the topic, not people who wrote about it two years ago. Tally the `author.id` values that show up most often — those are your first-tier targets. You can narrow the beat further with the topic, industry and [entity](/en/articles/getting-started/glossary#entity) filters instead of a headline keyword; [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) covers pinning a search to a company or person you want covered. ## How to qualify a reporter before you pitch[#](#how-to-qualify-a-reporter-before-you-pitch) Once you have a reporter’s ID, call `GET /v1/journalists/:id` to decide whether they are worth an email. The profile returns their `outlets` (which publications they write for), a `coverage` block that summarizes everything they have written, and `recent_articles` — up to five of their latest stories. ``` curl "https://api.apitube.io/v1/journalists/84213?api_key=YOUR_API_KEY" ``` The `coverage` block is the qualification data: ``` { "coverage": { "article_count": 1284, "first_seen": "2023-02-11", "last_seen": "2026-06-25", "sentiment": { "positive": 540, "neutral": 612, "negative": 132 }, "momentum": { "last_30_days": 41, "previous_30_days": 37, "change_pct": 11 }, "top_topics": [ { "id": 123, "name": "Artificial Intelligence", "count": 88 } ], "top_entities": [ { "id": 314, "name": "OpenAI", "count": 57 } ], "top_countries": [ { "id": 840, "name": "United States", "code": "us", "count": 700 } ], "top_languages": [ { "id": 1, "name": "English", "code": "en", "count": 1200 } ] } } ``` Read it like a media-kit fit check. `top_topics` and `top_entities` are the reporter’s real beat — pitch them only when your story lands inside it. `momentum` compares the last 30 days against the previous 30, and `last_seen` tells you when they last published, so you skip bylines that have gone quiet. `sentiment` counts how positively, neutrally or negatively they tend to frame coverage. If you only need the outlets and the fit signal fast, add `coverage=false` to skip the aggregate queries and get a lighter response. ## How to look up a reporter you already know by name[#](#how-to-look-up-a-reporter-you-already-know-by-name) When a name is already on your list, search the directory directly with `GET /v1/journalists`. The `name` filter is a substring match, so `name=Jane` returns every byline containing “Jane”, and one reporter publishing across several outlets is merged into a single record with an `outlets` array: ``` curl "https://api.apitube.io/v1/journalists?name=Jane%20Doe&per_page=50&api_key=YOUR_API_KEY" ``` Paginate with `page` (default `1`) and `per_page` (default `100`, maximum `250` — `200` on Basic, `50` on Starter, `10` on Free); `has_next_pages` is `true` only when a further record actually exists, because the endpoint probes for `per_page + 1` rows. Each result already carries a `links.articles` URL pointing at `/v1/news/everything?author.id=<id>`, so the next step is one click away. The [journalists directory guide](/en/articles/searching-and-filtering/entities/journalists-directory) walks through the list and profile endpoints in full. ## How to research everything a reporter has written[#](#how-to-research-everything-a-reporter-has-written) Before you pitch, read what a reporter has actually published so your email references their real work. Take the `id` and pass it to the search endpoint as `author.id`: ``` curl "https://api.apitube.io/v1/news/everything?author.id=84213&published_at.start=NOW-3MONTH" \ -H "X-API-Key: YOUR_API_KEY" ``` `author.id` accepts up to three IDs separated by commas with OR logic, so you can pull two or three related bylines in one call and combine them with any other filter — a date window, a language, a topic. You can also filter by `author.name` if you have not resolved the ID yet, though a name that is not found returns an HTTP 400 error, so IDs are the safer choice. See [how to filter news by author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) for the full `author.id` and `author.name` behavior. For every accepted parameter, the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) is the canonical list. # Common Questions[#](#common-questions) * [Can I search journalists directly by topic or beat?](#can-i-search-journalists-directly-by-topic-or-beat) * [Does looking up a journalist cost a request?](#does-looking-up-a-journalist-cost-a-request) * [How do I know if a journalist is still active?](#how-do-i-know-if-a-journalist-is-still-active) * [Why are the recent\_articles bodies cut off?](#why-are-the-recent_articles-bodies-cut-off) ## Can I search journalists directly by topic or beat?[#](#can-i-search-journalists-directly-by-topic-or-beat) Not directly. The `/v1/journalists` directory filters by `name` only, so there is no “give me every fintech reporter” call. You find beat reporters the other way around: search articles on the beat with `/v1/news/everything`, read the `author` object on each result, then look those IDs up in the directory. The `top_topics` and `top_entities` in a journalist’s `coverage` block then confirm the beat is really theirs and not a one-off story. ## Does looking up a journalist cost a request?[#](#does-looking-up-a-journalist-cost-a-request) A successful `GET /v1/journalists/:id` profile call charges one request against your plan. The `GET /v1/journalists` list is more forgiving: it charges one request only when it returns at least one match, so a search that finds nobody costs nothing. The article searches you run to discover bylines each count as a normal `/v1/news/everything` request. ## How do I know if a journalist is still active?[#](#how-do-i-know-if-a-journalist-is-still-active) Read three fields in the `coverage` block: `last_seen` is the date of their most recent article, `momentum.last_30_days` is how many they published in the last month, and `momentum.change_pct` compares that against the previous 30 days. A rising `change_pct` means they are ramping up on a topic; it is `null` when there was no prior-period activity to compare against, which usually flags a new or newly-tracked byline. ## Why are the recent\_articles bodies cut off?[#](#why-are-the-recent_articles-bodies-cut-off) On a Free plan or a [test key](/en/articles/getting-started/glossary#test-key-and-live-key), the article bodies inside `recent_articles` are truncated to a preview — the same content masking applied everywhere in the News API. The author, headline, outlets and coverage stats are always returned in full; only the article text is shortened. Use a live key on a paid plan to read the complete bodies. * * * ## Related Articles * [How to Find Journalists by Byline and Beat](/en/articles/searching-and-filtering/entities/journalists-directory) * [How to Filter News by Author](/en/articles/searching-and-filtering/by-attribute/filter-by-author) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) --- ## Brand, PR & Marketing URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing Monitor brand reputation, track competitors, catch negative mentions and build targeted media lists with the APITube News API. # Brand, PR & Marketing Brand monitoring, PR and media lists. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Beatrice and 1 other 2 authors 9 articles * [How to curate a newsletter with a news API](/en/articles/use-cases/brand-and-marketing/curate-newsletter) * [How to Detect Negative Mentions Quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions) * [How to Find Journalists for PR Outreach](/en/articles/use-cases/brand-and-marketing/find-journalists-pr) * [How to Measure PR and Media Coverage](/en/articles/use-cases/brand-and-marketing/measure-pr-coverage) * [How to Monitor Competitor Brands](/en/articles/use-cases/brand-and-marketing/monitor-competitors) * [How to Monitor Your Brand Reputation](/en/articles/use-cases/brand-and-marketing/brand-reputation-monitoring) * [How to Send a Daily News Digest to Telegram](/en/articles/use-cases/brand-and-marketing/telegram-news-digest) * [How to Send Brand Mention Alerts to Slack](/en/articles/use-cases/brand-and-marketing/slack-brand-alerts) * [How to Track Celebrity Buzz and Entertainment Hype](/en/articles/use-cases/brand-and-marketing/track-celebrity-buzz) --- ## How to Measure PR and Media Coverage URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/measure-pr-coverage Measure PR and media coverage with the APITube News API — count total mentions with /v1/news/count, compare share of voice across brands, and split coverage by… # How to Measure PR and Media Coverage Quantify mentions, share of voice, tone and coverage volume over time with /v1/news/count and facets ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fcount&organization_name=Tesla&published_at_start=NOW-30DAYS) # How to measure PR and media coverage[#](#how-to-measure-pr-and-media-coverage) To measure PR and media coverage, count how many articles mention your brand with the `/v1/news/count` endpoint, then break that total down by competitor, tone and time using the `facet` parameters. Counting is separate from reading: `/v1/news/count` returns just a number for your filters — no article bodies — so a coverage report is a handful of small, cheap calls rather than a full download. This counts every article mentioning Tesla in the last 30 days: ``` curl "https://api.apitube.io/v1/news/count?organization.name=Tesla&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" ``` You can send the key as an `X-API-Key: YOUR_API_KEY` header instead of the `api_key` query parameter. The response is a small JSON object — the total, a status and a [request id](/en/articles/getting-started/glossary#request-id) — and never any content: ``` { "status": "ok", "count": 12345, "request_id": "1b6e9c42-7a3d-4058-9f1e-5c2d8b4a6f30" } ``` ## How do I measure total coverage volume?[#](#how-do-i-measure-total-coverage-volume) Total coverage volume is a single `/v1/news/count` call whose filters describe “coverage of my brand”. Use `organization.name` for a company, `brand.name` for a consumer brand, or the numeric `entity.id` to pin one exact [entity](/en/articles/getting-started/glossary#entity) — each matches only articles that actually mention it. Add a `published_at.start` window so the number is scoped to a reporting period; `published_at.start` and `published_at.end` are inclusive and accept relative values like `NOW-30DAYS` or `NOW-7DAYS`, so you never have to compute dates yourself. ``` curl "https://api.apitube.io/v1/news/count?brand.name=Coca-Cola&published_at.start=NOW-7DAYS&language.code=en&api_key=YOUR_API_KEY" ``` Because `/v1/news/count` accepts every filter the search endpoints do, you can build the query on `/v1/news/everything` first, confirm the articles look right, then swap the path to `/v1/news/count` for the tally. Each count call costs **1 point** regardless of how large the total is — estimating a two-million-article result set costs the same as a five-article one. See [how to count news articles without downloading them](/en/articles/retrieval/count-articles) for the full behaviour. ## How do I measure share of voice against competitors?[#](#how-do-i-measure-share-of-voice-against-competitors) Share of voice is the fraction of coverage in your category that belongs to each brand. The simplest way is one count call per brand over the same window, then divide each total by the sum: ``` curl "https://api.apitube.io/v1/news/count?brand.name=Coca-Cola&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" curl "https://api.apitube.io/v1/news/count?brand.name=Samsung Galaxy&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" curl "https://api.apitube.io/v1/news/count?brand.name=Puma&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" ``` If you already know each brand’s numeric `entity.id`, you can get all the totals in one search request by faceting on `entity.id`. Filter the search to your set of brands (`entity.id` accepts up to three comma-separated IDs with OR logic) and ask the API to group the matching articles by entity — `per_page=1` keeps the article payload tiny while the facet counts still cover the whole matching set: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=314,42,88&facet=true&facet.field=entity.id&per_page=1&api_key=YOUR_API_KEY" ``` The response gains a `facets` object where `entity.id` is an array of `{ value, count }` pairs — one row per brand, `value` being the entity ID and `count` the number of matching articles — sorted from most-covered to least. That single grouped call is your share-of-voice table. ## How do I break coverage down by tone?[#](#how-do-i-break-coverage-down-by-tone) Coverage tone tells you whether the mentions are favourable. Run the same count three times, adding `sentiment.overall.polarity` set to `positive`, `negative` and `neutral` in turn — the three totals are your positive/negative/neutral split for the period: ``` curl "https://api.apitube.io/v1/news/count?organization.name=Tesla&sentiment.overall.polarity=negative&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" ``` `sentiment.overall.polarity` takes `positive`, `negative` or `neutral`. An unrecognized value is not rejected — it falls back to `neutral` — and only a value longer than 10 characters returns error `ER0103` (an empty value is simply ignored). This is the tone of the **article as a whole**, which is not the same as the tone aimed specifically at your brand inside it. When you need [sentiment](/en/articles/getting-started/glossary#sentiment) directed at the company itself, use the entity-level filter `entity.sentiment.polarity` instead — see [how to monitor news about a company or brand](/en/articles/searching-and-filtering/entities/monitor-company-news) for that distinction. ## How do I chart coverage volume over time?[#](#how-do-i-chart-coverage-volume-over-time) A coverage timeline — articles per day across the campaign — comes from range faceting. Set `facet.range=true`, point `facet.range.field` at `published_at`, and give a `facet.range.start` (inclusive) and `facet.range.end` (exclusive — the end date itself is not counted, so use the day after your last day); both are required, or the request returns `ER0332`. The optional `facet.range.gap` sets the bucket size and defaults to `+1DAY`: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&facet.range=true&facet.range.field=published_at&facet.range.start=2026-06-01&facet.range.end=2026-06-30&facet.range.gap=+1DAY&per_page=1&api_key=YOUR_API_KEY" ``` The counts arrive under a key named `published_at_ranges`, where each bucket is `{ range_start, range_end, count }` ordered oldest-first — exactly the shape you feed a “mentions per day” chart. Widen the gap to `+1WEEK` for a longer campaign. To see which outlets drive the coverage, facet on `source.id` instead: `facet=true&facet.field=source.id&facet.limit=20` returns your top 20 sources by article count. The full field list and range options are in [how to aggregate news results with facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) and the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Does building a coverage report cost a lot of credits?](#does-building-a-coverage-report-cost-a-lot-of-credits) * [Why don’t the facet counts match the results array?](#why-dont-the-facet-counts-match-the-results-array) * [Can I measure coverage on a test key?](#can-i-measure-coverage-on-a-test-key) ## Does building a coverage report cost a lot of credits?[#](#does-building-a-coverage-report-cost-a-lot-of-credits) No. Each `/v1/news/count` call is a flat **1 point** no matter how many articles match, and a faceted search is a single request that returns grouped counts instead of pages of content. A full report — one total, a share-of-voice comparison, a tone split and a timeline — is a small fixed number of calls, not a bulk export. Counting and faceting are the cheap path precisely because no article bodies are transferred. ## Why don’t the facet counts match the results array?[#](#why-dont-the-facet-counts-match-the-results-array) They measure different things. The `results` array is limited by your `page` and `per_page` values, while facet counts are computed over **every** article that matches your filters. A request that returns one article on the page (`per_page=1`) can still report thousands across its facet values — that is expected, and it is why you can keep the page tiny while the counts stay complete. ## Can I measure coverage on a test key?[#](#can-i-measure-coverage-on-a-test-key) Only roughly. On a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)**, `/v1/news/count` caps the returned total at 100 so the key cannot reveal the true catalogue size, which makes real volume and share-of-voice numbers unusable. A test key also masks article content with an upgrade marker rather than returning full bodies. Switch to a **live key** for accurate coverage figures and real reporting numbers. * * * ## Related Articles * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Aggregate News Results with Facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) --- ## How to Monitor Competitor Brands URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/monitor-competitors Monitor competitor brands with APITube: watch rivals with organization.name or brand.name, read tone with entity.sentiment.polarity, and stream new mentions… # How to Monitor Competitor Brands Track rival companies in one query with organization.name, brand.name, entity.sentiment.polarity and the live SSE stream ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&brand_name=Coca-Cola%2CSamsung) # How to monitor competitor brands[#](#how-to-monitor-competitor-brands) To monitor competitors, put their names in `organization.name` or `brand.name` on `/v1/news/everything` and read the results newest-first. One request can watch up to three rivals at once, `entity.sentiment.polarity` shows how each one is being talked about, and `ignore.brand.name` lets you follow the rest of your category while cutting out your own coverage. This tracks three sportswear rivals over the last week: ``` curl "https://api.apitube.io/v1/news/everything?brand.name=Coca-Cola,Samsung Galaxy,iPhone Air&published_at.start=NOW-7DAYS&language.code=en&api_key=YOUR_API_KEY" ``` Send the key as an `X-API-Key: YOUR_API_KEY` header instead of the `api_key` query parameter if you prefer. Because the default sort is `published_at` descending, the freshest competitor story is already at the top — no `sort` parameter needed. ## How do I track a single competitor’s news?[#](#how-do-i-track-a-single-competitors-news) Point one name filter at the rival: `organization.name` for a company, `brand.name` for a consumer brand. APITube resolves the name against the [entities](/en/articles/getting-started/glossary#entity) it tracks and returns only articles that actually mention that entity, so you avoid the false hits a plain keyword search produces. Add `language.code` to stay in one language and `published_at.start` to scope a window. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Alphabet Inc.&published_at.start=NOW-24HOURS&api_key=YOUR_API_KEY" ``` If the name is not tracked or is misspelled, the request returns a “not found” error rather than empty results. When that happens, switch to the numeric `entity.id`, which never changes for a given company and is the most reliable way to pin one exact competitor. The [find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) guide shows how to look up that ID. ## How do I watch several competitors in one request?[#](#how-do-i-watch-several-competitors-in-one-request) Both `organization.name` and `brand.name` accept up to three comma-separated values, and those values are matched with OR logic — so `brand.name=Coca-Cola,Samsung Galaxy,iPhone Air` returns any article that mentions at least one of the three. The `entity.id` filter works the same way, accepting up to three IDs at once, which is the sturdier option once you know each rival’s identifier: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=314,42,88&published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` Three is the hard limit per request: extra comma-separated values beyond the third are dropped. To follow more than three competitors, run one request per group of three, or split them into separate [saved searches](/en/articles/getting-started/glossary#saved-search). Keep each rival’s `entity.id` on hand so a rename or a spelling variant never breaks the watch. ## How do I follow my category but exclude my own brand?[#](#how-do-i-follow-my-category-but-exclude-my-own-brand) Competitive monitoring often means “everything in my space except us.” Use the `ignore.` variants — `ignore.brand.name` or `ignore.organization.name` — to subtract your own coverage from a broader search. Pair a category-defining `title` search with an exclusion of your brand so the feed is your rivals and the wider conversation, minus your own press: ``` curl "https://api.apitube.io/v1/news/everything?title=running%20shoes&ignore.brand.name=Coca-Cola&language.code=en&api_key=YOUR_API_KEY" ``` Words in a `title` search are combined with AND, so `title=running shoes` keeps articles whose headline contains both words. Layering `ignore.brand.name=Coca-Cola` on top removes anything that mentions your own brand, leaving the competitive landscape around you. Like the positive filters, the `ignore.` name filters accept up to three comma-separated values, so you can exclude a house of brands in one shot. ## How is each competitor being talked about?[#](#how-is-each-competitor-being-talked-about) Add `entity.sentiment.polarity` next to a name filter to keep only articles whose tone **toward that specific rival** is `positive`, `negative` or `neutral`. This is measured per entity, not for the article as a whole, so a broad market piece that quotes several brands is judged on how it treats the competitor you named — not its average mood: ``` curl "https://api.apitube.io/v1/news/everything?brand.name=Samsung Galaxy&entity.sentiment.polarity=negative&published_at.start=NOW-7DAYS&api_key=YOUR_API_KEY" ``` Entity-level tone is different from `sentiment.overall.polarity`, which describes the whole article. For competitor work the entity-level filter is usually what you want, because it catches a story that is rough on a rival even when the overall piece reads as balanced. See [how to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) for the full breakdown of that distinction. ## How do I surface a competitor’s biggest stories first?[#](#how-do-i-surface-a-competitors-biggest-stories-first) By default results are newest-first, which is right for a live watch but buries the story that actually mattered. Switch `sort.by` to `engagement` to rank a rival’s coverage by importance instead of timestamp — the engagement score blends signals such as breaking-news flags, image and video richness, positive overall [sentiment](/en/articles/getting-started/glossary#sentiment), freshness, and the source’s rank, so the loudest stories rise to the top: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&sort.by=engagement&sort.order=desc&per_page=20&api_key=YOUR_API_KEY" ``` `sort.order` accepts `asc` or `desc` and defaults to `desc`. Other useful modes are `relevance` (best headline match for your `title` terms), `quality`, and `trust`. Pull more rows per call with `per_page`, which tops out at 250 — 50 on Starter, 10 on Free — and page through the rest with `page`. ## How do I keep a live watch on competitors?[#](#how-do-i-keep-a-live-watch-on-competitors) Re-running the same search on a timer wastes requests and adds lag. The `/v1/news/stream` endpoint accepts the exact same competitor filters and pushes each new matching article over [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) (SSE) shortly after it is indexed, sending only articles newer than the ones you have already seen: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?brand.name=Coca-Cola,Samsung Galaxy,iPhone Air&language.code=en" ``` That gives you a clean, continuous feed of fresh competitor mentions rather than a repeat of your backlog. For a fully hands-off alert that calls your own server when a rival is in the news, set up a [webhook](/en/articles/getting-started/glossary#webhook) on a saved search — webhooks are created in the dashboard, not through an API call. # Common Questions[#](#common-questions) * [How many competitors can I track in one call?](#how-many-competitors-can-i-track-in-one-call) * [A competitor’s name returns an error. What now?](#a-competitors-name-returns-an-error-what-now) * [How is this different from measuring share of voice?](#how-is-this-different-from-measuring-share-of-voice) ## How many competitors can I track in one call?[#](#how-many-competitors-can-i-track-in-one-call) Three. The name filters `organization.name` and `brand.name`, and the numeric `entity.id`, each accept up to three comma-separated values in a single request, matched with OR logic. The same three-value limit applies to the `ignore.` exclusions. To watch a larger set, split the rivals across several requests or several saved searches and merge the feeds on your side. ## A competitor’s name returns an error. What now?[#](#a-competitors-name-returns-an-error-what-now) Name filters resolve against the entities APITube tracks, so an untracked or misspelled competitor name returns a “not found” error instead of empty results. Switch to that company’s numeric `entity.id`, which is stable and never changes, or look up the correct identifier first. The [monitor a company or brand](/en/articles/searching-and-filtering/entities/monitor-company-news) guide walks through finding and using an `entity.id`. ## How is this different from measuring share of voice?[#](#how-is-this-different-from-measuring-share-of-voice) Monitoring is about _reading_ the stream of competitor coverage as it happens; share of voice is about _counting_ it. When you want totals — how many articles mention each rival, or each brand’s slice of category coverage — use the `/v1/news/count` endpoint and facets instead of paging through articles. See [how to measure PR and media coverage](/en/articles/use-cases/brand-and-marketing/measure-pr-coverage) for the counting workflow. * * * ## Related Articles * [How to Monitor News About a Company or Brand](/en/articles/searching-and-filtering/entities/monitor-company-news) * [How to Detect Negative Mentions Quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions) * [How to Measure PR and Media Coverage](/en/articles/use-cases/brand-and-marketing/measure-pr-coverage) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) --- ## How to Send Brand Mention Alerts to Slack URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/slack-brand-alerts Send APITube brand mentions to Slack in real time: stream articles matching your brand over SSE and POST each one to a Slack incoming webhook — full script… # How to Send Brand Mention Alerts to Slack A complete, dependency-free Node.js script: stream brand mentions over SSE and post each one to a Slack channel ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 6, 2026 # How to send brand mention alerts to Slack[#](#how-to-send-brand-mention-alerts-to-slack) To get brand mentions in Slack the moment they are published, open one [SSE](/en/articles/getting-started/glossary#sse-stream) connection to `/v1/news/stream` filtered to your brand and POST each incoming article to a Slack incoming [webhook](/en/articles/getting-started/glossary#webhook). The whole pipeline is one Node.js script with no dependencies — about 50 lines, shown in full below — and it reconnects on drops without losing articles. ## Step 1: create a Slack incoming webhook[#](#step-1-create-a-slack-incoming-webhook) In Slack, create an app (or open an existing one) at `api.slack.com/apps`, enable **Incoming Webhooks**, and add a webhook for the channel that should receive alerts. Slack gives you a URL of the form `https://hooks.slack.com/services/T000/B000/XXXX` — posting JSON like `{"text": "hello"}` to it puts a message in the channel. Treat the URL as a secret: anyone who has it can post to your channel. ## Step 2: choose the stream filters[#](#step-2-choose-the-stream-filters) The stream accepts the same filters as a normal search, so build the query on `/v1/news/everything` first, confirm it returns the coverage you expect, then reuse it verbatim. For a company, filter with `organization.name`; for a consumer brand, `brand.name`; and to alert only on reputation risks, add `entity.sentiment.polarity=negative` — the tone measured toward your brand specifically, explained in [how to detect negative mentions quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions): ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?organization.name=Tesla&language.code=en&fl=id,title,href,source.domain" ``` The `fl` parameter trims each event to the fields the alert needs, so you are not parsing full article bodies just to build one Slack line. ## Step 3: the complete alert script[#](#step-3-the-complete-alert-script) Save this as `brand-alerts.mjs` and run it with `node brand-alerts.mjs` (Node 20+; `fetch` is built in). It parses the SSE wire format, posts every `article` event to Slack, and reconnects with `Last-Event-Id` after any drop so no mention is lost: ``` const API_KEY = process.env.APITUBE_API_KEY; const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL; const FILTERS = "organization.name=Tesla&language.code=en&fl=id,title,href,source.domain"; let lastEventId = null; async function postToSlack(article) { await fetch(SLACK_WEBHOOK_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: `New mention: <${article.href}|${article.title}> — ${article.source.domain}` }) }); } async function streamOnce() { const headers = { "X-API-Key": API_KEY }; if (lastEventId) headers["Last-Event-Id"] = lastEventId; const res = await fetch(`https://api.apitube.io/v1/news/stream?${FILTERS}`, { headers }); if (!res.ok) throw new Error(`stream refused: HTTP ${res.status}`); const reader = res.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; let event = { name: "", id: "", data: "" }; for (;;) { const { value, done } = await reader.read(); if (done) return; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); buffer = lines.pop(); for (const line of lines) { if (line.startsWith("event:")) event.name = line.slice(6).trim(); else if (line.startsWith("id:")) event.id = line.slice(3).trim(); else if (line.startsWith("data:")) event.data += line.slice(5).trim(); else if (line === "") { if (event.name === "article" && event.data) { lastEventId = event.id; await postToSlack(JSON.parse(event.data)); } else if (event.name === "error") { console.error("stream error:", event.data); } event = { name: "", id: "", data: "" }; } } } } for (;;) { try { await streamOnce(); } catch (err) { console.error(err.message); } await new Promise(resolve => setTimeout(resolve, 5000)); } ``` The outer loop is the resilience layer: the server ends every session after 6 hours by design, and networks drop — either way the script waits five seconds and reconnects, replaying `Last-Event-Id` so APITube first delivers everything you missed. The wire format details (event names, heartbeats, error events) are in [how to stream news with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## Step 4: test it without spending credits[#](#step-4-test-it-without-spending-credits) Run the script with a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** first: the stream sends real `article` events with masked content, and deliveries do not consume your quota. You will see masked titles arrive in Slack — proof the parsing, posting and reconnection all work. Then switch `APITUBE_API_KEY` to a live key for full content. # Common Questions[#](#common-questions) * [Why SSE instead of a webhook?](#why-sse-instead-of-a-webhook) * [What does this cost?](#what-does-this-cost) * [Can I watch several brands with one script?](#can-i-watch-several-brands-with-one-script) ## Why SSE instead of a webhook?[#](#why-sse-instead-of-a-webhook) A webhook needs a public HTTPS endpoint that APITube can reach; the SSE script runs anywhere — a laptop, a container, a box behind NAT — because it dials out. If you already run a public server, a webhook removes the long-lived connection from your side: register the same filters as a [saved search](/en/articles/getting-started/glossary#saved-search) and let APITube POST to you instead. Both deliver identical article objects. ## What does this cost?[#](#what-does-this-cost) One streaming credit per article actually delivered; the idle connection and heartbeats are free, so a quiet brand costs nothing between mentions. Note that the Free plan allows one concurrent stream (content is preview) — for more connections or full content use a paid plan, or run the same filters as a polling loop, as shown in [polling vs streaming](/en/articles/delivery-and-export/streaming/polling-vs-streaming). ## Can I watch several brands with one script?[#](#can-i-watch-several-brands-with-one-script) Yes — `organization.name` accepts up to three comma-separated values with OR logic (`organization.name=Tesla,Rivian Automotive`), and the same goes for `brand.name`. Past three, run one stream per group of three, or one stream per brand if you want per-channel routing in Slack: each stream stays within your plan’s connection slots. * * * ## Related Articles * [How to Monitor Your Brand Reputation](/en/articles/use-cases/brand-and-marketing/brand-reputation-monitoring) * [How to Detect Negative Mentions Quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Send a Daily News Digest to Telegram URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/telegram-news-digest Build a daily Telegram news digest with APITube: one request for the last 24 hours of matching articles, formatted and sent via the Telegram Bot API on a cron… # How to Send a Daily News Digest to Telegram One scheduled request for the last 24 hours of coverage, formatted and sent to a Telegram chat — complete script and cron line ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Tesla&language_code=en&published_at_start=NOW-24HOURS&sort_by=source.rank.opr&per_page=10&fl=id%2Ctitle%2Chref%2Csource.domain) # How to send a daily news digest to Telegram[#](#how-to-send-a-daily-news-digest-to-telegram) A daily news digest in Telegram is one scheduled API call: request the last 24 hours of articles that match your topic with `published_at.start=NOW-24HOURS`, format the results as one message, and post it to your chat through the Telegram Bot API. The full Node.js script is below — no dependencies — plus the cron line that runs it every morning. On a day with no coverage it sends nothing and, because empty search results are free, costs nothing. ## Step 1: create the bot and find your chat id[#](#step-1-create-the-bot-and-find-your-chat-id) Message `@BotFather` in Telegram, send `/newbot`, and copy the bot token it returns (the string like `123456:ABC-...`). Then open a chat with your new bot, send it any message, and fetch `https://api.telegram.org/bot<TOKEN>/getUpdates` in a browser — the response contains your `chat.id`. For a channel or group digest, add the bot there as an admin and use that chat’s id instead. ## Step 2: shape the digest query[#](#step-2-shape-the-digest-query) The digest is a normal search against `/v1/news/everything`, so tune it there first. This example collects yesterday’s coverage of a company, strongest sources first, trimmed to the fields the message needs: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&language.code=en&published_at.start=NOW-24HOURS&sort.by=source.rank.opr&per_page=10&fl=id,title,href,source.domain&api_key=YOUR_API_KEY" ``` `sort.by=source.rank.opr` puts articles from high-authority outlets at the top, which reads better in a short digest than raw recency — the score is explained in [what OPR is](/en/articles/trust-and-support/what-is-opr). Swap the filter for whatever your digest is about: a `category.id`, a `topic.id`, an `entity.id` or a plain `title` keyword all work the same way, as listed in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). ## Step 3: the complete digest script[#](#step-3-the-complete-digest-script) Save as `digest.mjs` and run with `node digest.mjs` (Node 20+). It fetches the day’s articles, formats an HTML message, and sends it — skipping the send entirely on a quiet day: ``` const API_KEY = process.env.APITUBE_API_KEY; const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN; const CHAT_ID = process.env.TELEGRAM_CHAT_ID; const params = new URLSearchParams({ "organization.name": "Tesla", "language.code": "en", "published_at.start": "NOW-24HOURS", "sort.by": "source.rank.opr", "per_page": "10", "fl": "id,title,href,source.domain" }); const res = await fetch(`https://api.apitube.io/v1/news/everything?${params}`, { headers: { "X-API-Key": API_KEY } }); if (!res.ok) { console.error(`search failed: HTTP ${res.status}`, await res.text()); process.exit(1); } const data = await res.json(); const articles = data.results ?? []; if (articles.length === 0) { console.log("no articles in the last 24h — nothing to send"); process.exit(0); } const esc = s => s.replace(/[&<>]/g, c => ({ "&": "&", "<": "<", ">": ">" })[c]); const lines = articles.map(a => `• <a href="${a.href}">${esc(a.title)}</a> — ${a.source.domain}`); const text = `<b>Daily news digest</b>\n\n${lines.join("\n")}`; const send = await fetch(`https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ chat_id: CHAT_ID, text, parse_mode: "HTML", disable_web_page_preview: true }) }); if (!send.ok) console.error("telegram send failed:", await send.text()); ``` Two details worth keeping: titles are HTML-escaped before they enter the message (a headline containing `<` or `&` would otherwise break Telegram’s HTML parsing), and `disable_web_page_preview` stops Telegram from unfurling the first link into a giant card. ## Step 4: schedule it[#](#step-4-schedule-it) Run the script once a day with cron — here, every morning at 09:00: ``` 0 9 * * * cd /opt/digest && APITUBE_API_KEY=... TELEGRAM_BOT_TOKEN=... TELEGRAM_CHAT_ID=... node digest.mjs ``` Because the query uses a relative `NOW-24HOURS` window anchored at run time, the schedule and the window stay aligned automatically. If you later change the cadence — say, twice a day — shrink the window to match (`NOW-12HOURS`) so editions do not repeat each other; the relative syntax is covered in [how to filter by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). # Common Questions[#](#common-questions) * [What does a daily digest cost?](#what-does-a-daily-digest-cost) * [Can one script send several digests?](#can-one-script-send-several-digests) * [Why not stream instead of polling once a day?](#why-not-stream-instead-of-polling-once-a-day) ## What does a daily digest cost?[#](#what-does-a-daily-digest-cost) One search request per run, and only when it returns articles — an empty result set is free, and the script exits before contacting Telegram. Ten items per day fits comfortably inside every plan, including Free at 10 requests per minute. ## Can one script send several digests?[#](#can-one-script-send-several-digests) Yes — loop over an array of `{filters, chatId}` pairs and run the fetch-format-send steps per entry. Each topic is its own charged request, so five digests cost at most five requests a day. Keep distinct topics in distinct Telegram chats rather than one merged message; readers mute what they cannot filter. ## Why not stream instead of polling once a day?[#](#why-not-stream-instead-of-polling-once-a-day) A digest is periodic by definition — the reader wants one message at 09 , not thirty pings across the day. Streaming pays off when seconds matter; for everything scheduled, a single request is simpler and cheaper. The trade-off is laid out in [polling vs streaming](/en/articles/delivery-and-export/streaming/polling-vs-streaming). * * * ## Related Articles * [How to curate a newsletter with a news API](/en/articles/use-cases/brand-and-marketing/curate-newsletter) * [How to Monitor Your Brand Reputation](/en/articles/use-cases/brand-and-marketing/brand-reputation-monitoring) * [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range) --- ## How to Track Celebrity Buzz and Entertainment Hype URL: https://support.apitube.io/en/articles/use-cases/brand-and-marketing/track-celebrity-buzz Track celebrity buzz with the APITube News API: resolve a name through /v1/people, rank coverage with sort.by=engagement, and read Facebook, X and Reddit… # How to Track Celebrity Buzz and Entertainment Hype Resolve a public figure to an entity id, rank their coverage by engagement, and read share counts to see what actually spread ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&person_name=Taylor+Swift&sort_by=engagement&per_page=50) # How to track celebrity buzz and entertainment hype[#](#how-to-track-celebrity-buzz-and-entertainment-hype) To track celebrity buzz, resolve the person’s name to an [entity](/en/articles/getting-started/glossary#entity) id through `/v1/people`, then query `/v1/news/everything` with `sort.by=engagement` — a composite ranking built for viral potential that weighs timeliness, media richness and positive [sentiment](/en/articles/getting-started/glossary#sentiment). Every article returns a `shares` object with Facebook, X and Reddit counts, so you can see which stories actually travelled rather than which merely got published. ``` curl "https://api.apitube.io/v1/news/everything?person.name=Taylor%20Swift&sort.by=engagement&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Pass the key as the `api_key` query parameter or as an `X-API-Key` header. Each result carries a `shares` object alongside the usual article fields. ## How do you resolve a celebrity name to a stable id?[#](#how-do-you-resolve-a-celebrity-name-to-a-stable-id) `person.name` is quick to write, but it matches the extracted person entity by name, so two public figures who share a name land in the same feed. An entity id does not. Resolve the name once through the people directory: ``` curl "https://api.apitube.io/v1/people?name=Taylor%20Swift" \ -H "X-API-Key: YOUR_API_KEY" ``` The response includes an `id` (for example `1035093`), Wikipedia and Wikidata links, and a `coverage` block summarising how the press has been treating that person. Feed that id into `entity.id` to pull articles unambiguously: ``` curl "https://api.apitube.io/v1/news/everything?entity.id=1035093&sort.by=engagement&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Ids are stable, so resolve once and store the result rather than looking the name up on every request. The people directory and its `coverage` block are covered in [how to use the people directory](/en/articles/searching-and-filtering/entities/people-directory). ## How do you rank celebrity coverage by how viral it is?[#](#how-do-you-rank-celebrity-coverage-by-how-viral-it-is) `sort.by` accepts five composite modes, and `engagement` is the one tuned for social spread. It favours recent articles with images or video and positive framing — the profile of a story that gets shared rather than filed. `controversy` is its mirror image, surfacing polarising coverage instead: ``` # What is spreading right now curl "https://api.apitube.io/v1/news/everything?person.name=Taylor%20Swift&sort.by=engagement&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" # What is dividing people curl "https://api.apitube.io/v1/news/everything?person.name=Taylor%20Swift&sort.by=controversy" \ -H "X-API-Key: YOUR_API_KEY" ``` The other three modes are `relevance` (query matching plus quality signals), `quality` (editorial curation) and `trust` (source credibility, weighted heavily toward high-ranking domains). Full behaviour of each mode is described in [how to use advanced sort modes](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes). ## How do you read the share counts on an article?[#](#how-do-you-read-the-share-counts-on-an-article) Every article carries a `shares` object with a per-platform breakdown: ``` { "shares": { "total": 408, "facebook": 216, "twitter": 128, "reddit": 64 } } ``` Share counts are aggregated gradually over roughly two hours from publication, so a story published minutes ago will show a low number that keeps climbing. Comparing a fresh article against a day-old one on raw share count therefore understates the fresh one. Note also that shares are a **response field and a sort key, not a filter** — there is no minimum-shares filter parameter. To find high-share articles, sort by them and apply your own threshold in code. The sort keys are `shares.facebook.min`, `shares.twitter.min` and `shares.reddit.min`; the `.min` suffix is part of the key name and does not set a floor, and direction comes from `sort.order`: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Taylor%20Swift&sort.by=shares.reddit.min&sort.order=desc&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Dropping the `.min` suffix does not fail loudly — `sort.by=shares.reddit` is silently ignored and you get an unsorted page, so keep the exact key name. ## How do you tell adoring coverage from a backlash?[#](#how-do-you-tell-adoring-coverage-from-a-backlash) Sentiment filters split the feed by tone. `sentiment.overall.polarity` takes `positive`, `neutral` or `negative`; `sentiment.overall.score` is the underlying number from `-1` to `1` and accepts `.min` and `.max` bounds: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Taylor%20Swift&sentiment.overall.polarity=negative&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` The useful metric is the share of negative coverage rather than its raw volume — a star with ten times the coverage will always have more negative articles in absolute terms. Run `/v1/news/count` twice, once unfiltered and once with the polarity filter, and divide. For a per-mention rather than per-article view, [entity-level sentiment](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) scores how each individual entity is treated inside an article, which matters when one piece covers several people at once. ## How do you scope buzz to a genre or a market?[#](#how-do-you-scope-buzz-to-a-genre-or-a-market) Entertainment splits into fine-grained categories: `medtop:20000005` is cinema, `medtop:20000002` is arts and entertainment overall. Combine one with a person filter to isolate their film coverage from their music or personal coverage: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Taylor%20Swift&category.id=medtop:20000005&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Prefer a specific subcategory over the top-level `medtop:01000000`, which spans all arts, culture and media and is one of the largest categories in the corpus — very broad category queries combined with other filters can time out. For geography, `facet=true&facet.field=source.country.id` returns a country breakdown of the whole match set in one request, which tells you where a story is landing without fetching any articles. # Common Questions[#](#common-questions) * [Can I filter articles by number of shares?](#can-i-filter-articles-by-number-of-shares) * [Why do share counts look too low on brand-new articles?](#why-do-share-counts-look-too-low-on-brand-new-articles) * [What is the difference between person.name and entity.id?](#what-is-the-difference-between-personname-and-entityid) * [How do I compare buzz across several celebrities?](#how-do-i-compare-buzz-across-several-celebrities) ## Can I filter articles by number of shares?[#](#can-i-filter-articles-by-number-of-shares) No. Shares exist as response fields and as sort keys (`shares.facebook.min`, `shares.twitter.min`, `shares.reddit.min`), but not as filter parameters — there is no minimum-shares filter, and the `.min` in those key names is part of the sort key rather than a threshold. Sort by `engagement` or by a specific platform’s share count, take the first page, and apply your threshold client-side. This is deliberate: a fixed share threshold ages badly, because what counts as viral differs enormously between a niche music blog and a national outlet. ## Why do share counts look too low on brand-new articles?[#](#why-do-share-counts-look-too-low-on-brand-new-articles) Social share scores are collected progressively over about two hours from the article’s publication time, so a story indexed minutes ago has only partial counts. Any ranking that compares fresh and mature articles on raw shares will be biased against the fresh ones. Either wait out the two-hour window before scoring, or use `sort.by=engagement`, which weighs timeliness alongside media and sentiment signals rather than relying on share counts alone. ## What is the difference between person.name and entity.id?[#](#what-is-the-difference-between-personname-and-entityid) `person.name` matches the extracted person entity by name, so two people sharing a name return in the same feed. `entity.id` matches one specific resolved entity, which is unambiguous. Resolve the id once through `/v1/people?name=` and store it — ids are stable, and the profile at `/v1/people/{id}` also returns a `coverage` block with `article_count`, `momentum`, `sentiment`, `top_sources` and `top_topics` that you would otherwise have to compute yourself. ## How do I compare buzz across several celebrities?[#](#how-do-i-compare-buzz-across-several-celebrities) Run the same request per name against `/v1/news/count` over a fixed time window and compare the numbers — one cheap request each, no article payloads. For a richer comparison, fetch `/v1/people/{id}` for each and read `coverage.momentum.change_pct`, which already expresses whether attention is rising or falling relative to the previous period. Then pull articles only for the names that moved, sorted by `engagement`, to see what caused the shift. * * * ## Related Articles * [How to Track News About a Person](/en/articles/searching-and-filtering/entities/track-news-about-a-person) * [How to Use the People Directory](/en/articles/searching-and-filtering/entities/people-directory) * [How to Use Advanced Sort Modes](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) --- ## How to build news trading signals for algo trading URL: https://support.apitube.io/en/articles/use-cases/finance/algorithmic-trading-signals Build news-driven trading signals with APITube: stream matching articles over SSE, score tone with entity-level sentiment, and gate on source quality and… # How to build news trading signals for algo trading Turn real-time news, entity detection and sentiment scores into machine-readable signals your trading system can consume ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 6, 2026 # How to build news trading signals for algo trading[#](#how-to-build-news-trading-signals-for-algo-trading) To feed news into a trading system, combine three APITube features: the **[SSE](/en/articles/getting-started/glossary#sse-stream) stream** (`/v1/news/stream`) delivers matching articles as they are indexed, **[entity](/en/articles/getting-started/glossary#entity) detection** pins each article to the companies it actually talks about, and **entity-level [sentiment](/en/articles/getting-started/glossary#sentiment)** scores the tone toward each company on a -1 to 1 scale. Your bot consumes a single filtered stream and reacts to scored, machine-readable events instead of parsing headlines. ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?organization.name=Tesla&language.code=en" ``` Every filter of a normal search works on the stream, so the query above pushes only English articles mentioning Tesla — nothing to poll, nothing to deduplicate across repeated searches. ## What latency should you expect from news signals?[#](#what-latency-should-you-expect-from-news-signals) Be realistic about the clock: the stream checks for new matching articles roughly every **30 seconds** and delivers them as they are indexed, not tick-by-tick. That makes APITube signals right for minute-scale strategies — sentiment shifts, breaking-event reaction, coverage-volume spikes — not for microsecond arbitrage against the exchange feed. Two practical knobs matter for a bot: `stream.max_age` (a rolling window in minutes) drops late-indexed backfill before it is delivered or billed, so an old article can never fire a “new news” rule; and the connection lives at most 6 hours before the server asks you to reconnect. Details are in [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse). ## How do you score an article into a signal?[#](#how-do-you-score-an-article-into-a-signal) A usable signal needs a number, not a headline. Every article already carries scores your pipeline can threshold without any NLP of your own: * **Tone toward the company:** `entity.sentiment.polarity` (`positive` / `negative` / `neutral`) and the bracketing filters `entity.sentiment.score.min` / `entity.sentiment.score.max` measure sentiment toward the entity itself, so a negative remark about one ticker inside a neutral market wrap still triggers. * **Tone of the whole article:** `sentiment.overall.score.min` / `.max` on the same -1 to 1 scale. * **Urgency:** `is_breaking=1` keeps only stories flagged as breaking. This request streams only strongly negative coverage of one company — an early-warning feed ready for a threshold rule: ``` curl -N -H "X-API-Key: YOUR_API_KEY" \ "https://api.apitube.io/v1/news/stream?organization.name=Tesla&entity.sentiment.polarity=negative&entity.sentiment.score.max=-0.5" ``` If a company name fails to resolve, look up its stable numeric id first and pass `entity.id` instead — [how to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) shows the lookup. ## How do you keep noise out of the signal?[#](#how-do-you-keep-noise-out-of-the-signal) False positives cost money, so gate the stream on quality before the score ever reaches your strategy: * **Source floor:** `source.rank.opr.min=7` keeps only widely-referenced publishers ([OPR](/en/articles/getting-started/glossary#opr-open-pagerank) is a 0–10 authority scale) — a rumor blog and a wire service should not move the same signal. * **Scope:** `category.id=medtop:04000000` limits coverage to the IPTC _economy, business and finance_ category. * **Payload trim:** the `fl` parameter selects only the fields you consume (say `id,title,published_at,entities`), shrinking each event your parser handles. For backtesting, run the identical filters against `/v1/news/everything` with a `published_at.start` / `published_at.end` window — the search endpoint accepts the same parameters as the stream, so your historical sample matches what the live feed would have delivered. The full parameter list is in the official [News API reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Can I stream several tickers on one connection?](#can-i-stream-several-tickers-on-one-connection) * [How is streaming billed for a bot that runs 24/7?](#how-is-streaming-billed-for-a-bot-that-runs-247) * [Should I use webhooks instead of SSE?](#should-i-use-webhooks-instead-of-sse) ## Can I stream several tickers on one connection?[#](#can-i-stream-several-tickers-on-one-connection) Yes — filters accept comma-separated values, so `organization.name=Tesla,Nvidia` matches articles mentioning either company on a single connection. Your consumer then reads the `entities` array of each event to route the article to the right per-ticker signal, including each entity’s own sentiment block. ## How is streaming billed for a bot that runs 24/7?[#](#how-is-streaming-billed-for-a-bot-that-runs-247) Streaming draws from its own credit pool, separate from REST requests, and you pay per delivered article — an open connection that delivers nothing costs nothing beyond its slot. Narrow filters are therefore also a cost control: the negative-only Tesla stream above bills a fraction of an unfiltered firehose. See [how credits work](/en/articles/billing/credits/how-credits-work). ## Should I use webhooks instead of SSE?[#](#should-i-use-webhooks-instead-of-sse) Use SSE when your bot is a long-running process that can hold a connection; use [webhooks](/en/articles/getting-started/glossary#webhook) when you would rather APITube call your HTTP endpoint as matches appear — for example from a serverless stack. The filters are the same saved-search model either way, so switching later does not change your query logic. * * * ## Related Articles * [How to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) * [How to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) --- ## Finance & Market Intelligence URL: https://support.apitube.io/en/articles/use-cases/finance Track markets, companies, earnings and cryptocurrency with the APITube News API using entity, sentiment, date and real-time filters. # Finance & Market Intelligence Markets, companies, earnings and crypto. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) By Tasha and 1 other 2 authors 6 articles * [How to build market intelligence from news](/en/articles/use-cases/finance/market-intelligence) * [How to build news trading signals for algo trading](/en/articles/use-cases/finance/algorithmic-trading-signals) * [How to monitor companies, earnings and M&A](/en/articles/use-cases/finance/monitor-companies-mna) * [How to monitor cryptocurrency news](/en/articles/use-cases/finance/monitor-crypto) * [How to Monitor Energy and Fuel Price News](/en/articles/use-cases/finance/monitor-energy-markets) * [How to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) --- ## How to build market intelligence from news URL: https://support.apitube.io/en/articles/use-cases/finance/market-intelligence Build market intelligence with APITube: scope a sector with category.id or industry.id, rank movers with /v1/news/trends, aggregate with facets, then export. # How to build market intelligence from news Turn news coverage into market intelligence: scope a sector, rank what's moving with trends, break it down with facets, and export the dataset ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&category_id=medtop%3A04000000&published_at_start=NOW-30DAYS&per_page=250) # How to build market intelligence from news[#](#how-to-build-market-intelligence-from-news) To build market intelligence from news, use one endpoint — `/v1/news/everything` — and layer four moves on top of it: scope coverage to a sector with `category.id` or `industry.id`, rank what is moving with the `/v1/news/trends` endpoint, break the slice down by source, player or tone with `facet`, and pull the dataset out with `export`. There is no separate market-intelligence route; every step is a filter on a search you already know how to run. ``` # Last 30 days of economy, business and finance coverage curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&published_at.start=NOW-30DAYS&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header, and every filter below works on both `GET` (query string) and `POST` (JSON body). ## How do you scope coverage to a market or sector?[#](#how-do-you-scope-coverage-to-a-market-or-sector) Market intelligence starts by pinning the slice you care about. `category.id` takes an IPTC media-topic code — `medtop:04000000` is _economy, business and finance_, so it keeps market coverage in and general news out. For a tighter cut, add `industry.id`, a numeric industry id (up to three, comma-separated): ``` # Finance coverage, English only curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` An unknown category code returns HTTP 400 with error `ER0206`, and an unknown industry id returns `ER0210`, so a typo fails loudly instead of silently returning the wrong slice. See [how to filter news by industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) for resolving a sector to its numeric id. ## How do you see what is moving in a market?[#](#how-do-you-see-what-is-moving-in-a-market) Once the sector is scoped, `/v1/news/trends` tells you what dominates it. It runs a grouped count over the same filtered slice and returns the top values ranked by how many articles reference each one. Aggregate on up to five fields at once — `entity.id`, `category.id`, `topic.id`, `industry.id` or `source.id`: ``` # Top companies and topics in finance coverage curl "https://api.apitube.io/v1/news/trends?field=entity.id,topic.id&category.id=medtop:04000000&per_page=10" \ -H "X-API-Key: YOUR_API_KEY" ``` Ranking by raw volume answers “what is popular,” but market intelligence usually wants momentum. Add `trending=true` to score each value by its recent activity versus its baseline, so a rising theme rises to the top even before it is the loudest. Trends look back at most **30 days** and each call costs **1 point**. See [how to discover trending topics and entities](/en/articles/retrieval/discover-trends) for the full field list and the compare mode. ## How do you track how loud a theme is getting?[#](#how-do-you-track-how-loud-a-theme-is-getting) A single number over successive windows is a cheap early signal. `/v1/news/count` returns the size of a filtered slice without downloading any articles, so you can watch a theme accelerate or fade: ``` # How many finance stories mention inflation this week curl "https://api.apitube.io/v1/news/count?category.id=medtop:04000000&title=inflation&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` The response is a small `{ "status": "ok", "count": ..., "request_id": ... }` object, and the call costs **1 point**. Run it for last-7-days versus the previous week to see whether coverage of a theme is picking up, then drill into the articles only when the count moves. See [how to count matching articles without downloading them](/en/articles/retrieval/count-articles). ## How do you break a market down by source, sentiment or player in one call?[#](#how-do-you-break-a-market-down-by-source-sentiment-or-player-in-one-call) Facets turn one search into a set of grouped counts. Set `facet=true` and list up to five fields in `facet.field` — one request can tell you which outlets dominate the sector, the positive/negative/neutral split of its coverage, and the companies mentioned most: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&facet=true&facet.field=source.id,sentiment.overall.polarity,entity.id&facet.limit=20" \ -H "X-API-Key: YOUR_API_KEY" ``` `facet.limit` defaults to 10 and caps at 100 per field; `facet.mincount` drops long-tail values so the breakdown is not buried in one-off mentions. Other useful market fields include `topic.id`, `industry.id` and time buckets such as `published.month`. A missing or unsupported field returns errors in the `ER0310`–`ER0313` range. See [how to aggregate results with facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets). ## How do you read the market’s mood?[#](#how-do-you-read-the-markets-mood) Every article already carries a [sentiment](/en/articles/getting-started/glossary#sentiment) score from −1 (most negative) to 1 (most positive), so you filter and sort on it rather than computing tone yourself. Filter with `sentiment.overall.polarity` (`positive`, `negative` or `neutral`), or rank the slice with `sort.by=sentiment.overall.score`: ``` # Most negative finance coverage first curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sort.by=sentiment.overall.score&sort.order=asc" \ -H "X-API-Key: YOUR_API_KEY" ``` For tone toward one company rather than the whole article, switch to [entity](/en/articles/getting-started/glossary#entity)\-level sentiment. [How to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) covers the full sentiment workflow, including `entity.sentiment.polarity`. ## How do you surface the stories that matter, not just the newest?[#](#how-do-you-surface-the-stories-that-matter-not-just-the-newest) Results default to `published_at` (newest first), which is rarely what you want for a market read. `sort.by` accepts several computed modes: `engagement` (social traction), `quality`, `trust` (source authority), `controversy` and `media_richness`, plus `relevance` and `source.rank.opr`: ``` # Highest-engagement finance stories this week curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sort.by=engagement&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` Pair `sort.order=asc` or `desc` with any mode. See [how to sort by controversy, trust and social shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes) for what each mode ranks on. ## How do you export a market dataset for analysis?[#](#how-do-you-export-a-market-dataset-for-analysis) When you need the underlying articles in a tool, add `export` to the `everything` request. Supported values are `csv`, `tsv`, `xml`, `rss`, `xlsx`, `parquet`, `jsonl` and `ndjson`: ``` # Pull a 30-day finance dataset as JSON Lines curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&published_at.start=NOW-30DAYS&per_page=250&export=jsonl" \ -H "X-API-Key: YOUR_API_KEY" -o finance.jsonl ``` `per_page` defaults to 100 and maxes out at **250**, or **50** on Starter and **10** on Free — a larger value returns `ER0171` — and you walk further with `page`. On the Free plan, paging stops after the first 5 pages (`ER0173`), so a deep back-fill needs a paid plan. See [how to export for data pipelines](/en/articles/delivery-and-export/export/export-data-pipelines). The canonical parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated market-intelligence endpoint?](#is-there-a-dedicated-market-intelligence-endpoint) * [How far back can a trends study look?](#how-far-back-can-a-trends-study-look) * [How large a page can I export at once?](#how-large-a-page-can-i-export-at-once) * [Do trends and count requests cost the same?](#do-trends-and-count-requests-cost-the-same) ## Is there a dedicated market-intelligence endpoint?[#](#is-there-a-dedicated-market-intelligence-endpoint) No. Market intelligence uses the same `/v1/news/everything`, `/v1/news/trends` and `/v1/news/count` endpoints as any other search, plus the `category.id`, `industry.id`, `facet`, `sentiment.*`, `sort.by` and `export` parameters. You scope a sector, rank what is moving, break it down and export — there is no separate route to learn. ## How far back can a trends study look?[#](#how-far-back-can-a-trends-study-look) The `/v1/news/trends` endpoint is computed over a rolling window of at most **30 days**. Omit the dates for the default last-30-days window, or set `published_at.start` / `published_at.end` inside a 30-day span; a wider range is rejected. Split longer studies into 30-day chunks and compare them. ## How large a page can I export at once?[#](#how-large-a-page-can-i-export-at-once) `per_page` caps at **250**, or **50** on Starter and **10** on Free — a higher value returns `ER0171` (HTTP 400). Page through larger sets with `page`, keeping the same filters and `export` value on each request. On the Free plan, [pagination](/en/articles/getting-started/glossary#pagination) stops after the first 5 pages (`ER0173`), so deep exports for a market dataset need a paid plan. ## Do trends and count requests cost the same?[#](#do-trends-and-count-requests-cost-the-same) Each `/v1/news/trends` call costs **1 point** regardless of how many fields you aggregate, and each `/v1/news/count` call also costs **1 point**. Both are cheaper than pulling full articles, so use them to decide _what_ to fetch, then run `everything` only on the slices worth downloading. * * * ## Related Articles * [How to discover trending topics and entities](/en/articles/retrieval/discover-trends) * [How to aggregate results with facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) * [How to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) * [How to export for data pipelines (JSONL, Parquet)](/en/articles/delivery-and-export/export/export-data-pipelines) --- ## How to monitor companies, earnings and M&A URL: https://support.apitube.io/en/articles/use-cases/finance/monitor-companies-mna Monitor companies for earnings, M&A, IPOs and funding with the APITube News API: filter by event.type, pin a company with organization.name, and stream events… # How to monitor companies, earnings and M&A Track mergers, acquisitions, earnings, IPOs and funding for any company with the event.type filter ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Microsoft&event_type=merger-acquisition%2Cearnings) # How to monitor companies, earnings and M&A[#](#how-to-monitor-companies-earnings-and-ma) To monitor companies for earnings, mergers, acquisitions and other corporate events, query `/v1/news/everything` with the `event.type` filter — for example `event.type=merger-acquisition,earnings` — and pin the company with `organization.name` or a numeric `entity.id`. APITube tags each article with a single primary business event, so you filter on what actually happened rather than guessing keywords. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Microsoft&event.type=merger-acquisition,earnings" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header, and every filter below works on both `GET` (query string) and `POST` (request body). ## How do you filter for M&A, earnings and IPO news?[#](#how-do-you-filter-for-ma-earnings-and-ipo-news) Use `event.type`, which accepts a comma-separated list of up to five event codes. For company and market monitoring, the business codes are the ones you want: `merger-acquisition`, `earnings`, `ipo`, `funding-round`, `layoffs`, `bankruptcy`, `product-launch`, `partnership`, `executive-change`, `lawsuit`, `stock-movement`, `spin-off`, `contract-award` and `regulatory-action`. ``` # Deal-flow: mergers, acquisitions, IPOs and funding rounds curl "https://api.apitube.io/v1/news/everything?event.type=merger-acquisition,ipo,funding-round" \ -H "X-API-Key: YOUR_API_KEY" ``` An unsupported `event.type` value does not silently pass — the request returns HTTP 400 and lists the codes it rejected, pointing you to `/v1/news/event-types`. Send a `GET` to that endpoint for the full set of codes and their categories before hard-coding a value. ## How do you catch every business event at once?[#](#how-do-you-catch-every-business-event-at-once) Instead of listing individual codes, pass `event.category=business` to match all business events in one filter. The category groups every business code — earnings, M&A, IPO, funding, layoffs, bankruptcy, lawsuits, executive changes, regulatory action and more — so you never miss a corporate development you did not think to name. The other two categories are `society` and `environment`; an unknown category returns a 400 error. ``` # Any business event about this company, newest first curl "https://api.apitube.io/v1/news/everything?organization.name=Nvidia&event.category=business" \ -H "X-API-Key: YOUR_API_KEY" ``` Results come back sorted by `published_at` (newest first) by default, which is what you want for an event watch. See [how to filter news by event type and category](/en/articles/searching-and-filtering/events/filter-by-event-type) for the full list of codes and the `ignore.event.type` exclude filter. ## How do you focus on one company?[#](#how-do-you-focus-on-one-company) `event.type` on its own returns events across every company. To watch a single company, add `organization.name` (resolved to a known organization [entity](/en/articles/getting-started/glossary#entity)) or a numeric `entity.id`. You can pass up to three company names, comma-separated: ``` # Earnings coverage for either company curl "https://api.apitube.io/v1/news/everything?organization.name=Alphabet Inc.,Tesla&event.type=earnings" \ -H "X-API-Key: YOUR_API_KEY" ``` If `organization.name` returns a _not found_ error, the exact spelling did not resolve to an entity. Look the company up first and filter by its stable `entity.id`, which does not depend on capitalization or exact wording — [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) covers resolving a name to an id. ## How do you tell whether an event is good or bad for the company?[#](#how-do-you-tell-whether-an-event-is-good-or-bad-for-the-company) Layer [sentiment](/en/articles/getting-started/glossary#sentiment) on top of the event filter. Article-level tone comes from `sentiment.overall.polarity` (`positive`, `negative` or `neutral`); to score how the coverage treats the company **specifically**, use `entity.sentiment.polarity`, which scores each mention of the company separately from the surrounding article: ``` # Negative coverage of layoffs or lawsuits at this company curl "https://api.apitube.io/v1/news/everything?organization.name=Meta&event.type=layoffs,lawsuit&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` Both polarities pair with a numeric scale from **\-1 (most negative) to 1 (most positive)**: `sentiment.overall.score.min` / `.max` for the article and `entity.sentiment.score.min` / `.max` for the company. See [how to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) for the full sentiment workflow. ## How do you bound the window and page through results?[#](#how-do-you-bound-the-window-and-page-through-results) Bound the reporting period with `published_at.start` and `published_at.end`. They accept absolute dates (`2026-06-01`) and Solr-style relative values such as `NOW-1MONTH`, `NOW-7DAY` or `NOW-1WEEK`: ``` # This quarter's M&A and IPO events, 250 per page curl "https://api.apitube.io/v1/news/everything?event.type=merger-acquisition,ipo&published_at.start=NOW-3MONTH&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at **250**, or **50** on Starter and **10** on Free — a larger value returns an out-of-range error — and you walk further with `page`. On the Free plan, paging stops after the first 5 pages, so use a paid plan when you need a deep back-fill of a company’s event history. ## How do you get corporate events in real time?[#](#how-do-you-get-corporate-events-in-real-time) For a live feed, keep the **same filters** but open the [SSE](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream` instead of polling `everything`. The stream pushes new matching events as they are published and supports `Last-Event-Id`, so a restart resumes without gaps: ``` curl -N "https://api.apitube.io/v1/news/stream?organization.name=Tesla&event.category=business" \ -H "X-API-Key: YOUR_API_KEY" ``` See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for handling the event stream. The canonical parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated M&A or earnings endpoint?](#is-there-a-dedicated-ma-or-earnings-endpoint) * [How many event types can I request at once?](#how-many-event-types-can-i-request-at-once) * [What is the difference between event.type and event.category?](#what-is-the-difference-between-eventtype-and-eventcategory) * [Why does organization.name say the company was not found?](#why-does-organizationname-say-the-company-was-not-found) ## Is there a dedicated M&A or earnings endpoint?[#](#is-there-a-dedicated-ma-or-earnings-endpoint) No. Company and event monitoring uses the same `/v1/news/everything` endpoint as any other search, plus the `event.type`, `event.category`, `organization.name`, `entity.sentiment.*` and `published_at` filters. There is no separate deals or earnings route — you describe the events and companies you want and combine the filters in one request. ## How many event types can I request at once?[#](#how-many-event-types-can-i-request-at-once) Up to five, comma-separated, in a single `event.type` parameter. Each article carries one primary event code, so `event.type=merger-acquisition,ipo,earnings` returns articles whose primary event is any one of those (OR logic). To discover every valid code, call `GET /v1/news/event-types`. ## What is the difference between event.type and event.category?[#](#what-is-the-difference-between-eventtype-and-eventcategory) `event.type` matches specific codes such as `earnings` or `merger-acquisition`. `event.category` matches a whole group — `business`, `society` or `environment` — and business expands to all business codes at once. Use `event.type` when you care about specific developments and `event.category=business` when you want any corporate event. ## Why does organization.name say the company was not found?[#](#why-does-organizationname-say-the-company-was-not-found) `organization.name` resolves the name to a known organization entity before filtering, and an unrecognized spelling returns an HTTP 400 error. Resolve the company to a stable numeric `entity.id` first, then filter by `entity.id` instead — ids do not depend on exact spelling or capitalization, so they avoid the not-found case. * * * ## Related Articles * [How to filter news by event type and category](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) * [How to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to monitor cryptocurrency news URL: https://support.apitube.io/en/articles/use-cases/finance/monitor-crypto Monitor cryptocurrency news via the APITube News API: search Bitcoin or Ethereum by title or entity, filter by sentiment and date, and stream new articles live. # How to monitor cryptocurrency news Track Bitcoin, Ethereum, tokens and exchanges with title search, entity filters, sentiment and real-time SSE ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 Updated July 29, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=Bitcoin&language_code=en&per_page=50) # How to monitor cryptocurrency news[#](#how-to-monitor-cryptocurrency-news) To monitor cryptocurrency news, query `/v1/news/everything` with a **title** or **[entity](/en/articles/getting-started/glossary#entity)** search for the coins, tokens or companies you care about — for example `title=Bitcoin` — then narrow the watch with the standard `language.code`, `published_at.start/end` and [sentiment](/en/articles/getting-started/glossary#sentiment) filters, and stream new matches in real time over [SSE](/en/articles/getting-started/glossary#sse-stream). You build a crypto feed from the same building blocks used for any topic, so the same request can follow a single coin, one exchange, or the whole market. ``` curl "https://api.apitube.io/v1/news/everything?title=Bitcoin&language.code=en&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` ## How do you search for Bitcoin, Ethereum and other coins?[#](#how-do-you-search-for-bitcoin-ethereum-and-other-coins) The quickest watch is a **title** search. Pass the coin or token name in the `title` parameter, and the API matches it in article headlines: ``` # Headlines about Bitcoin curl "https://api.apitube.io/v1/news/everything?title=Bitcoin" -H "X-API-Key: YOUR_API_KEY" ``` To cover several coins at once, use the boolean `query` parameter with `OR`, and combine terms with `AND`/`NOT` to tighten the match: ``` # Bitcoin or Ethereum headlines, dropping "prediction" spam curl "https://api.apitube.io/v1/news/everything?query=(Bitcoin OR Ethereum) AND NOT prediction" \ -H "X-API-Key: YOUR_API_KEY" ``` For a multi-word phrase, wrap it in quotes; add `~N` to allow up to _N_ words between the terms — `title="Bitcoin ETF"~2`. See [how to use AND, OR and NOT in search](/en/articles/searching-and-filtering/keyword-search/boolean-search) for the full boolean syntax. ## How do you track a specific coin, token or exchange precisely?[#](#how-do-you-track-a-specific-coin-token-or-exchange-precisely) Keyword search can catch false matches (a ticker that is also a common word, or a company that shares a name). To pin the watch to an exact thing, filter by **entity** with `entity.id`. Look up the numeric id for a coin, token issuer or exchange with entity autocomplete, then pass it in: ``` # All articles that mention the entity with id 12345 (e.g. a specific exchange) curl "https://api.apitube.io/v1/news/everything?entity.id=12345" -H "X-API-Key: YOUR_API_KEY" ``` Entity filtering resolves to a disambiguated thing rather than a word, so you avoid unrelated hits. Read [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) to get the id and combine entities with keywords. ## How do you filter crypto news by language, date and freshness?[#](#how-do-you-filter-crypto-news-by-language-date-and-freshness) Layer the standard filters on top of your coin search to keep the feed relevant: * **`language.code`** — restrict to a language, e.g. `language.code=en` (comma-separate up to three codes). * **`published_at.start`** and **`published_at.end`** — bound a date window, e.g. `published_at.start=2026-06-01&published_at.end=2026-06-30`. * **`is_breaking=1`** — return only high-importance items, useful for market-moving headlines. * **`sort.by`** — results default to `published_at` newest-first; set `sort.order=asc` to walk forward in time. ``` curl "https://api.apitube.io/v1/news/everything?query=(Bitcoin OR Ethereum)&language.code=en&published_at.start=2026-06-01&published_at.end=2026-06-30&is_breaking=1" \ -H "X-API-Key: YOUR_API_KEY" ``` Note the closed date window. Because `query` searches article headlines, the `published_at` range is capped at **31 days** per request — an open-ended `published_at.start` would stretch to now and return `ER0110`. Leave the dates off entirely and the search covers the last 31 days, reported back as an `ER0366` warning in `meta.warnings`. To follow a coin across several months, loop over one month at a time; see [how to filter news by date range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## How do you gauge market sentiment on a coin?[#](#how-do-you-gauge-market-sentiment-on-a-coin) Every article carries a `sentiment` block (`overall`, `title`, `body`) with a score and polarity, so you can weigh whether coverage of a coin is positive or negative. To measure tone **toward the coin or company specifically** — not the whole article — use `entity.sentiment.polarity` with a value of `positive`, `negative` or `neutral`: ``` # Negative coverage that mentions this exchange entity curl "https://api.apitube.io/v1/news/everything?entity.id=12345&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` That is how you catch a wave of negative sentiment about one token even when the surrounding article is neutral — entity-level sentiment scores each mention separately from the article as a whole. ## How do you get crypto news in real time?[#](#how-do-you-get-crypto-news-in-real-time) For a live feed, keep the **same filters** but open the SSE stream at `/v1/news/stream` instead of polling `everything`. The stream pushes new matching articles as they are published and supports `Last-Event-Id` so you can resume without gaps: ``` curl -N "https://api.apitube.io/v1/news/stream?query=(Bitcoin OR Ethereum)&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for handling the event stream. # Common Questions[#](#common-questions) * [Do I need a special crypto plan or endpoint?](#do-i-need-a-special-crypto-plan-or-endpoint) * [How do I avoid false matches on coin names?](#how-do-i-avoid-false-matches-on-coin-names) * [How many crypto articles can I pull per request?](#how-many-crypto-articles-can-i-pull-per-request) * [How do I get only breaking crypto headlines?](#how-do-i-get-only-breaking-crypto-headlines) ## Do I need a special crypto plan or endpoint?[#](#do-i-need-a-special-crypto-plan-or-endpoint) No. Cryptocurrency monitoring uses the same `/v1/news/everything` endpoint and the same `title`, `query`, `entity.id`, `language.code`, `published_at` and sentiment filters as any other topic. You do not switch endpoints — you just describe the coins and constraints you want. ## How do I avoid false matches on coin names?[#](#how-do-i-avoid-false-matches-on-coin-names) Two ways: search the headline with `title` instead of matching everywhere, and prefer `entity.id` when a coin or exchange name is ambiguous. An entity filter matches a disambiguated thing, so `entity.id` for an exchange will not pull in unrelated articles that merely reuse the same word. You can also add `NOT` terms to the boolean `query` to drop noise. ## How many crypto articles can I pull per request?[#](#how-many-crypto-articles-can-i-pull-per-request) Up to **250** per request with `per_page` (for example `per_page=250`), then move through the pages with `page`. On the Free plan, paging is capped at the first few pages, so use a paid plan when you need to walk deep result sets. ## How do I get only breaking crypto headlines?[#](#how-do-i-get-only-breaking-crypto-headlines) Add `is_breaking=1` to your request. It is a `0/1` flag that limits results to articles APITube marks as high-importance, which is a good filter for market-moving crypto news rather than routine coverage. * * * ## Related Articles * [How to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to monitor breaking news and real-time events](/en/articles/searching-and-filtering/events/monitor-breaking-news) * [How to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Monitor Energy and Fuel Price News URL: https://support.apitube.io/en/articles/use-cases/finance/monitor-energy-markets Monitor energy and fuel news with the APITube News API: scope the sector with industry.id, track tone with sentiment filters, and rank momentum with… # How to Monitor Energy and Fuel Price News Scope fuel, coal and specialty energy with industry filters, then read tone and momentum with sentiment and trends ![Kent Hudson](/images/authors/kent-hudson-apitube-io-128.jpg) Written by Kent Hudson July 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&industry_id=326%2C331%2C353&sort_by=published_at&sort_order=desc&per_page=50) # How to monitor energy and fuel price news[#](#how-to-monitor-energy-and-fuel-price-news) To monitor energy and fuel news, scope `/v1/news/everything` with `industry.id` — `326` is Fuel (exploration, extraction, transport and consumer fuel products), `331` is Coal logistics, `353` is Specialty Energy (marine, ocean vessel and jet fuel). Then layer [sentiment](/en/articles/getting-started/glossary#sentiment) on top to read market mood, and use `/v1/news/trends` to see which parts of the sector are gaining attention. ``` curl "https://api.apitube.io/v1/news/everything?industry.id=326,331,353&sort.by=published_at&sort.order=desc&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Pass the key as the `api_key` query parameter or as an `X-API-Key` header. `industry.id` takes up to three comma-separated numeric IDs with OR logic. ## Which industry IDs cover the energy sector?[#](#which-industry-ids-cover-the-energy-sector) Energy is spread across several classifiers, and the description matters because the boundaries are not obvious: * **`326` — Fuel.** Exploration, extraction and transport of raw fuel materials plus the consumer products made from them, including related equipment and energy generation. Explicitly **excludes electric utilities**. * **`331` — Coal logistics.** Moving coal and its waste products by rail and sea for use as fuel. * **`353` — Specialty Energy.** Non-automotive fuels: marine, ocean vessel and jet fuel. Because electric utilities sit outside `326`, a feed built only on these three IDs will cover hydrocarbons and miss grid and power-generation coverage. Resolve additional IDs from free text with `/v1/suggest/industries?prefix=energy`, or browse the [APITube industry list](https://docs.apitube.io/platform/news-api/list-of-industries). Every article returns an `industries` array so you can see which classifier matched. The filter’s rules are covered in [how to filter news by industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry). ## How do you narrow to price coverage specifically?[#](#how-do-you-narrow-to-price-coverage-specifically) The sector feed carries everything from drilling permits to refinery maintenance. Add `title` to require price language in the headline: ``` curl "https://api.apitube.io/v1/news/everything?industry.id=326&title=oil%20prices&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` Multiple words in `title` are matched with AND regardless of order, so `title=oil prices` requires both words somewhere in the headline. Wrap the phrase in double quotes — `title="oil prices"` — to require that exact order, which trims roughly a quarter of the matches in practice. Use `ignore.title` to strip a recurring noise term, and `organization.name` when you want a specific producer’s coverage regardless of headline wording. ## How do you read market mood rather than volume?[#](#how-do-you-read-market-mood-rather-than-volume) Sentiment filters split the feed by tone. `sentiment.overall.polarity` accepts `positive`, `neutral` or `negative`, and `sentiment.overall.score` gives you the raw value from `-1` to `1` with `.min` and `.max` bounds: ``` curl "https://api.apitube.io/v1/news/everything?industry.id=326&sentiment.overall.polarity=negative&published_at.start=NOW-30DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` Raw negative counts follow total coverage volume, so a busy news week always produces more negative articles. Track the **ratio** instead — call `/v1/news/count` once with the industry filter and once with the polarity added, over the same window, and divide. A rising negative share while total volume stays flat is the signal worth alerting on. See [how to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) for the full parameter set. ## How do you see which parts of the sector are heating up?[#](#how-do-you-see-which-parts-of-the-sector-are-heating-up) `/v1/news/trends` aggregates a field and ranks values by article count, which turns “what is the energy sector talking about” into one request. The `field` parameter accepts `source.id`, `category.id`, `topic.id`, `industry.id` and `entity.id` — other field names are rejected with an HTTP 400: ``` curl "https://api.apitube.io/v1/news/trends?field=industry.id&industry.id=326,331,353&per_page=10&trending=true" \ -H "X-API-Key: YOUR_API_KEY" ``` With `trending=true` each result carries a `trending_score` — the ratio of recent to historical activity, where above `1` means rising and below `1` means declining — plus `trending_history` and `growth_rate`. Adding `compare=true` with `compare_window=7DAYS` returns `previous_count`, `change_absolute` and `change_percent` against the prior period, and unlocks sorting by `change` or `trending_score`. Every standard news filter narrows the set before aggregation, so the trends call above ranks only within the energy industries. More detail in [how to discover trending topics and entities](/en/articles/retrieval/discover-trends). ## How do you compare energy coverage across markets?[#](#how-do-you-compare-energy-coverage-across-markets) `source.country.code` scopes to where the outlet is based, which works well for national energy press and regulators: ``` curl "https://api.apitube.io/v1/news/count?industry.id=326&source.country.code=us&published_at.start=NOW-30DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` For a full geographic breakdown in one call rather than one request per country, use faceting: `facet=true&facet.field=source.country.id` returns counts across the entire match set. Pair it with `per_page=1` so you pay for the aggregation and not for article payloads. This same combination underpins the sector dashboards described in [how to build market intelligence from news](/en/articles/use-cases/finance/market-intelligence). # Common Questions[#](#common-questions) * [Does industry.id=326 include electricity and utilities?](#does-industryid326-include-electricity-and-utilities) * [Can I get commodity prices from the API?](#can-i-get-commodity-prices-from-the-api) * [Which fields can I use with /v1/news/trends?](#which-fields-can-i-use-with-v1newstrends) * [How do I track a single producer rather than the whole sector?](#how-do-i-track-a-single-producer-rather-than-the-whole-sector) ## Does industry.id=326 include electricity and utilities?[#](#does-industryid326-include-electricity-and-utilities) No. The Fuel classifier covers exploration, extraction and transport of raw fuel materials, the consumer products derived from them, and related equipment and energy generation — but its definition explicitly excludes electric utilities. A feed built on `326`, `331` and `353` is a hydrocarbons feed. If your coverage needs to include grid operators and power retailers, resolve their industry IDs separately with `/v1/suggest/industries` and run a second request, since `industry.id` caps at three values per call. ## Can I get commodity prices from the API?[#](#can-i-get-commodity-prices-from-the-api) No. APITube indexes news coverage, not market data — there is no price field, no ticker and no time series of quotes. What you get is the reporting around prices: how much is being written, by whom, in what tone, and which parts of the sector are gaining attention. That is useful as a sentiment or attention overlay on top of a real price feed, and it is what the sentiment and trends filters above are for. Quoted figures appear inside the article `body` only when the reporter wrote them. ## Which fields can I use with /v1/news/trends?[#](#which-fields-can-i-use-with-v1newstrends) Exactly five: `source.id`, `category.id`, `topic.id`, `industry.id` and `entity.id`. Up to five can be combined in one comma-separated `field` value. Anything else — including attribute-style names that work as ordinary filters — is rejected with an HTTP 400 and an explicit list of the allowed fields in the error message. All the normal news filters still apply to a trends call and narrow the set before aggregation. ## How do I track a single producer rather than the whole sector?[#](#how-do-i-track-a-single-producer-rather-than-the-whole-sector) Use `organization.name` to match the company [entity](/en/articles/getting-started/glossary#entity) anywhere in the article, or `title` to require its name in the headline when you want only stories genuinely about that producer. Combine either with the industry filter to drop coverage that mentions the company in an unrelated context. For a comparable scoreboard across several producers, loop the same request over your watchlist against `/v1/news/count` with a fixed time window — one small request each, no article payloads — then fetch articles only for the names whose volume moved. * * * ## Related Articles * [How to Filter News by Industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Build Market Intelligence from News](/en/articles/use-cases/finance/market-intelligence) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) --- ## How to track stock-market sentiment URL: https://support.apitube.io/en/articles/use-cases/finance/stock-market-sentiment Track stock-market sentiment with APITube: scope to finance coverage, filter by tone, and measure sentiment toward one company with entity-level polarity. # How to track stock-market sentiment Measure the tone of finance coverage and gauge sentiment toward a company with polarity filters and sentiment sorting ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 2, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&category_id=medtop%3A04000000&sentiment_polarity=negative&sort_by=sentiment.overall.score&sort_order=asc&per_page=50) # How to track stock-market sentiment[#](#how-to-track-stock-market-sentiment) To track stock-market [sentiment](/en/articles/getting-started/glossary#sentiment), query `/v1/news/everything`, scope the results to finance coverage with `category.id=medtop:04000000`, and read tone with the `sentiment.overall.polarity` filter or by sorting on `sort.by=sentiment.overall.score`. Every article APITube returns already carries a sentiment score, so you never compute tone yourself — you filter and sort on a value the API attaches during processing. ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sentiment.overall.polarity=negative&sort.by=sentiment.overall.score&sort.order=asc&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. The `medtop:04000000` code is the IPTC category for _economy, business and finance_, so it keeps market coverage in and general news out. ## How do you gauge the market’s overall mood?[#](#how-do-you-gauge-the-markets-overall-mood) The fastest read on the market is the share of positive versus negative coverage in the finance category. Filter by tone with `sentiment.overall.polarity`, which accepts `positive`, `negative` or `neutral` (case-insensitive) and keeps only articles that match: ``` # Positive finance coverage, newest first curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sentiment.overall.polarity=positive&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` To rank by how strong the tone is rather than filter, sort with `sort.by=sentiment.overall.score`. Scores run from **\-1 (most negative) to 1 (most positive)**, so `sort.order=asc` surfaces the most negative market stories first and `sort.order=desc` the most positive. Results are sorted by `published_at` (newest first) by default, so set `sort.by` explicitly when you want a tone ranking. ## How do you measure sentiment toward one company or stock?[#](#how-do-you-measure-sentiment-toward-one-company-or-stock) Article-level polarity describes the whole story, which can bury how a single ticker is treated inside a broader piece. To measure tone **toward one company specifically**, pin the company with `organization.name` (or a numeric `entity.id`) and add `entity.sentiment.polarity`: ``` # Coverage that speaks negatively about Tesla, not just negative articles that mention it curl "https://api.apitube.io/v1/news/everything?organization.name=Tesla&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` `entity.sentiment.polarity` accepts `positive`, `negative` or `neutral`, and `entity.sentiment.score.min` / `entity.sentiment.score.max` bracket the same -1 to 1 scale for the [entity](/en/articles/getting-started/glossary#entity) alone. This scores each mention of the company separately from the article as a whole, so you catch a wave of negative sentiment about one stock even when the surrounding market piece is neutral. See [how to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) for the full entity-level parameters. If `organization.name` returns a _not found_ error, look up the exact entity with autocomplete first — [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) covers resolving names to a stable `entity.id`. ## How do you score sentiment on a numeric scale?[#](#how-do-you-score-sentiment-on-a-numeric-scale) Polarity answers “good, bad or flat?”, but a trading signal usually needs a threshold. Every sentiment layer is also scored from -1 to 1, and `sentiment.overall.score.min` / `sentiment.overall.score.max` bound that range. This returns only strongly negative finance coverage — useful for an early-warning feed: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sentiment.overall.score.max=-0.5" \ -H "X-API-Key: YOUR_API_KEY" ``` A value outside -1 to 1, or a non-numeric value, returns HTTP 400 with a sentiment validation error, so keep thresholds inside that band. The same `-1..1` band applies to `entity.sentiment.score.*`, so you can set a hard cut-off on company-level tone the same way. ## How do you bound the window and pull enough articles?[#](#how-do-you-bound-the-window-and-pull-enough-articles) Sentiment is only meaningful over a defined period, so bound the window with `published_at.start` and `published_at.end`. They accept absolute dates (`2026-06-01`) and relative Solr-style values such as `NOW-7DAY`, `NOW-1WEEK` or `NOW-1MONTH`: ``` # Last 7 days of negative finance coverage, 250 per page curl "https://api.apitube.io/v1/news/everything?category.id=medtop:04000000&sentiment.overall.polarity=negative&published_at.start=NOW-7DAY&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at **250**, or **50** on Starter and **10** on Free (a larger value returns an out-of-range error); walk further with `page`. On the Free plan, paging stops after the first 5 pages, so use a paid plan when you need deep result sets for a sentiment average. ## How do you track sentiment shifts in real time?[#](#how-do-you-track-sentiment-shifts-in-real-time) For a live tone feed, keep the **same filters** but open the [SSE](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream` instead of polling `everything`. The stream pushes new matching articles as they are published and supports `Last-Event-Id` so you can resume without gaps: ``` curl -N "https://api.apitube.io/v1/news/stream?category.id=medtop:04000000&sentiment.overall.polarity=negative&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) for handling the event stream. The canonical parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Do I need a special finance or markets endpoint?](#do-i-need-a-special-finance-or-markets-endpoint) * [What is the difference between article and entity sentiment?](#what-is-the-difference-between-article-and-entity-sentiment) * [Why does organization.name say the company was not found?](#why-does-organizationname-say-the-company-was-not-found) * [How do I sort by the strongest negative coverage?](#how-do-i-sort-by-the-strongest-negative-coverage) ## Do I need a special finance or markets endpoint?[#](#do-i-need-a-special-finance-or-markets-endpoint) No. Stock-market sentiment uses the same `/v1/news/everything` endpoint and the same `sentiment.*`, `entity.sentiment.*`, `category.id`, `published_at` and `sort.by` filters as any other topic. You scope to finance with `category.id=medtop:04000000` and read tone with the sentiment parameters — there is no separate markets route. ## What is the difference between article and entity sentiment?[#](#what-is-the-difference-between-article-and-entity-sentiment) `sentiment.overall.polarity` and `sentiment.overall.score` describe the tone of the whole article. `entity.sentiment.polarity` and `entity.sentiment.score.*` describe the tone toward a single mentioned thing — a company, person or brand — scored independently of the surrounding text. Use article sentiment for the market’s overall mood and entity sentiment when you care about one ticker. See [how to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) for the article-level parameters. ## Why does organization.name say the company was not found?[#](#why-does-organizationname-say-the-company-was-not-found) `organization.name` resolves the name to a known entity before filtering, and an unrecognized name returns an HTTP 400 error. Resolve the company to a stable numeric `entity.id` with entity autocomplete, then filter by `entity.id` instead — ids do not depend on exact spelling or capitalization, so they avoid the not-found case. ## How do I sort by the strongest negative coverage?[#](#how-do-i-sort-by-the-strongest-negative-coverage) Set `sort.by=sentiment.overall.score` and `sort.order=asc`. Because the score runs from -1 (most negative) to 1 (most positive), ascending order returns the most negative articles first. Combine it with `category.id=medtop:04000000` to keep the ranking inside finance coverage. * * * ## Related Articles * [How to get sentiment toward a specific company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## Use Cases & Solutions URL: https://support.apitube.io/en/articles/use-cases Ready-made scenarios that combine APITube News API filters to solve a real task — brand monitoring, market intelligence, risk and research. ![](/images/collections/forecast.png) # Use Cases & Solutions Ready-made scenarios for real tasks. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) By Tasha and 4 others 5 authors 30 articles Worked examples of products people build on the APITube News API, grouped by field: finance (market intelligence, stock sentiment), brand and marketing (competitor monitoring, PR outreach), risk and safety, society and health monitoring, and research on trust and misinformation. Each use case pairs the business problem with the concrete filters and endpoints that solve it, so they double as advanced query examples. If you are still deciding what to build, skim two or three — the filter patterns repeat across fields and transfer well. ## [Brand, PR & Marketing](/en/articles/use-cases/brand-and-marketing) * * * * [How to curate a newsletter with a news API](/en/articles/use-cases/brand-and-marketing/curate-newsletter) * [How to Detect Negative Mentions Quickly](/en/articles/use-cases/brand-and-marketing/detect-negative-mentions) * [How to Find Journalists for PR Outreach](/en/articles/use-cases/brand-and-marketing/find-journalists-pr) * [How to Measure PR and Media Coverage](/en/articles/use-cases/brand-and-marketing/measure-pr-coverage) * [How to Monitor Competitor Brands](/en/articles/use-cases/brand-and-marketing/monitor-competitors) * [How to Monitor Your Brand Reputation](/en/articles/use-cases/brand-and-marketing/brand-reputation-monitoring) * [How to Send a Daily News Digest to Telegram](/en/articles/use-cases/brand-and-marketing/telegram-news-digest) * [How to Send Brand Mention Alerts to Slack](/en/articles/use-cases/brand-and-marketing/slack-brand-alerts) * [How to Track Celebrity Buzz and Entertainment Hype](/en/articles/use-cases/brand-and-marketing/track-celebrity-buzz) ## [Finance & Market Intelligence](/en/articles/use-cases/finance) * * * * [How to build market intelligence from news](/en/articles/use-cases/finance/market-intelligence) * [How to build news trading signals for algo trading](/en/articles/use-cases/finance/algorithmic-trading-signals) * [How to monitor companies, earnings and M&A](/en/articles/use-cases/finance/monitor-companies-mna) * [How to monitor cryptocurrency news](/en/articles/use-cases/finance/monitor-crypto) * [How to Monitor Energy and Fuel Price News](/en/articles/use-cases/finance/monitor-energy-markets) * [How to track stock-market sentiment](/en/articles/use-cases/finance/stock-market-sentiment) ## [Risk, Security & Safety](/en/articles/use-cases/risk-and-safety) * * * * [How to Monitor Airline and Travel Disruptions](/en/articles/use-cases/risk-and-safety/monitor-travel-disruptions) * [How to Monitor Corporate and Supplier Risk](/en/articles/use-cases/risk-and-safety/corporate-risk) * [How to Monitor Cybersecurity Threats with a News API](/en/articles/use-cases/risk-and-safety/cybersecurity-monitoring) * [How to Monitor Emergencies and Crises in Real Time](/en/articles/use-cases/risk-and-safety/emergency-monitoring) * [How to Research a Company or Person for Due Diligence](/en/articles/use-cases/risk-and-safety/due-diligence) * [How to Track Product Recalls and Safety Alerts](/en/articles/use-cases/risk-and-safety/track-product-recalls) ## [Society, Health & Trends](/en/articles/use-cases/society-health) * * * * [How to Forecast Social Trends from News](/en/articles/use-cases/society-health/social-trends) * [How to Monitor Climate and Pollution News](/en/articles/use-cases/society-health/monitor-climate-news) * [How to Monitor Healthcare and Medical News](/en/articles/use-cases/society-health/healthcare-monitoring) * [How to Monitor Political Events and Elections](/en/articles/use-cases/society-health/political-monitoring) * [How to Track Disease Outbreaks](/en/articles/use-cases/society-health/track-outbreaks) ## [Trust, Misinformation & Research](/en/articles/use-cases/trust-and-research) * * * * [How Data Scientists and Researchers Use APITube](/en/articles/use-cases/trust-and-research/data-science-research) * [How to fact-check a claim or article](/en/articles/use-cases/trust-and-research/fact-check-claim) * [How to Find the Original Source of a Story](/en/articles/use-cases/trust-and-research/find-original-source) * [How to Identify Fake News and Misinformation](/en/articles/use-cases/trust-and-research/detect-fake-news) --- ## How to Monitor Corporate and Supplier Risk URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety/corporate-risk Monitor corporate and supplier risk with the APITube News API: track each vendor by entity, filter risk events like bankruptcy and recalls, and stream alerts. # How to Monitor Corporate and Supplier Risk Watch a portfolio of suppliers by entity, catch bankruptcy, lawsuit and recall events, and stream the alerts in real time ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Boeing&event_category=business&published_at_start=NOW-1WEEK) # How to monitor corporate and supplier risk[#](#how-to-monitor-corporate-and-supplier-risk) To monitor corporate and supplier risk, query `/v1/news/everything`, pin each supplier with `organization.name` (or its numeric `entity.id`), and keep only the coverage that signals trouble with `event.type` — codes like `bankruptcy`, `lawsuit`, `recall` and `layoffs`. There is no separate “risk” endpoint: you assemble a risk feed from the shared filter chain, then point the **same** filters at the `/v1/news/stream` [SSE](/en/articles/getting-started/glossary#sse-stream) feed or a dashboard [webhook](/en/articles/getting-started/glossary#webhook) to get alerted the moment a supplier hits the news. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Boeing&event.category=business&published_at.start=NOW-1WEEK" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. This request returns business-event coverage of one supplier from the last seven days, newest first (results sort by `published_at` descending by default). ## How do you watch a portfolio of suppliers?[#](#how-do-you-watch-a-portfolio-of-suppliers) Track suppliers by **[entity](/en/articles/getting-started/glossary#entity)**, not by loose keywords, so a company name never collides with an unrelated word. Pin one vendor with `organization.name`, which resolves the name to a tracked organization and matches every article that mentions it. You can pass up to three comma-separated names, combined with **OR** logic, so one request covers a small supplier portfolio: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Boeing,Airbus,Rolls-Royce" \ -H "X-API-Key: YOUR_API_KEY" ``` Each name must be 1–120 characters. If a name does not resolve, the request stops with a _not found_ error — look the vendor up with entity autocomplete and switch to the stable numeric `entity.id` instead, which does not depend on exact spelling: ``` curl "https://api.apitube.io/v1/suggest/entities?prefix=Boeing" -H "X-API-Key: YOUR_API_KEY" # take the numeric "id" from a result: curl "https://api.apitube.io/v1/news/everything?entity.id=12345" -H "X-API-Key: YOUR_API_KEY" ``` `entity.id` also accepts up to three comma-separated ids with OR logic. To silence a noisy vendor without dropping the rest, exclude it with `ignore.organization.name`. See [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity) for the full entity rules. ## How do you catch corporate risk events?[#](#how-do-you-catch-corporate-risk-events) A supplier appearing in the news is not automatically bad news. Narrow to the events that actually signal risk with `event.type`, which matches the primary business event the pipeline tagged on each article. Risk-relevant business codes include `bankruptcy`, `layoffs`, `lawsuit`, `recall`, `data-breach`, `regulatory-action`, `closure`, `stock-movement` and `executive-change`. You can pass up to five codes, combined with OR: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Boeing&event.type=lawsuit,recall,regulatory-action" \ -H "X-API-Key: YOUR_API_KEY" ``` To cast a wider net over every business event at once, use `event.category=business` instead of listing codes (the other categories are `society` and `environment`). An unknown event code stops the request with an HTTP 400 error, so pull the exact list of valid codes from `/v1/news/event-types` first, and remove event types you don’t care about with `ignore.event.type`. See [how to filter news by event type and category](/en/articles/searching-and-filtering/events/filter-by-event-type) for the full event rules. ## How do you surface only negative coverage about a supplier?[#](#how-do-you-surface-only-negative-coverage-about-a-supplier) Bad news is negative news. Once a supplier is pinned, add `entity.sentiment.polarity=negative` to score the tone **toward that supplier specifically**, separate from the rest of the article — so you catch a negative mention of one vendor even inside an otherwise upbeat industry piece: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Boeing&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` `entity.sentiment.polarity` accepts `positive`, `negative` or `neutral`. For a sharper cut, bound the entity’s [sentiment](/en/articles/getting-started/glossary#sentiment) score (a −1 to 1 band) with `entity.sentiment.score.min` and `entity.sentiment.score.max` — for example `entity.sentiment.score.max=-0.3` keeps only clearly negative mentions. This is different from `sentiment.overall.polarity`, which scores the tone of the **whole article** rather than the supplier’s slice of it. ## How do you keep the feed recent and urgent?[#](#how-do-you-keep-the-feed-recent-and-urgent) A risk desk wants the newest and most urgent items first. Bound the window with `published_at.start`, which accepts absolute dates (`2026-06-01`) and relative Solr-style values (`NOW-1DAY`, `NOW-1WEEK`, `NOW-3MONTHS`), and add `is_breaking=1` (exactly `0` or `1`) to keep only stories flagged as breaking: ``` curl "https://api.apitube.io/v1/news/everything?event.category=business&is_breaking=1&published_at.start=NOW-1DAY&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at 250 (10 on Free, 50 on Starter, 200 on Basic); walk deeper with `page`. On the Free plan, paging stops after the first 5 pages, so use a paid plan for wide sweeps. To watch a whole supplier sector rather than named vendors, swap the entity selector for `industry.id` (a numeric industry code). To trim each result to just what an alert needs, add `fl=id,title,source.domain,published_at`. ## How do you get supplier-risk alerts in real time?[#](#how-do-you-get-supplier-risk-alerts-in-real-time) Polling `everything` returns what already exists; real risk monitoring needs push. Keep the exact same filters and open the Server-Sent Events stream at `/v1/news/stream` — it runs the same filter chain and pushes each new matching article as it is published, polling every 30 seconds with a 30-second heartbeat, and supports the `Last-Event-Id` header so you can resume without gaps: ``` curl -N "https://api.apitube.io/v1/news/stream?organization.name=Boeing&event.type=lawsuit,recall,bankruptcy" \ -H "X-API-Key: YOUR_API_KEY" ``` Each delivered article counts as one request against your stream quota. If you would rather have APITube `POST` risk items to your own endpoint (a Slack channel, a GRC tool), create a **webhook** — that is done in the dashboard, not over the API, and it pushes matching articles to your URL with a signed request. The full parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated corporate-risk endpoint?](#is-there-a-dedicated-corporate-risk-endpoint) * [How do I track many suppliers at once?](#how-do-i-track-many-suppliers-at-once) * [Which event types signal corporate risk?](#which-event-types-signal-corporate-risk) * [How do I get alerted the moment a supplier is in trouble?](#how-do-i-get-alerted-the-moment-a-supplier-is-in-trouble) ## Is there a dedicated corporate-risk endpoint?[#](#is-there-a-dedicated-corporate-risk-endpoint) No. Corporate and supplier risk monitoring uses the same `/v1/news/everything` endpoint and the same `organization.name`, `entity.id`, `event.type`, `entity.sentiment.*`, `is_breaking` and `published_at` filters as any other subject. You define what counts as risk with those filters — there is no separate risk route. ## How do I track many suppliers at once?[#](#how-do-i-track-many-suppliers-at-once) `organization.name` and `entity.id` each accept up to three comma-separated values, combined with OR logic, so a single request can cover three vendors. For a larger portfolio, run one request per group of suppliers, or widen to a whole sector with `industry.id`. Exclude vendors you don’t want with `ignore.organization.name`. ## Which event types signal corporate risk?[#](#which-event-types-signal-corporate-risk) Use the `business` event codes that map to trouble: `bankruptcy`, `layoffs`, `lawsuit`, `recall`, `data-breach`, `regulatory-action`, `closure`, `stock-movement` and `executive-change`. Pass up to five in `event.type` (OR logic), or use `event.category=business` to include every business event. Validate codes against `/v1/news/event-types` — an unknown code returns an HTTP 400 error. ## How do I get alerted the moment a supplier is in trouble?[#](#how-do-i-get-alerted-the-moment-a-supplier-is-in-trouble) Move from polling to push. Open the `/v1/news/stream` SSE feed with your supplier and event filters to receive new matching articles as they publish, resuming with `Last-Event-Id` after a drop, or create a webhook in the dashboard so APITube `POST`s each risk item to your endpoint. Both carry the same filters you use on search. * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Get Sentiment Toward a Specific Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to Filter News by Event Type and Category](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Monitor Cybersecurity Threats with a News API URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety/cybersecurity-monitoring Monitor cybersecurity threats with the APITube News API: track ransomware and data-breach coverage by keyword, follow one vendor's incidents, and get real-time… # How to Monitor Cybersecurity Threats with a News API Track ransomware, data breaches and vendor incidents by keyword and entity, then stream the alerts in real time ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=ransomware&language_code=en&published_at_start=NOW-7DAY) # How to monitor cybersecurity threats[#](#how-to-monitor-cybersecurity-threats) To monitor cybersecurity threats, query `/v1/news/everything` and narrow it to security coverage with a keyword search on `title` (for terms like `ransomware` or `data breach`), pin a vendor with `organization.name`, and add `is_breaking=1` for urgent stories. There is no separate “security” endpoint — you assemble a threat feed from the shared filter chain, then point the **same** filters at the `/v1/news/stream` [SSE](/en/articles/getting-started/glossary#sse-stream) feed or a dashboard [webhook](/en/articles/getting-started/glossary#webhook) to get alerted the moment a new incident is published. ``` curl "https://api.apitube.io/v1/news/everything?title=ransomware&language.code=en&published_at.start=NOW-7DAY" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. This request returns English articles whose **title** mentions ransomware from the last seven days. ## How do you catch threats by keyword?[#](#how-do-you-catch-threats-by-keyword) The `title` filter is the core of threat monitoring: it matches security terms in the headline. A value must be 2–100 characters. When you pass several words without quotes, they are combined with **AND** logic and each word is matched as a whole token — so `title=data breach` returns titles that contain both `data` and `breach`, not either one alone. ``` # Both words must appear in the title curl "https://api.apitube.io/v1/news/everything?title=data%20breach&published_at.start=NOW-1WEEK" \ -H "X-API-Key: YOUR_API_KEY" ``` To require the words **next to each other** as an exact phrase, wrap them in quotes; add `~N` (N between 0 and 10) to allow up to N words of slop between them: ``` # Exact phrase, then a looser "supply chain … attack" match curl 'https://api.apitube.io/v1/news/everything?title="zero-day"' -H "X-API-Key: YOUR_API_KEY" curl 'https://api.apitube.io/v1/news/everything?title="supply chain attack"~2' -H "X-API-Key: YOUR_API_KEY" ``` To cut recurring false positives — for example gaming or movie “breach” stories — remove noise terms with `ignore.title`, which follows the same rules. ## How do you follow one vendor or product’s incidents?[#](#how-do-you-follow-one-vendor-or-products-incidents) Article-level keyword search casts a wide net. To track incidents affecting a **specific company**, pin it with `organization.name` (or a numeric `entity.id`); use `brand.name` for a product line. Pair it with `sentiment.overall.polarity=negative` to bias toward bad news such as outages and compromises: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Microsoft&sentiment.overall.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` To measure tone **toward the vendor specifically** rather than the whole article, add `entity.sentiment.polarity=negative` (it also accepts `positive` and `neutral`, scored on the same −1 to 1 band as `entity.sentiment.score.min` / `entity.sentiment.score.max`). If `organization.name` returns a _not found_ error, the name did not resolve to a tracked [entity](/en/articles/getting-started/glossary#entity) — look it up first and filter by the stable numeric `entity.id` instead, as covered in [how to find news mentioning a person or company](/en/articles/searching-and-filtering/entities/find-news-by-entity). ## How do you scope to a security topic or category?[#](#how-do-you-scope-to-a-security-topic-or-category) Beyond keywords, you can narrow to a whole subject with `topic.id` or a broad IPTC section with `category.id`. Both accept up to three comma-separated values with OR logic. Do not guess the identifier — discover the right one with autocomplete, which requires a `prefix`: ``` curl "https://api.apitube.io/v1/suggest/topics?prefix=cyber" -H "X-API-Key: YOUR_API_KEY" curl "https://api.apitube.io/v1/suggest/categories?prefix=technology" -H "X-API-Key: YOUR_API_KEY" ``` Take the `id` from a result and drop it straight into `topic.id` or `category.id`. An unknown identifier stops the whole request with an HTTP 400 error, so validate it with suggest first. See [how to filter news by topic](/en/articles/searching-and-filtering/by-attribute/filter-by-topic) for the full topic rules. ## How do you keep only urgent, breaking incidents?[#](#how-do-you-keep-only-urgent-breaking-incidents) A live security team usually wants the newest and most urgent items first. `is_breaking=1` keeps only stories the pipeline flagged as breaking (it accepts exactly `0` or `1`), and results are sorted newest-first by default. Bound the window with `published_at.start`, which accepts absolute dates (`2026-06-01`) and relative Solr-style values (`NOW-1DAY`, `NOW-1WEEK`), and pull a full page: ``` curl "https://api.apitube.io/v1/news/everything?title=cyberattack&is_breaking=1&published_at.start=NOW-1DAY&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at 250 (10 on Free, 50 on Starter, 200 on Basic); walk deeper with `page`. On the Free plan, paging stops after the first 5 pages, so use a paid plan for large sweeps. To trim each result to just what an alert needs, add `fl=id,title,source.domain,published_at`. ## How do you get threat alerts in real time?[#](#how-do-you-get-threat-alerts-in-real-time) Polling `everything` returns what already exists; real threat monitoring needs push. Keep the exact same filters and open the Server-Sent Events stream at `/v1/news/stream` — it runs the same filter chain and pushes each new matching article as it is published, polling every 30 seconds with a 30-second heartbeat, and supports the `Last-Event-Id` header so you can resume without gaps: ``` curl -N "https://api.apitube.io/v1/news/stream?title=ransomware&is_breaking=1" \ -H "X-API-Key: YOUR_API_KEY" ``` Each delivered article counts as one request against your stream quota. If you would rather have APITube `POST` incidents to your own endpoint (for a SIEM or a Slack alert), create a **webhook** — that is done in the dashboard, not over the API, and it pushes matching articles to your URL with a signed request. See [how to set up a webhook for a saved search](/en/articles/delivery-and-export/webhooks/set-up-webhook) and [how to monitor breaking news](/en/articles/searching-and-filtering/events/monitor-breaking-news). The full parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated cybersecurity endpoint?](#is-there-a-dedicated-cybersecurity-endpoint) * [How do I track one vendor’s breaches specifically?](#how-do-i-track-one-vendors-breaches-specifically) * [Why does title=data breach miss the exact phrase?](#why-does-titledata-breach-miss-the-exact-phrase) * [How do I get alerted the moment a breach is reported?](#how-do-i-get-alerted-the-moment-a-breach-is-reported) ## Is there a dedicated cybersecurity endpoint?[#](#is-there-a-dedicated-cybersecurity-endpoint) No. Cybersecurity monitoring uses the same `/v1/news/everything` endpoint and the same `title`, `organization.name`, `topic.id`, `is_breaking`, `sentiment.*` and `published_at` filters as any other subject. You define what counts as a threat with those filters — there is no separate security route. ## How do I track one vendor’s breaches specifically?[#](#how-do-i-track-one-vendors-breaches-specifically) Pin the company with `organization.name` (or its numeric `entity.id`) and add `entity.sentiment.polarity=negative`. That scores the tone toward the vendor itself, separate from the rest of the article, so you catch negative coverage about one vendor even inside a broader industry piece. If the name does not resolve, filter by `entity.id` instead — ids do not depend on exact spelling. ## Why does title=data breach miss the exact phrase?[#](#why-does-titledata-breach-miss-the-exact-phrase) Multiple words in `title` are combined with AND and matched as whole tokens, so `title=data breach` returns any headline containing both `data` and `breach` in any position. To require the exact phrase, wrap it in quotes: `title="data breach"`. Add `~N` (0–10) after the closing quote to allow up to N words between them. ## How do I get alerted the moment a breach is reported?[#](#how-do-i-get-alerted-the-moment-a-breach-is-reported) Move from polling to push. Open the `/v1/news/stream` SSE feed with your threat filters to receive new matching articles as they publish, resuming with `Last-Event-Id` after a drop, or create a webhook in the dashboard so APITube `POST`s each incident to your endpoint. Both carry the same filters you use on search. * * * ## Related Articles * [How to Monitor Breaking News and Real-Time Events](/en/articles/searching-and-filtering/events/monitor-breaking-news) * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) * [How to Set Up a Webhook for a Saved Search](/en/articles/delivery-and-export/webhooks/set-up-webhook) --- ## How to Research a Company or Person for Due Diligence URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety/due-diligence Run due diligence with the APITube News API: pull a company or person's news profile, filter their coverage by date and negative sentiment, and weight verified… # How to Research a Company or Person for Due Diligence Pull a subject's full news history, weight credible sources and score its reputation with entity filters ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 23, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&organization_name=Wirecard&entity_sentiment_polarity=negative&published_at_start=2018-01-01&published_at_end=2020-12-31) # How to research a company or person for due diligence[#](#how-to-research-a-company-or-person-for-due-diligence) To run due diligence on a company or person with the APITube News API, start from its directory profile — `/v1/companies/:id` or `/v1/people/:id` — for a coverage snapshot, then pull the subject’s full news history from `/v1/news/everything` using `organization.name` or `person.name` (or a numeric `entity.id`), a `published_at` window, and `entity.sentiment.polarity=negative` to surface red flags. There is no dedicated “due diligence” endpoint: you assemble the dossier from the shared filter chain and weight it toward credible, verified sources. ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Wirecard&entity.sentiment.polarity=negative&published_at.start=2018-01-01&published_at.end=2020-12-31" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as an `X-API-Key` header or as the `api_key` query parameter. The request above returns articles from 2018–2020 that mention the company **and** carry negative [sentiment](/en/articles/getting-started/glossary#sentiment) toward that company specifically. ## How do you pull a subject’s news profile first?[#](#how-do-you-pull-a-subjects-news-profile-first) Before searching articles, look the subject up in the directory to get a stable identifier and a coverage summary. The `/v1/companies` list accepts a `name` search (companies resolve to organization and brand [entities](/en/articles/getting-started/glossary#entity)); take the numeric `id` from a result and request the full profile at `/v1/companies/:id`: ``` # 1. Find the company and its id curl "https://api.apitube.io/v1/companies?name=Tesla" -H "X-API-Key: YOUR_API_KEY" # 2. Pull the full profile for that id curl "https://api.apitube.io/v1/companies/1580517" -H "X-API-Key: YOUR_API_KEY" # 1580517 = Tesla, Inc. ``` The profile call returns the entity’s profile plus a `coverage` summary and a `recent_articles` list. Coverage is included by default — pass `coverage=false` to skip it — and each profile call counts as one request. People work the same way through `/v1/people` and `/v1/people/:id`. One caveat for research keys: on the Free plan and on [test keys](/en/articles/getting-started/glossary#test-key-and-live-key) the `recent_articles` content is masked (placeholder text), so use a live paid key when you need real article bodies. An unknown id returns a `404` with error `ER0151`. ## How do you gather a subject’s full news history?[#](#how-do-you-gather-a-subjects-full-news-history) The profile is a snapshot; a due-diligence review needs the full history. Query `/v1/news/everything` and pin the subject with `organization.name` (for a company) or `person.name` (for an individual), then bound the period with `published_at.start` and `published_at.end`. Both dates accept absolute values (`2019-06-01`) and relative Solr-style values such as `NOW-1WEEK` or `NOW-1MONTH`: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Elon%20Musk&published_at.start=2015-01-01&sort.by=published_at&sort.order=asc" \ -H "X-API-Key: YOUR_API_KEY" ``` Names must resolve to a tracked entity. If `organization.name` or `person.name` returns a _not found_ error (`ER0220` for organizations, `ER0216` for people), the spelling did not match — grab the numeric `entity.id` from the directory step and filter by that instead, since ids do not depend on exact spelling. `entity.id` takes up to three comma-separated ids. Sorting oldest-first with `sort.by=published_at&sort.order=asc` gives you a chronological timeline, which is what a background check usually wants. ## How do you surface negative coverage and red flags?[#](#how-do-you-surface-negative-coverage-and-red-flags) Two different sentiment filters matter here, and mixing them up gives wrong results. `entity.sentiment.polarity=negative` scores the tone **toward the subject itself**, so you catch negative mentions of one company even inside a broadly neutral article. `sentiment.overall.polarity=negative` scores the **whole article’s** tone instead. For reputation screening, `entity.sentiment` is the sharper tool: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Boeing&entity.sentiment.polarity=negative&published_at.start=NOW-1MONTH" \ -H "X-API-Key: YOUR_API_KEY" ``` Both accept `positive`, `negative` and `neutral`. To grade intensity rather than direction, add `entity.sentiment.score.min` and `entity.sentiment.score.max` — a number from `-1` to `1` — so `entity.sentiment.score.max=-0.5` keeps only strongly negative coverage. The full behaviour is covered in [how to get sentiment toward a company or person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment). ## How do you weight credible, verified sources?[#](#how-do-you-weight-credible-verified-sources) Due-diligence findings are only as trustworthy as the outlets that published them, so filter out low-quality sources before you read. `is_verified_source=1` keeps only articles from higher-ranked, non-duplicate sources, and `source.rank.opr.min` sets a floor on the Open Page Rank (a 0–10 authority score) so you can demand established publishers: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=Rivian Automotive&is_verified_source=1&source.rank.opr.min=6&sort.by=trust" \ -H "X-API-Key: YOUR_API_KEY" ``` Adding `sort.by=trust` ranks the surviving articles by credibility, so the most reliable reporting rises to the top — see [how to sort news by controversy, trust and social shares](/en/articles/searching-and-filtering/sorting-and-shaping/sort-advanced-modes). For a stricter cut, `is_high_quality=1` keeps only non-duplicate articles from ranked sources that also carry images and a named author. More options are in [how to filter for high-quality, verified sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources). ## How do you measure exposure without downloading everything?[#](#how-do-you-measure-exposure-without-downloading-everything) To size up how much has been written about a subject — for a risk score or a first pass — call `/v1/news/count`. It runs the exact same filters as the search but returns only a total, so it is fast and cheap (one point per call) and never loads article bodies: ``` curl "https://api.apitube.io/v1/news/count?organization.name=Theranos&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` The response is a small object — `{ "status": "ok", "count": 1234, "request_id": "..." }`. Compare the negative-sentiment count against the total count to get a quick “share of bad news” ratio for the subject. Details are in [how to count news articles without downloading them](/en/articles/retrieval/count-articles). ## How do you export the dossier?[#](#how-do-you-export-the-dossier) Once the filters are right, export the matching articles for the file. Add `export=csv` or `export=xlsx` to turn any search into a spreadsheet a compliance team can review offline: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Elon%20Musk&entity.sentiment.polarity=negative&per_page=250&export=csv&fl=id,title,source.domain,published_at,sentiment.overall.polarity" \ -H "X-API-Key: YOUR_API_KEY" -o dossier.csv ``` `per_page` defaults to 100 and maxes out at 250 (10 on Free, 50 on Starter, 200 on Basic); walk deeper with `page`. On the Free plan, paging stops after the first 5 pages, so use a paid plan for a full sweep. Trim each row to the fields you need with `fl` (a comma-separated list) to keep the export small. See [how to export news to CSV or Excel](/en/articles/delivery-and-export/export/export-csv-excel). # Common Questions[#](#common-questions) * [Is there a dedicated due-diligence endpoint?](#is-there-a-dedicated-due-diligence-endpoint) * [How do I track sentiment about the subject specifically?](#how-do-i-track-sentiment-about-the-subject-specifically) * [What if the company or person name does not resolve?](#what-if-the-company-or-person-name-does-not-resolve) * [Why is the article content in a profile masked?](#why-is-the-article-content-in-a-profile-masked) ## Is there a dedicated due-diligence endpoint?[#](#is-there-a-dedicated-due-diligence-endpoint) No. Due diligence uses the same `/v1/news/everything` search and the same `organization.name`, `person.name`, `entity.id`, `entity.sentiment.*`, `published_at`, `is_verified_source` and `source.rank.opr.min` filters as any other subject. The directory endpoints `/v1/companies/:id` and `/v1/people/:id` add a profile and coverage summary on top, but you define what “due diligence” means with those filters — there is no separate route. ## How do I track sentiment about the subject specifically?[#](#how-do-i-track-sentiment-about-the-subject-specifically) Use `entity.sentiment.polarity`, not `sentiment.overall.polarity`. `entity.sentiment` scores tone toward the entity you pinned (the company or person), so you catch negative coverage about that one subject even inside an otherwise neutral article. `sentiment.overall` scores the whole article’s tone. For intensity, narrow with `entity.sentiment.score.min` / `entity.sentiment.score.max` on the −1 to 1 scale. ## What if the company or person name does not resolve?[#](#what-if-the-company-or-person-name-does-not-resolve) `organization.name` and `person.name` are matched against tracked entities, so a name that does not match returns a 400 error (`ER0220` for organizations, `ER0216` for people). Look the subject up first with `/v1/companies` or `/v1/people`, take the numeric `id`, and filter by `entity.id` instead — ids are stable and do not depend on spelling or punctuation. ## Why is the article content in a profile masked?[#](#why-is-the-article-content-in-a-profile-masked) On the Free plan and on test keys, the `recent_articles` returned by `/v1/companies/:id` and `/v1/people/:id` (and article bodies across search) are truncated to placeholder text as a preview. This is a plan/key restriction, not a data gap — switch to a live paid key to read full article content in your dossier. The full parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). * * * ## Related Articles * [How to Find News Mentioning a Person or Company](/en/articles/searching-and-filtering/entities/find-news-by-entity) * [How to Get Sentiment Toward a Company or Person](/en/articles/searching-and-filtering/sentiment/entity-level-sentiment) * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [How to Count News Articles Without Downloading Them](/en/articles/retrieval/count-articles) --- ## How to Monitor Emergencies and Crises in Real Time URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety/emergency-monitoring Monitor emergencies and crises in real time with the APITube News API: filter by event.category, is_breaking and a geo radius, then stream new alerts over SSE. # How to Monitor Emergencies and Crises in Real Time Assemble a live emergency feed from event, breaking and geo filters, then push new alerts over SSE ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&event_category=environment&is_breaking=1&published_at_start=NOW-24HOURS) # How to monitor emergencies and crises in real time[#](#how-to-monitor-emergencies-and-crises-in-real-time) To monitor emergencies in real time, query `/v1/news/everything` and narrow it with `event.category=environment` (earthquakes, floods, wildfires, hurricanes and more) or `event.category=society` (accidents, conflict, terrorism, health-crisis), add `is_breaking=1` to keep only urgent stories, then point the **same** filters at the `/v1/news/stream` [SSE](/en/articles/getting-started/glossary#sse-stream) feed so each new incident is pushed to you the moment it is indexed. There is no separate “emergency” endpoint — you build a crisis feed from the shared filter chain and stream it. ``` curl "https://api.apitube.io/v1/news/everything?event.category=environment&is_breaking=1&published_at.start=NOW-24HOURS" \ -H "X-API-Key: YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header. This request returns breaking environmental-disaster coverage from the last 24 hours, and results are sorted newest-first by default (`sort.by=published_at`, `sort.order=desc`). ## How do you filter for disasters and crisis events?[#](#how-do-you-filter-for-disasters-and-crisis-events) The `event.type` and `event.category` filters classify articles by what happened. `event.category` accepts one of three groups — `business`, `society`, or `environment` — and an unknown value stops the request with an HTTP 400 (`ER0503`). For emergencies you mostly want `environment` and `society`. To target exact incident types instead of a whole group, use `event.type` with up to five comma-separated codes: ``` # Up to five disaster types in one call curl "https://api.apitube.io/v1/news/everything?event.type=earthquake,flood,wildfire,hurricane,tornado&published_at.start=NOW-1DAY" \ -H "X-API-Key: YOUR_API_KEY" ``` Valid environment codes include `earthquake`, `hurricane`, `flood`, `wildfire`, `tornado`, `tsunami`, `volcanic-eruption`, `drought` and `avalanche`; society codes include `terrorism`, `accident`, `conflict`, `crime`, `protest` and `health-crisis`. An unrecognized code returns `ER0502`, so do not guess — pull the full list from `/v1/news/event-types` first. Exclude noise with `ignore.event.type`. See [how to filter news by event type](/en/articles/searching-and-filtering/events/filter-by-event-type) for the complete rules. ## How do you keep only urgent, breaking stories?[#](#how-do-you-keep-only-urgent-breaking-stories) `is_breaking=1` keeps only articles the pipeline flagged as urgent; it accepts exactly `0` or `1` (any other value returns `ER0186`). Combine it with a tight time window using `published_at.start`, which takes absolute dates (`2026-07-01`) and relative Solr-style values such as `NOW-6HOURS`, `NOW-1DAY` or `NOW-1WEEK`: ``` curl "https://api.apitube.io/v1/news/everything?event.category=society&is_breaking=1&published_at.start=NOW-6HOURS&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at 250 (10 on Free, 50 on Starter, 200 on Basic); walk deeper with `page`. On the Free plan, paging stops after the first 5 pages (`ER0173`), so use a paid plan for wide sweeps. Trim each result to just what an alert needs with `fl=id,title,source.domain,published_at`. ## How do you limit a crisis feed to one region?[#](#how-do-you-limit-a-crisis-feed-to-one-region) Big disasters are geographic. Pin the feed to an area with a radius search: pass `location.lat` and `location.lng` together (both are required, or you get `ER0406`) plus `location.radius` in kilometres, up to 20000. Add `has_location_geo=1` to drop articles that have no coordinates at all. ``` # Environmental emergencies within 200 km of Los Angeles curl "https://api.apitube.io/v1/news/everything?event.category=environment&location.lat=34.05&location.lng=-118.24&location.radius=200&has_location_geo=1" \ -H "X-API-Key: YOUR_API_KEY" ``` For a rectangular area, use `location.bbox=minLat,maxLat,minLng,maxLng` instead of a radius. You can also carve out a ring — say, everything **between** 50 km and 300 km from a point — by adding `location.radius.min`. See [how to find news near a coordinate or bounding box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) for the geo filter in full. ## How do you get emergency alerts pushed in real time?[#](#how-do-you-get-emergency-alerts-pushed-in-real-time) Polling `everything` returns what already exists; a live crisis desk needs push. Keep the exact same filters and open the Server-Sent Events stream at `/v1/news/stream` — it runs the same filter chain and pushes each new matching article as it is indexed, with heartbeat comments to keep the connection open: ``` curl -N "https://api.apitube.io/v1/news/stream?event.category=environment&is_breaking=1&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream is `tail -f` on the news firehose: it only sends articles that appear **after** you connect, and each delivered article is emitted as an `event: article` with an `id:` line. Pass that id back in the `Last-Event-Id` header to resume without gaps after a drop. Each delivered article counts as one request against your streaming quota, which is a separate pool from your normal request credits. The number of simultaneous streams you can open depends on your plan (Free allows 1; exceeding your limit returns `ER0360`). If you would rather have APITube `POST` incidents to your own endpoint (a SIEM or a Slack alert), create a **[webhook](/en/articles/getting-started/glossary#webhook)** — that is done in the dashboard, not over the API. The full parameter list lives in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated emergency or disaster endpoint?](#is-there-a-dedicated-emergency-or-disaster-endpoint) * [What is the difference between event.category and event.type?](#what-is-the-difference-between-eventcategory-and-eventtype) * [How do I restrict alerts to my city or country?](#how-do-i-restrict-alerts-to-my-city-or-country) * [How do I get notified the moment a crisis is reported?](#how-do-i-get-notified-the-moment-a-crisis-is-reported) ## Is there a dedicated emergency or disaster endpoint?[#](#is-there-a-dedicated-emergency-or-disaster-endpoint) No. Emergency monitoring uses the same `/v1/news/everything` endpoint and the same `event.category`, `event.type`, `is_breaking`, `location.*` and `published_at` filters as any other subject. You define what counts as a crisis with those filters — there is no separate emergency route. ## What is the difference between event.category and event.type?[#](#what-is-the-difference-between-eventcategory-and-eventtype) `event.category` is the broad group (`environment`, `society`, or `business`) and matches every incident type inside it. `event.type` targets specific codes such as `earthquake` or `terrorism`, up to five at once. Use the category for a wide safety net and the type when you only care about certain kinds of events. An unknown value in either returns an HTTP 400, so confirm codes against `/v1/news/event-types`. ## How do I restrict alerts to my city or country?[#](#how-do-i-restrict-alerts-to-my-city-or-country) Add a radius search — `location.lat`, `location.lng` and `location.radius` (kilometres, up to 20000) — or a `location.bbox` rectangle, and set `has_location_geo=1` so only geolocated articles come through. `location.lat` and `location.lng` must always be sent together. For a broader match you can also filter by country with the standard source and location attributes covered elsewhere in the docs. ## How do I get notified the moment a crisis is reported?[#](#how-do-i-get-notified-the-moment-a-crisis-is-reported) Move from polling to push. Open the `/v1/news/stream` SSE feed with your emergency filters to receive new matching articles as they are indexed, resuming with `Last-Event-Id` after a drop, or create a webhook in the dashboard so APITube `POST`s each incident to your endpoint. Both carry the same filters you use on search, and both are the fastest way to react to a developing situation. See [how to track disasters and disease outbreaks](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) for a worked disaster feed. * * * ## Related Articles * [How to Filter News by Natural Disaster and Disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) * [How to Filter News by Event Type](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## Risk, Security & Safety URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety Monitor corporate risk, cybersecurity threats, emergencies and due-diligence signals with the APITube News API using keyword, entity, breaking and real-time filters. # Risk, Security & Safety Corporate risk, threats and due diligence. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) By Tasha and 2 others 3 authors 6 articles * [How to Monitor Airline and Travel Disruptions](/en/articles/use-cases/risk-and-safety/monitor-travel-disruptions) * [How to Monitor Corporate and Supplier Risk](/en/articles/use-cases/risk-and-safety/corporate-risk) * [How to Monitor Cybersecurity Threats with a News API](/en/articles/use-cases/risk-and-safety/cybersecurity-monitoring) * [How to Monitor Emergencies and Crises in Real Time](/en/articles/use-cases/risk-and-safety/emergency-monitoring) * [How to Research a Company or Person for Due Diligence](/en/articles/use-cases/risk-and-safety/due-diligence) * [How to Track Product Recalls and Safety Alerts](/en/articles/use-cases/risk-and-safety/track-product-recalls) --- ## How to Monitor Airline and Travel Disruptions URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety/monitor-travel-disruptions Monitor travel disruptions with the APITube News API: scope airlines and airports with industry.id, split by event.type=accident or protest, and stream… # How to Monitor Airline and Travel Disruptions Watch airlines, airports and air traffic with industry filters, then split the feed into accidents, strikes and breaking incidents ![Jacob Partington](/images/authors/jacob-partington-apitube-io-128.jpg) Written by Jacob Partington July 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&industry_id=14%2C18%2C49&sort_by=published_at&sort_order=desc&per_page=50) # How to monitor airline and travel disruptions[#](#how-to-monitor-airline-and-travel-disruptions) To monitor travel disruptions, scope `/v1/news/everything` to the aviation industries — `18` for passenger airlines, `49` for airport management, `14` for aircraft, `46` for air traffic management — and then split that feed by what went wrong: `event.type=accident` for incidents, `event.type=protest` for strikes and industrial action, `is_breaking=1` for anything urgent. Aviation is not a category in the news taxonomy; it is an industry, so `industry.id` is the filter that scopes it. ``` curl "https://api.apitube.io/v1/news/everything?industry.id=14,18,49&sort.by=published_at&sort.order=desc&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Pass the key as the `api_key` query parameter or as an `X-API-Key` header. `industry.id` accepts up to three comma-separated numeric IDs with OR logic. ## Which industry IDs cover airlines and airports?[#](#which-industry-ids-cover-airlines-and-airports) Four IDs carry most aviation coverage, and they describe different parts of the journey: * **`18` — Passenger Airline.** Aircraft used by airlines to carry passengers commercially. This is the carrier-level feed: cancellations, fleet decisions, route changes. * **`49` — Airport Management.** Terminal facilities, airport staff, passenger handling and on-site emergency services. Use it for ground-side disruption such as terminal closures. * **`46` — Air Traffic Management.** Routes, flight paths, takeoff and landing sequencing, tower and ground control. This is where controller staffing and systems outages surface. * **`14` — Aircraft.** Civilian aircraft themselves, commercial and private, including cargo and helicopters. Use it for airframe and manufacturer coverage rather than operations. Because `industry.id` is capped at three values per request, pick the three that match your use case rather than trying to cover all four at once. Resolve additional IDs from free text with `/v1/suggest/industries?prefix=airport`, or browse the [APITube industry list](https://docs.apitube.io/platform/news-api/list-of-industries). More on the filter itself in [how to filter news by industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry). ## How do you separate accidents from strikes?[#](#how-do-you-separate-accidents-from-strikes) `event.type` classifies what happened, and two codes carry most travel disruption. `accident` covers crashes, runway incidents and equipment failures; `protest` covers strikes, walkouts and industrial action, which in aviation is often the bigger cause of cancelled flights: ``` # Safety incidents at passenger airlines curl "https://api.apitube.io/v1/news/everything?industry.id=18&event.type=accident&published_at.start=NOW-30DAYS" \ -H "X-API-Key: YOUR_API_KEY" # Industrial action affecting airlines and airports curl "https://api.apitube.io/v1/news/everything?industry.id=18,49&event.type=protest&published_at.start=NOW-30DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` `event.type` takes up to five codes with OR logic, and an unrecognised code returns an HTTP 400 — pull the valid set from `/v1/news/event-types` instead of guessing. The event label is used for matching only and is not returned on the article object, so read `title` and `body` for the specifics. Because strike coverage often names the union or the airline rather than using the word “strike”, the event filter catches more than a keyword search would; adding `title=strike` narrows it hard and will miss stories that describe the action differently. ## How do you catch disruption while it is still developing?[#](#how-do-you-catch-disruption-while-it-is-still-developing) `is_breaking=1` keeps only articles the pipeline flagged as urgent, and it accepts exactly `0` or `1`. Pair it with a tight window using `published_at.start`, which takes absolute dates such as `2026-07-01` or relative values such as `NOW-6HOURS`: ``` curl "https://api.apitube.io/v1/news/everything?industry.id=18,49&is_breaking=1&published_at.start=NOW-6HOURS&per_page=100" \ -H "X-API-Key: YOUR_API_KEY" ``` Trim the payload to what an alert actually needs with `fl=id,title,source.domain,published_at` — there is no reason to transfer full article bodies into a dashboard row. For the general rules on urgency filtering see [how to monitor breaking news](/en/articles/searching-and-filtering/events/monitor-breaking-news). ## How do you watch one airline or one airport?[#](#how-do-you-watch-one-airline-or-one-airport) Add `title` to require the operator’s name in the headline, which drops passing mentions inside industry roundups: ``` curl "https://api.apitube.io/v1/news/everything?industry.id=18&title=Lufthansa&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` Multiple words in `title` are matched with AND regardless of order, so `title=Heathrow delays` requires both words somewhere in the headline; quote the phrase to force the exact order. For coverage that mentions the carrier anywhere in the body rather than only in the headline, use `organization.name`. Airports are geographic, so a radius search is often a better fit than a name: pass `location.lat` and `location.lng` together with `location.radius` in kilometres, and add `has_location_geo=1` to drop articles with no coordinates. That geo filter is documented in [how to find news near a coordinate or bounding box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius). ## How do you push disruption alerts instead of polling?[#](#how-do-you-push-disruption-alerts-instead-of-polling) Keep the same filters and open the [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream`. It runs the identical filter chain and pushes each new matching article as it is indexed: ``` curl -N "https://api.apitube.io/v1/news/stream?industry.id=18,49&is_breaking=1&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream delivers only articles indexed **after** you connect, so it is a live tail rather than a backfill — run one `everything` request first to seed your current state. Each article arrives as an `event: article` with an `id:` line; send the last id back in the `Last-Event-Id` header to resume without gaps after a dropped connection. Streamed articles draw on a separate streaming quota, and concurrent stream limits depend on your plan (`ER0360` when exceeded). For delivery into a rota system or an ops channel, create a [webhook](/en/articles/getting-started/glossary#webhook) in the dashboard so APITube `POST`s each incident to your endpoint. # Common Questions[#](#common-questions) * [Is there an aviation or travel category?](#is-there-an-aviation-or-travel-category) * [Why does a strike show up under event.type=protest?](#why-does-a-strike-show-up-under-eventtypeprotest) * [Can I filter by flight number or route?](#can-i-filter-by-flight-number-or-route) * [How do I cover more than three aviation industries at once?](#how-do-i-cover-more-than-three-aviation-industries-at-once) ## Is there an aviation or travel category?[#](#is-there-an-aviation-or-travel-category) No. Aviation is modelled as an industry, not as a news category, so you scope it with `industry.id` (`18` passenger airline, `49` airport management, `46` air traffic management, `14` aircraft) rather than with `category.id`. Categories describe the subject of the story in IPTC terms; industries describe the economic sector it belongs to. For travel disruption the industry axis is the one that isolates the right coverage. ## Why does a strike show up under event.type=protest?[#](#why-does-a-strike-show-up-under-eventtypeprotest) The event taxonomy groups industrial action, walkouts and demonstrations under the `protest` code in the society category; there is no separate `strike` code. That grouping is why the event filter finds more disruption than a keyword search — articles about a cabin crew walkout are classified as `protest` even when the word “strike” never appears in the headline. Confirm available codes against `/v1/news/event-types` before hard-coding any of them. ## Can I filter by flight number or route?[#](#can-i-filter-by-flight-number-or-route) Not as structured fields. APITube indexes news coverage, so flight numbers, routes and tail numbers appear inside the article `body` when the reporter wrote them, but they are not extracted into filterable fields. Use `title` or `organization.name` to scope to the carrier, then match the flight identifier in your own code against `title` and `body`. For airport-level scoping, a geo radius around the airport’s coordinates works better than trying to match its name. ## How do I cover more than three aviation industries at once?[#](#how-do-i-cover-more-than-three-aviation-industries-at-once) `industry.id` caps at three values per request, so run two requests and merge the results, deduplicating on article `id`. One request for operations (`18,49,46`) and one for equipment (`14`) is a natural split. If you are counting rather than reading, `/v1/news/count` makes this cheap — one small request per industry group, no article payloads, and the numbers add up cleanly as long as you keep the time window identical across calls. * * * ## Related Articles * [How to Filter News by Industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) * [How to Monitor Breaking News](/en/articles/searching-and-filtering/events/monitor-breaking-news) * [How to Find News Near a Coordinate or Bounding Box](/en/articles/searching-and-filtering/by-attribute/filter-by-geo-radius) * [How to Monitor Emergencies and Crises in Real Time](/en/articles/use-cases/risk-and-safety/emergency-monitoring) --- ## How to Track Product Recalls and Safety Alerts URL: https://support.apitube.io/en/articles/use-cases/risk-and-safety/track-product-recalls Track product recalls with the APITube News API: filter with event.type=recall, narrow by industry.id and source.country.code, then stream new alerts over SSE. # How to Track Product Recalls and Safety Alerts Build a recall feed with event.type=recall, scope it to your sector and market, then push new alerts as they appear ![Erick Horn](/images/authors/erick-horn-apitube-io-128.jpg) Written by Erick Horn July 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&event_type=recall&published_at_start=NOW-7DAYS&per_page=50) # How to track product recalls and safety alerts[#](#how-to-track-product-recalls-and-safety-alerts) To track product recalls, query `/v1/news/everything` with `event.type=recall` — the event classifier tags articles that report a manufacturer pulling a product from the market. Add `industry.id` to keep only your sector, `source.country.code` to keep only your market, and `published_at.start` to bound the window. There is no separate recall endpoint; a recall feed is the standard filter chain with one event type applied. ``` curl "https://api.apitube.io/v1/news/everything?event.type=recall&published_at.start=NOW-7DAYS&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` You can send the key as the `api_key` query parameter or as an `X-API-Key` header. Results come back newest-first by default (`sort.by=published_at`, `sort.order=desc`). ## How do you filter news for product recalls?[#](#how-do-you-filter-news-for-product-recalls) `event.type=recall` is one of the business-category event codes returned by `/v1/news/event-types`. It accepts up to five comma-separated codes with OR logic, so you can widen a safety feed to neighbouring events in the same request: ``` # Recalls plus the litigation and enforcement that often follows curl "https://api.apitube.io/v1/news/everything?event.type=recall,lawsuit,regulatory-action&published_at.start=NOW-30DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` An unrecognised code stops the request with an HTTP 400, so pull the valid list from `/v1/news/event-types` rather than guessing. The `recall` label is used for matching only — it is not echoed back on the article object, so treat the filter itself as the signal and read `title`, `description` and `body` for the product details. Use `ignore.event.type` to strip event classes you do not want, for example `ignore.event.type=earnings,partnership` to drop routine corporate coverage. The complete rules live in [how to filter news by event type](/en/articles/searching-and-filtering/events/filter-by-event-type). ## How do you limit recalls to your industry?[#](#how-do-you-limit-recalls-to-your-industry) Recall coverage spans food, pharmaceuticals, vehicles and consumer electronics at once. `industry.id` cuts it down to the sector you actually sell into, taking up to three numeric IDs with OR logic: ``` # Vehicle manufacturing, vehicle sales and EV charging curl "https://api.apitube.io/v1/news/everything?event.type=recall&industry.id=801,805,807" \ -H "X-API-Key: YOUR_API_KEY" ``` Industry IDs are numbers, not names — `801` is Vehicle Manufacturing, `805` is Vehicle Sales, `807` is EV Charging. Resolve free text into an ID with `/v1/suggest/industries?prefix=vehicle`, or browse the full table in the [APITube industry list](https://docs.apitube.io/platform/news-api/list-of-industries). Each returned article carries an `industries` array, so you can see which classifier matched. Filtering by industry is covered in depth in [how to filter news by industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry). ## How do you watch recalls for one brand or manufacturer?[#](#how-do-you-watch-recalls-for-one-brand-or-manufacturer) Add `title` to require the company name in the headline. Headline matching drops the passing mentions you get when a brand appears halfway down an industry roundup: ``` curl "https://api.apitube.io/v1/news/everything?event.type=recall&title=Toyota&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Multiple words in `title` are matched with AND regardless of order, so `title=infant formula` requires both words in the headline. Wrap the phrase in double quotes — `title="infant formula"` — to require that exact order. For company-wide coverage rather than headline-only matching, use `organization.name` instead, which matches the organisation [entity](/en/articles/getting-started/glossary#entity) anywhere in the article. ## How do you separate urgent recalls from routine coverage?[#](#how-do-you-separate-urgent-recalls-from-routine-coverage) Two filters do most of the triage. `is_breaking=1` keeps only articles the pipeline flagged as urgent, and it accepts exactly `0` or `1`. `sentiment.overall.polarity=negative` keeps the coverage that frames the recall as a problem rather than a neutral notice: ``` curl "https://api.apitube.io/v1/news/everything?event.type=recall&is_breaking=1&source.country.code=us&published_at.start=NOW-24HOURS" \ -H "X-API-Key: YOUR_API_KEY" ``` `source.country.code` filters by where the outlet is based, which works well for national safety regulators and trade press but will miss a foreign paper covering the same recall. Combine it with `language.code` when you serve a specific market. To size a wave before pulling articles, call `/v1/news/count` with the same filters — it returns a single number and no article payloads, which makes month-over-month comparisons cheap. ## How do you get recall alerts pushed instead of polling?[#](#how-do-you-get-recall-alerts-pushed-instead-of-polling) Keep the filters and point them at the [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream`. It runs the same filter chain and pushes each new matching article as it is indexed: ``` curl -N "https://api.apitube.io/v1/news/stream?event.type=recall&industry.id=801&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream only delivers articles indexed **after** you connect — it is not a backfill. Each article arrives as an `event: article` with an `id:` line; pass the last id back in the `Last-Event-Id` header to resume without gaps after a drop. Delivered articles draw on a streaming quota that is separate from your normal request credits, and the number of concurrent streams depends on your plan (Free allows one; exceeding the limit returns `ER0360`). If you would rather have APITube `POST` each recall to your own endpoint, create a [webhook](/en/articles/getting-started/glossary#webhook) in the dashboard. # Common Questions[#](#common-questions) * [Is there a dedicated product recall endpoint?](#is-there-a-dedicated-product-recall-endpoint) * [Does the API return the recalled product name or lot number?](#does-the-api-return-the-recalled-product-name-or-lot-number) * [How far back can I search for recalls?](#how-far-back-can-i-search-for-recalls) * [Can I track recalls for competitors as well as my own brand?](#can-i-track-recalls-for-competitors-as-well-as-my-own-brand) ## Is there a dedicated product recall endpoint?[#](#is-there-a-dedicated-product-recall-endpoint) No. Product recalls use the same `/v1/news/everything` endpoint as every other subject, narrowed with `event.type=recall`. There is no separate recall route and no recall-specific response schema — you define the feed with the standard filters and read the details out of the article text. ## Does the API return the recalled product name or lot number?[#](#does-the-api-return-the-recalled-product-name-or-lot-number) Not as structured fields. APITube indexes news coverage of a recall, not the regulator’s filing, so specifics like lot numbers, affected serial ranges and remedy instructions appear in the article `body` when the reporter included them. Use `entities` to get the organisations and products the enrichment pipeline recognised, then read `body` for the operational detail. For the authoritative recall notice, follow `href` to the source article and on to the regulator it cites. ## How far back can I search for recalls?[#](#how-far-back-can-i-search-for-recalls) Recall coverage goes back as far as the rest of the archive — bound it with `published_at.start` and `published_at.end`, which take absolute dates such as `2026-01-01` or relative values such as `NOW-30DAYS`. Deep historical sweeps need paging, and on the Free plan paging stops after the first few pages, so wide multi-year pulls require a paid plan. ## Can I track recalls for competitors as well as my own brand?[#](#can-i-track-recalls-for-competitors-as-well-as-my-own-brand) Yes, and it is the same request run per company. Loop `title=<company>` over your watchlist against `/v1/news/count` to get a comparable recall volume per brand over a fixed window, then fetch the articles only for the names that moved. Because `event.type` and `title` combine freely, you can also split the comparison by event — recalls versus lawsuits versus regulatory actions — to see whether a competitor’s problem is contained or escalating. * * * ## Related Articles * [How to Filter News by Event Type](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to Filter News by Industry](/en/articles/searching-and-filtering/by-attribute/filter-by-industry) * [How to Monitor Emergencies and Crises in Real Time](/en/articles/use-cases/risk-and-safety/emergency-monitoring) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Monitor Healthcare and Medical News URL: https://support.apitube.io/en/articles/use-cases/society-health/healthcare-monitoring Monitor healthcare news with the APITube News API: combine a subject filter with disease.name, organization.name, sentiment and trends, then stream over SSE. # How to Monitor Healthcare and Medical News Build a live medical-news feed from subject, disease, organization and sentiment filters — no dedicated healthcare endpoint required ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=healthcare&language_code=en&sort_by=published_at&sort_order=desc) # How to monitor healthcare and medical news[#](#how-to-monitor-healthcare-and-medical-news) To monitor healthcare and medical news, query `/v1/news/everything` and narrow it with a subject filter — a `title` keyword or an IPTC `category.id` — then layer on `language.code`, a `published_at` window and newest-first sorting. There is **no** dedicated healthcare endpoint: you assemble a medical-news feed from the shared filter chain, escalate to [entity](/en/articles/getting-started/glossary#entity) filters like `disease.name` and `organization.name` for precise tracking, and point the same filters at the `/v1/news/stream` [SSE](/en/articles/getting-started/glossary#sse-stream) feed when you need coverage pushed live. ``` curl "https://api.apitube.io/v1/news/everything?title=healthcare&language.code=en&sort.by=published_at&sort.order=desc" \ -H "X-API-Key: YOUR_API_KEY" ``` You can send the key as an `X-API-Key` header or as the `api_key` query parameter, and call the endpoint with `GET` (query parameters) or `POST` (JSON body). Different parameters combine with AND, so each filter you add narrows the medical feed further. ## How do you pull a broad healthcare news feed?[#](#how-do-you-pull-a-broad-healthcare-news-feed) Start with a subject filter. The simplest is a `title` keyword — `title=vaccine` or `title=clinical%20trial` — which matches whole tokens in the article headline and must be 2 to 100 characters (a value outside that range returns `ER0007`). Results are sorted newest-first by default (`sort.by=published_at`, `sort.order=desc`); switch to `sort.by=relevance` to rank by how well the headline matches your keywords. For a whole subject area rather than one word, use `category.id` with an IPTC media-topic code. Category codes look like `medtop:15000000` and are validated against the categories APITube tracks, so an unknown code stops the request with `ER0206`. Do not guess a health code — look it up first with the suggest endpoint, whose `id` is exactly what `category.id` expects: ``` curl "https://api.apitube.io/v1/suggest/categories?prefix=health&api_key=YOUR_API_KEY" ``` See [how to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) for the full rules, including combining up to three codes with OR logic. ## How do you narrow medical news to a country and time window?[#](#how-do-you-narrow-medical-news-to-a-country-and-time-window) Add `source.country.code` (a two-letter code such as `us` or `gb`, up to three comma-separated) to keep only publishers from a country, and a `published_at` window to scope the feed in time. `published_at.start` and `published_at.end` accept absolute dates like `2026-06-01` or Solr-style relative values such as `NOW-7DAYS` and `NOW-1WEEK`: ``` curl "https://api.apitube.io/v1/news/everything?title=hospital&source.country.code=us&published_at.start=NOW-7DAYS&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at 250 — 10 on Free, 50 on Starter (a larger value returns `ER0171`); walk deeper with `page`. On the Free plan, paging stops after the first 5 pages (`ER0173`), so use a paid plan for wide historical sweeps. An unknown country code returns `ER0212`. ## How do you track a specific disease, drug maker or health body?[#](#how-do-you-track-a-specific-disease-drug-maker-or-health-body) Keyword search matches text; entity filters match the tagged thing itself, which is far cleaner for tracking a named disease or organization. Use `disease.name` for illnesses and outbreaks (entity type `disease`) and `organization.name` for a specific health body or company (entity type `organization`). Each accepts up to three comma-separated names, 1 to 120 characters, with OR logic: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=influenza,malaria&published_at.start=NOW-14DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` The name must match an entity APITube already tracks, or the request stops — an unknown `disease.name` returns `ER0226` and an unknown `organization.name` returns `ER0220`. Resolve the exact spelling and type first with `GET /v1/suggest/entities?prefix=` (a missing `prefix` returns `ER0346`); each result carries an `id`, `name` and `type`, and that numeric `id` also works directly as `entity.id`. For a worked outbreak feed, see [how to track disasters and disease outbreaks](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks). ## How do you surface negative or high-risk medical coverage?[#](#how-do-you-surface-negative-or-high-risk-medical-coverage) For safety and reputation work you often want only the coverage with a negative tone. Add `sentiment.overall.polarity=negative` to keep articles the pipeline scored as negative overall (it accepts `positive`, `negative` or `neutral`). To measure the tone expressed **toward** a tracked entity — a drug, a hospital chain — instead of the whole article, use `entity.sentiment.polarity` (`positive`, `negative` or `neutral`; an invalid value returns `ER0290`) alongside the entity selector. Because medical misinformation is a real risk, tighten the feed to trustworthy publishers with `is_verified_source=1`, which keeps only higher-ranked sources and drops duplicates: ``` curl "https://api.apitube.io/v1/news/everything?organization.name=World%20Health%20Organization%20Regional%20Office%20for%20the%20Eastern%20Mediterranean&sentiment.overall.polarity=negative&is_verified_source=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ## How do you find trending health topics?[#](#how-do-you-find-trending-health-topics) To see what is rising in health coverage rather than a flat list of articles, call `/v1/news/trends` with `field=topic.id` (or `field=entity.id`). It groups matching articles and returns each value with a count, and adding `trending=true` computes a trending score by comparing recent volume against the trailing window: ``` curl "https://api.apitube.io/v1/news/trends?field=topic.id&title=health&trending=true&api_key=YOUR_API_KEY" ``` The trends endpoint runs the same filter chain, so every filter above applies. It returns up to 100 results per request, looks back at most 30 days, and each call counts as one request. See [how to discover trending topics and entities](/en/articles/retrieval/discover-trends) for the full trends reference. ## How do you get medical news in real time?[#](#how-do-you-get-medical-news-in-real-time) Polling `everything` returns what already exists; a live health desk needs push. Keep the exact same filters and open the Server-Sent Events stream at `/v1/news/stream` — it runs the same filter chain and pushes each new matching article as it is indexed: ``` curl -N "https://api.apitube.io/v1/news/stream?disease.name=influenza&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream only sends articles that appear **after** you connect. If you would rather have APITube `POST` new coverage to your own endpoint, create a **[webhook](/en/articles/getting-started/glossary#webhook)** — that is set up in the dashboard, not over the API. See [how to stream news in real time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse), and the full parameter list in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated healthcare or medical endpoint?](#is-there-a-dedicated-healthcare-or-medical-endpoint) * [How do I find the right health category code?](#how-do-i-find-the-right-health-category-code) * [Should I use a keyword or disease.name to track an illness?](#should-i-use-a-keyword-or-diseasename-to-track-an-illness) * [Do these healthcare queries cost extra?](#do-these-healthcare-queries-cost-extra) ## Is there a dedicated healthcare or medical endpoint?[#](#is-there-a-dedicated-healthcare-or-medical-endpoint) No. Healthcare monitoring uses the same `/v1/news/everything` endpoint and the same `title`, `category.id`, `disease.name`, `organization.name`, `sentiment.*` and `published_at` filters as any other subject. You define what counts as medical news with those filters — there is no separate healthcare route. ## How do I find the right health category code?[#](#how-do-i-find-the-right-health-category-code) Call `GET /v1/suggest/categories?prefix=health` (or another subject word such as `medicine`). Each result returns an `id` in the IPTC form `medtop:...` that you drop straight into `category.id` — no conversion needed. A missing `prefix` returns `ER0346`, and passing a code APITube does not track to `category.id` returns `ER0206`. ## Should I use a keyword or disease.name to track an illness?[#](#should-i-use-a-keyword-or-diseasename-to-track-an-illness) Use `disease.name`. A `title` keyword matches the word in the headline, which can miss articles that name the illness only in the body or catch unrelated uses of the word. `disease.name` matches the tagged disease entity itself (type `disease`), so it returns coverage about the illness. Resolve the exact name through `/v1/suggest/entities?prefix=` before filtering, because an unknown name returns `ER0226`. ## Do these healthcare queries cost extra?[#](#do-these-healthcare-queries-cost-extra) No filter costs extra — `disease.name`, `sentiment.overall.polarity`, `is_verified_source` and the rest are part of one request. A call to `/v1/news/everything` counts as a request, and a `/v1/news/trends` call counts as one request too. Streaming over `/v1/news/stream` draws from a separate streaming quota, where each delivered article counts against that pool rather than your normal request credits. * * * ## Related Articles * [How to Filter News by Natural Disaster and Disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## Society, Health & Trends URL: https://support.apitube.io/en/articles/use-cases/society-health Monitor healthcare, disease outbreaks, politics and social trends with the APITube News API using subject, entity, sentiment and trends filters. # Society, Health & Trends Healthcare, politics and social trends. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) By Tasha 1 author 5 articles * [How to Forecast Social Trends from News](/en/articles/use-cases/society-health/social-trends) * [How to Monitor Climate and Pollution News](/en/articles/use-cases/society-health/monitor-climate-news) * [How to Monitor Healthcare and Medical News](/en/articles/use-cases/society-health/healthcare-monitoring) * [How to Monitor Political Events and Elections](/en/articles/use-cases/society-health/political-monitoring) * [How to Track Disease Outbreaks](/en/articles/use-cases/society-health/track-outbreaks) --- ## How to Monitor Climate and Pollution News URL: https://support.apitube.io/en/articles/use-cases/society-health/monitor-climate-news Monitor climate and pollution coverage with the APITube News API: use IPTC environment subcategories, add disaster event types, and track tone with sentiment… # How to Monitor Climate and Pollution News Track climate change, global warming and pollution with IPTC subcategories, then layer disaster events and sentiment on top ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 27, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&category_id=medtop%3A20000418&sort_by=published_at&sort_order=desc&per_page=50) # How to monitor climate and pollution news[#](#how-to-monitor-climate-and-pollution-news) To monitor climate and pollution coverage, filter `/v1/news/everything` by IPTC environment categories rather than by keywords. `medtop:06000000` is the whole environment branch; underneath it sit narrower categories that map cleanly onto beats — `medtop:20000418` climate change, `medtop:20000419` global warming, `medtop:20000424` environmental pollution, `medtop:20000425` air pollution, `medtop:20000429` water pollution. ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:20000418&sort.by=published_at&sort.order=desc&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Pass the key as the `api_key` query parameter or as an `X-API-Key` header. Category filtering scopes by the subject of the story, which is why it beats searching for the word “climate” — an article about a drought’s effect on wheat prices is classified correctly even if the word never appears. ## Which category IDs cover climate and pollution?[#](#which-category-ids-cover-climate-and-pollution) The environment branch is hierarchical, and picking the right depth is the whole trick. `medtop:06000000` returns everything environmental, which is broad enough to include conservation, parks and waste management alongside climate. The narrower IDs are usually what you want: * **`medtop:20000418` — climate change.** The core policy, science and impact beat. * **`medtop:20000419` — global warming.** Narrower than climate change, focused on warming itself. * **`medtop:20000424` — environmental pollution.** The parent pollution category. * **`medtop:20000425` — air pollution** and **`medtop:20000429` — water pollution.** Medium-specific slices of the above. * **`medtop:20000420` — conservation** and **`medtop:20000426` — environmental clean-up.** Remediation and protection rather than damage. `category.id` accepts several comma-separated IDs with OR logic, so a combined climate-and-pollution beat is one request: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:20000418,medtop:20000419,medtop:20000424&per_page=50" \ -H "X-API-Key: YOUR_API_KEY" ``` Each returned article carries a `categories` array showing which classifiers matched, so you can route a story to the right desk. Browse the full tree in the [APITube category list](https://docs.apitube.io/platform/news-api/list-of-categories), and see [how to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) for the filter’s rules. ## How do you add extreme weather and disaster events?[#](#how-do-you-add-extreme-weather-and-disaster-events) Categories describe subject matter; events describe what happened. For physical climate impacts, `event.type` carries the specific incident codes and accepts up to five at once: ``` curl "https://api.apitube.io/v1/news/everything?event.type=earthquake,hurricane,flood,wildfire,drought&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` Environment-category event codes include `earthquake`, `hurricane`, `flood`, `wildfire`, `tornado`, `tsunami`, `volcanic-eruption`, `drought` and `avalanche`. If you want the whole group rather than named codes, `event.category=environment` matches every environmental incident type in one filter. An unrecognised value returns an HTTP 400, so confirm codes against `/v1/news/event-types` before hard-coding them. A worked disaster feed is covered in [how to filter news by natural disaster and disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks). Note that not every plausible-sounding code carries coverage. Verify a code returns results with `/v1/news/count` before you build a dashboard panel on it — a filter that is syntactically valid but empty will silently show you nothing. ## How do you track whether climate coverage is turning negative?[#](#how-do-you-track-whether-climate-coverage-is-turning-negative) [Sentiment](/en/articles/getting-started/glossary#sentiment) filters split a climate feed by tone. `sentiment.overall.polarity` takes `positive`, `neutral` or `negative`; `sentiment.overall.score` is the underlying value from `-1` to `1` with `.min` and `.max` bounds: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:20000418&sentiment.overall.polarity=negative&published_at.start=NOW-30DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` Absolute counts of negative articles track total volume more than they track mood, so measure the **share**: run `/v1/news/count` once with the category alone and once with the polarity filter added, then divide. Keep the time window identical across both calls. Sentiment rules are covered in [how to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment). ## How do you compare climate coverage across countries?[#](#how-do-you-compare-climate-coverage-across-countries) Faceting returns aggregated counts instead of articles, so one request gives you the geography of a beat. `facet=true` plus `facet.field=source.country.id` breaks the whole match set down by where the outlet is based: ``` curl "https://api.apitube.io/v1/news/everything?category.id=medtop:20000418&facet=true&facet.field=source.country.id&facet.limit=20&per_page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` Counts cover every matching article, not just the current page, so keep `per_page=1` and skip the payload you would throw away. `facet.field` takes up to five fields, so you can add `language.id` or `sentiment.overall.polarity` in the same call. Range faceting on `published_at` turns the same query into a publication timeline. Both are explained in [how to aggregate results with facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets). Remember that `source.country.code` and `source.country.id` describe where the **publisher** sits, not where the flood happened. For the location of the event itself, use the geo radius filters or read `locations_mentioned` on each article. # Common Questions[#](#common-questions) * [Should I use a category or a keyword search for climate news?](#should-i-use-a-category-or-a-keyword-search-for-climate-news) * [What is the difference between climate change and global warming categories?](#what-is-the-difference-between-climate-change-and-global-warming-categories) * [Why does an event type return zero articles?](#why-does-an-event-type-return-zero-articles) * [How do I find climate news about a specific region?](#how-do-i-find-climate-news-about-a-specific-region) ## Should I use a category or a keyword search for climate news?[#](#should-i-use-a-category-or-a-keyword-search-for-climate-news) Use the category. `category.id=medtop:20000418` matches articles the classifier judged to be about climate change, including ones that never use the phrase — a story about crop failures or insurance repricing lands in the category on subject, not on wording. A `title` keyword search does the opposite: it is precise about the words and blind to the subject. Start from the category and add `title` only when you need to narrow to a named policy, company or event within that beat. ## What is the difference between climate change and global warming categories?[#](#what-is-the-difference-between-climate-change-and-global-warming-categories) `medtop:20000418` (climate change) is the broader beat — policy, adaptation, science, economics and impacts. `medtop:20000419` (global warming) sits underneath it and is narrower, centred on the warming itself. In practice climate change carries several times the volume, so use it as your default and add global warming only when you specifically want the temperature-focused slice. Both can be passed together in one comma-separated `category.id`. ## Why does an event type return zero articles?[#](#why-does-an-event-type-return-zero-articles) A code being valid is not the same as a code being populated. `event.type` rejects unrecognised values with an HTTP 400, but a recognised code with no classified coverage simply returns an empty result set and no error. Always check a new code with `/v1/news/count` before wiring it into a feed. When a code comes back empty, fall back to the category axis — the environment categories cover the same subject matter through a different classifier and are consistently populated. ## How do I find climate news about a specific region?[#](#how-do-i-find-climate-news-about-a-specific-region) Filter on the event location rather than the publisher. Pass `location.lat` and `location.lng` together with `location.radius` in kilometres for a radius search, or `location.bbox` for a rectangle, and add `has_location_geo=1` so only geolocated articles come through. `source.country.code` is a different thing — it filters by where the outlet is based, which is a reasonable proxy for local press coverage but will miss international reporting on the same region. * * * ## Related Articles * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Filter News by Natural Disaster and Disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Aggregate Results with Facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) --- ## How to Monitor Political Events and Elections URL: https://support.apitube.io/en/articles/use-cases/society-health/political-monitoring Monitor political news with APITube: combine event.type (election, protest) with person.name, sentiment and a country filter, then stream new coverage over SSE. # How to Monitor Political Events and Elections Track elections, protests, policy changes and named politicians by combining event.type, entity and sentiment filters — no dedicated politics endpoint required ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&event_type=election&language_code=en&sort_by=published_at&sort_order=desc) # How to monitor political events and elections[#](#how-to-monitor-political-events-and-elections) To monitor political events, query `/v1/news/everything` and combine an `event.type` filter — such as `election`, `protest`, `policy-change`, `scandal` or `diplomacy` — with [entity](/en/articles/getting-started/glossary#entity) filters like `person.name` for a politician and `organization.name` for a party or government body, then scope the feed with `source.country.code`, a `published_at` window and a `sentiment` filter. There is **no** dedicated politics endpoint: you assemble a political-news feed from the shared filter chain and point the exact same filters at the `/v1/news/stream` [SSE](/en/articles/getting-started/glossary#sse-stream) feed when you need coverage pushed live. ``` curl "https://api.apitube.io/v1/news/everything?event.type=election&language.code=en&sort.by=published_at&sort.order=desc" \ -H "X-API-Key: YOUR_API_KEY" ``` You can send the key as an `X-API-Key` header or as the `api_key` query parameter, and call the endpoint with `GET` (query parameters) or `POST` (JSON body). Every parameter you add combines with AND, so each filter narrows the political feed further. ## How do you filter for elections, protests and policy changes?[#](#how-do-you-filter-for-elections-protests-and-policy-changes) The cleanest way to catch political happenings is the `event.type` filter, which matches the event the pipeline detected in each article rather than a keyword in the text. The political values live in the `society` group: `election`, `protest`, `policy-change`, `scandal`, `diplomacy`, `conflict`, `human-rights`, `crime`, `terrorism` and `migration`. You can pass up to five types, comma-separated, and they combine with OR: ``` curl "https://api.apitube.io/v1/news/everything?event.type=election,protest,policy-change&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` An unsupported value stops the request with `ER0502` and points you to `GET /v1/news/event-types`, which returns every valid `event.type` together with its category. You can also cast a wider net with `event.category=society`, but note that group also includes non-political events like `accident`, `death` and `health-crisis`, so listing the specific political `event.type` values keeps the feed tighter. See [how to filter news by event type and category](/en/articles/searching-and-filtering/events/filter-by-event-type) for the full rules. ## How do you track a specific politician, party or government body?[#](#how-do-you-track-a-specific-politician-party-or-government-body) Keyword search matches text; entity filters match the tagged thing itself, which is far cleaner for tracking a named person or organization. Use `person.name` for a politician (entity type `person`) and `organization.name` for a party, ministry or government body (entity type `organization`). Each accepts up to three comma-separated names, 1 to 120 characters, with OR logic: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Emmanuel%20Macron&event.type=diplomacy" \ -H "X-API-Key: YOUR_API_KEY" ``` The name must match an entity APITube already tracks, or the request stops — an unknown `person.name` returns `ER0216` and an unknown `organization.name` returns `ER0220`. Resolve the exact spelling and type first with `GET /v1/suggest/entities?prefix=`; each result carries an `id`, `name` and `type`, and that numeric `id` also works directly as `entity.id`. For an ongoing person feed, see [how to track news about a specific person](/en/articles/searching-and-filtering/entities/track-news-about-a-person). ## How do you narrow politics to one country and time window?[#](#how-do-you-narrow-politics-to-one-country-and-time-window) Add `source.country.code` (a two-letter code such as `us` or `gb`, up to three comma-separated) to keep only publishers from a country, and a `published_at` window to scope the feed in time. `published_at.start` and `published_at.end` accept absolute dates like `2026-06-01` or relative values such as `NOW-7DAYS` and `NOW-1WEEK`: ``` curl "https://api.apitube.io/v1/news/everything?event.type=election&source.country.code=us&published_at.start=NOW-14DAYS&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at 250 — 10 on Free, 50 on Starter (a larger value returns `ER0171`); walk deeper with `page`. On the Free plan, paging stops after the first 5 pages (`ER0173`), so use a paid plan for wide sweeps around an election. An unknown country code returns `ER0212`. To filter by the place a story is _about_ rather than where its publisher sits, use the `location.name` entity filter instead (entity type `location`, unknown name returns `ER0218`). ## How do you measure the tone of political coverage?[#](#how-do-you-measure-the-tone-of-political-coverage) Political monitoring is often about [sentiment](/en/articles/getting-started/glossary#sentiment), not just volume. Add `sentiment.overall.polarity=negative` to keep articles the pipeline scored as negative overall (it accepts `positive`, `negative` or `neutral`). To measure the tone expressed **toward** a specific politician rather than the whole article, use `entity.sentiment.polarity` (`positive`, `negative` or `neutral`; an invalid value returns `ER0290`) alongside the `person.name` selector: ``` curl "https://api.apitube.io/v1/news/everything?person.name=Emmanuel%20Macron&entity.sentiment.polarity=negative" \ -H "X-API-Key: YOUR_API_KEY" ``` Because political reporting varies by outlet, you can restrict the feed to higher-ranked publishers with `is_verified_source=1`, which keeps sources with an [Open PageRank](/en/articles/getting-started/glossary#opr-open-pagerank) (OPR) of 5 or more and drops duplicates. You can also split coverage by the publisher’s political leaning with `source.bias`, which takes `left`, `center` or `right`. See [how to filter news by sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) for the score-based options. ## How do you catch breaking political news in real time?[#](#how-do-you-catch-breaking-political-news-in-real-time) Polling `everything` returns what already exists; a live politics desk needs push. First narrow to important stories with `is_breaking=1` (it accepts `0` or `1`), then keep the same filters and open the Server-Sent Events stream at `/v1/news/stream`, which runs the identical filter chain and pushes each new matching article as it is indexed: ``` curl -N "https://api.apitube.io/v1/news/stream?event.type=election,protest&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream only sends articles that appear **after** you connect, and it draws from a separate streaming quota: each delivered article counts against your SSE points rather than your normal request credits, and a failed delivery is refunded. If you would rather have APITube `POST` new coverage to your own endpoint, create a **[webhook](/en/articles/getting-started/glossary#webhook)** — that is set up in the dashboard, not over the API. ## How do you see which political topics are trending?[#](#how-do-you-see-which-political-topics-are-trending) To see what is rising in political coverage rather than a flat list of articles, call `/v1/news/trends` with `field=entity.id` (or `field=topic.id`). It groups matching articles and returns each value with a count, and adding `trending=true` computes a trending score by comparing recent volume against the trailing window: ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&event.type=election&trending=true&api_key=YOUR_API_KEY" ``` The trends endpoint runs the same filter chain, so every filter above applies. It returns up to 100 results per request and looks back at most 30 days. The full parameter list lives in the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Is there a dedicated politics or elections endpoint?](#is-there-a-dedicated-politics-or-elections-endpoint) * [Which event.type values cover political news?](#which-eventtype-values-cover-political-news) * [Should I use a keyword or person.name to track a politician?](#should-i-use-a-keyword-or-personname-to-track-a-politician) * [How do I limit political news to one country?](#how-do-i-limit-political-news-to-one-country) ## Is there a dedicated politics or elections endpoint?[#](#is-there-a-dedicated-politics-or-elections-endpoint) No. Political monitoring uses the same `/v1/news/everything` endpoint and the same `event.type`, `person.name`, `organization.name`, `sentiment.*`, `source.country.code` and `published_at` filters as any other subject. You define what counts as political news with those filters — there is no separate politics route. ## Which event.type values cover political news?[#](#which-eventtype-values-cover-political-news) The political values sit in the `society` group and include `election`, `protest`, `policy-change`, `scandal`, `diplomacy`, `conflict`, `human-rights`, `crime`, `terrorism` and `migration`. Pass up to five at once, comma-separated, in `event.type`. To confirm the current list, call `GET /v1/news/event-types`, which returns every valid value with its category; an unknown value returns `ER0502`. ## Should I use a keyword or person.name to track a politician?[#](#should-i-use-a-keyword-or-personname-to-track-a-politician) Use `person.name`. A `title` keyword matches the word in the headline, which can miss articles that name the politician only in the body or catch unrelated people with the same name. `person.name` matches the tagged person entity itself (type `person`), so it returns coverage about that individual. Resolve the exact name through `/v1/suggest/entities?prefix=` before filtering, because an unknown name returns `ER0216`. ## How do I limit political news to one country?[#](#how-do-i-limit-political-news-to-one-country) Add `source.country.code` with a two-letter code (for example `us`, `gb` or `fr`) to keep only publishers based in that country; you can pass up to three, comma-separated. To instead filter by the country a story is _about_, use the `location.name` entity filter. An unknown `source.country.code` returns `ER0212`, and the code must be exactly two characters or you get `ER0246`. * * * ## Related Articles * [How to Filter News by Event Type and Category](/en/articles/searching-and-filtering/events/filter-by-event-type) * [How to Track News About a Specific Person](/en/articles/searching-and-filtering/entities/track-news-about-a-person) * [How to Filter News by Sentiment](/en/articles/searching-and-filtering/sentiment/filter-by-sentiment) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How to Forecast Social Trends from News URL: https://support.apitube.io/en/articles/use-cases/society-health/social-trends Forecast social trends with the APITube News API: run /v1/news/trends over a society slice and read trending, compare and time_bucket signals to catch rising… # How to Forecast Social Trends from News Spot rising social topics early with /v1/news/trends — trending scores, period-over-period change and time\_bucket series ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum August 22, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Ftrends&field=entity.id&category_id=medtop%3A14000000&trending=true) # How to forecast social trends from news[#](#how-to-forecast-social-trends-from-news) To forecast social trends from news, call the `/v1/news/trends` endpoint over a society slice of coverage and read its momentum signals. APITube does **not** predict the future for you — it tells you which topics, [entities](/en/articles/getting-started/glossary#entity) and categories are _rising right now_, so you can spot a social trend while it is still building instead of after it peaks. Add `trending=true` for a per-value trending score, `compare=true` for period-over-period change, or `time_bucket` for a day-by-day series, then narrow the set with the same filters you would use on `/v1/news/everything`. This ranks the fastest-moving entities in society coverage over the last 30 days: ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&category.id=medtop:14000000&trending=true&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as an `X-API-Key` header, and call the endpoint with `GET` (filters as query parameters) or `POST` (filters as a JSON body). The `category.id=medtop:14000000` code is the IPTC top-level **society** category, so the ranking covers only articles the pipeline tagged as society news. ## How do you spot a rising social trend, not just a popular one?[#](#how-do-you-spot-a-rising-social-trend-not-just-a-popular-one) Popularity and momentum are different questions: a topic can be large but flat. Add `trending=true` to compute a **trending score** for each value — the ratio of its recent 2-day average to its trailing 14-day average, so a score above 1 means the trend is rising and below 1 means it is fading. Each value also comes back with `trending_history`, the daily counts behind the score. Tune the look-back window with `trending_days` (default 14, allowed range 7 to 30). Trend on `entity.id` to watch people and organizations, `topic.id` for subject tags, or `category.id` for broad IPTC sections: ``` curl "https://api.apitube.io/v1/news/trends?field=topic.id&category.id=medtop:07000000&trending=true&trending_days=7&api_key=YOUR_API_KEY" ``` Here `medtop:07000000` is the **health** category, so a 7-day trending window surfaces which health subjects are gaining coverage fastest this week — an early read on an emerging social conversation. ## How do you tell whether a social topic is growing or fading?[#](#how-do-you-tell-whether-a-social-topic-is-growing-or-fading) To measure direction, use `compare=true` with a `compare_window`. The endpoint counts each value in your current window, then counts the same window shifted back by `compare_window`, and returns the difference as `previous_count`, `change_absolute` and `change_percent`. A value that had zero articles in the previous period but appears now is reported as `change_percent` of `100`, which flags a genuinely new trend. Add `sort=change` to rank the biggest movers first (this sort mode is only available when `compare=true`): ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&category.id=medtop:14000000&published_at.start=NOW-7DAYS&compare=true&compare_window=7DAYS&sort=change&api_key=YOUR_API_KEY" ``` `compare_window` is **required** whenever `compare=true`; omitting it returns error `ER0352`. It accepts the same relative-duration formats as the date filters — `24HOURS`, `7DAYS`, `1WEEK`, or short aliases like `1w` and `2m` — and the shift is clamped between 1 hour and 1 year. Set `compare_window=1YEAR` to compare this week against the same week last year. The mechanics are covered in full in [how to compare news trends between two periods](/en/articles/retrieval/compare-trends). ## How do you chart a social trend day by day?[#](#how-do-you-chart-a-social-trend-day-by-day) To see the _shape_ of a trend rather than a single delta, use `time_bucket`. Set it to `hour`, `day`, `week` or `month`, and each value returns a `buckets` map of counts per interval plus a `total`, ordered by total descending. A rising curve across the buckets is your leading indicator: ``` curl "https://api.apitube.io/v1/news/trends?field=category.id&published_at.start=NOW-14DAYS&time_bucket=day&api_key=YOUR_API_KEY" ``` In `time_bucket` mode the `value` is the raw id and is not enriched with a name. Use `compare` when you want one period-over-period number and `time_bucket` when you want the day-by-day curve; run them as separate requests rather than combining the two in one call. ## How do you focus trends on a social subject?[#](#how-do-you-focus-trends-on-a-social-subject) Trends are computed over exactly the articles your filters select, so every standard search filter works here too. To scope a social-trends study, combine an IPTC category with a language and a date window. The society-related IPTC codes include **society** (`medtop:14000000`), **health** (`medtop:07000000`) and **science and technology** (`medtop:13000000`); you can pass up to three category codes, comma-separated, and they combine with OR. For a precise subject instead of a broad section, use `topic.id` (a named subject tag such as `industry.crypto_news`, up to three with OR logic): ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&category.id=medtop:14000000&language.code=en&published_at.start=NOW-30DAYS&api_key=YOUR_API_KEY" ``` Every code is checked against the categories and topics APITube already tracks: an unknown `category.id` returns `ER0206` and an unknown `topic.id` returns `ER0208`, and the whole request stops on the first bad value. See [how to filter news by category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) for the full IPTC rules. ## How do you track the mood behind a social trend?[#](#how-do-you-track-the-mood-behind-a-social-trend) A rising trend is often about tone, not just volume. Because the trends endpoint runs the shared filter chain, add `sentiment.overall.polarity` to restrict the ranking to articles the pipeline scored a certain way. It accepts `positive`, `negative` or `neutral`, so you can surface which entities are driving _negative_ social coverage as it climbs: ``` curl "https://api.apitube.io/v1/news/trends?field=entity.id&category.id=medtop:14000000&sentiment.overall.polarity=negative&trending=true&api_key=YOUR_API_KEY" ``` Reading the trending score alongside a negative-[sentiment](/en/articles/getting-started/glossary#sentiment) filter tells you not only that a social topic is rising, but that it is rising _in a critical direction_ — the kind of early signal a reputation, policy or public-health team wants first. ## What are the limits and cost of trends requests?[#](#what-are-the-limits-and-cost-of-trends-requests) The `field` parameter is required (missing or invalid returns `ER0350`) and accepts up to five comma-separated values. The current window is **capped at 30 days** and defaults to the last 30 days if you pass no dates — a wider range returns `ER0353`. `per_page` defaults to 10 and maxes out at 100. Each `/v1/news/trends` call costs **1 point**, no matter how many fields you aggregate. The endpoint is **paid-only**: a free key gets `403 ER0706` instead of results. On a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** the structure and counts come back, but every trend `value` is replaced with the placeholder `[Upgrade subscription plan]`, so switch to a live key to read real entity and category values. The usual limits apply: `ER0176` (HTTP 402) when your account has no points, and `ER0203` (HTTP 429) when you exceed 50 requests per minute on a live key (200 on Corporate, 15 on a test key), with repeated violations triggering a temporary ban (`ER0204`). For the complete field and response reference, see [how to discover trending topics and entities](/en/articles/retrieval/discover-trends) and the official [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [Does APITube predict future social trends?](#does-apitube-predict-future-social-trends) * [Which field should I trend on for social trends?](#which-field-should-i-trend-on-for-social-trends) * [How far back can a social-trends study look?](#how-far-back-can-a-social-trends-study-look) * [Why are my trend values masked?](#why-are-my-trend-values-masked) ## Does APITube predict future social trends?[#](#does-apitube-predict-future-social-trends) No. The `/v1/news/trends` endpoint does not forecast the future — it measures momentum in the news that already exists. The `trending` score (recent volume versus the trailing window), `compare` change (`change_percent` versus a shifted period) and `time_bucket` series are leading indicators: you build the forecast by acting on a trend while it is still rising. Treat a `trending_score` above 1 or a large positive `change_percent` as “this is accelerating,” not as a guaranteed prediction. ## Which field should I trend on for social trends?[#](#which-field-should-i-trend-on-for-social-trends) Use `field=entity.id` to track which people and organizations are gaining coverage, `field=topic.id` for named subject tags, and `field=category.id` for broad IPTC sections such as society (`medtop:14000000`) or health (`medtop:07000000`). You can aggregate up to five fields in one call by passing them comma-separated, for example `field=entity.id,topic.id`, to power an entity list and a topic breakdown from a single request. ## How far back can a social-trends study look?[#](#how-far-back-can-a-social-trends-study-look) The current window you measure is capped at **30 days** and defaults to the last 30 days when you pass no dates; a wider `published_at` range returns `ER0353`, so split longer studies into 30-day chunks. The `compare_window` offset is separate from that cap and can reach up to a year back, so you can keep a 7-day current window and still compare it against the same week a year ago. ## Why are my trend values masked?[#](#why-are-my-trend-values-masked) If every trend `value` reads `[Upgrade subscription plan]`, you are calling `/v1/news/trends` with a test key. Test keys return the real structure, counts and percentages so you can build against the shape of the response, but they hide the underlying entity, topic and category values. Switch to a live key to see the real social trends. * * * ## Related Articles * [How to Discover Trending Topics and Entities](/en/articles/retrieval/discover-trends) * [How to Compare News Trends Between Two Periods](/en/articles/retrieval/compare-trends) * [How to Filter News by Category](/en/articles/searching-and-filtering/by-attribute/filter-by-category) * [How to Monitor Healthcare and Medical News](/en/articles/use-cases/society-health/healthcare-monitoring) --- ## How to Track Disease Outbreaks URL: https://support.apitube.io/en/articles/use-cases/society-health/track-outbreaks Track disease outbreaks with APITube: pair disease.name with the health-crisis event type, scope by country and date window, then stream new coverage over SSE. # How to Track Disease Outbreaks Build an outbreak surveillance feed by pairing the disease.name entity filter with the health-crisis event type ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-128.jpg) Written by Tasha Tatum July 4, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&disease_name=malaria&event_type=health-crisis&published_at_start=NOW-7DAYS) # How to track disease outbreaks[#](#how-to-track-disease-outbreaks) To track a disease outbreak, query `/v1/news/everything` and combine the `disease.name` [entity](/en/articles/getting-started/glossary#entity) filter (the tagged illness) with `event.type=health-crisis` (articles the pipeline classified as a health crisis), then scope the feed to a country and a recent date window. `disease.name` matches the disease entity itself rather than a keyword, so it returns coverage about the outbreak instead of every article that happens to contain the word: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=malaria&event.type=health-crisis&published_at.start=NOW-7DAYS" \ -H "X-API-Key: YOUR_API_KEY" ``` You can send the key as an `X-API-Key` header or as the `api_key` query parameter, and call the endpoint with `GET` (query parameters) or `POST` (JSON body). Different parameters combine with AND, so each filter you add narrows the outbreak feed further. ## How to build an outbreak surveillance feed[#](#how-to-build-an-outbreak-surveillance-feed) Start with the disease entity. `disease.name` filters to articles tagged with a specific illness (entity type `disease`), accepts up to three comma-separated names with OR logic, and requires each name to be 1 to 120 characters. That lets one request watch several outbreaks at once: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=malaria,dengue fever,COVID-19&language.code=en&sort.by=published_at&sort.order=desc" \ -H "X-API-Key: YOUR_API_KEY" ``` Results are newest-first by default (`sort.by=published_at`, `sort.order=desc`); switch to `sort.by=relevance` to rank by how well each article matches. The name must resolve to an entity APITube already tracks — an unknown `disease.name` stops the request with `ER0226`, and a name outside the 1–120 character range returns `ER0152`. For the full filter reference, see [how to track disasters and disease outbreaks](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks). ## How to focus on outbreak events, not general disease coverage[#](#how-to-focus-on-outbreak-events-not-general-disease-coverage) A disease is mentioned in routine research, funding and history pieces as well as active outbreaks. To bias the feed toward crisis coverage, add `event.type=health-crisis`. The `event.type` filter matches an article’s primary classified event and accepts up to five comma-separated codes. `health-crisis` sits in the `society` event category, so you can also cast a wider net with `event.category=society`: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=influenza&event.type=health-crisis" \ -H "X-API-Key: YOUR_API_KEY" ``` An unknown `event.type` returns `ER0502`, and an unknown `event.category` returns `ER0503` (valid categories: `business`, `society`, `environment`). To see every valid code and its category, call `GET /v1/news/event-types` — it returns the full list as `{ code, category }` pairs, so you never have to guess a spelling. ## How to scope an outbreak to a country and time window[#](#how-to-scope-an-outbreak-to-a-country-and-time-window) Outbreaks are geographic, so limit the feed to where it is happening. `source.country.code` keeps only publishers from a two-letter country code (such as `us` or `gb`), and a `published_at` window keeps the feed current. `published_at.start` and `published_at.end` accept absolute dates like `2026-06-01` or Solr-style relative values such as `NOW-7DAYS` and `NOW-1WEEK`: ``` curl "https://api.apitube.io/v1/news/everything?disease.name=COVID-19&source.country.code=ng&published_at.start=NOW-14DAYS&per_page=250" \ -H "X-API-Key: YOUR_API_KEY" ``` `per_page` defaults to 100 and maxes out at 250 — 10 on Free, 50 on Starter (a larger value returns `ER0171`); walk deeper with `page`. An unknown country code returns `ER0212`. To measure the tone expressed **toward** the disease itself, add `entity.sentiment.polarity=negative` (it accepts `positive`, `negative` or `neutral`; an invalid value returns `ER0290`) — useful for separating alarm-driven coverage from reassurance. ## How to catch breaking outbreak alerts[#](#how-to-catch-breaking-outbreak-alerts) When an outbreak escalates, you want the articles the pipeline flagged as important. Add `is_breaking=1` to keep only breaking coverage (`is_breaking=0` keeps the rest; any other value returns `ER0186`): ``` curl "https://api.apitube.io/v1/news/everything?disease.name=dengue fever&is_breaking=1&sort.by=published_at&sort.order=desc" \ -H "X-API-Key: YOUR_API_KEY" ``` Because filters combine with AND, this returns only breaking articles about the named disease, newest first — a tight signal for a public-health desk rather than a full firehose. ## How to receive outbreak coverage in real time[#](#how-to-receive-outbreak-coverage-in-real-time) Polling `everything` returns what already exists; live surveillance needs push. Keep the exact same filters and open the [Server-Sent Events](/en/articles/getting-started/glossary#sse-stream) stream at `/v1/news/stream` — it runs the same filter chain and pushes each new matching article as it is indexed (the poll cycle is 30 seconds): ``` curl -N "https://api.apitube.io/v1/news/stream?disease.name=malaria&event.type=health-crisis&language.code=en" \ -H "X-API-Key: YOUR_API_KEY" ``` The stream only sends articles that appear **after** you connect, and you can trim stale backfill with `stream.max_age` (a rolling window in minutes; an invalid value returns `ER0363`). For a broader medical feed built the same way, see [how to monitor healthcare and medical news](/en/articles/use-cases/society-health/healthcare-monitoring), and the full parameter list in the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything). # Common Questions[#](#common-questions) * [How is disease.name different from the health-crisis event type?](#how-is-diseasename-different-from-the-health-crisis-event-type) * [Which event type covers disease outbreaks?](#which-event-type-covers-disease-outbreaks) * [How do I find the exact disease name to track?](#how-do-i-find-the-exact-disease-name-to-track) * [Can I get outbreak alerts pushed to me automatically?](#can-i-get-outbreak-alerts-pushed-to-me-automatically) ## How is disease.name different from the health-crisis event type?[#](#how-is-diseasename-different-from-the-health-crisis-event-type) They filter on different signals. `disease.name` matches the tagged disease entity (type `disease`) mentioned in an article, so it identifies _which_ illness the coverage is about. `event.type=health-crisis` matches an article’s primary classified event, so it identifies _what kind_ of story it is. Using both together — `disease.name=malaria&event.type=health-crisis` — returns crisis-type coverage about that specific disease, which is tighter than either filter alone. ## Which event type covers disease outbreaks?[#](#which-event-type-covers-disease-outbreaks) `health-crisis`, which belongs to the `society` event category. Pass it as `event.type=health-crisis`, or widen to `event.category=society` to include neighbouring society events. Call `GET /v1/news/event-types` to see every valid code and category; passing a code that is not on that list returns `ER0502`. ## How do I find the exact disease name to track?[#](#how-do-i-find-the-exact-disease-name-to-track) `disease.name` resolves against the entities APITube tracks, so the name must match one. Look it up with entity autocomplete: call `GET /v1/suggest/entities?prefix=` with the start of the name (a missing `prefix` returns `ER0346`). Each result includes an `id`, `name` and `type` — a `type` of `disease` confirms a value you can pass to `disease.name`, and that numeric `id` also works directly as `entity.id`. ## Can I get outbreak alerts pushed to me automatically?[#](#can-i-get-outbreak-alerts-pushed-to-me-automatically) Yes. Point the same filters at the `/v1/news/stream` SSE endpoint to have new matching articles streamed to you as they are indexed. If you would rather have APITube `POST` new coverage to your own URL, create a **[webhook](/en/articles/getting-started/glossary#webhook)** — that is set up in the dashboard, not over the API. Streaming draws from a separate streaming quota, where each delivered article counts against that pool rather than your normal request credits. * * * ## Related Articles * [How to Filter News by Natural Disaster and Disease](/en/articles/searching-and-filtering/events/track-disasters-and-outbreaks) * [How to Monitor Healthcare and Medical News](/en/articles/use-cases/society-health/healthcare-monitoring) * [How to Stream News in Real Time with SSE](/en/articles/delivery-and-export/streaming/stream-with-sse) --- ## How Data Scientists and Researchers Use APITube URL: https://support.apitube.io/en/articles/use-cases/trust-and-research/data-science-research Build labeled news datasets with APITube: size sets with /v1/news/count, check balance with facets, pin a date window, then export JSONL or Parquet. # How Data Scientists and Researchers Use APITube Size a news dataset with count, check label balance with facets, pin a reproducible window, then bulk-export the labeled corpus as JSONL or Parquet ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Fcount&language_code=en&published_at_start=2026-01-01&published_at_end=2026-03-31) # How data scientists and researchers use APITube[#](#how-data-scientists-and-researchers-use-apitube) Data scientists use the APITube News API to build labeled news datasets without scraping or hand-annotating. The workflow is four steps: size the set with `GET /v1/news/count`, check label balance with the `facet` parameter, pin a reproducible date window with `published_at.start` and `published_at.end`, then pull the corpus out in bulk with `export=jsonl` or `export=parquet`, paging through `per_page` up to 250 records at a time (10 on Free, 50 on Starter, 200 on Basic). Every article already ships with structured NLP labels — [sentiment](/en/articles/getting-started/glossary#sentiment), [entities](/en/articles/getting-started/glossary#entity), categories, topics and keywords — so the corpus is labeled the moment you download it. ``` curl "https://api.apitube.io/v1/news/count?language.code=en&published_at.start=2026-01-01&published_at.end=2026-03-31&api_key=YOUR_API_KEY" ``` You can send the key as a header (`X-API-Key: YOUR_API_KEY`) instead of the `api_key` query parameter. Start with the count, because it tells you how big the download will be before you commit to it. ## How do I size a news dataset before downloading it?[#](#how-do-i-size-a-news-dataset-before-downloading-it) Call `GET /v1/news/count` with the exact filters your dataset needs. It runs your query and returns only the total — no article bodies — so you learn the row count for one request instead of paging through everything: ``` { "status": "ok", "count": 48210, "request_id": "..." } ``` A `count` call charges one request against your plan regardless of how large the total is, which makes it the cheap way to plan a pull. Two caveats matter for research: on a **[test key](/en/articles/getting-started/glossary#test-key-and-live-key)** the count is capped at 100 so it cannot reveal the real catalog size, and an **unfiltered** count returns a catalog-wide figure rather than your dataset — always scope it with the same filters (language, date, category, entity) you will export. See [counting matching articles without downloading them](/en/articles/retrieval/count-articles) for the full endpoint behavior. ## What labels come with each article?[#](#what-labels-come-with-each-article) Each article record is pre-annotated, so you rarely need a separate labeling step. Alongside the text (`title`, body, and readability counts like `read_time`, `sentences_count`, `paragraphs_count`, `words_count`, `characters_count`), every record carries nested NLP fields: `sentiment` (overall, title and body polarity plus a score from `-1` to `1`), `entities` (people, organizations, brands, locations with per-entity sentiment), `categories`, `topics`, `industries`, `keywords`, `media`, and the source with its rank. The boolean flags `is_duplicate`, `is_free` and `is_breaking` are included too. That is the difference between APITube and a raw scrape: sentiment classification, named-entity recognition and topic labels are already attached, so you can train or evaluate on them directly instead of running your own annotation pipeline. ## How do I check class balance before I train?[#](#how-do-i-check-class-balance-before-i-train) Skewed classes wreck a model, so inspect the label distribution before downloading. The `facet` parameter groups the whole matching set by a field and returns counts, without pulling articles. Facet by the labels you plan to model — sentiment polarity, category, language, source country — in a single request: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2026-01-01&published_at.end=2026-03-31&facet=true&facet.field=sentiment.overall.polarity,category.id,language.id&per_page=1&api_key=YOUR_API_KEY" ``` The response adds a `facets` object where each field is an array of `{ value, count }` pairs computed over every matching article, not just the page. You can now see, for example, that negative articles are a fifth of the positive ones and adjust your sampling before you spend requests downloading. Faceting accepts up to five fields per call and its own `facet.limit` (default `10`, cap `100`); the [faceting guide](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) lists every groupable field. ## How do I build a reproducible corpus?[#](#how-do-i-build-a-reproducible-corpus) Reproducibility comes from a **closed, absolute date window**. Set both `published_at.start` and `published_at.end` to fixed dates in the past (`YYYY-MM-DD`, or a full timestamp), rather than a relative value like `NOW-30DAYS` that moves every run. Because a past window stops matching newly published articles, the same filters return the same corpus each time you run the pull: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2026-01-01&published_at.end=2026-01-31&language.code=en&category.id=medtop:04000000&per_page=250&api_key=YOUR_API_KEY" ``` Add `language.code` to fix the language of the set — repeat the pull per language for a multilingual corpus — and layer any classification filter (`category.id`, `topic.id`, `industry.id`, `entity.id`) to scope the domain. Record the exact query string alongside your dataset so the corpus can be regenerated or extended later with the same parameters. ## How do I pull the corpus out in bulk?[#](#how-do-i-pull-the-corpus-out-in-bulk) Add `export=jsonl` for one full article object per line, or `export=parquet` for a typed columnar file that loads straight into pandas, DuckDB or Spark. The export runs on top of your search, so the file contains exactly the filtered articles: ``` curl "https://api.apitube.io/v1/news/everything?published_at.start=2026-01-01&published_at.end=2026-01-31&language.code=en&per_page=250&page=1&export=jsonl&api_key=YOUR_API_KEY" -o corpus_p1.jsonl ``` Each request exports the current page, up to 250 records (`per_page` max is 250, or 200 on Basic, 50 on Starter and 10 on Free; asking for more returns HTTP 400 `ER0171`), so a large dataset is a loop over `page=1`, `page=2`, … appended together. To trim each record to the columns your model needs, add `fl` with a comma-separated field list — for example `fl=id,title,sentiment,entities,categories` — which slims both the JSON response and the export. The [data-pipeline export guide](/en/articles/delivery-and-export/export/export-data-pipelines) covers the JSONL and Parquet formats and page-by-page downloads in detail. # Common Questions[#](#common-questions) * [Can I download more than 250 articles in one request?](#can-i-download-more-than-250-articles-in-one-request) * [Are the article bodies full text for training?](#are-the-article-bodies-full-text-for-training) * [Does building a dataset use a lot of requests?](#does-building-a-dataset-use-a-lot-of-requests) ## Can I download more than 250 articles in one request?[#](#can-i-download-more-than-250-articles-in-one-request) No. `per_page` is capped at 250 — 50 on Starter, 10 on Free — and a higher value returns HTTP 400 with error `ER0171`. Build a bigger dataset by paging: keep `per_page` at your plan ceiling and increment `page` until a page comes back short. One more limit to plan around — the **Free plan can only reach the first 5 pages** (error `ER0173` beyond that), so a large corpus needs a paid plan that lifts the [pagination](/en/articles/getting-started/glossary#pagination) cap. ## Are the article bodies full text for training?[#](#are-the-article-bodies-full-text-for-training) Only on a live, paid key. On a **Free plan or a test key** the article body is truncated to a preview and masked with an upgrade marker — the same content masking applied across the News API — while the labels, entities and sentiment are still returned. For a training corpus that needs the complete text, use a live key on a paid plan. ## Does building a dataset use a lot of requests?[#](#does-building-a-dataset-use-a-lot-of-requests) Each API call is a single request against your plan, and exporting does not cost extra — an exported page counts the same as a normal search page. Sizing with `count` and checking balance with `facet` are one request each, so the planning phase is cheap; the bulk cost is the download itself, which is one request per 250-record page. For the exact parameter names and limits, the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) is canonical. * * * ## Related Articles * [How to Export News for Data Pipelines (JSONL, Parquet)](/en/articles/delivery-and-export/export/export-data-pipelines) * [How to Aggregate News Results with Facets](/en/articles/searching-and-filtering/sorting-and-shaping/aggregate-with-facets) * [How to Count Matching Articles Without Downloading Them](/en/articles/retrieval/count-articles) * [How to Paginate Through News API Results](/en/articles/searching-and-filtering/sorting-and-shaping/paginate-results) --- ## How to Identify Fake News and Misinformation URL: https://support.apitube.io/en/articles/use-cases/trust-and-research/detect-fake-news Spot misinformation with the News API: there is no fake-news flag, so combine source quality (OPR), verified sources, bias, clickbait and duplicate signals. # How to Identify Fake News and Misinformation There is no single fake-news flag — combine source quality, bias, clickbait and duplicate signals to score how trustworthy a story is ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=election+fraud&is_verified_source=1&is_clickbait=0&is_duplicate=0) # How to identify fake news and misinformation[#](#how-to-identify-fake-news-and-misinformation) The APITube News API has no single “is\_fake” flag — misinformation is not a field, it is a judgement you build from signals. The reliable approach is to combine several verifiable credibility filters in one request: weight toward high-rank and verified sources, drop clickbait and manipulative framing, remove duplicate re-posts, and check a source’s political lean. This query keeps coverage from strong sources, excludes clickbait, and drops duplicate re-posts: ``` curl "https://api.apitube.io/v1/news/everything?title=election%20fraud&is_verified_source=1&is_clickbait=0&is_duplicate=0&api_key=YOUR_API_KEY" ``` You can pass the key as the `api_key` query parameter or as the `X-API-Key` header. None of these filters _proves_ a story true or false; together they raise or lower the odds that what you are reading is credible, which is exactly how a human vets a source. ## Is there a single “fake news” flag in the API?[#](#is-there-a-single-fake-news-flag-in-the-api) No. There is no boolean that labels an article as fake or true, because credibility is not something the crawler can measure directly. What the API does expose is a set of measurable proxies for trustworthiness — the source’s authority rank, whether it is a verified source, its political bias, whether the headline is clickbait, and whether the piece is a duplicate. You assemble these into a credibility check. Start strict and loosen if you get too few results: ``` curl "https://api.apitube.io/v1/news/everything?title=miracle%20cure&is_verified_source=1&is_clickbait=0&is_duplicate=0&source.bias=center&api_key=YOUR_API_KEY" ``` Each parameter below is one signal in that check, and each has a dedicated guide if you want the full behaviour. ## How to weight results toward trustworthy sources[#](#how-to-weight-results-toward-trustworthy-sources) The strongest single signal is source authority, measured by Open Page Rank ([OPR](/en/articles/getting-started/glossary#opr-open-pagerank)). Two shortcut filters bundle this for you: * `is_verified_source=1` keeps only sources with an OPR of **5 or higher** _and_ automatically drops duplicates — the tightest built-in quality gate. * `is_premium_source=1` is stricter still, keeping only sources with an OPR of **6 or higher**. For manual control, `source.rank.opr.min` sets your own floor — for example `source.rank.opr.min=7` for only the most authoritative outlets. Higher OPR means a more widely-linked, more established site, which correlates with editorial accountability: ``` curl "https://api.apitube.io/v1/news/everything?title=vaccine&source.rank.opr.min=6&is_duplicate=0&api_key=YOUR_API_KEY" ``` See [how to filter for high-quality, verified sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) for the difference between the three, and [what is the OPR score](/en/articles/trust-and-support/what-is-opr) for how the rank itself is built. ## How to spot clickbait and manipulative framing[#](#how-to-spot-clickbait-and-manipulative-framing) Misinformation often rides on an emotionally loaded headline that the body does not back up. Two [sentiment](/en/articles/getting-started/glossary#sentiment) signals catch that pattern. `is_clickbait=1` returns articles whose headline tone sharply disagrees with the body tone and whose headline sentiment is strong — the classic bait-and-switch — while `is_clickbait=0` filters those out of a clean feed. For a finer knob, `sentiment_gap.min` measures the raw distance between headline sentiment and body sentiment on a 0-to-2 scale; a large gap flags a headline written to provoke rather than inform: ``` curl "https://api.apitube.io/v1/news/everything?title=climate&sentiment_gap.min=0.8&api_key=YOUR_API_KEY" ``` Use `is_clickbait=1` or a high `sentiment_gap.min` when you are _hunting_ for suspect stories to review, and `is_clickbait=0` when you want them kept out of a trustworthy feed. The [detect and filter clickbait](/en/articles/searching-and-filtering/content-quality/filter-clickbait) guide covers both directions. ## How to check a source’s political lean[#](#how-to-check-a-sources-political-lean) A source’s slant is not misinformation on its own, but knowing it helps you read a story in context and balance a set of results. `source.bias` filters by the outlet’s political lean and accepts `left`, `center` and `right` (up to three, comma-separated). To read across the spectrum on one topic, pull each lean and compare how the same event is framed: ``` curl "https://api.apitube.io/v1/news/everything?title=immigration&source.bias=left,center,right&api_key=YOUR_API_KEY" ``` Balancing bias is a defence against a one-sided narrative: if only one side is reporting a claim, that itself is a signal to dig deeper. There is a matching `ignore.source.bias` to exclude a lean you do not want. ## How to verify a specific claim and trace its spread[#](#how-to-verify-a-specific-claim-and-trace-its-spread) Filters narrow the field; verification confirms a single claim. Two tools finish the job. To trace how far a story spread and reach its origin, follow the duplicates back to the first publisher — [how to find the original source of a story](/en/articles/use-cases/trust-and-research/find-original-source) walks through using the [story cluster](/en/articles/getting-started/glossary#story) to do this. To check a concrete statement against the underlying reporting, the `/v1/fact-check` endpoint extracts the claims in your text and returns a verdict for each one, plus a summary. Fact-check is a paid feature: on the free plan it returns `403` with error code `ER0706`, so it needs a paid subscription. The [fact-check a claim or article](/en/articles/use-cases/trust-and-research/fact-check-claim) guide shows the request and response in full. For the complete list of every parameter used here, the [News API parameters reference](https://docs.apitube.io/platform/news-api/everything) is the canonical source. # Common Questions[#](#common-questions) * [Can the API tell me an article is definitely fake?](#can-the-api-tell-me-an-article-is-definitely-fake) * [What is the difference between is\_verified\_source and is\_premium\_source?](#what-is-the-difference-between-is_verified_source-and-is_premium_source) * [Does source.bias support an “unbiased” value?](#does-sourcebias-support-an-unbiased-value) ## Can the API tell me an article is definitely fake?[#](#can-the-api-tell-me-an-article-is-definitely-fake) No. There is no field that classifies an article as fake or true. The API gives you measurable credibility signals — source rank (OPR), verified-source status, political bias, clickbait detection and duplicate detection — plus a `/v1/fact-check` endpoint for verifying a specific claim. You combine those into a judgement; the API supplies the evidence, not the verdict. ## What is the difference between is\_verified\_source and is\_premium\_source?[#](#what-is-the-difference-between-is_verified_source-and-is_premium_source) Both are OPR shortcuts. `is_verified_source=1` keeps sources with an OPR of 5 or higher and also removes duplicate articles in the same pass. `is_premium_source=1` is stricter, requiring an OPR of 6 or higher. Use `is_verified_source` for a broad trustworthy feed and `is_premium_source` when you want only top-tier outlets; for a custom threshold, set `source.rank.opr.min` yourself. ## Does source.bias support an “unbiased” value?[#](#does-sourcebias-support-an-unbiased-value) No. `source.bias` accepts `left`, `center` and `right` only. If you want centrist coverage, use `source.bias=center`; to exclude a particular lean, use `ignore.source.bias`. Any value outside left, center and right is ignored rather than applied, so check the spelling if a bias filter seems to have no effect. * * * ## Related Articles * [How to Filter for High-Quality, Verified Sources](/en/articles/searching-and-filtering/content-quality/filter-for-trusted-sources) * [How to Detect and Filter Clickbait](/en/articles/searching-and-filtering/content-quality/filter-clickbait) * [How to Find the Original Source of a Story](/en/articles/use-cases/trust-and-research/find-original-source) --- ## How to fact-check a claim or article URL: https://support.apitube.io/en/articles/use-cases/trust-and-research/fact-check-claim Fact-check a claim or article with the APITube News API: send a claim, text, or article id to /v1/fact-check and get an 8-level verdict, confidence and… # How to fact-check a claim or article Verify a statement, raw article text, or a stored article against APITube's live news corpus and get per-claim verdicts with evidence ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Ffact-check&claim=OpenAI) # How to fact-check a claim or article[#](#how-to-fact-check-a-claim-or-article) To fact-check a claim or article, send it to the `/v1/fact-check` endpoint with **one** of three inputs — a single `claim`, raw article `text`, or an article `id` already in the corpus. The endpoint pulls real, recent articles that match each claim, grounds its answer in them (retrieval-augmented fact-checking), and returns a verdict on an 8-level scale with a confidence score, a short explanation, and the evidence articles behind it. It never answers from a model’s memory alone. ``` curl "https://api.apitube.io/v1/fact-check?claim=OpenAI released GPT-5 in 2024" \ -H "X-API-Key: YOUR_API_KEY" ``` Both `GET` and `POST` work and take the same parameters (query string for `GET`, JSON body for `POST`). Authenticate with an `X-API-Key` header, the `api_key` query parameter, or an `Authorization: Bearer YOUR_API_KEY` header. If you don’t have a key yet, see [where to find and create your API key](/en/articles/setup-and-installation/account-and-keys/get-your-api-key). ## What does /v1/fact-check return?[#](#what-does-v1fact-check-return) The endpoint returns a `summary` plus a `claims` array. Each claim gets a `verdict` on this 8-level scale, a `confidence` value from 0 to 1, an `as_of` date (`YYYY-MM-DD`), a plain-language `explanation`, and its `evidence`: `true` · `mostly_true` · `mixed` · `misleading` · `mostly_false` · `false` · `unverified` · `outdated` `unverified` means the corpus held too little evidence to confirm or refute the claim; `outdated` means the claim was once true but newer evidence contradicts it. The `summary` rolls this up into an `overall_verdict`, an `overall_confidence`, and a `verdict_breakdown` (a count per verdict). Every item in `evidence` carries the source `article_id`, `title`, `url`, `source` domain, `source_authority`, `published_at`, a `snippet`, a `stance` (`supports`, `refutes`, or `neutral`), and a `relevance` score from 0 to 1. ## How do you check a single statement?[#](#how-do-you-check-a-single-statement) Pass one factual statement in `claim` (5–500 characters). In this mode your statement is used directly (no automatic claim extraction): ``` curl "https://api.apitube.io/v1/fact-check?claim=The Eiffel Tower is in Paris" \ -H "X-API-Key: YOUR_API_KEY" ``` A `claim` shorter than 5 or longer than 500 characters returns HTTP 400. The `claim` parameter expects a single, self-contained assertion — to check a whole paragraph or article, use `text` or `id` instead so the claims are extracted for you. ## How do you fact-check a full article or a stored one?[#](#how-do-you-fact-check-a-full-article-or-a-stored-one) For longer input use `POST` and send either `text` or `id`. With `text` (100–10000 characters, title plus body), APITube extracts the individual claims for you and checks each one. With `id` it loads that article straight from the corpus and does the same — handy when you already retrieved the article and have its numeric id from [getting a single article by ID](/en/articles/retrieval/get-article-by-id). ``` # Fact-check an article already in the corpus by its id curl -X POST "https://api.apitube.io/v1/fact-check" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": 123456789, "max_claims": 5 }' ``` If you send more than one input, priority is `id` > `text` > `claim`. Two optional caps tune the work: `max_claims` (how many claims to extract and verify — 1 to 5, and 5 is also the default) and `evidence_per_claim` (how many evidence articles to pull per claim — 1 to 20, default 5, so you can ask for more evidence than the default but not more claims). Both are clamped server-side, so a value outside the range is silently pulled back into it rather than rejected. ## How does APITube decide each verdict?[#](#how-does-apitube-decide-each-verdict) For every claim, APITube searches the live news corpus for articles whose **titles** match the claim, ranks the candidates by source authority — the same [OPR (Open Page Rank) score](/en/articles/trust-and-support/what-is-opr) exposed as `source_authority` — and then by recency, and judges the claim strictly against that evidence. Because the verdict is tied to what’s actually published, more authoritative and more recent coverage carries more weight. When no matching articles exist in the corpus, the claim comes back as `unverified` rather than a guess — a signal to widen the wording or wait for coverage to appear. ## What does fact-checking cost and who can use it?[#](#what-does-fact-checking-cost-and-who-can-use-it) Fact Check is a **paid feature** and is **not available on the Free plan** — a Free-plan key returns HTTP 403 with code `ER0706`. Each request costs **5 points**, and that charge only applies when the request returns at least one claim (see [how requests and credits work](/en/articles/billing/credits/how-credits-work)). The endpoint also has its own **[rate limit](/en/articles/getting-started/glossary#rate-limit) of 10 requests per minute**, separate from and stricter than the global API limit, because every request runs language-model inference. If you’re weighing which plan unlocks it, see [which plan is right for me](/en/articles/getting-started/which-plan-is-right). The full parameter and response reference lives in the [Fact Check documentation](https://docs.apitube.io/platform/news-api/fact-check). # Common Questions[#](#common-questions) * [Which input should I use: claim, text or id?](#which-input-should-i-use-claim-text-or-id) * [Why did I get an unverified verdict?](#why-did-i-get-an-unverified-verdict) * [Why is my fact-check request returning 403?](#why-is-my-fact-check-request-returning-403) * [How many claims does one request check?](#how-many-claims-does-one-request-check) ## Which input should I use: claim, text or id?[#](#which-input-should-i-use-claim-text-or-id) Use `claim` to verify one short statement directly, `text` to check a full article you have in hand (100–10000 characters), and `id` to check an article already in APITube’s corpus. If more than one is present, the endpoint uses `id` first, then `text`, then `claim`. All three cost the same 5 points per request. ## Why did I get an unverified verdict?[#](#why-did-i-get-an-unverified-verdict) `unverified` means APITube found no supporting or refuting articles in the news corpus for that claim. Evidence is matched against article titles, so very general, misspelled, or brand-new claims often return nothing. Rephrase the claim with the specific names, places, or dates that a headline would use, then try again. ## Why is my fact-check request returning 403?[#](#why-is-my-fact-check-request-returning-403) A 403 with code `ER0706` means the key is on the Free plan, where Fact Check is disabled — upgrade to a paid plan to enable it. A 403 can also mean the key is scoped to specific endpoints and lacks the `fact_check` permission; see [how to limit a key to specific endpoints](/en/articles/account-and-dashboard/keys/key-scopes) to add it. ## How many claims does one request check?[#](#how-many-claims-does-one-request-check) Up to 5. For `text` and `id` inputs, APITube extracts claims automatically and verifies each, bounded by `max_claims` (maximum 5). A single `claim` input is always one claim. Each verified claim gets its own verdict, confidence, explanation, and evidence list in the `claims` array. * * * ## Related Articles * [How to get a single article by ID](/en/articles/retrieval/get-article-by-id) * [What is the OPR (Open Page Rank) score?](/en/articles/trust-and-support/what-is-opr) * [How do requests and credits work?](/en/articles/billing/credits/how-credits-work) * [Which plan is right for me?](/en/articles/getting-started/which-plan-is-right) --- ## How to Find the Original Source of a Story URL: https://support.apitube.io/en/articles/use-cases/trust-and-research/find-original-source Find the original source of a news story with APITube: sort oldest-first by published_at and compare the story cluster's timestamps to see who published first. # How to Find the Original Source of a Story Trace who published first by sorting coverage chronologically and comparing published\_at across sources ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-128.jpg) Written by Beatrice Riddick July 3, 2026 Updated July 6, 2026 [Open this example in the API Playground ↗](https://dashboard.apitube.io/playground?endpoint=%2Fv1%2Fnews%2Feverything&title=OpenAI+acquisition&sort_by=published_at&sort_order=asc) # How to find the original source of a story[#](#how-to-find-the-original-source-of-a-story) The original source of a story is the article that published it first, so the fastest way to find it with the APITube News API is to sort coverage by publication time, oldest first. Run a search on the topic with `sort.by=published_at&sort.order=asc`, and the first result is the earliest article APITube indexed for that query. There is no separate “who broke it” endpoint — the earliest `published_at` timestamp is the signal you rank on. ``` curl "https://api.apitube.io/v1/news/everything?title=OpenAI%20acquisition&sort.by=published_at&sort.order=asc&api_key=YOUR_API_KEY" ``` `sort.by` defaults to `published_at` and `sort.order` defaults to `desc` (newest first), so the one part you must flip is `sort.order=asc` to put the oldest coverage on top. Each result carries a `published_at` field in ISO 8601 (for example `2026-06-20T08:00:00.000Z`) and a `source.domain`, so the top row tells you both _when_ and _which outlet_ published first. ## How to trace the original source from an article you already have[#](#how-to-trace-the-original-source-from-an-article-you-already-have) If you already hold one article and want the rest of the coverage around it, call the story endpoint with that article’s ID: `/v1/news/story/:id`. It reads the source article’s headline, keeps the meaningful keywords, and returns other articles whose titles share them — the same-story coverage across other outlets. ``` curl "https://api.apitube.io/v1/news/story/1234567?api_key=YOUR_API_KEY" ``` One thing to know: the story endpoint ranks results by **keyword overlap**, not by date, so the first row is the closest headline match, not the earliest article. To find the original among them, read the `published_at` value on each result and pick the smallest one. Every article object also exposes a `story.uri` pointing back at `/v1/news/story/{id}`, so you can pivot from any search hit straight into its cluster. See [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) for the full mechanics of that endpoint. ## How to narrow the search to the window the story broke in[#](#how-to-narrow-the-search-to-the-window-the-story-broke-in) A pure oldest-first sort can surface unrelated older articles that happen to match your keywords. Bound the search to the days around the event with `published_at.start` and `published_at.end`, then the earliest result inside that window is a much cleaner “first published” candidate: ``` curl "https://api.apitube.io/v1/news/everything?title=OpenAI%20acquisition&published_at.start=2026-06-19&published_at.end=2026-06-21&sort.by=published_at&sort.order=asc&api_key=YOUR_API_KEY" ``` Both `published_at.start` and `published_at.end` accept a date or full timestamp. You can also pass a single `published_at=2026-06-20` to limit results to that one calendar day. For the full date syntax, see [How to Filter News by Date Range](/en/articles/searching-and-filtering/by-attribute/filter-by-date-range). ## Which response fields identify the source?[#](#which-response-fields-identify-the-source) Once you have the earliest article, three fields tell you exactly where it came from: * `href` — the direct URL of the article on the publisher’s site. * `source.domain` — the publishing domain, e.g. `reuters.com`. * `source.home_page_url` — the outlet’s home page, useful for attribution. `source.type` labels the kind of outlet (for example a news site or a blog). Pair the earliest `published_at` with these fields and you have a defensible answer for who published the story first and where. To trim the payload to just what you need, add `fl=id,href,published_at,source.domain`. # Common Questions[#](#common-questions) * [Does the story endpoint return results in chronological order?](#does-the-story-endpoint-return-results-in-chronological-order) * [How many articles can one request return?](#how-many-articles-can-one-request-return) * [Why is the article content shortened?](#why-is-the-article-content-shortened) * [What does an original-source lookup cost?](#what-does-an-original-source-lookup-cost) ## Does the story endpoint return results in chronological order?[#](#does-the-story-endpoint-return-results-in-chronological-order) No. `/v1/news/story/:id` ranks its results by how many headline keywords overlap with the source article, so the top result is the closest match, not the earliest article. To order the same-story coverage by time, either compare the `published_at` field across the returned results yourself, or run a normal `/v1/news/everything` search with `sort.by=published_at&sort.order=asc`. Both approaches use the same publication timestamp; only the search route sorts by it for you. ## How many articles can one request return?[#](#how-many-articles-can-one-request-return) `per_page` defaults to **100** and accepts up to **250** — **50** on Starter, **10** on Free; a larger value returns `ER0171` (HTTP 400). Walk through additional pages with `page`. For tracing an original source you rarely need more than the first page of an oldest-first sort, but a wide date window may need paging to reach the earliest match. ## Why is the article content shortened?[#](#why-is-the-article-content-shortened) Only the article **body** is masked on **Free-plan keys and on [test keys](/en/articles/getting-started/glossary#test-key-and-live-key)** (those starting with `api_test_`), which append an upgrade marker (`...[Upgrade subscription plan]`) to `body` and `body_html`. The fields you need for source tracing — `href`, `source.domain`, `source.home_page_url` and `published_at` — are returned in full on every plan, so this workflow works on a free key; a paid live key adds the full article text. ## What does an original-source lookup cost?[#](#what-does-an-original-source-lookup-cost) A `/v1/news/everything` search and a `/v1/news/story/:id` call each cost **1 credit**, and a story call only charges you when it returns at least one related article. The story endpoint can return `ER0235` (HTTP 404) if the ID matches no article, or `ER0240` (HTTP 404) if the source headline has no usable keywords to build a story from. The canonical list of every parameter used here lives in the official [parameters reference](https://docs.apitube.io/platform/news-api/everything). * * * ## Related Articles * [How to Get All Articles Covering the Same Story](/en/articles/retrieval/get-story-cluster) * [How to Sort News by Relevance, Date or Quality](/en/articles/searching-and-filtering/sorting-and-shaping/sort-modes) --- ## Trust, Misinformation & Research URL: https://support.apitube.io/en/articles/use-cases/trust-and-research Verify claims, trace the original source of a story and study coverage with the APITube News API using story clusters, chronological sorting and date filters. # Trust, Misinformation & Research Verify claims and trace a story's source. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) By Beatrice 1 author 4 articles * [How Data Scientists and Researchers Use APITube](/en/articles/use-cases/trust-and-research/data-science-research) * [How to fact-check a claim or article](/en/articles/use-cases/trust-and-research/fact-check-claim) * [How to Find the Original Source of a Story](/en/articles/use-cases/trust-and-research/find-original-source) * [How to Identify Fake News and Misinformation](/en/articles/use-cases/trust-and-research/detect-fake-news) --- ## Guides and answers for the APITube News API. URL: https://support.apitube.io/en Guides and answers for the APITube News API. [ ![](/images/collections/get-started.svg) ## Getting Started What the API does and your first search. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) 3 authors 12 articles ](/en/articles/getting-started)[ ![](/images/collections/company-settings.png) ## Setup & Installation Get your key and connect SDKs, no-code and AI. ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) 3 authors 19 articles ](/en/articles/setup-and-installation)[ ![](/images/collections/analysis-tools.png) ## Searching & Filtering News Search and filter news by keyword and more. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) 3 authors 43 articles ](/en/articles/searching-and-filtering)[ ![](/images/collections/insights-dashboard.svg) ## News Endpoints & Retrieval Headlines, local news, clusters and trends. ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) 2 authors 10 articles ](/en/articles/retrieval)[ ![](/images/collections/reports.png) ## News Data & Content What's inside each article and how it's structured. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) 1 author 11 articles ](/en/articles/news-data)[ ![](/images/collections/consolidate-benchmark.png) ## Real-time Delivery & Export Real-time streaming, webhooks and export formats. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) 2 authors 14 articles ](/en/articles/delivery-and-export)[ ![](/images/collections/forecast.png) ## Use Cases & Solutions Ready-made scenarios for real tasks. ![Tasha Tatum](/images/authors/tasha-tatum-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) 5 authors 30 articles ](/en/articles/use-cases)[ ![](/images/collections/account-billing.svg) ## Account & Dashboard Keys, usage logs, profile and preferences. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Jacob Partington](/images/authors/jacob-partington-apitube-io-64.jpg) 3 authors 19 articles ](/en/articles/account-and-dashboard)[ ![](/images/collections/account-billing.svg) ## Plans, Billing & Credits Plans, credits, quota and payments. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) 2 authors 15 articles ](/en/articles/billing)[ ![](/images/collections/user-management-security.png) ## Teams & Workspaces Workspaces, roles and shared billing. ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) 2 authors 8 articles ](/en/articles/teams-and-workspaces)[ ![](/images/collections/account-billing.svg) ## Referrals & Rewards Invite friends and earn account credit. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Brian Hollis](/images/authors/brian-hollis-apitube-io-64.jpg) 2 authors 4 articles ](/en/articles/referrals)[ ![](/images/collections/faqs.png) ## Troubleshooting & Errors Fix common errors and failed requests. ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) 2 authors 11 articles ](/en/articles/troubleshooting)[ ![](/images/collections/user-management-security.png) ## Trust, Coverage & Support Source authority, coverage and support. ![Beatrice Riddick](/images/authors/beatrice-riddick-apitube-io-64.jpg) ![Erick Horn](/images/authors/erick-horn-apitube-io-64.jpg) ![Kent Hudson](/images/authors/kent-hudson-apitube-io-64.jpg) 3 authors 7 articles ](/en/articles/trust-and-support) ## What's new [Full changelog](https://docs.apitube.io/platform/changelog) * 1.0.54 September 11, 2026 Dataset exports — bulk export of articles to a file, straight from the dashboard (Datasets in the sidebar) * 1.0.53 September 1, 2026 Pay-as-you-go now needs your explicit consent — a balance switch in the dashboard decides whether prepaid money can pay for requests * 1.0.52 August 15, 2026 Add the prompt parameter — describe the news you want in plain language and the API builds the filters for you, inside the same request