Crypto News API
Four REST endpoints. Translated crypto news as JSON — for apps, bots, and publisher CMS tools.
Auth: X-API-Key header on every request
Quickstart
Get your first articles in five minutes: get an API key, send one GET, read the JSON array.
Code Examples
curl -X GET "https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/?lang=en&limit=3" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: application/json"Response
[
{
"original_id": 2147,
"language": "en",
"title": "OKX will launch IRYS/USD and IRYS/EUR for spot trading",
"content": "To support the growth of the unified USD and EUR ecosystem...",
"created_at": "2026-05-27T05:00:00",
"meta": {
"token_mentions": ["IRYS"],
"thumbnail_url": "https://img.upgate.online/crypto/2147",
"source_name": "OKX",
"category": "exchanges",
"sentiment": "positive",
"feed_type": null
}
}
]Endpoints at a Glance
Four GET endpoints under /api/v1/crypto/. Standard endpoints return translated news. Publication endpoints return adapted copy for your publication (Premium add-on).
Standard Feed
Live news feeds in apps and websites
GET /api/v1/crypto/articles/translated/Standard Snapshot
Cron jobs, Telegram bots, and dashboards
GET /api/v1/crypto/articles/translated/latest-snapshot/Publication Feed
Live feed written in your publication's voice (Premium)
GET /api/v1/crypto/publication-feed/Publication Snapshot
Scheduled pulls of edited stories (Premium)
GET /api/v1/crypto/publication-feed/latest-snapshot/Which one do I need?
| Your goal | Use this |
|---|---|
| Scrollable feed in an app | Standard Feed or Publication Feed |
| Cron job, bot, or dashboard | Standard Snapshot or Publication Snapshot |
| Stories in your publication's voice | Publication Feed (Premium) |
| Raw translated wire copy | Standard Feed or Standard Snapshot |
Time windows
| Endpoint | Window |
|---|---|
| Standard Feed | Last 2 days (scroll archive) |
| Standard Snapshot | No time window — latest by created_at |
| Publication Feed | Rolling delivery window (about 7 days) |
| Publication Snapshot | No checkpoint — latest adapted stories |
Which Endpoint?
Answer three quick questions — we'll suggest the right endpoint.
Which endpoint should I use?
Pick your use case — we'll suggest the right endpoint.
What are you building?
Integration Guide: News Feed
Poll with direction=newer while your app is open. The API returns only unseen articles. With direction=newer, [] means nothing new.
Code Examples
const API_BASE = "https://api.upgate.online"
const PATH = "/api/v1/crypto/articles/translated/"
async function pollFeed({ apiKey, lang = "en", limit = 10 }) {
const url = new URL(API_BASE + PATH)
url.searchParams.set("lang", lang)
url.searchParams.set("limit", String(limit))
url.searchParams.set("direction", "newer")
const res = await fetch(url, {
headers: { "X-API-Key": apiKey, Accept: "application/json" },
})
if (!res.ok) throw new Error((await res.json().catch(() => ({}))).detail || res.status)
return res.json() // [] = no new articles
}
setInterval(async () => {
for (const article of await pollFeed({ apiKey: process.env.UPGATE_API_KEY })) {
renderCard(article)
}
}, 60_000) // must respect frequency_minutes + daily_limit on your planIntegration Guide: Cron & Alerts
Call Snapshot on a schedule from your server. Track original_id yourself so you never alert on the same story twice.
Code Examples
const seen = new Set()
function ingestNew(articles) {
return articles.filter((a) => !seen.has(a.original_id) && seen.add(a.original_id))
}
async function tick() {
const res = await fetch(
'https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/?lang=en&limit=10&token=BTC',
{ headers: { 'X-API-Key': process.env.UPGATE_API_KEY } }
)
for (const article of ingestNew(await res.json())) await notify(article)
}
setInterval(tick, 5 * 60_000)Authentication
Send your API key in the X-API-Key header on every request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| X-API-Key | string | Yes | Your UpGate API key from Dashboard → Key & Test Example: YOUR_API_KEY |
| Accept | string | No | Recommended: application/json Example: application/json |
| X-Request-ID | string | No | Optional ID for support — echoed in the response Example: trace-abc-123 |
Code Examples
curl -X GET "https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/?limit=1&lang=en" \
-H "X-API-Key: YOUR_API_KEY"Standard Feed
For scrollable feeds. The server remembers how far each user has read — no page numbers needed. Returns articles from the last 2 days only.
How the Standard Feed works
First request GET ?direction=newer → latest articles Poll for new items GET ?direction=newer → articles the user has not seen yet [] → nothing new (you are up to date) Scroll into older items (2-day window) GET ?direction=older → older articles [] → end of the 2-day archive The server tracks read progress per API key and language. You never send page numbers or cursor tokens. For live feeds, always use direction=newer.
Endpoint
https://api.upgate.online/api/v1/crypto/articles/translated/Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lang | string | No | en or fa. Default: en Example: en |
| limit | integer | No | 1–100 endpoint max. Also capped by max_items_per_request on your key. Example: 10 |
| direction | string | No | newer = unseen. older = scroll back. Default: newer if no checkpoint yet; otherwise older. Always pass newer for live feeds. Example: newer |
| token | string | No | Filter by token symbol (case-insensitive) Example: BTC |
Code Examples
curl -G "https://api.upgate.online/api/v1/crypto/articles/translated/" \
-H "X-API-Key: YOUR_API_KEY" \
--data-urlencode "lang=en" \
--data-urlencode "limit=10" \
--data-urlencode "direction=newer"Standard Snapshot
Returns the latest articles by created_at. No time window, no read tracking — best for cron jobs, bots, and alerts.
Endpoint
https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lang | string | No | en or fa. Default: en Example: en |
| limit | integer | No | 1–50. Default: 10. Also capped by max_items_per_request. Example: 10 |
| token | string | No | Filter by token symbol (case-insensitive) Example: BTC |
Code Examples
curl -G "https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/" \
-H "X-API-Key: YOUR_API_KEY" \
--data-urlencode "lang=en" \
--data-urlencode "limit=10" \
--data-urlencode "token=BTC"Publication Edition
Publication Edition rewrites stories for your publication's tone and audience. Set up Publication Identity in your dashboard, then call Publication endpoints with the same API key.
Standard vs Publication
| Standard | Publication (Premium) | |
|---|---|---|
| Content | Translated wire copy | Adapted for your publication |
| Plans | Trial and paid API plans | Publication Edition add-on |
| Time window | Feed: 2 days. Snapshot: none | Feed: ~7 days. Snapshot: none |
| Read progress | Separate checkpoint per feed type | Separate checkpoint per feed type |
| meta.feed_type | null | publication |
| Language | lang query param | Publication Identity target language overrides lang |
| Setup | API key only | Publication Identity in dashboard first |
Publication Feed
Scrollable feed of adapted stories (~7-day window). Same parameters as Standard Feed, but requires Publication Edition and a configured publication profile.
Endpoint
https://api.upgate.online/api/v1/crypto/publication-feed/Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lang | string | No | en or fa. Overridden by Publication Identity target language when set. Example: en |
| limit | integer | No | 1–100 endpoint max. Also capped by max_items_per_request. Example: 10 |
| direction | string | No | newer or older only — invalid values return HTTP 400. Always use newer for live feeds. Example: newer |
| token | string | No | Filter by token — max 16 alphanumeric characters Example: ETH |
Code Examples
curl -G "https://api.upgate.online/api/v1/crypto/publication-feed/" \
-H "X-API-Key: YOUR_API_KEY" \
--data-urlencode "lang=en" \
--data-urlencode "limit=10" \
--data-urlencode "direction=newer"Publication Snapshot
Latest adapted stories without advancing Feed read progress. Track original_id on your side.
Endpoint
https://api.upgate.online/api/v1/crypto/publication-feed/latest-snapshot/Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lang | string | No | en or fa. Overridden by Publication Identity target language when set. Example: en |
| limit | integer | No | 1–50. Default: 10 Example: 10 |
| token | string | No | Filter by token — max 16 alphanumeric characters Example: SOL |
Code Examples
curl -G "https://api.upgate.online/api/v1/crypto/publication-feed/latest-snapshot/" \
-H "X-API-Key: YOUR_API_KEY" \
--data-urlencode "lang=en" \
--data-urlencode "limit=10"Response Format
Every endpoint returns a JSON array of articles. There is no wrapper object.
Response
[
{
"original_id": 2147,
"language": "en",
"title": "OKX will launch IRYS/USD and IRYS/EUR for spot trading",
"content": "To support the growth of the unified USD and EUR ecosystem...",
"created_at": "2026-05-27T05:00:00",
"meta": {
"token_mentions": ["IRYS"],
"thumbnail_url": "https://img.upgate.online/crypto/2147",
"source_name": "OKX",
"category": "exchanges",
"sentiment": "positive",
"feed_type": null
}
}
]Article fields
| Field | Type | Description |
|---|---|---|
| original_id | integer | Unique ID — use this to detect duplicates |
| language | string | en or fa |
| title | string | Headline |
| content | string | Body text (Markdown-ready; RTL when lang=fa) |
| created_at | string (ISO 8601) | When UpGate processed the story (UTC) |
| meta.token_mentions | string[] | Token symbols, e.g. ["BTC", "ETH"] |
| meta.source_name | string | Original publisher, e.g. OKX |
| meta.category | string | Topic (see table below) |
| meta.sentiment | string | positive, negative, or neutral |
| meta.thumbnail_url | string | Image URL — https://img.upgate.online/crypto/{id} |
| meta.has_watermark | boolean | null | Whether the source image had a watermark |
| meta.feed_type | string | null | null on Standard feeds; publication on Publication feeds |
| meta.adaptation_id | integer | null | Publication Edition ID (Publication feeds only) |
| meta.publication_identity_version | integer | null | Publication profile version used |
| meta.hot_score | float | null | Live score when hot_score is enabled on your key |
| meta.hot_score_static | float | null | Score at processing time |
Response headers
| Header | When | Description |
|---|---|---|
| X-Request-ID | Always | Trace ID — send this to support |
| X-Feed-Message | Standard Feed | Human-readable feed status |
| X-Feed-Message | Publication feeds | Human-readable feed status |
| X-Feed-Message-Code | Publication feeds | Machine code, e.g. feed_up_to_date |
| X-Feed-Count | Publication feeds | Number of articles returned |
Categories
| Label | Description |
|---|---|
| market_trends | Price action, market analysis, ETF flows |
| regulation_policy | Regulation, policy, legal news |
| project_updates | Upgrades, roadmaps, team announcements |
| defi | DeFi protocols and yields |
| nft | NFT markets and collections |
| memecoin | Meme coins and community tokens |
| exchanges | Listings, delistings, exchange updates |
| security_hacks | Hacks, exploits, vulnerabilities |
| adoption_partnerships | Adoption, partnerships, integrations |
| technology_innovation | L2, consensus, technical upgrades |
| mining_infrastructure | Mining, staking, infrastructure |
| macro_economy | Macro factors affecting crypto |
| unclassified | Low-confidence classification |
Languages
| Code | Language | Default |
|---|---|---|
| en | English | Yes |
| fa | Persian (RTL) | No |
Errors Cheat Sheet
Common responses and what to do about them.
Response
HTTP 429
{
"detail": "Rate limit exceeded. Please wait 1 minutes between requests."
}
HTTP 200 (normal)
[]Symptoms & fixes
| What you see | Meaning | What to do |
|---|---|---|
| [] + direction=newer | No new articles | Normal — keep polling. |
| [] + direction=older | End of archive window | Normal on Standard Feed (2-day window). |
| HTTP 401 | Invalid, inactive, or expired key | Copy the key again from Dashboard → Key & Test. Renew at upgate.online/pricing if expired. |
| HTTP 403 | Publication Edition not enabled | Enable Publication Edition from upgate.online/pricing or billing. |
| HTTP 409 | Publication Identity not set up | Configure Publication Identity in your dashboard first. |
| HTTP 429 (wait N min) | frequency_minutes — called too soon | Wait N minutes, then retry. |
| HTTP 429 (daily limit) | daily_limit reached for today | Wait until UTC midnight or upgrade at upgate.online/pricing. |
| HTTP 400 (max items) | limit exceeds max_items_per_request | Lower the limit parameter. |
| HTTP 400 (invalid lang) | Unsupported language | Use en or fa only. |
| HTTP 400 (invalid direction/token) | Bad query on Publication feeds | Use newer/older; token max 16 alphanumeric chars. |
| HTTP 503 | Publication Edition temporarily off | Retry later. |
| HTTP 500 | Server error | Retry with backoff. Contact support with X-Request-ID. |
FAQ
Common questions from developers integrating UpGate.
Frequently asked questions
How do I get an API key?
Start the free 7-day trial at upgate.online/login?mode=signup, or purchase a plan at upgate.online/pricing. After sign-in, copy your key from Dashboard → Key & Test.
Do you support webhooks?
No. Poll Feed endpoints for live apps, or Snapshot endpoints on a schedule.
Which languages are supported?
English (en) and Persian (fa). Default is en if you omit lang.
Is there a sandbox?
No public sandbox. Use the 7-day trial for your own key, or the docs demo tester (5 tries/day).
How do I filter by token?
Add ?token=BTC to any endpoint. Matching is case-insensitive. Publication feeds also require alphanumeric tokens (max 16 chars).
What's the difference between Standard and Publication feeds?
Standard returns translated wire copy. Publication returns stories adapted for your publication. Publication requires the Premium add-on and dashboard setup.
Can I use both Standard and Publication feeds?
Yes. Each feed type tracks read progress separately.
Rate Limits & Quotas
Each API key has limits set when your account is provisioned. See Dashboard → Key & Test for your current values.
Limit types
| Limit | What it means | HTTP code |
|---|---|---|
| frequency_minutes | Minimum minutes between consecutive requests | 429 |
| daily_limit | Max requests per UTC day | 429 |
| max_items_per_request | Max value for the limit query param | 400 |
| access_expires_at | Key expiry (trial ends after 7 days) | 401 |
Typical plan limits (API calls)
| Plan | daily_limit | max_items | frequency_minutes |
|---|---|---|---|
| 7-day trial (Basic profile) | 3 | 3 | 1 |
| Pro | 30 | 5 | 1 |
| Premium / Enterprise profile | 200 | 10 | 1 |
Support
For integration help, contact support with your X-Request-ID, endpoint path, and request time. To get an API key, use the trial or pricing links — not email.
