Read the project events feed (cursored catch-up or newest-first display order)
The durable, ordered, per-project feed of operationally significant facts — deploy activations, mailbox suspensions, transfers, lifecycle cliffs, verification outcomes. Answers "what happened to my project since cursor C" in one call. Read-only and never lifecycle-gated: a frozen project's feed stays readable (that is when you most need it). Authorize-before-reveal: unauthorized callers get 403, never a 404 existence oracle. After every deploy, the apply/promote success response's next_actions[] hands you this route with a cursor positioned at your own deploy_activated event. Two pagination modes, disjoint by construction: the default ascending catch-up (cursor — "what's new since") and the display-order read order=desc (+ before for older pages — "latest N, then the rest of history"). A desc response still carries the live high-water cursor, so a display surface flips to catch-up polling without a discovery call. Each event's next_actions[] entries carry kind: pointer (a read — safe to follow whenever, no judgment implied) or remediation (a change the platform is suggesting). A remediation may also carry precondition, the machine-checkable condition under which it is still warranted — renew_tier states one, because it spends money and is moot the moment the organization renews by another route. Treat an unqualified remediation as advice, not a live claim. Every event carries project_id; on this feed it is always this project, and it is null only on the organization feed, where facts that belong to no project also appear. A fact OUTLIVES the project it describes — deleting a project no longer erases its history, so a row may name a project that no longer exists.
Request
- Base URL: https://api.run402.com
- URL: https://api.run402.com/projects/v1/{project_id}/events
- Auth: one of:
- HTTP bearer
- API key in header SIGN-IN-WITH-X
- HTTP bearer
- HTTP bearer
Path parameters
Run402 project ID. Public IDs are not UUIDs.
Target project id. A service_key reads only its OWN project's feed; principals and delegates authorize via project.read.
Query parameters
Opaque cursor from a prior response's page-level cursor. Returns events strictly after it. Omit on first contact to start from the earliest retained event. Ascending catch-up only — it does not compose with order=desc (400); display reads page older via before. A cursor is bound to the PROJECTION that issued it (its scope and its source/event_type filters) and is not portable: replaying a project feed's cursor against the org feed, or an unfiltered cursor against a filtered read, returns reset: true + earliest_cursor rather than silently skipping the rows the other projection omitted. An event id is NOT a cursor — the same fact carries the same id in every feed, which is exactly why it cannot also encode a position; passing one back resets.
console-project-events-feed: desc selects the display-order read — the newest N visible events first (the visibility watermark applies identically), with before_cursor in the response when older rows remain. asc is the default's explicit alias, byte-identical to omitting the param. Any other value is rejected 400.
console-project-events-feed: opaque cursor (a prior desc response's before_cursor) bounding the page from above, exclusive — returns the next OLDER page. Requires order=desc (400 otherwise). Projection-bound like cursor: one issued for a different scope or filter set is unusable here. A malformed or foreign value follows the reset semantics: 200 with reset: true, earliest_cursor, and a restart from the newest page — never a bare 4xx.
Page size (default 50, max 200).
app-events-emit-lane: filter to just the app lane (source='app') or just platform-emitted rows (source<>'app' — the platform's internal producer split, e.g. gateway/apply/email-lambda-events, is an implementation detail; the public dichotomy is app vs. platform). Composes with cursor/limit (and order/before) unchanged: cursor stays the raw unfiltered high-water mark and has_more reflects the filtered view. Omit to see both.
app-events-emit-lane: comma-separated event_type names to filter to, e.g. signature_completed,booking_created. Each name must match ^[a-z][a-z0-9_]{2,63}$ or the request is rejected 400. Composes with source/cursor/limit (and order/before) unchanged.
event-attention-rules: only events at or above this severity (info < notice < warn < critical). Composes with source/event_type/cursor/limit (and order/before). Joins the page cursor's projection exactly as source and event_type do: a cursor from a filtered read replayed on a read with different filters takes the reset path, never a silent partial page. info filters nothing and is treated as absent. Any other value is 400 VALIDATION_FAILED.
Headers
SIWX auth header — base64-encoded JSON payload containing a signed CAIP-122 (EIP-4361) message. See https://docs.x402.org/extensions/sign-in-with-x.
Response
Feed page
Example response
{
"platform_incidents": [
{
"id": "inc_9b21fa0c7d4e15a3",
"subsystem": "gateway"
}
]
}Changes
No recorded changes to this operation across all 1 revision of this API.