Updates Portal API
The Updates Portal exposes a small public JSON API so you can poll status, ingest changelog entries, watch the roadmap, and check known issues from your own systems. No authentication required. The API serves the English text only; a language prefix in the path is ignored.
Base URL
https://updates.foura.ai
Service Status
GET /api/v1/status
Returns the live operational status of every FourA service, plus active and recent incidents. Server-side cached for 15 seconds, so polling more often than that returns the same payload.
curl https://updates.foura.ai/api/v1/status
{
"overall": "operational",
"services": [
{
"slug": "api",
"name": "API",
"description": "...",
"status": "operational",
"daily": [
{ "date": "2026-05-19", "status": "operational", "major_outage_minutes": 0, "partial_outage_minutes": 0, "degraded_minutes": 0, "internal_degraded_minutes": 0 }
]
}
],
"active_incidents": [],
"recent_incidents": [
{ "id": "...", "service_slug": "api", "service_name": "API", "impact": "minor", "started_at": "...", "resolved_at": "..." }
]
}
| Top-level field | Type | Description |
|---|---|---|
overall |
string | operational if every service is healthy, otherwise one of the service status values |
services |
array | One entry per monitored service with slug, name, description, current status, and daily history (up to 90 days) |
active_incidents |
array | Incidents that are currently open |
recent_incidents |
array | Resolved incidents from the last 14 days |
Service status values: operational, degraded, partial_outage, major_outage, maintenance.
Incident impact values: minor (degraded performance), major (partial disruption), critical (service disruption).
Polling pattern
Use this endpoint to wire FourA status into your own dashboard or paging system.
When the status data can't be fetched, the endpoint answers 502 with {"error": "Monitor unreachable"}. Treat that as an unknown status rather than a bad one, and try again on the next poll.
import requests
def check_foura():
r = requests.get("https://updates.foura.ai/api/v1/status", timeout=5)
r.raise_for_status() # raises on the 502 "Monitor unreachable" answer: retry next poll
data = r.json()
if data["overall"] != "operational":
# Page on-call, post to Slack, flip a feature flag, etc.
for svc in data["services"]:
if svc["status"] != "operational":
print(f"{svc['name']}: {svc['status']}")
return data
The legacy GET /api/status returns 410 Gone and points callers here.
Changelog
GET /api/changelog
Returns published changelog entries in reverse chronological order.
curl "https://updates.foura.ai/api/changelog?limit=20"
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 | 1-indexed page number |
limit |
integer | 20 | Entries per page (max 50) |
category |
string | - | Filter to new, improved, or fixed |
{
"entries": [
{
"id": 42,
"title": "...",
"body": "Markdown body",
"category": "new",
"tags": "[\"api\",\"dashboard\"]",
"published": 1,
"published_at": "2026-05-19T12:00:00Z",
"created_at": "2026-05-19 11:42:08",
"updated_at": "2026-05-19 11:44:31"
}
],
"total": 137,
"page": 1,
"limit": 20
}
| Field | Type | Description |
|---|---|---|
id |
integer | Entry ID |
title |
string | Entry title |
body |
string | Markdown body |
category |
string | new, improved, or fixed |
tags |
string | A JSON array encoded as a string. Parse it before use: json.loads(entry["tags"]). |
published |
integer | Always 1 here. The endpoint only returns published entries. |
published_at |
string | ISO 8601 with a Z suffix |
created_at |
string | YYYY-MM-DD HH:MM:SS, UTC, with no zone marker |
updated_at |
string | Same format as created_at |
The two timestamp formats are different on purpose: published_at is the editorial date and carries a zone, while created_at and updated_at are storage timestamps. Both are UTC. A parser that assumes one format for all three will throw on the other two.
RSS
The full changelog (30 most recent entries) is also published as RSS at:
https://updates.foura.ai/rss
Subscribe in Feedly, Miniflux, Thunderbird, or any reader. The feed body matches the changelog body, including markdown rendered to HTML.
Roadmap
GET /api/roadmap
Returns every published roadmap item, sorted by vote count then creation time.
curl https://updates.foura.ai/api/roadmap
{
"items": [
{
"id": 12,
"title": "...",
"description": "...",
"status": "planned",
"category": "developer-experience",
"votes": 23,
"target_date": "Q3 2026",
"completed_at": null,
"created_at": "2026-03-30 09:32:47"
}
]
}
Item status values: planned, in_progress, done, cancelled. The board at updates.foura.ai/roadmap renders three columns, so an item set to cancelled reaches you through this endpoint and never appears on the page.
category is a lowercase slug, not the label the page prints. Slugs in use today: api, infrastructure, developer-experience, dashboard, billing, analytics, authentication. Treat the list as open, since a new item can introduce a new one.
target_date is free text ("Q3 2026"), not a date. completed_at is null until an item ships, then ISO 8601 with a Z suffix (2026-09-01T10:15:30.000Z), the same format as a changelog entry's published_at. created_at uses YYYY-MM-DD HH:MM:SS in UTC. The two formats differ inside one object, so parse each field on its own.
Voting
POST /api/roadmap/:id/vote
Toggles a vote on a single roadmap item. Votes are anonymous and tied to the caller's IP plus the first 50 characters of its User-Agent. Calling again removes the vote. An unknown or unpublished item answers 404 {"error": "Not found"}.
curl -X POST https://updates.foura.ai/api/roadmap/12/vote
{ "votes": 24, "voted": true }
voted reports the post-call state: true if your vote was added, false if it was removed.
The roadmap endpoints, GET /api/roadmap and this one, are limited to 30 requests per minute per source IP. Over that, the answer is {"error": "Too many votes, slow down"}.
Known Issues
GET /api/issues
Returns issues tracked by FourA support.
curl "https://updates.foura.ai/api/issues?tab=open"
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
tab |
string | open |
open for active issues, resolved for resolved/closed |
{
"issues": [
{
"id": 5,
"title": "...",
"body": "Markdown description",
"severity": "medium",
"status": "investigating",
"service_id": 3,
"resolution": "",
"opened_at": "2026-05-18T09:00:00Z",
"resolved_at": null,
"service_name": "API"
}
]
}
| Field | Type | Description |
|---|---|---|
id |
integer | Issue ID |
title |
string | Short summary |
body |
string | Markdown description |
severity |
string | low, medium, high, or critical |
status |
string | open, investigating, resolved, or closed |
service_id |
integer or null | Numeric ID of the affected service. null when the issue isn't tied to one. |
service_name |
string or null | The service's display name, resolved for you. Read this instead of mapping service_id yourself. |
resolution |
string | How it was fixed. Empty string while the issue is open. |
opened_at |
string | ISO 8601 with a Z suffix |
resolved_at |
string or null | ISO 8601 with a Z suffix, null while open |
service_id is a numeric foreign key, not the slug you see on the status page. Match issues to services by service_name.
The issue payload is a fixed column list and carries no modification timestamp. Order or age an issue by opened_at and resolved_at. Of the three public collections, only changelog entries return created_at and updated_at.
The resolved tab returns the 30 most recently resolved issues and stops there. The open tab returns all of them.
Notes
- All endpoints are public and need no API key. The roadmap endpoints are limited to 30 requests per minute per source IP; the others carry no rate limit of their own today, so poll status no more often than its 15-second cache warrants.
- Responses are JSON over HTTPS. Roadmap and issues take no paging parameters. The one cap is
?tab=resolvedon issues, which returns 30 rows. - For free-text or raw HTML versions of the changelog, use the
/rssfeed instead of/api/changelog.
Related
- Service Status: Read the same data in the browser
- Changelog: Browse entries with filters and pagination
- Roadmap: Vote on items in the UI
- Known Issues: Read open and resolved issues
- Updates Portal: Section overview