UpGate Logo

Crypto

Quickstart

Get your first article in about 5 minutes — request a 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_client_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"
    }
  }
]

Which Endpoint?

Not sure whether to use ScrollBoost or Snapshot? Use the chooser below.

Which endpoint should I use?

Pick your use case — we suggest the right call.

What are you building?

Integration Guide: News Feed

Poll ScrollBoost with direction=newer while your app is open. The server tracks read position — you do not send cursors. Append new articles to your UI; treat [] as up to date.

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) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.detail || `HTTP ${res.status}`)
  }
  return res.json() // [] = no new articles (not an error)
}

const apiKey = process.env.UPGATE_API_KEY
setInterval(async () => {
  const batch = await pollFeed({ apiKey, lang: "en", limit: 10 })
  for (const article of batch) {
    renderCard(article) // title, meta.thumbnail_url, meta.sentiment
  }
}, 60_000) // interval ≥ frequency_minutes on your plan

Integration Guide: Cron & Alerts

Poll Snapshot from a server or cron job. Stateless — deduplicate by original_id on your side. Ideal for dashboards, Telegram bots, and token filters (?token=BTC).

Code Examples

const API_BASE = "https://api.upgate.online"
const PATH = "/api/v1/crypto/articles/translated/latest-snapshot/"
const seen = new Set()

async function pollSnapshot({ apiKey, lang = "en", limit = 10, token }) {
  const params = { lang, limit: String(limit) }
  if (token) params.token = token
  const url = new URL(API_BASE + PATH)
  Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v))

  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()
}

function ingestNew(articles) {
  return articles.filter((a) => {
    if (seen.has(a.original_id)) return false
    seen.add(a.original_id)
    return true
  })
}

async function tick() {
  const apiKey = process.env.UPGATE_API_KEY
  const fresh = ingestNew(await pollSnapshot({ apiKey, lang: "en", limit: 10, token: "BTC" }))
  for (const article of fresh) await notify(article)
}
setInterval(tick, 5 * 60_000)

Overview

Translated crypto news for your product — headlines, body text, thumbnails, token tags, categories, and sentiment. Output in English (en) or Persian (fa, RTL). Two GET endpoints: one for scrollable feeds, one for server-side polling.

What each article includes

DeliverableDetails
Translated title & bodyen or localized — Markdown-ready
Topic categorymarket_trends, exchanges, regulation_policy, and more
Sentimentpositive, negative, or neutral
Token tagsmeta.token_mentions — e.g. BTC, ETH, SOL
Source labelmeta.source_name — publisher name
ThumbnailCDN URL via meta.thumbnail_url — no extra auth

Endpoints

EndpointStatefulMax limitUse when
GET /articles/translated/Yes100 (default 10)Building a scrollable news feed in your app
GET /articles/translated/latest-snapshot/No50 (default 10)Polling from a server, dashboard, or cron job

Authentication

Pass your API key in the X-API-Key header on every request. Keys are issued per account with rate limits configured at onboarding.

Parameters

NameTypeRequiredDescription
X-API-KeystringYesAPI key issued by UpGate
Example: your_client_api_key
AcceptstringNoapplication/json
Example: application/json
X-Request-IDstringNoOptional; echoed in the response for support
Example: my-trace-id-123

Code Examples

curl -X GET "https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/?limit=1" \
  -H "X-API-Key: your_client_api_key"

ScrollBoost Feed

Intelligent scroll pagination with server-side checkpoints. No cursor tokens. Articles limited to a rolling 2-day window.

ScrollBoost state flow

First request
  GET ?direction=newer     → latest articles

Poll for new items
  GET ?direction=newer     → unseen articles only
  []                       → nothing new (up to date)

Scroll into older items (2-day window)
  GET ?direction=older    → older articles
  []                       → no more history available

Position is tracked server-side per API key and language.
You do not send cursor or offset parameters.
For feed polling, always pass direction=newer on every request.

Endpoint

GEThttps://api.upgate.online/api/v1/crypto/articles/translated/

Parameters

NameTypeRequiredDescription
langstringNoen or fa. Default: fa
Example: en
limitintegerNo1–100, capped by plan max_items_per_request
Example: 10
directionstringNonewer (unseen) or older (history). If omitted: newer when no checkpoint yet, otherwise older. Always pass newer for feed polling.
Example: newer
tokenstringNoFilter by token symbol (case-insensitive)
Example: BTC

Code Examples

curl -X GET "https://api.upgate.online/api/v1/crypto/articles/translated/?lang=en&limit=10&direction=newer" \
  -H "X-API-Key: your_api_key_here"

Snapshot API

Returns the latest articles without tracking read history. Use for dashboards, cron jobs, and alerts. Deduplicate by original_id on your side.

Endpoint

GEThttps://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/

Parameters

NameTypeRequiredDescription
langstringNoen or fa. Default: fa
Example: en
limitintegerNo1–50. Default: 10
Example: 10
tokenstringNoFilter by token symbol
Example: BTC

Code Examples

curl -X GET "https://api.upgate.online/api/v1/crypto/articles/translated/latest-snapshot/?lang=en&limit=10&token=BTC" \
  -H "X-API-Key: your_api_key_here"

Response Format

Both endpoints return a JSON array of articles. There is no wrapper object.

Response

[{ "original_id": 2147, "title": "...", "meta": { "token_mentions": ["IRYS"], "sentiment": "positive" } }]

Article fields

FieldTypeDescription
original_idintegerUnique article ID — use for deduplication
languagestringen or fa
titlestringTranslated headline
contentstringTranslated body (Markdown supported; RTL when localized)
created_atstring (ISO 8601)Translation creation time (UTC), not original publish time
meta.token_mentionsstring[]Detected token symbols e.g. ["BTC", "ETH"]
meta.source_namestringOriginal source e.g. OKX, CoinDesk
meta.categorystringTopic category (see table below)
meta.sentimentstringpositive | negative | neutral
meta.thumbnail_urlstringImage Gateway URL: https://img.upgate.online/crypto/{id}
meta.has_watermarkbooleanWhether source image had a watermark

Categories

LabelDescription
market_trendsPrice action, market analysis, ETF flows
regulation_policyRegulation, policy, legal news
project_updatesUpgrades, roadmaps, team announcements
defiDeFi protocols and yields
nftNFT markets and collections
memecoinMeme coins and community tokens
exchangesListings, delistings, exchange updates
security_hacksHacks, exploits, vulnerabilities
adoption_partnershipsAdoption, partnerships, integrations
technology_innovationL2, consensus, technical upgrades
mining_infrastructureMining, staking, infrastructure
macro_economyMacro factors affecting crypto
unclassifiedLow-confidence classification

Languages

CodeLanguageDefault
enEnglishNo
faLocalized (RTL)Yes

Errors Cheat Sheet

What you see in production, what it means, and what to do next.

Response

HTTP 429
{
  "detail": "Rate limit exceeded. Please wait 1 minutes between requests."
}

HTTP 200 (normal)
[]

Symptoms & fixes

What you seeMeaningWhat to do
[] (empty array)No new or matching articlesNormal — keep polling. Not an error.
HTTP 401 + detailInvalid, inactive, or expired API keyVerify X-API-Key. Contact team@upgate.online if newly issued.
HTTP 429 + wait N minutesfrequency_minutes — too soon after last requestWait N minutes, then retry. Add backoff in cron jobs.
HTTP 429 + daily limitdaily_limit exceeded for your API keyStop polling until next UTC day or upgrade plan.
HTTP 400 + max itemslimit param exceeds max_items_per_requestLower the limit query param.
HTTP 400 + invalid langUnsupported lang codeUse en or fa only.
HTTP 500Server errorRetry with exponential backoff. Email team@upgate.online with X-Request-ID.
Docs demo limit messageShared docs tester quota (not your key)Use your own API key, or try again tomorrow.

FAQ

Answers to the most common integration questions.

Frequently asked questions

Do you support webhooks?

No. Integrate via polling — ScrollBoost for feeds, Snapshot for cron jobs.

Which languages are supported?

en and fa language codes. Default is fa when lang is omitted.

Is there a sandbox?

No public sandbox. Contact team@upgate.online for an API key.

How do I filter by token?

Add ?token=BTC (case-insensitive) to either endpoint.

Rate Limits & Quotas

Per-client limits set at provisioning. Enforced on every request.

Limit types

LimitDescriptionHTTP code
frequency_minutesMinimum wait between consecutive requests429
daily_limitMaximum requests per day429
max_items_per_requestMaximum value of the limit parameter400
access_expires_atKey expiry date401

Support

Need help? Contact team@upgate.online with your X-Request-ID, endpoint path, and approximate request time.