HTTP Response Codes
The APITube News API uses conventional HTTP response codes to indicate the success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error due to the information provided by the client, and codes in the 5xx range indicate an error on the server side.
| HTTP Response Code | Status | Description |
|---|---|---|
200 | ok | Everything worked as expected. |
400 | not_ok | API request is malformed or contains invalid parameters. |
401 | not_ok | API key is invalid or missing. |
402 | not_ok | You have no points on your account. |
403 | not_ok | Access denied: IP address is not in the allowed list. |
404 | not_ok | Entry not found. |
429 | not_ok | The emergence of this error code indicates surpassing the rate limit allocated for your plan. You must wait for the rate limit to reset before initiating additional requests. |
500 | not_ok | The appearance of this error code signifies an unforeseen server error. Typically, this is a transient problem, so it's advisable to attempt your request again at a later time. |
502 | not_ok | An upstream service is temporarily unavailable. This is usually transient, so retry your request shortly. |
API Error Codes
This section lists all error codes returned by the API. Each error includes a unique code identifier (ER####), HTTP status code, and description.
Authentication & Authorization Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0175 | 401 | API key is invalid or missing. Not returned in practice — the global auth hook answers first with 401 ER0201 (no key) or 401 ER0202 (bad key). |
ER0176 | 402 | You have no points on your account. |
ER0177 | 402 | Monthly pay-as-you-go spending limit reached. |
ER0200 | 400 | API key is required. Not returned in practice — the global auth hook answers first with 401 ER0201, so a request without a key never reaches the controllers that raise this code. |
ER0201 | 401 | API key is required. Provide it via X-API-Key header or api_key query parameter. |
ER0202 | 401 | API key is invalid. |
ER0230 | 401 | API key has expired. |
The same ER0176 code (always 402) is reused by the SSE stream with a different message — "You have no SSE points on your account." REST requests and streaming draw from separate credit pools, so the message tells you which balance is empty (regular points vs SSE points).
API Key Restriction Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0601 | 403 | Access denied: your IP address is not allowed for this API key. |
ER0602 | 403 | Access denied: your domain is not allowed for this API key. |
ER0603 | 403 | Access denied: this API key is not authorized for this endpoint. Required scope: {scope}. |
Rate Limiting Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0203 | 429 | Rate limit exceeded. You can make X requests per minute. Try again in Y. |
ER0204 | 429 | You have been temporarily banned for exceeding rate limits. Try again in Y. |
ER0184 | 429 | Too many concurrent requests for your account. Please retry shortly. |
ER0184 is a different ceiling from ER0203: it limits how many queries your account may run at the same moment (Free 1, Starter 2, Basic 2, Professional 3, Corporate 4), not how many you send per minute. Requests over the limit wait in a short queue first, so you only see ER0184 when that queue is full or a queued request timed out. The response carries a Retry-After header — retry after it, and lower the number of parallel calls rather than the request rate. Streaming endpoints (/v1/news/stream, /v1/news/ws) are exempt from this limit.
Repeatedly exceeding the per-minute rate limit (30 violations) results in a temporary ban returned as 429 ER0204. Note that the same ER0204 code is also used with HTTP status 400 by the author filter ("Author with name not found."). Always branch on the HTTP status alongside the error code: 429 means a rate-limit ban, 400 means the author lookup failed.
General Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0179 | 400 | Parameter must be sent once, not repeated. |
ER0182 | 404 | Requested endpoint not found. Please check the URL and try again. |
ER0183 | 500 | Something went wrong. |
ER0180 | 504 | Query timed out. Narrow the filters or the published_at range and try again. |
ER0179 is returned when the same query parameter appears more than once in the URL, for example ?title=bitcoin&title=tesla. Send each parameter a single time. To match several values, use the boolean query parameter — ?query=title:(bitcoin OR tesla).
Article Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0001 | 400 | Invalid article.id value. |
ER0002 | 400 | article.id must be between 1 and 20 characters. |
ER0231 | 400 | Article ID is required. (story endpoint) |
ER0232 | 400 | Article ID is required. (article endpoint) |
ER0234 | 400 | Invalid article id — article ids are integers. (/v1/news/article, /v1/news/story/{id}) |
ER0235 | 404 | Article not found. |
ER0240 | 404 | No keywords found in article title. |
Duplicate Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0003 | 400 | Invalid is_duplicate value. |
ER0004 | 400 | is_duplicate must be 0 or 1. |
Paywall Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0005 | 400 | Invalid is_paywall value. |
ER0006 | 400 | is_paywall must be 0 or 1. |
Title Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0007 | 400 | title must be between 2 and 100 characters. |
ER0008 | 400 | ignore.title must be between 2 and 100 characters. |
ER0009 | 400 | title_starts_with must be between 2 and 100 characters. |
ER0010 | 400 | title_ends_with must be between 2 and 100 characters. |
ER0011 | 400 | title_pattern must be between 2 and 200 characters. |
ER0340 | 400 | Phrase in quotes must be between 3 and 200 characters (2 for CJK). |
ER0341 | 400 | Slop value must be between 0 and 10. |
ER0349 | 400 | Too many title terms that cannot use the token index. |
ER0351 | 400 | Unclosed quote in title. Every opening quote needs a closing one. |
Most title terms are matched against a token index, which requires whole words separated by spaces or punctuation. Three kinds of terms cannot use it and are matched as substrings instead: terms containing a separator (eur/usd, AT&T, S&P), single characters, and CJK text (Chinese, Japanese, Korean — written without spaces between words). Substring matching is slower and also matches inside longer words, so a single request may use at most 8 such terms; beyond that the request is rejected with ER0349.
When a request does use substring matching, the response carries an ER0367 warning in meta.warnings listing the affected terms.
Media Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0012 | 400 | Invalid media.images.count value. |
ER0013 | 400 | media.images.count must be greater than or equal to 0. |
ER0014 | 400 | media.images.count must be between 1 and 10 characters. |
ER0015 | 400 | Invalid media.images.count.min value. |
ER0016 | 400 | media.images.count.min must be greater than or equal to 0. |
ER0017 | 400 | media.images.count.min must be between 1 and 10 characters. |
ER0018 | 400 | Invalid media.images.count.max value. |
ER0019 | 400 | media.images.count.max must be greater than or equal to 0. |
ER0020 | 400 | media.images.count.max must be between 1 and 10 characters. |
ER0021 | 400 | Invalid media.images.width.min value. |
ER0022 | 400 | media.images.width.min must be greater than or equal to 0. |
ER0023 | 400 | media.images.width.min must be between 1 and 10 characters. |
ER0024 | 400 | Invalid media.images.width.max value. |
ER0025 | 400 | media.images.width.max must be greater than or equal to 0. |
ER0026 | 400 | media.images.width.max must be between 1 and 10 characters. |
ER0027 | 400 | Invalid media.images.height.min value. |
ER0028 | 400 | media.images.height.min must be greater than or equal to 0. |
ER0029 | 400 | media.images.height.min must be between 1 and 10 characters. |
ER0030 | 400 | Invalid media.images.height.max value. |
ER0031 | 400 | media.images.height.max must be greater than or equal to 0. |
ER0032 | 400 | media.images.height.max must be between 1 and 10 characters. |
ER0033 | 400 | Invalid media.videos.count value. |
ER0034 | 400 | media.videos.count must be greater than or equal to 0. |
ER0035 | 400 | media.videos.count must be between 1 and 10 characters. |
ER0036 | 400 | Invalid media.videos.count.min value. |
ER0037 | 400 | media.videos.count.min must be between 1 and 10 characters. |
ER0038 | 400 | Invalid media.videos.count.max value. |
ER0039 | 400 | media.videos.count.max must be greater than or equal to 0. |
ER0040 | 400 | media.videos.count.max must be between 1 and 10 characters. |
ER0041 | 400 | has_image must be 0 or 1. |
ER0042 | 400 | has_video must be 0 or 1. |
ER0043 | 400 | has_hq_images must be 0 or 1. |
ER0233 | 400 | is_media_rich must be 0 or 1. |
ER0245 | 400 | media.videos.count.min must be greater than or equal to 0. |
ER0250 | 400 | is_landscape_media must be 0 or 1. |
ER0251 | 400 | is_portrait_media must be 0 or 1. |
ER0252 | 400 | has_multiple_images must be 0 or 1. |
ER0253 | 400 | has_fullhd_images must be 0 or 1. |
ER0254 | 400 | has_4k_images must be 0 or 1. |
ER0255 | 400 | has_mobile_optimized_images must be 0 or 1. |
ER0256 | 400 | is_instagram_ready must be 0 or 1. |
ER0257 | 400 | is_twitter_card_ready must be 0 or 1. |
ER0258 | 400 | has_consistent_image_sizes must be 0 or 1. |
ER0259 | 400 | has_thumbnail must be 0 or 1. |
ER0260 | 400 | has_social_share_image must be 0 or 1. |
ER0261 | 400 | has_mixed_media must be 0 or 1. |
Source Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0044 | 400 | Invalid source.rank.opr.min value. |
ER0045 | 400 | source.rank.opr.min must be greater than or equal to 0. |
ER0046 | 400 | source.rank.opr.min must be between 1 and 10 characters. |
ER0047 | 400 | Invalid source.rank.opr.max value. |
ER0048 | 400 | source.rank.opr.max must be greater than or equal to 0. |
ER0049 | 400 | source.rank.opr.max must be between 1 and 10 characters. |
ER0050 | 400 | Invalid source.id value. |
ER0051 | 400 | source.id must be greater than or equal to 0. |
ER0052 | 400 | source.id must be between 1 and 20 characters. |
ER0053 | 400 | Invalid ignore.source.id value. |
ER0054 | 400 | ignore.source.id must be greater than or equal to 0. |
ER0055 | 400 | ignore.source.id must be between 1 and 20 characters. |
ER0057 | 400 | source.domain must be between 1 and 255 characters. |
ER0059 | 400 | ignore.source.domain must be between 1 and 255 characters. |
ER0195 | 400 | is_premium_source must be 0 or 1. |
ER0196 | 400 | is_verified_source must be 0 or 1. |
ER0212 | 400 | Source country code not found. |
ER0213 | 400 | Source country code not found. (ignore filter) |
ER0214 | 400 | Source domain name not found. |
ER0215 | 400 | Source domain name not found. (ignore filter) |
ER0246 | 400 | source.country.code must be 2 characters. |
ER0247 | 400 | ignore.source.country.code must be 2 characters. |
Language Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0061 | 400 | language.code must be between 1 and 2 characters. |
ER0063 | 400 | ignore.language.code must be between 1 and 2 characters. |
ER0237 | 400 | Language with code not found. |
ER0239 | 400 | Language with code not found. (ignore filter) |
Author Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0064 | 400 | Invalid author.id value. |
ER0066 | 400 | author.id must be between 1 and 20 characters. |
ER0067 | 400 | Invalid ignore.author.id value. |
ER0069 | 400 | ignore.author.id must be between 1 and 20 characters. |
ER0070 | 400 | has_author must be 0 or 1. |
ER0071 | 400 | author.name must be between 1 and 100 characters. |
ER0073 | 400 | ignore.author.name must be between 1 and 100 characters. |
ER0204 | 400 | Author with name not found. |
ER0205 | 400 | Author with name not found. (ignore filter) |
Sentiment Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0074 | 400 | Invalid sentiment.title.score.min value. |
ER0075 | 400 | sentiment.title.score.min must be between -1 and 1. |
ER0076 | 400 | sentiment.title.score.min must be between 1 and 10 characters. |
ER0077 | 400 | Invalid sentiment.title.score.max value. |
ER0078 | 400 | sentiment.title.score.max must be between -1 and 1. |
ER0079 | 400 | sentiment.title.score.max must be between 1 and 10 characters. |
ER0080 | 400 | Invalid sentiment.title.score value. |
ER0081 | 400 | sentiment.title.score must be between -1 and 1. |
ER0082 | 400 | sentiment.title.score must be between 1 and 10 characters. |
ER0083 | 400 | sentiment.title.polarity must be between 1 and 10 characters. |
ER0084 | 400 | Invalid sentiment.body.score.min value. |
ER0085 | 400 | sentiment.body.score.min must be between -1 and 1. |
ER0086 | 400 | sentiment.body.score.min must be between 1 and 10 characters. |
ER0087 | 400 | Invalid sentiment.body.score.max value. |
ER0088 | 400 | sentiment.body.score.max must be between -1 and 1. |
ER0089 | 400 | sentiment.body.score.max must be between 1 and 10 characters. |
ER0090 | 400 | Invalid sentiment.body.score value. |
ER0091 | 400 | sentiment.body.score must be between -1 and 1. |
ER0092 | 400 | sentiment.body.score must be between 1 and 10 characters. |
ER0093 | 400 | sentiment.body.polarity must be between 1 and 10 characters. |
ER0094 | 400 | Invalid sentiment.overall.score.min value. |
ER0095 | 400 | sentiment.overall.score.min must be between -1 and 1. |
ER0096 | 400 | sentiment.overall.score.min must be between 1 and 10 characters. |
ER0097 | 400 | Invalid sentiment.overall.score.max value. |
ER0098 | 400 | sentiment.overall.score.max must be between -1 and 1. |
ER0099 | 400 | sentiment.overall.score.max must be between 1 and 10 characters. |
ER0100 | 400 | Invalid sentiment.overall.score value. |
ER0101 | 400 | sentiment.overall.score must be between -1 and 1. |
ER0102 | 400 | sentiment.overall.score must be between 1 and 10 characters. |
ER0103 | 400 | sentiment.overall.polarity must be between 1 and 10 characters. |
ER0243 | 400 | sentiment.mixed must be 0 or 1. |
ER0244 | 400 | sentiment.consistent must be 0 or 1. |
ER0249 | 400 | sentiment_gap.max must be between 0 and 2. |
ER0342 | 400 | is_clickbait must be 0 or 1. |
ER0343 | 400 | Invalid sentiment_gap.min value. |
ER0344 | 400 | sentiment_gap.min must be between 0 and 2. |
ER0345 | 400 | Invalid sentiment_gap.max value. |
Published Date Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0104 | 400 | Invalid published_at.start value. |
ER0105 | 400 | published_at.start must be between 1 and 30 characters. |
ER0106 | 400 | Invalid published_at.end value. |
ER0107 | 400 | published_at.end must be between 1 and 30 characters. |
ER0108 | 400 | published_at must be between 1 and 30 characters. |
ER0109 | 400 | Invalid published_at value. |
ER0110 | 400 | Date range exceeds the maximum of 31 days for title search. |
ER0371 | 400 | published_at.start must be before published_at.end. Not reachable — belongs to the disabled /v1/sources/{id}/stats endpoint. |
ER0110 only applies when the request also searches article titles — that is, when it uses title, title_starts_with, title_ends_with, title_pattern or query. A title search may not span more than 31 days of published_at. Split a longer period into month-sized windows and page through each one.
ER0366 is a warning, not an error: the request succeeds with HTTP 200. It appears when a title search arrives without published_at.start and published_at.end, and the last 31 days are searched by default. The warning is returned in meta.warnings alongside the results, and the same information is available in the x-query-window-clamped response header (useful for export formats, which 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. Pass published_at.start / published_at.end to pick a different 31-day window.",
"links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" }
}
]
}
}ER0367 is also a warning, returned in the same meta.warnings array with HTTP 200. It appears when one or more title terms cannot use the token index and are matched as substrings instead — see ER0349 for which terms those are. Substring matching also matches inside longer words, so title=C++ will match a headline containing C++17. Quote the term (title="C++") if you want it treated as an exact phrase.
ER0368 is a warning too, and it names parameters the endpoint does not accept. Unknown parameters are ignored rather than rejected — a request with a typo (langauge.code=en) or a name that does not exist (entity.name, product.name) still returns 200, but the filter you meant was never applied and the result set is wider than you expect. The warning lists exactly which names were dropped:
{
"meta": {
"warnings": [
{
"code": "ER0368",
"message": "Unknown parameter(s) ignored: entity.name, langauge.code. They did not affect the result — check the spelling against the endpoint reference."
}
]
}
}The check runs against the endpoint's own parameter list, so a parameter that is valid elsewhere but not here (sort.by on /v1/news/count, hl on /v1/news/raw) is reported as well. /v1/news/stream and /v1/news/ws are not covered.
Category Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0112 | 400 | category.id must be between 1 and 40 characters. |
ER0115 | 400 | ignore.category.id must be between 1 and 40 characters. |
ER0206 | 400 | Category with ID not found. |
ER0207 | 400 | Category with ID not found. (ignore filter) |
ER0241 | 404 | Category not found. |
ER0242 | 404 | Category not found. |
Topic Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0117 | 400 | topic.id must be between 1 and 80 characters. |
ER0120 | 400 | ignore.topic.id must be between 1 and 80 characters. |
ER0149 | 404 | Topic not found. |
ER0208 | 400 | Topic with ID not found. |
ER0209 | 400 | Topic with ID not found. (ignore filter) |
Industry Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0121 | 400 | Invalid industry.id value. |
ER0123 | 400 | industry.id must be between 1 and 20 characters. |
ER0124 | 400 | Invalid ignore.industry.id value. |
ER0126 | 400 | ignore.industry.id must be between 1 and 20 characters. |
ER0150 | 404 | Industry not found. |
ER0210 | 400 | Industry with ID not found. |
ER0211 | 400 | Industry with ID not found. (ignore filter) |
Entity Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0127 | 400 | Invalid entity.id value. |
ER0128 | 400 | entity.id must be between 1 and 30 characters. |
ER0129 | 400 | Invalid ignore.entity.id value. |
ER0130 | 400 | ignore.entity.id must be between 1 and 120 characters. |
ER0132 | 400 | person.name must be between 1 and 120 characters. |
ER0134 | 400 | ignore.person.name must be between 1 and 120 characters. |
ER0136 | 400 | location.name must be between 1 and 120 characters. |
ER0138 | 400 | ignore.location.name must be between 1 and 120 characters. |
ER0140 | 400 | organization.name must be between 1 and 120 characters. |
ER0142 | 400 | ignore.organization.name must be between 1 and 120 characters. |
ER0144 | 400 | brand.name must be between 1 and 120 characters. |
ER0146 | 400 | ignore.brand.name must be between 1 and 120 characters. |
ER0148 | 400 | disaster.name must be between 1 and 120 characters. |
ER0151 | 404 | Entity not found. |
ER0152 | 400 | disease.name must be between 1 and 120 characters. |
ER0154 | 400 | ignore.disease.name must be between 1 and 120 characters. |
ER0156 | 400 | event.name must be between 1 and 120 characters. |
ER0158 | 400 | ignore.event.name must be between 1 and 120 characters. |
ER0160 | 400 | sport.name must be between 1 and 120 characters. |
ER0162 | 400 | ignore.sport.name must be between 1 and 120 characters. |
ER0216 | 400 | Entity person name not found. |
ER0217 | 400 | Entity person name not found. (ignore filter) |
ER0218 | 400 | Entity location name not found. |
ER0219 | 400 | Entity location name not found. (ignore filter) |
ER0220 | 400 | Entity organization name not found. |
ER0221 | 400 | Entity organization name not found. (ignore filter) |
ER0222 | 400 | Entity brand name not found. |
ER0223 | 400 | Entity brand name not found. (ignore filter) |
ER0224 | 400 | Entity disaster name not found. |
ER0225 | 400 | Entity disaster name not found. (ignore filter) |
ER0226 | 400 | Entity disease name not found. |
ER0227 | 400 | Entity disease name not found. (ignore filter) |
ER0228 | 400 | Entity event name not found. |
ER0229 | 400 | Entity event name not found. (ignore filter) |
ER0248 | 400 | ignore.disaster.name must be between 1 and 120 characters. |
ER0290 | 400 | entity.sentiment.polarity must be positive, negative or neutral. |
ER0291 | 400 | entity.sentiment.score.min must be a number between -1 and 1. |
ER0292 | 400 | entity.sentiment.score.max must be a number between -1 and 1. |
ER0293 | 400 | entity.sentiment.* requires an entity selector: entity.id, person.name, organization.name, location.name, brand.name, event.name, disease.name, disaster.name or sport.name. |
ER0294 | 400 | source.bias must be one of: left, center, right. |
ER0295 | 400 | ignore.source.bias must be one of: left, center, right. |
ER0296 | 400 | sentiment.title.polarity must be positive, negative or neutral. |
ER0297 | 400 | sentiment.body.polarity must be positive, negative or neutral. |
ER0298 | 400 | sentiment.overall.polarity must be positive, negative or neutral. |
ER0299 | 400 | per_page must be at least 1. |
ER0307 | 400 | percentile must be an integer between 1 and 100. |
ER0308 | 400 | time_bucket must be one of: hour, day, week, month. |
ER0309 | 400 | sort.by must be one of the documented sort fields. |
ER0314 | 400 | sort.order must be asc or desc. |
The per-entity sentiment filters describe how an article feels about a particular entity, so they only work next to a selector that names that entity. On their own they would have to scan every entity mention ever indexed, which is why the API rejects them with ER0293 instead of running the query.
Breaking News Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0185 | 400 | Invalid is_breaking value. |
ER0186 | 400 | is_breaking must be 0 or 1. |
Read Time Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0187 | 400 | Invalid read_time value. |
ER0188 | 400 | read_time must be between 0 and 1000 minutes. |
ER0189 | 400 | Invalid read_time.min value. |
ER0190 | 400 | read_time.min must be between 0 and 1000 minutes. |
ER0191 | 400 | Invalid read_time.max value. |
ER0192 | 400 | read_time.max must be between 0 and 1000 minutes. |
ER0193 | 400 | is_long_read must be 0 or 1. |
ER0194 | 400 | is_short_read must be 0 or 1. |
ER0302 | 400 | is_deep_dive must be 0 or 1. |
ER0347 | 400 | is_quick_read must be 0 or 1. |
ER0348 | 400 | is_medium_read must be 0 or 1. |
The same ER0302 code (also 400) is reused by the webhooks endpoints with a different message — "Invalid or disallowed webhook URL." Both are 400; distinguish them by which endpoint you called and by the message text.
Pagination Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0170 | 400 | 'Per page' is not a number. |
ER0171 | 400 | Limit is out of range. Your plan allows up to N results per page. (per_page must be 250 or less; 50 on Starter, 10 on Free) |
ER0172 | 400 | Page is not a number. |
ER0173 | 400 | Free plan is limited to the first 5 pages. Upgrade your subscription plan to paginate further. |
Readability Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0262 | 400 | Invalid readability.fk_grade value. |
ER0263 | 400 | readability.fk_grade must be between 0 and 30. |
ER0264 | 400 | Invalid readability.fk_grade.min value. |
ER0265 | 400 | readability.fk_grade.min must be between 0 and 30. |
ER0266 | 400 | Invalid readability.fk_grade.max value. |
ER0267 | 400 | readability.fk_grade.max must be between 0 and 30. |
ER0268 | 400 | Invalid readability.ease value. |
ER0269 | 400 | readability.ease must be between 0 and 100. |
ER0270 | 400 | Invalid readability.ease.min value. |
ER0271 | 400 | readability.ease.min must be between 0 and 100. |
ER0272 | 400 | Invalid readability.ease.max value. |
ER0273 | 400 | readability.ease.max must be between 0 and 100. |
ER0274 | 400 | Invalid readability.ari value. |
ER0275 | 400 | readability.ari must be between 0 and 30. |
ER0276 | 400 | Invalid readability.ari.min value. |
ER0277 | 400 | readability.ari.min must be between 0 and 30. |
ER0278 | 400 | Invalid readability.ari.max value. |
ER0279 | 400 | readability.ari.max must be between 0 and 30. |
ER0280 | 400 | readability.difficulty must be one of: beginner, intermediate, advanced, expert. |
ER0281 | 400 | readability.audience must be one of: children, general, professional, academic. |
ER0282 | 400 | Invalid readability.age value. |
ER0283 | 400 | readability.age must be between 6 and 22. |
ER0284 | 400 | Invalid readability.age.min value. |
ER0285 | 400 | readability.age.min must be between 6 and 22. |
ER0286 | 400 | Invalid readability.age.max value. |
ER0287 | 400 | readability.age.max must be between 6 and 22. |
ER0288 | 400 | is_easy_read must be 0 or 1. |
ER0289 | 400 | is_difficult_read must be 0 or 1. |
Quality Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0303 | 400 | is_high_quality must be 0 or 1. |
The same ER0303 code (also 400) is reused by the webhooks GET, PATCH and DELETE /{id} endpoints with a different message — "Invalid webhook ID." Both are 400; distinguish them by which endpoint you called and by the message text.
Field Selection Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0300 | 400 | fl must be a string. |
ER0301 | 400 | fl cannot be empty. |
Facet Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0310 | 400 | facet.field is required when facet=true. |
ER0311 | 400 | facet.field cannot be empty. |
ER0312 | 400 | facet.field cannot contain more than 5 fields. |
ER0313 | 400 | Invalid field in facet.field. |
ER0330 | 400 | facet.range.field is required when facet.range=true. |
ER0331 | 400 | Invalid field in facet.range.field. |
ER0332 | 400 | facet.range.start and facet.range.end are required for range faceting. |
ER0333 | 400 | facet.range.start / facet.range.end must be a date like 2026-08-01 (or a number for numeric fields). |
ER0334 | 400 | facet.range.gap must look like 1DAY, 2WEEKS, 1MONTH (or a positive number for numeric fields). |
Highlight Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0320 | 400 | hl.fl cannot be empty when hl=true. |
ER0321 | 400 | hl.fl cannot contain more than 5 fields. |
ER0322 | 400 | Invalid field in hl.fl. |
Location Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0400 | 400 | location.bbox must be 4 comma-separated values: minLat,maxLat,minLng,maxLng. |
ER0401 | 400 | location.bbox latitudes must be between -90 and 90. |
ER0402 | 400 | location.bbox longitudes must be between -180 and 180. |
ER0403 | 400 | location.bbox minLat must be less than or equal to maxLat. |
ER0404 | 400 | location.bbox minLng must be less than or equal to maxLng. |
ER0405 | 400 | has_location_geo must be 0 or 1. |
ER0406 | 400 | location.lat and location.lng are required when using radius filters. |
ER0407 | 400 | location.lat must be a valid latitude between -90 and 90. |
ER0408 | 400 | location.lng must be a valid longitude between -180 and 180. |
ER0409 | 400 | location.radius must be a positive number up to 20000 km. |
ER0410 | 400 | location.radius.min must be a non-negative number up to 20000 km. |
ER0411 | 400 | location.radius.min must be less than location.radius. |
ER0412 | 400 | At least one of location.radius or location.radius.min must be provided. |
Trends Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0350 | 400 | field is required. |
ER0352 | 400 | compare_window is required when compare=true or has invalid format. |
ER0353 | 400 | Invalid date range. Maximum allowed range is 30 days for trends endpoint. |
ER0354 | 400 | sort must be one of the allowed trends sort fields (change and trending_score need period comparison). |
ER0355 | 400 | order must be asc or desc. |
Event Type Filter Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0501 | 400 | Invalid event.type value. |
ER0502 | 400 | Invalid event type(s). See /v1/news/event-types for valid types. |
ER0503 | 400 | Invalid event.category. Valid categories: business, society, environment. |
ER0504 | 400 | Invalid ignore.event.type(s). |
Suggest Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0346 | 400 | Prefix in query required. |
SSE Stream Errors
ER0360 and ER0363 are returned as HTTP responses when the connection is rejected on connect. The others are delivered mid-stream as SSE error events (event: error) on an already-open 200 connection, after which the stream closes — reconnect (with Last-Event-ID) to resume.
| Error Code | HTTP Status | Description |
|---|---|---|
ER0360 | 429 | Maximum SSE connections reached for your plan. |
ER0361 | 200 (stream event) | API key revoked — the stream was closed because the key was revoked. |
ER0362 | 200 (stream event) | Stream lifetime exceeded (6h max session) — reconnect to continue. |
ER0363 | 400 | Invalid stream.max_age — must be a positive integer number of minutes. |
ER0364 | 200 (stream event) | SSE session terminated by API — closed via DELETE /v1/news/stream/sessions or key rotation. |
WebSocket Stream Errors
Delivered over the WebSocket stream as a JSON message with type: "error" on the already-open connection, after which the socket closes.
| Error Code | Description |
|---|---|
ER0365 | Connection replaced by a newer connection (takeover) — a second WebSocket opened with the same API key took over, closing this one. |
Local News Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0420 | 400 | Invalid insights value. |
ER0421 | 400 | Could not geocode place. Try a more specific name, add country, or pass lat/lng. |
ER0422 | 400 | sort must be one of: distance, published_at, relevance. |
ER0423 | 400 | ranking must be one of: balanced, proximity, authority, fresh. |
ER0424 | 400 | A w.* ranking weight must be a non-negative number. |
Source Stats Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0370 | 404 | Source not found. Not reachable — /v1/sources/{id}/stats is currently disabled and returns 404 ER0182. |
Webhook Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0302 | 400 | Invalid or disallowed webhook URL. (Same code is used by the read-time is_deep_dive filter.) |
ER0303 | 400 | Invalid webhook ID. (Same code is used by the is_high_quality quality filter.) |
ER0304 | 404 | Webhook not found. |
ER0305 | 400 | Invalid status. Allowed values listed in the error message. |
ER0306 | 400 | filters must be an object (or contains invalid filters). |
Fact-Check Errors
| Error Code | HTTP Status | Description |
|---|---|---|
ER0700 | 400 | Provide one of the parameters: id, text, or claim. |
ER0701 | 400 | text must be between 100 and 10000 characters. |
ER0702 | 404 | Article with the provided id was not found. |
ER0703 | 502 | Fact-check service is temporarily unavailable. Please try again later. |
ER0704 | 400 | id must be a valid integer. |
ER0705 | 400 | claim must be between 5 and 500 characters. |
ER0706 | 403 | Fact-check is not available on the free plan. Please upgrade your subscription. |
Query Parameter Errors
The boolean query parameter validates its input and reuses the code numbers ER0701–ER0706 — but here they are always HTTP 400 with different messages (parse and validation failures), unlike the Fact-Check codes above which use 404/502/403. When a request sends query, treat these codes as query-validation errors; branch on the HTTP status and message, not the code alone.
| Error Code | HTTP Status | Description |
|---|---|---|
ER0701 | 400 | Query could not be parsed, is empty, is not a string, or produced no condition. |
ER0702 | 400 | Unknown field, or a {{ }} block was used on a field other than entity. |
ER0703 | 400 | Query is too long, has too many predicates, or is nested too deeply. |
ER0704 | 400 | Unsupported syntax — regex, fuzzy (~), boost (^) and wildcard are not supported. |
ER0705 | 400 | A field value failed validation (invalid number, enum, date, range, coordinates, etc.). |
ER0706 | 400 | Range syntax is not supported for this field. |
ER0710 | 400 | Invalid condition inside an entity {{ }} block (bad id, field, or sentiment value). |
ER0711 | 400 | Empty entity block {{}}. |
ER0712 | 400 | Malformed entity block — check {{ }} pairing. |
Plan gates
Features that the Free plan does not include are refused with 403 ER0706 before the request reaches the search engine, so nothing is billed:
| Feature | Refused for | Message |
|---|---|---|
Export formats (export=csv|tsv|xml|rss|xlsx|parquet|jsonl) | Free | Export formats are not available on the free plan. Please upgrade your subscription. |
Trends (/v1/news/trends) | Free | Trends API is not available on the free plan. Please upgrade your subscription. |
Fact Check (/v1/fact-check) | Free | Fact-check is not available on the free plan. Please upgrade your subscription. |
| MCP server | Free | MCP server is not available on the free plan. Please upgrade your subscription. |
prompt parameter | Free, Starter | Prompt search is not available on your plan. Please upgrade your subscription. |
export=json and requests without export work on every plan — only the alternative formats are gated.
Prompt Errors
Returned by the prompt parameter while it is being translated into filters — before the search itself runs.
ER0706 carries several meanings on this page: the plan gates above (403), a query range error (400) and the prompt plan gate (403). Branch on the HTTP status and the message, never on the code alone — a 403 ER0706 on a request that sent prompt means the plan does not include natural-language search.
| Error Code | HTTP Status | Description |
|---|---|---|
ER0706 | 403 | Prompt search is not available on your plan. Please upgrade your subscription. |
ER0800 | 400 | prompt must be a string between 3 and 500 characters. |
ER0801 | 502 | Prompt understanding service is temporarily unavailable. Please try again later. |
ER0802 | 400 | prompt could not be translated into any filter. Please be more specific. |
ER0802 also appears when every parameter the prompt produced was discarded — because you passed those parameters explicitly, or because the endpoint does not support them. The meta.prompt.ignored array of a successful request shows the same reasons; see Reading the prompt interpretation.
Account-level failures are checked before the translation runs, so an invalid key or an exhausted balance returns the usual ER0201/ER0202, ER0176 or ER0177 and no parse fee is charged. The plan gate (ER0706) is checked at the same point, and ER0801 is free too — points are only deducted after a successful translation.
On the WebSocket stream (/v1/news/ws) these codes do not arrive as an HTTP status. The server sends an error frame and then closes the socket with code 4001:
{ "type": "error", "code": "ER0800", "message": "prompt must be a string between 3 and 500 characters." }MCP Server Errors
The MCP server (https://mcp.apitube.io/) authenticates the same API keys as the REST API, so it returns the same codes — ER0201/ER0202 for a missing or invalid key, ER0230 for an expired one, ER0601/ER0602 for IP and referrer restrictions, ER0603 for a key without the matching scope, and ER0706 on the Free plan. It adds one code of its own:
| Error Code | HTTP Status | Description |
|---|---|---|
ER0900 | 503 | Key validation is temporarily unavailable — PostgreSQL did not answer. Retry in a few seconds. |
ER0900 is deliberately not ER0202: the server does not know whether the key is valid, it only knows it could not check. Treat it as a transient failure and retry rather than reissuing the key. The MCP health endpoint (GET /ping) returns the same code with PostgreSQL is unavailable. when the database is down.