Migrating from Perigon
Replace /v1/all with /v1/news/everything. Check three differences: page numbers start at 1, adjacent search terms use AND, and sentiment scores use a different scale.
Why teams switch
| Perigon | APITube | |
|---|---|---|
| Articles per request | 100 | 250 |
| Sentiment | Three probabilities per article | Signed score for title, body, overall, and per entity |
| Category taxonomy | 15 fixed names | IPTC MediaTopics — thousands of codes, plus topics and industries |
| Publisher metadata | Source name and domain | Domain, country, political bias, Open Page Rank |
| Article text | Full content | Full body and body_html, plus a summary made from sentences in the article |
Your first request
# Perigon — page 0 is the first page
curl "https://api.goperigon.com/v1/all?q=tesla&language=en&page=0&size=100" \
-H "x-api-key: YOUR_KEY"# APITube — page 1 is the first page
curl "https://api.apitube.io/v1/news/everything?title=tesla&language.code=en&page=1&per_page=100" \
-H "X-API-Key: YOUR_API_KEY"Three differences to handle
1. Convert page numbers. Perigon starts at 0; APITube starts at 1. APITube treats page=0 as page 1, so forwarding page numbers unchanged can repeat the first page. Send perigon_page + 1.
2. Choose AND or OR explicitly. Perigon reads q=Elon Musk as Elon OR Musk. APITube reads title=Elon Musk as Elon AND Musk. Use query=title:(Elon OR Musk) to keep OR matching. Quoted phrases such as "Elon Musk" work the same way on both.
3. Sentiment scores need adjustment. Perigon returns positive, negative and neutral probabilities that add up to 1. APITube returns a score from negative to positive for each sentiment field. Use score ≈ positive − negative as a starting point: positiveSentimentFrom=0.6 becomes sentiment.overall.score.min=0.2. Check the results and adjust the threshold. There is no equivalent for neutralSentimentFrom or neutralSentimentTo.
Parameter mapping
| Perigon | APITube | Note |
|---|---|---|
q | title or query | Headlines only, and the default operator inverts — see above |
title | title | Lossless |
content, desc, url | — | No body, description or URL search |
category | category.id | 13 of 15 names map to IPTC codes, max 3 |
excludeCategory | ignore.category.id | |
topic | topic.id | Different taxonomies — verify each value |
source | source.domain | Max 3, exact domain |
excludeSource | ignore.source.domain | |
sourceCountry | source.country.code | |
companyName | organization.name | Strip legal suffixes — Apple Inc returns 400 |
personName | person.name | Must match a person name known to the API |
companyDomain | — | Different meaning — the company's site, not the publisher |
companyId, personWikidataId | — | APITube entity ids are its own |
byline | author.name | Real journalist names only; desk names return 400 |
language | language.code | No ru, no uk |
from / to | published_at.start / .end | |
addDateFrom, refreshDateFrom | — | Publication date only |
positiveSentimentFrom / To | sentiment.overall.score.min / .max | Approximate |
negativeSentimentFrom / To | sentiment.overall.score.max / .min | Approximate, sign inverts |
neutralSentimentFrom / To | — | No neutral axis |
showReprints=false | is_duplicate=0 | Reprint grouping is lost |
medium=Video | has_video=1 | "Has a video" ≠ "is a video" |
lat / lon / maxDistance | /v1/news/local lat / lng / radius | A different endpoint |
page | page | +1 |
size | per_page | 250 max; 10 on Free, 50 on Starter, 200 on Basic (400 ER0171 above) |
sortBy=date | sort.by=published_at | |
sortBy=relevance | — | Returns 500 with a search term; use sort.by=source.rank.opr |
The full table of every Articles parameter is in the migration kit.
What does not carry over
Body-text search. content=, desc= and url= have no equivalent, and APITube ignores unknown parameters silently — forwarding them returns the whole index with a 200. Search headlines and filter the returned body locally.
Wildcards. q=immuni* fails the same way: title=immuni* is accepted and returns the entire index. Expand into query=title:(immunity OR immunization OR immunology).
Relevance boosting. ^2 has no equivalent. Sent verbatim it becomes a literal search term.
Google Content Categories. taxonomy=/Finance/Banking and prefixTaxonomy use a hierarchy with no mechanical mapping to IPTC. Pick an IPTC code by hand.
Grouped and related articles. APITube has no equivalent for /v1/stories/all or its clusterId filter. Each article has story.id, which you can use to group results in your code. There is no equivalent for /v1/vector/news/all or vector embeddings, the numeric representations used for similarity search. For article summaries, use the summary array instead of /v1/summarize.
Russian and Ukrainian. language.code=ru and uk return 400 ER0237. There is no substitute.
What you gain
APITube returns up to 250 articles per request, compared with Perigon's 100. The limits are 10 on Free, 50 on Starter and 200 on Basic.
Articles include separate title and body sentiment, sentiment about each entity, IPTC MediaTopics, topics, industries, publisher political bias, Open Page Rank and readability scores. Results can be exported in eight formats.
Next steps
- perigon-apitube-migration-kit — Articles parameter mappings, 13 verified category codes, query and sentiment conversion guides, and Node.js and Python compatibility libraries (101 tests). Includes an AI prompt for converting multiple queries.
- Parameters reference
- Common migration issues