API reference
Everything Blog API
Base URL https://api.everythingblog.in · version v1 · openapi.yaml · openapi.json
Authentication
Send your key in X-API-Key or Authorization: Bearer <key>. Keys are eb_live_… (production) or eb_test_…; both authenticate against the same data today, and the prefix identifies the key in logs. A key can carry a lower per-minute limit, a lower monthly limit and an expiry date; the dashboard sets them at creation.
Endpoints
The live endpoint table is unavailable right now. The same information is in the OpenAPI document.
Feed item shape
GET /v1/feed?limit=&cursor=&category=&rank= returns up to 50 items (20 by default). Fields that your plan does not include are omitted rather than nulled, so tldr and summary are absent on the free plan.
{
"items": [
{
"id": "6f1c8a2e-1f4e-4f1a-9c2f-0a1b2c3d4e5f",
"story_id": "0b7f...",
"title": "Central bank holds rates as inflation cools",
"tldr": "Policymakers left the benchmark rate unchanged for a third meeting.",
"summary": "The central bank kept its policy rate...",
"publisher": "Example News",
"category": "Business",
"sentiment": "neutral",
"published_at": "2026-10-18T06:12:00Z",
"read_time": 4,
"is_bookmarked": false,
"is_liked": false,
"confidence_score": 0.87,
"url": "https://example.com/story"
}
],
"next_cursor": "eyJvZmZzZXQiOjIwfQ",
"total": 412
}Limits and quotas
Two independent limits apply to every request: a per-minute rate limit and a monthly allowance. Every metered response carries both in its headers (account endpoints like this one do not, because they never consume allowance):
| Header | Meaning |
|---|---|
| X-RateLimit-Limit | Requests allowed this minute for this key. |
| X-RateLimit-Remaining | Requests left in the current minute. |
| X-RateLimit-Reset | Unix timestamp (seconds) when the minute resets. |
| X-Quota-Limit | Effective monthly limit (includes anything your spend cap buys). Omitted on unmetered plans. |
| X-Quota-Remaining | Requests left this period. |
| X-Quota-Reset | Unix timestamp (seconds) your allowance resets at. |
| Retry-After | Seconds to wait — sent with 429 responses. |
| X-Request-Id | Correlation id for this request; include it in bug reports. |
| X-Required-Feature | Sent with 403 when the plan is missing a feature. |
A rejected request is never billed: throttling and quota refusals do not consume allowance and do not appear in your usage numbers at all. The allowance resets on your own billing anniversary (the date shown in the dashboard), not on the first of the month.
Errors
Every failure is one JSON shape, with a stable machine code to switch on:
{
"error": "the plan's monthly allowance is spent",
"code": "quota_exceeded",
"request_id": "req_9f2c41ab77d0"
}| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request body or parameters failed validation. The message names the field. |
| 401 | unauthorized | No credential was sent. |
| 401 | invalid_api_key | The key is not recognised. |
| 401 | key_revoked | The key was revoked (rotating a key revokes the previous one). |
| 401 | key_expired | The key's expiry date has passed. |
| 402 | quota_exceeded | The plan's monthly allowance is spent. Read X-Quota-Reset. |
| 402 | spend_cap_reached | Your own spend cap is reached. Raise it or wait for the reset. |
| 403 | plan_required | The plan does not include this endpoint; X-Required-Feature names the feature. |
| 403 | key_limit_reached | The plan's key limit is reached. Revoke a key or upgrade. |
| 404 | not_found | The resource does not exist, or is not visible to this account. |
| 409 | conflict | The resource already exists (for example a taken username). |
| 429 | rate_limited | Too many requests this minute. Read Retry-After. |
| 5xx | internal_error | Our fault. The request is refunded against your monthly counter. |
| 503 | service_unavailable | A dependency is down or the feature is not configured here. Retryable. |
Pagination
List endpoints return items, total and, when more remain, next_cursor. Send it back as ?cursor=. A cursor points at a position, so items arriving while you page cannot make you skip or repeat one. Treat next_cursor as opaque, and stop when it is absent.
Retries and idempotency
Reads (GET) are always safe to retry. Retry only after a 429 (respecting Retry-After) or a 5xx/503, and use exponential backoff with jitter so a bad minute does not become a thundering herd.
- Writes are idempotent except where noted: adding a bookmark, removing one, and revoking a key can be repeated safely.
- Attention:
POST /v1/articles/:id/likeis a toggle — retrying it undoes the first call. Read the response rather than retrying blindly. POST /v1/eventsappends: a retry records the event twice. Send your own event id insidepayloadand dedupe on your side if that matters.- This API does not use idempotency keys; the rules above are the contract, so a retry never charges you twice for the same work.
Versioning and deprecation
- The version is in the path (
/v1). Within it, fields are added, never silently removed or repurposed; write your parser to ignore unknown fields. - A breaking change ships as
/v2alongside/v1: nothing is switched off under your feet. - Deprecations are announced in the changelog at least 90 days before
/v1behaviour changes, and the old and new behaviour run in parallel until the announced date. - Contract version in this document:
1.0.0.
Legal and operational
Acceptable use, attribution requirements and data retention are in the terms and acceptable use policy. Current availability is on the status page.