For developers and AI agents
Public API
A free, read-only JSON API for The Civic Circle's published stories and events, for developers and AI agents.
The basics
- No key or sign-up. Send a plain GET request.
- Read-only. Only published stories and events are returned; drafts never are.
- CORS is open, so you can call it from a browser.
- Dates are ISO 8601 in UTC. Event dates in filters and the
datefield are Pacific time. - Every URL is absolute. Every story includes its
sources: links to the public records it is based on. - Responses are cached for up to 10 minutes. New stories appear within that window, usually sooner.
- Please link to the story URL when you quote or summarize our reporting.
List stories
GET /api/v1/articles
Published stories, newest first.
| Parameter | What it does |
|---|---|
beat | One of: city-hall, county, schools, port-and-development, public-safety, roads-and-utilities, business, community |
place | A community name, such as Longview or Castle Rock. Not case-sensitive. |
limit | How many to return, 1 to 100. Default 20. |
Example: /api/v1/articles?beat=schools&place=Kelso&limit=5
{
"data": [
{
"slug": "longview-council-approves-water-rate-increase",
"url": "https://civiccircle.news/story/longview-council-approves-water-rate-increase",
"apiUrl": "https://civiccircle.news/api/v1/articles/longview-council-approves-water-rate-increase",
"headline": "Longview council approves water rate increase",
"dek": "Residential water bills will rise about $4 a month.",
"beat": { "id": "city-hall", "label": "City Hall", "url": "https://civiccircle.news/beat/city-hall" },
"places": ["Longview"],
"publishedAt": "2026-11-14T02:15:00.000Z",
"updatedAt": "2026-11-14T02:15:00.000Z",
"meetingDate": "2026-11-13",
"keyFacts": ["Vote was 6-1"],
"sources": [
{ "title": "Council agenda packet", "url": "https://...", "accessedAt": "2026-11-13" }
],
"image": null,
"shareImageUrl": "https://civiccircle.news/og/story/longview-council-approves-water-rate-increase"
}
],
"meta": { "count": 1, "filters": { "beat": "city-hall", "place": null, "limit": 20 } }
}Get one story
GET /api/v1/articles/{slug}
Everything in the list format, plus bodyMarkdown (the full story), corrections (each with a note and date), reviewedBy and a disclosure line explaining how the story was made. Returns 404 if the story does not exist or is not published.
List events
GET /api/v1/events
Published events, soonest first. Without from, only events that have not ended are returned.
| Parameter | What it does |
|---|---|
city | A community name, such as Kelso. Not case-sensitive. |
from | YYYY-MM-DD (start of that day, Pacific) or a full ISO 8601 datetime. Events still running at that time are included. |
to | YYYY-MM-DD (through the end of that day, Pacific) or an ISO 8601 datetime. |
limit | 1 to 200. Default 50. |
Example: /api/v1/events?city=Kelso&from=2026-11-01&to=2026-11-30
{
"data": [
{
"slug": "kelso-school-board-meeting",
"url": "https://civiccircle.news/events/kelso-school-board-meeting",
"title": "Kelso School Board meeting",
"startsAt": "2026-11-24T02:30:00.000Z",
"endsAt": "2026-11-24T04:30:00.000Z",
"allDay": false,
"date": "2026-11-23",
"timeZone": "America/Los_Angeles",
"venue": { "name": "...", "streetAddress": "...", "city": "Kelso", "state": "WA", "postalCode": "98626" },
"cost": "Free",
"isFree": true,
"sourceUrl": "https://...",
"calendarUrl": "https://civiccircle.news/events/kelso-school-board-meeting/calendar.ics"
}
],
"meta": { "count": 1, "timeZone": "America/Los_Angeles", "filters": { "city": "Kelso", "from": null, "to": null, "limit": 50 } }
}Errors
Errors return a 4xx or 5xx status with { "error": { "code", "message" } }. A bad filter returns 400 with invalid_query and a message saying what to fix. A missing story returns 404 with not_found.
Other ways in
- RSS feed of the 50 newest stories, and one per beat, such as schools.
- Events calendar: subscribe in Google Calendar, Apple Calendar or Outlook.
- llms.txt: a plain-text guide to the site for AI agents.
- Sitemap and news sitemap.