Chronicle API
Read-only JSON for the world record behind the chronicle. GET only. A token is required. The token is not printed on this page.
There is one address, /api/narrative.php. The resource is the path after it. Facts
are /events. One play window, villages and chat together, is /session/latest.
Hosts
| World | Base |
|---|---|
| Staging | https://stagingrvian.u.rudgalvis.com/api/narrative.php |
| Production | https://travikas.rudgalvis.com/api/narrative.php |
/api/narrative.php/events is the events list. If the server drops the path after the
script, use ?resource=events and keep the other query parameters.
Times are unix seconds. The world timezone is on /meta (often Europe/Bucharest).
Auth
No cookies. Do not put the token in the query string.
Authorization: Bearer <token> or
X-Narrative-Token: <token> curl -sS -H "Authorization: Bearer $TOKEN" \
https://stagingrvian.u.rudgalvis.com/api/narrative.php/session/latest Getting a token
This is not a Twitter or X developer key, and there is no sign-up form on the site. The operator of
that world creates a shared secret for that host and gives it to you. Staging and production use
different secrets. Put the value only in the Authorization: Bearer or X-Narrative-Token header — never in the URL.
How the operator writes the secret on the server is not documented on this public page.
Errors
| Situation | HTTP | Body |
|---|---|---|
| Token file missing or empty | 404 | not_found |
| Missing or wrong token | 401 | unauthorized |
| Unknown path | 404 | unknown_resource |
| POST, PUT, or anything but GET | 405 | method_not_allowed |
/players or /alliances without session_start | 400 | session_start_required |
/oasis without from and to | 400 | from_and_to_required |
/session/… with no data and outside a window | 404 | no_session |
| OPTIONS (browser preflight) | 204 | empty |
Error bodies look like {"ok":false,"error":"unauthorized"}. A 401 also sends WWW-Authenticate: Bearer.
Pages
/sessions, /snapshots, /events, and /chat are
paged. /session/… is one payload.
| Query | Meaning |
|---|---|
limit | Page size. Default 200, maximum 500. |
since_id | Exclusive cursor. Row id, except /sessions where it is session_start. |
next_id | First id of the next page, or null when the list is finished. Send it back as since_id. |
include_payload=0 | Drop JSON blobs on snapshots and events. |
A session bundle caps each list at 2000 rows and sets truncated: true if any list
overflowed. Page /events and /chat yourself when that happens.
A chapter pull
GET /meta— timezone and the clock windows.GET /sessions— which play windows already have snapshots.GET /session/latestorGET /session/{unix}— one window.GET /oasis?from=&to=— clear, late hopper, and ambush for that span.- Charts across many windows:
GET /snapshots, walkingsince_id.
session_start=latest means the newest snapshot window, else the newest event window,
else the current play window (0 when the game is closed).
Resources
GET / or /meta
World name, server, timezone, speed, commence, current_session_start (0 outside play
hours), and the window list. No table read.
GET /sessions
Play windows that already have snapshot rows. Each item: session_start, villages, players, pop, off_power, troops. Sums use the preferred portrait: close when that window has a close, otherwise
open. Open and close are never added together.
GET /snapshots
One row per village per window. Preferred portrait unless you ask otherwise.
| Query | Meaning |
|---|---|
session_start | latest or unix. Omit it to walk history with since_id. |
kind | Default preferred. open / 0, close / 1, or all (both; do not double-count). |
uid wref alliance_id | Filters. alliance_id may be 0. |
Fields: session_start, kind (0 open, 1 close), taken_at, uid, player_name, alliance_id at snapshot time, wref, village_name, pop, hourly wood_prod clay_prod iron_prod crop_prod (crop_prod is after upkeep and can be negative), warehouse_capacity, granary_capacity, off_power (field
attack, without catapults, rams, chiefs, or settlers), def_inf_power, def_cav_power, catapults, rams, chiefs, troop_count, wall_level, cranny_capacity, trapper_traps, ap, dp. payload is units (u1… and hero) and tribe 1, 2, or 3, unless include_payload=0.
GET /players and /alliances
Rollups for one session_start (latest allowed). Required. Same kind query as snapshots. The response includes kind: preferred, open, close, or all.
Players, sorted by population: uid, name, alliance_id, villages, pop, the four productions, both capacities, attack and defense
powers, catapults, rams, chiefs, troop_count, cranny_capacity, trapper_traps, wall_level (maximum), ap, dp.
Alliances: alliance_id, players, villages, pop,
productions, capacities, off_power, troop_count, catapults, chiefs. alliance_id 0 is unaffiliated.
GET /events
Facts as they happened. Fight size (skirmish, battle, great battle) is not stored. Compute it from these rows and the snapshots.
| Query | Meaning |
|---|---|
session_start | Events tagged with that window. 0 is off-hours. |
from to | Event time range, inclusive, unix. |
type | Comma list, for example battle,raid,conquest. |
actor_uid target_uid | Who acted, who was hit. |
type | Meaning |
|---|---|
battle raid scout | Combat. |
conquest | Village taken. |
village_destroyed | Razed. |
building_complete | A building finished. payload.notable marks Palace, Residence, Treasury, Wonder, walls, and milestones. |
ww_progress | Wonder level. |
artifact | Claim. |
hero_death | Attacker or defender hero. |
alliance_create alliance_join alliance_leave alliance_kick alliance_war | Alliance life. |
medals_week | Weekly ribbons. |
Shared fields: id, time, session_start, type, actor_uid, target_uid, from_wref, to_wref, troops_attacker, troops_defender, losses_attacker, losses_defender, resources_moved, payload (names and unit
breakdowns at that moment).
An oasis fight with Nature as target_uid can still be a player waiting on the tile.
Use /oasis to split clear, late hopper, and ambush.
GET /oasis
Requires from and to (unix). Labels each oasis fight clear (animals only), late_hopper (empty tile), or ambush (a player defense was already there). A player tribe on the defender side
proves an ambush even when the tile owner is still Nature.
The body includes counts, the three lists, and ambush_gate. Say there
were zero ambushes only when notices_scanned and reports_scanned are true
and ambush_count is 0. An ambush row may carry defender_uid for the writer. The published reading names the raider only.
GET /chat
Public channel and alliance chat. Private messages are never in this API.
| Query | Meaning |
|---|---|
from to | Message time. |
scope | global, or an alliance id. |
uid | Author. |
Fields: id, chat_id, time, uid, name, scope, msg.
GET /session/latest or /session/{unix}
One play window: session_start, session_end, kind, label, truncated, then snapshots, players, alliances, events, and chat. Events fall inside the window.
Chat is that range plus 30 minutes on each side. Snapshots use the preferred portrait. An empty
snapshot list is normal until the window has been recorded.