Events
2 operations under /v1/events (GET POST): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
GET /v1/events/summary
https://api.codespar.dev/v1/events/summaryCount the project's events in a window, by type
Events the calling credential's project recorded inside the window, counted by type. Counts only, never a payload. A test-fire is not counted, whatever type it was sent as.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
window | "1h" | "24h" | "7d" | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | window is not one of the listed values. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
by_type | object | yes | Only types with at least one event appear. |
total | integer | yes | — |
window | string | yes | — |
curl -X GET https://api.codespar.dev/v1/events/summary \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/events/summary HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/events/summary",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/events/summary", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.get("/v1/events/summary");{
"window": "string",
"total": 0,
"by_type": {}
}POST /v1/events/{event_id}/replay
https://api.codespar.dev/v1/events/{event_id}/replayRe-dispatch a stored event to its subscribers
Re-runs the fan-out for an event that is already stored. The event itself is untouched: no new event row is written, so server-side de-duplication and the audit trail stay intact, and each dispatch appends its own fresh delivery row.
The event resolves only inside the calling credential's org AND project, so an event id from a sibling project is 404 here rather than replayed into the current project's subscribers.
WITHOUT trigger_id the event goes to every ACTIVE subscription in this project whose subscribed event type matches the stored event's and whose condition, if it has one, holds for the stored payload. With it, the fan-out is narrowed to that one subscription, which is the useful shape when debugging a single receiver — and the subscription is checked up front, so a mismatch or a paused subscription is refused before anything is delivered rather than dropped silently downstream.
202, NOT 200, AND THE NUMBERS ARE HANDOFF COUNTS. dispatched is how many active subscriptions the event was handed to and recorded against: each gets a delivery row and settles independently, so a receiver that is down does not lower this number and does not fail the call — its failed delivery is retried. rejected is how many dispatches left NO delivery row — the dispatch failed, or its attempt could not be recorded even in minimal form — so nothing will retry them, and a non-zero rejected is ours to investigate, not the receiver's. dispatched + rejected is the number of matching subscriptions. Both zero means nothing in this project subscribes to this event's type — it is not an error, and it is the answer you get when the subscription you meant lives in another project.
A write-scope refusal while recording a dispatch is never folded into rejected: the rest of the fan-out still runs, and then the call answers with the refusal itself (write_scope_undeclared and its siblings, in their own { error, remediation } envelope), because that is a defect on our side and not a receiver outcome.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
event_id | string | yes | Id of a stored event in the calling credential's org and project. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
trigger_id | string | no | Narrow the fan-out to one subscription. It must live in the same org and project, subscribe to this event's type, and be active; each of those is a different refusal below. |
Responses
| Status | Body | Description |
|---|---|---|
202 | object | Accepted — the dispatches were handed off. It is not a statement that any receiver answered. |
400 | object | The named subscription is subscribed to a different event type than the stored event. details carries trigger_event and event_type so the mismatch does not have to be guessed. |
404 | object | No such event, or no such subscription, inside the calling credential's org and project. The two codes are distinct so a caller can tell which of the two ids was wrong. |
409 | object | The named subscription exists and matches the event type but is not active. details.status carries the state it is actually in. |
Response 202
| Field | Type | Required | Description |
|---|---|---|---|
dispatched | integer | yes | Active subscriptions the event was handed to and recorded against. A failing receiver does not lower it: its delivery is recorded and retried. |
event_id | string | yes | Echoes the replayed event. Unchanged: replay does not mint a new event. |
rejected | integer | yes | Dispatches that left no delivery row — the dispatch failed, or its attempt could not be recorded — so nothing will retry them. Not counted in dispatched. |
trigger_id | string,null | yes | Echoes the query parameter, or null when the fan-out was not narrowed. |
curl -X POST https://api.codespar.dev/v1/events/{event_id}/replay \
-H "Authorization: Bearer $CODESPAR_API_KEY"POST /v1/events/{event_id}/replay HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.post(
"https://api.codespar.dev/v1/events/{event_id}/replay",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/events/{event_id}/replay", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.post("/v1/events/{event_id}/replay", {
path: {
event_id: "event_0000000000000000"
}
});{
"event_id": "event_0000000000000000",
"dispatched": 0,
"rejected": 0,
"trigger_id": "trg_0000000000000000"
}Webhook Deliveries
1 operation under /v1/webhook-deliveries (GET): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.
Audit
3 operations under /v1/audit (GET POST): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.