Authentication
Every request needs an API key. Keys are issued by an Inspire News administrator under Admin › Integrations. Send the key in either header:
Authorization: Bearer ink_your_key X-Api-Key: ink_your_key
Each key may make 120 requests per minute (REST and MCP combined). Over the limit you get 429 Too Many Requests with a Retry-After header. A missing or invalid key returns 401.
REST API
Base URL: https://www.inspirenews.xyz/api/v1. All responses are JSON (camelCase). Lists are paged with page (from 1) and pageSize (1–50).
| Endpoint | Description |
|---|---|
GET /categories | All sections with their ids. |
GET /news?category=&page=&pageSize= | Latest stories, newest first. category is an id or a section name. |
GET /news/{id} | One story with its plain-text body. Archived stories have archived: true. |
GET /search?q=&page=&pageSize= | Search headlines and keywords. |
GET /trending/news?hours=24&count=10&category= | Stories with the highest trend score. |
GET /trending/topics?hours=24&count=20 | Trending keywords with frequency and velocity. |
GET /insights?category= | Latest AI trend insight per section (or one section). |
GET /me | Checks your key. |
Example
curl -H "Authorization: Bearer ink_your_key" "https://www.inspirenews.xyz/api/v1/search?q=oil&pageSize=5"
{
"items": [
{
"id": "6720c1…",
"title": "Oil climbs as …",
"summary": "…",
"url": "https://www.inspirenews.xyz/Home/News_detail_improved?newsID=6720c1…",
"sourceUrl": "https://publisher.example/story",
"imageUrl": "https://…",
"categoryId": "65f…",
"category": "Business",
"source": "Publisher name",
"publishedUtc": "2026-10-30T08:15:00Z",
"sentiment": "Neutral",
"trendScore": 71.4,
"keywords": ["oil", "opec"]
}
],
"page": 1, "pageSize": 5, "total": 128
}
Please show the publisher name and link to sourceUrl when you display a story.
Webhooks
An administrator registers your HTTPS endpoint. We then send a POST with a JSON body:
{
"id": "evt_9f0c…",
"type": "news.published",
"created": "2026-10-30T08:20:11Z",
"data": { "categoryId": "65f…", "category": "Business", "count": 7, "items": [ /* stories, same shape as the API */ ] }
}
| Event | When |
|---|---|
news.published | New stories were added to a section (one event per section per fetch, up to 25 stories). |
insight.generated | A trend insight was written for a section. data has the same shape as /api/v1/insights. |
webhook.test | Sent when an administrator presses “Send test”. |
Verifying the signature
Each request carries X-Inspire-Signature: t=<unix time>,v1=<hex>, where v1 is HMAC-SHA256(secret, t + "." + rawBody). Recompute it over the raw body, compare in constant time, and reject requests older than 5 minutes. X-Inspire-Delivery is the event id; use it to ignore duplicates. Answer with any 2xx within 15 seconds — otherwise we retry after 5 s and 30 s.
// Node.js (Express)
const crypto = require("crypto");
app.post("/webhooks/inspire", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("X-Inspire-Signature") || "";
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
const expected = crypto.createHmac("sha256", process.env.INSPIRE_WEBHOOK_SECRET)
.update(parts.t + "." + req.body).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
const ok = fresh && parts.v1 && expected.length === parts.v1.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
if (!ok) return res.sendStatus(401);
const event = JSON.parse(req.body);
// … handle event.type …
res.sendStatus(204);
});
# Python (Flask)
import hmac, hashlib, time
@app.post("/webhooks/inspire")
def inspire():
parts = dict(p.split("=", 1) for p in request.headers.get("X-Inspire-Signature", "").split(","))
body = request.get_data()
expected = hmac.new(SECRET.encode(), f"{parts['t']}.".encode() + body, hashlib.sha256).hexdigest()
if abs(time.time() - int(parts["t"])) > 300 or not hmac.compare_digest(expected, parts.get("v1", "")):
abort(401)
return "", 204
MCP server for AI agents
Endpoint: https://www.inspirenews.xyz/mcp (Streamable HTTP, stateless, protocol versions 2025-06-18 / 2025-03-26 / 2024-11-05). Add it to any MCP client that supports remote servers:
{
"mcpServers": {
"inspire-news": {
"type": "http",
"url": "https://www.inspirenews.xyz/mcp",
"headers": { "Authorization": "Bearer ink_your_key" }
}
}
}
Clients that only support local (stdio) servers can use the mcp-remote bridge:
{
"mcpServers": {
"inspire-news": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://www.inspirenews.xyz/mcp", "--header", "Authorization:Bearer ${INSPIRE_KEY}"],
"env": { "INSPIRE_KEY": "ink_your_key" }
}
}
}
| Tool | Arguments |
|---|---|
search_news | query (required), page, page_size |
get_latest_news | category, page, page_size |
get_article | id (required) |
list_categories | — |
get_trending_news | hours, count, category |
get_trending_topics | hours, count |
get_trend_insights | category |
All tools are read-only. Results include structuredContent plus the same JSON as text.