Natural Language Search
The prompt parameter lets you describe the news you want in ordinary words instead of assembling filters by hand. The News API translates that sentence into its regular parameters, runs the search, and returns the exact parameters it used in meta.prompt.
promptis a premium feature — available on Basic and above. On the Free and Starter plans it returns403 ER0706. Each translation costs 2 points on a cache miss.
curl "https://api.apitube.io/v1/news/everything?prompt=Tesla%20and%20Elon%20Musk%20news%20in%20English%20for%20the%20last%2010%20days&api_key=YOUR_API_KEY"That single request produces the same result as writing the filters yourself:
person.name=Elon Musk
organization.name=Tesla
language.code=en
published_at.start=NOW-10DAYThe parameter reference for prompt lives on the Parameters page. This page explains how the translation behaves, how to read its output, and where it stops.
How it differs from the MCP server and Ask News
APITube has three ways to ask for news in plain language, and they live in different places:
| Surface | Where the language is interpreted | What you get back |
|---|---|---|
prompt parameter | Inside the API, before the search runs | The normal JSON response, plus meta.prompt |
| MCP Server | In the AI assistant, which then calls the API with filters | Whatever your assistant does with the articles |
| Ask News (dashboard) | In the chat interface, which calls the API for you | A written answer with sources |
If you are writing code, prompt is the one you want: one HTTP call, no assistant in the loop, no extra dependency, and a machine-readable record of how the sentence was understood.
What the translation can produce
The translation only emits parameters that already exist in the API. It cannot invent a filter, and it cannot invent an identifier.
Text search. Wording that no structured field covers becomes a headline search: up to 3 terms in title, 100 characters in total. An exact wording you put in quotes stays a quoted phrase. There is no full-text search over article bodies, so a prompt cannot search inside the text of an article.
Entities. People become person.name, places location.name, companies and organizations organization.name, product brands brand.name, named events event.name, diseases disease.name, natural disasters disaster.name, sports sport.name. Up to 3 values each.
Taxonomy. Broad sections become category.id, but only from the 17 top-level IPTC categories — politics and government, economy, business and finance, sport, health and so on. This is deliberate: a free search over category names would silently turn "technology" into "nanotechnology". Narrower subjects go to topic.id and industry.id instead.
Sources and people who write them. Publisher domains become source.domain, journalists author.name.
Language and geography. Article language becomes language.code, publisher country source.country.code.
Time. Periods become published_at.start and published_at.end, always written as date math — "the last 10 days" is stored as NOW-10DAY, not as a calendar date. The expression is resolved at request time, so the same interpretation stays correct tomorrow.
Everything else. Tone becomes sentiment.overall.polarity, ordering becomes sort.by and sort.order, an article count becomes per_page, and the boolean qualities become is_breaking, has_image, has_video, is_paywall and is_long_read (1 to require, 0 to exclude).
How names become identifiers
The language model returns names, never IDs. Identifiers are looked up afterwards against APITube's own reference books, which is why a prompt cannot produce a category or entity that does not exist.
Entity names are matched exactly, ignoring case. A near match is not accepted on purpose: the entity book has no generic "Earthquake", it has dozens of specific ones like "2013 Aceh earthquake", and picking one of those would quietly replace a broad question with a single 2013 event.
When an entity name cannot be resolved, the request is not rejected. The name is searched in the headline instead, and the attempted filter is reported in meta.prompt.ignored with reason: not_found. Non-entity values that fail to resolve — an unknown domain, an unknown topic — are simply dropped and reported the same way. An empty result set is bad; a 400 where articles were expected is worse.
Topics and industries are matched by name, preferring an exact match and otherwise the shortest matching name, which is the broadest one available.
Reading meta.prompt
Every JSON response to a request that used prompt carries the interpretation:
{
"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
}
}
}| Field | Meaning |
|---|---|
text | Your prompt, trimmed, exactly as it was parsed. |
applied | The parameters that were added to the request. This is the request that actually ran. |
ignored | Values that were understood but not used, each with a field, a value and a reason. |
cached | true when this wording had already been parsed, meaning no parse fee was charged. |
Which language model performs the translation is an implementation detail and is not part of the response — it can change without notice, and nothing in your integration should depend on it.
Why a value was ignored
reason | What happened | What to do |
|---|---|---|
not_found | The name is not in the reference book. Entity names fall back to a headline keyword. | Look the real name up with Suggest and pass the ID yourself. |
explicit_param | You sent that parameter yourself; your value was kept. | Nothing — this is the intended precedence. |
unsupported_on_endpoint | The endpoint does not accept that filter. | Move the request to /v1/news/everything. |
invalid_date | The period could not be read as a date or as date math. | Pass published_at.start / published_at.end yourself. |
title_too_long | The term did not fit the 100-character title budget and was dropped whole rather than cut. | Shorten the prompt. |
title_window_clamped | The prompt produced a headline search plus a range wider than 31 days, so published_at.start was moved to the 31-day limit. | Expected — see Search window limit. |
Combining a prompt with ordinary parameters
A parameter you send explicitly always beats the same parameter derived from the prompt. This makes the two safe to mix: pin what must be exact, let the prompt handle the rest.
# The prompt asks for English, but language.code=de wins
curl "https://api.apitube.io/v1/news/everything?prompt=Tesla%20news%20in%20English&language.code=de&api_key=YOUR_API_KEY"The overridden value shows up as {"field": "language.code", "value": "en", "reason": "explicit_param"}.
Everything the prompt produced is an ordinary parameter afterwards, so sorting, pagination, field selection, faceting and the export formats all work exactly as they do on a hand-written request.
Endpoint behaviour
| Endpoint | Behaviour |
|---|---|
/v1/news/everything, /v1/news/top-headlines, /v1/news/local, /v1/news/count, /v1/news/trends | Full support, meta.prompt in the response. |
/v1/news/category, /v1/news/topic, /v1/news/industry, /v1/news/entity | Full support. The path already fixes one dimension; the prompt fills in the rest. |
/v1/news/raw | Accepted, but this endpoint only understands published_at.start, published_at.end, sort.order and per_page. Everything else is reported with reason: unsupported_on_endpoint. |
/v1/news/stream | The prompt is validated and its filters are applied to the stream, but SSE has no JSON envelope, so there is no meta.prompt to read. |
/v1/news/ws | Supported. The expanded filters come back in the subscribed acknowledgement frame. |
/v1/news/article, /v1/news/story, /v1/fact-check, /v1/suggest/* | prompt is ignored entirely. No translation runs and nothing is charged. |
prompt works both as a query-string parameter and inside a POST body, on every endpoint above.
Cost, caching and quota
A translation costs 2 points on top of the endpoint's own cost — but only on a cache miss. Interpretations are cached for 24 hours against the normalized wording (leading and trailing spaces removed, case folded, repeated spaces collapsed), so Tesla NEWS and tesla news are the same cached entry and the second one is free. meta.prompt.cached tells you which of the two happened.
Caching is safe because what gets cached is the intent, not a resolved query: relative periods stay NOW-10DAY, and names are resolved against the live reference books on every request.
Your quota is checked before the language model is called, so an exhausted account gets 402 ER0176 (or 402 ER0177 on a pay-as-you-go cap) without being charged for a translation it never received. A failure inside the translation service is free too.
Plan availability
prompt is available on Basic and above. On Free and Starter the request fails with 403 ER0706 before the translation runs, so nothing is charged. Every other way of searching — the regular filters, the boolean query language, all endpoints — works on every plan.
| Plan | prompt |
|---|---|
| Free | No — 403 ER0706 |
| Starter | No — 403 ER0706 |
| Basic | Yes |
| Professional | Yes |
| Corporate | Yes |
Errors
| Code | HTTP | When |
|---|---|---|
ER0706 | 403 | The plan does not include prompt (Free and Starter). Nothing is charged. |
ER0800 | 400 | The prompt is shorter than 3 or longer than 500 characters. |
ER0801 | 502 | The translation service is unavailable. Nothing is charged; retry. |
ER0802 | 400 | Nothing usable came out of the prompt — either no filter was found in it, or everything it produced was overridden or unsupported. |
There is no silent fallback: if the prompt cannot be translated, the request fails instead of returning an unfiltered result set you might mistake for an answer.
On /v1/news/ws these arrive as an error frame followed by close code 4001. Full list: Prompt Errors.
Writing prompts that work
- Name things the way an encyclopedia would. "Elon Musk" resolves; "the Tesla guy" becomes a headline keyword.
- Ask for one intent per request. The translation keeps at most 3 values per field, so a prompt listing eight companies loses five of them.
- Say the period out loud. "In the last two weeks", "since the start of the month" — these become date math. A prompt without a period searches without a date filter, unless it also triggers a headline search, which is capped at 31 days.
- Check
meta.prompt.appliedthe first time. It is the fastest way to see whether the sentence was read the way you meant it. - Pin what must be exact. If the language or the source must not drift, pass
language.codeorsource.domainyourself and let the prompt handle the topic.
Next steps
- Parameter reference:
prompt - Resolve a name to an ID by hand: Suggest
- Let an assistant drive the API instead: MCP Server