Get up and running with Free Crypto News in 5 minutes. No signup, no API key — just make a request.
| I want to... | Go to |
|---|---|
| Call the API from my terminal | Step 1: Your First API Call |
| Use a Python/JS/Go SDK | Step 3: Use an SDK |
| Self-host the project | Self-Hosting |
| Contribute code | Development Setup |
| Build a bot (Discord/Slack/Telegram) | Integration Examples |
No signup, no API key — just call it:
curl https://cryptocurrency.cv/api/news?limit=3Example response:
{
"articles": [
{
"title": "Bitcoin Surges Past $95K as Institutional Demand Grows",
"source": "CoinDesk",
"link": "https://coindesk.com/...",
"pubDate": "2026-03-01T14:30:00Z",
"category": "bitcoin",
"sentiment": "positive"
},
{
"title": "Ethereum Layer 2 TVL Hits New Record",
"source": "The Block",
"link": "https://theblock.co/...",
"pubDate": "2026-03-01T13:15:00Z",
"category": "ethereum",
"sentiment": "positive"
}
],
"count": 3,
"source": "aggregated"
}That's it! Every endpoint works the same way — just
GETthe URL and parse the JSON. No browserUser-Agentneeded either: cURL, wget, HTTPie and AI agents (GPTBot, ClaudeBot, PerplexityBot and friends) are all welcome callers.
!!! note "Free tier returns at most 3 articles"
Without an API key, /api/news returns 3 articles per request, with
full article bodies stripped and summaries truncated. The response says so
plainly: it carries "limited": true, "maxResults": 3, and a pagination
block describing what you actually received rather than the uncapped result
set. Upgrade to Pro, or pay per request with x402 to lift the cap.
The site feeds are not capped: `/feed.xml` and `/feed.json` each publish 50
items, no key required.
# Bitcoin news only
curl https://cryptocurrency.cv/api/bitcoin
# DeFi news
curl https://cryptocurrency.cv/api/defi
# Search for specific topics
curl "https://cryptocurrency.cv/api/search?q=ethereum+ETF"
# Get AI-generated daily digest
curl https://cryptocurrency.cv/api/digest
# Market sentiment
curl https://cryptocurrency.cv/api/sentimentInstall an SDK to skip boilerplate. Available for Python, JavaScript, TypeScript, React, Go, PHP, Ruby, Rust, Java, Kotlin, Swift, C#, and R.
Python: (from a clone: pip install ./sdk/python)
from crypto_news import CryptoNewsClient
client = CryptoNewsClient()
for article in client.get_news(limit=5)['articles']:
print(f"{article['source']}: {article['title']}")JavaScript:
import { CryptoNews } from '@nirholas/crypto-news';
const client = new CryptoNews();
const articles = await client.getLatest(5);
articles.forEach(a => console.log(a.title));Go:
package main
import (
"fmt"
cryptonews "github.com/nirholas/cryptocurrency.cv/sdk/go"
)
func main() {
client := cryptonews.NewClient()
articles, _ := client.GetLatest(5)
for _, a := range articles {
fmt.Printf("%s: %s\n", a.Source, a.Title)
}
}React:
// React hooks ship in sdk/react of the repository (not yet on npm): copy or link that package
import { useCryptoNews } from './sdk/react';
function NewsFeed() {
const { articles, loading } = useCryptoNews({ limit: 10 });
if (loading) return <p>Loading...</p>;
return articles.map(a => <ArticleCard key={a.link} article={a} />);
}PHP:
<?php
require_once 'vendor/autoload.php';
$client = new CryptoNews\Client();
$articles = $client->getLatest(5);
foreach ($articles as $article) {
echo $article['source'] . ': ' . $article['title'] . "\n";
}cURL (no SDK needed):
# Get latest 5 articles as JSON
curl -s https://cryptocurrency.cv/api/news?limit=5 | jq '.articles[] | .title'Subscribe to live news via Server-Sent Events (SSE):
const eventSource = new EventSource('https://cryptocurrency.cv/api/sse');
eventSource.addEventListener('news', (event) => {
cError Handling
### HTTP Status Codes
All API endpoints return standard HTTP status codes:
| Code | Meaning |
|------|---------|
| 200 | Success |
| 400 | Bad request — check your parameters |
| 404 | Endpoint or resource not found |
| 429 | Rate limited — slow down and check `Retry-After` header |
| 500 | Server error — try again later |
### Rate Limit Headers
Every response includes rate limit information:X-RateLimit-Limit: 120 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 2026-08-28T04:00:00.000Z X-RateLimit-Tier: free-tier
`X-RateLimit-Reset` is an ISO 8601 timestamp, not a Unix epoch.
Anonymous callers get **120 requests per hour per IP** on the free-tier routes
(`/api/news*`, `/api/prices*`, `/api/sources*`, `/api/market*`, `/api/archive*`,
`/api/rss*`, `/api/atom*`, `/api/fear-greed`, `/api/trending`, `/api/unlocks`
and friends). Other routes are tighter: 20 requests/hour for a programmatic
client, 10 for a browser. `/api/health` and `/api/version` are exempt entirely.
For higher limits, [upgrade to a paid tier or pay per request with x402](./PREMIUM.md).
### Example: Handling Errors in Python
```python
import requests
response = requests.get('https://cryptocurrency.cv/api/news?limit=5')
if response.status_code == 200:
articles = response.json()['articles']
for a in articles:
print(a['title'])
elif response.status_code == 429:
retry_after = response.headers.get('Retry-After', 60)
print(f"Rate limited. Retry in {retry_after} seconds.")
else:
print(f"Error: {response.status_code}")
/api/sse is a Server-Sent Events stream. It needs no key and is exempt from
rate limiting. Every event's data is a JSON object carrying an articles
array and a timestamp.
const eventSource = new EventSource('https://cryptocurrency.cv/api/sse');
eventSource.addEventListener('news', (event) => {
const { articles } = JSON.parse(event.data);
updateFeed(articles);
});
eventSource.addEventListener('breaking', (event) => {
const { articles } = JSON.parse(event.data);
articles.forEach((a) => showBreakingAlert(a.title));
});The stream also emits connected on open, heartbeat to keep the connection
alive, error on an upstream failure, and close before shutting down.
See Real-Time docs for WebSocket and push notification options.
curl -X POST https://cryptocurrency.cv/api/ai \
-H "Content-Type: application/json" \
-d '{
"action": "sentiment",
"title": "Bitcoin Surges Past $100K",
"content": "Bitcoin reached a new all-time high today..."
}'Example response:
{
"sentiment": "bullish",
"score": 0.87,
"confidence": "high",
"summary": "Strong positive sentiment driven by price milestone and institutional interest."
}# Clone the repo
git clone https://github.com/nirholas/cryptocurrency.cv.git
cd cryptocurrency.cv
# Install dependencies
pnpm install
# Start development server
bun run devOpen http://localhost:3000 🎉
docker run -p 3000:3000 ghcr.io/nirholas/free-crypto-news- Node.js 18+ — Download
- pnpm —
npm install -g pnpm(package manager) - Bun —
curl -fsSL https://bun.sh/install | bash(script runner) - Git — Download
# Clone
git clone https://github.com/nirholas/cryptocurrency.cv.git
cd cryptocurrency.cv
# Install
pnpm install
# Create environment file
cp .env.example .env.local
# Start dev server
bun run devAdd to .env.local:
# Choose one AI provider:
GROQ_API_KEY=gsk_... # Free at console.groq.com (recommended)
# or
OPENAI_API_KEY=sk-... # OpenAI - GPT models
# or
ANTHROPIC_API_KEY=sk-ant-... # Anthropic - Claude modelsTip: Groq is free and fast — great for getting started. You can switch providers later.
# Unit tests (vitest, watch mode)
npm test
# Unit tests, single run
npm run test:run
# Unit tests with coverage
npm run test:coverage
# E2E tests (Playwright)
npm run test:e2ebun run build
bun run start// discord-bot.js
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] });
client.on('messageCreate', async (message) => {
if (message.content === '!news') {
const res = await fetch('https://cryptocurrency.cv/api/news?limit=5');
const { articles } = await res.json();
const text = articles.map(a => `📰 **${a.title}**\n${a.link}`).join('\n\n');
message.reply(text);
}
});
client.login(process.env.DISCORD_TOKEN);// slack-bot.js
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
app.message('crypto news', async ({ message, say }) => {
const res = await fetch('https://cryptocurrency.cv/api/news?limit=5');
const { articles } = await res.json();
await say({
blocks: articles.map(a => ({
type: 'section',
text: { type: 'mrkdwn', text: `*${a.title}*\n${a.source} • <${a.link}|Read more>` }
}))
});
});
app.start(3000);# telegram-bot.py
from telegram import Update
from telegram.ext import Application, CommandHandler
import requests
async def news(update: Update, context):
res = requests.get('https://cryptocurrency.cv/api/news?limit=5')
articles = res.json()['articles']
text = '\n\n'.join([f"📰 *{a['title']}*\n{a['link']}" for a in articles])
await update.message.reply_text(text, parse_mode='Markdown')
app = Application.builder().token(os.getenv('TELEGRAM_TOKEN')).build()
app.add_handler(CommandHandler('news', news))
app.run_polling()<!-- Add to your HTML -->
<div id="crypto-news-widget"></div>
<script src="https://cryptocurrency.cv/widget/ticker.js"></script>
<script>
CryptoNewsWidget.init('#crypto-news-widget', {
limit: 5,
theme: 'dark',
autoRefresh: true
});
</script>Now that you're up and running, explore deeper:
| I want to... | Read this |
|---|---|
| See all API endpoints | API Reference |
| Build an AI-powered app | AI Features Guide |
| Stream real-time news | Real-Time Guide |
| Follow step-by-step tutorials | Tutorials |
| Use an SDK | SDKs |
| Integrate with ChatGPT or Claude | AI Integrations |
| Browse all features | Features Guide |
"Cannot connect to localhost:3000"
- Make sure you ran
bun run devand it completed without errors - Check that port 3000 isn't already in use:
lsof -i :3000 - Try a different port:
PORT=3001 bun run dev
"pnpm: command not found"
npm install -g pnpm"bun: command not found"
curl -fsSL https://bun.sh/install | bashAPI returns empty articles array
- This is normal on a fresh install — news is fetched every 5 minutes
- Wait a few minutes, then try again
- Or use the hosted API at
https://cryptocurrency.cv/api/newsimmediately
AI endpoints return errors
- Make sure you've set an AI provider key in
.env.local - Groq is the easiest to set up (free at console.groq.com)
- 💬 GitHub Discussions — Ask questions
- 🐛 Report Issues — File bug reports
- ⭐ Star the repo if you find it useful!