Skip to content

CloudEvents & Knative Eventing

YipYap’s CloudEvents surface has three distinct API planes:

  1. Inbound ingest: external systems push CloudEvents into YipYap.
  2. Consumer transports: the yipyap-knative-source ContainerSource drains events out over HTTP long-poll or SSE stream.
  3. Reply audit: admins review the accepted/rejected reply log.

For conceptual documentation, see Knative Eventing → Overview.

SaaS Free tier is blocked from all CloudEvents endpoints (402 plan_gate_blocked). Pro and Enterprise receive per-tier rate limits; see Rate Limits. FOSS builds are tier-blind: every operator has access.

MethodPathDescriptionAuth
POST/api/v1/cloudevents/ingest/{token}Push a CloudEvent (single or batched).Org token in path OR OIDC Bearer.
GET/api/v1/cloudevents/pollLong-poll for outbound events.Bearer API key.
GET/api/v1/cloudevents/streamSSE stream of outbound events.Bearer API key.
GET/api/v1/knative/source-configMode + cadence hints for the yipyap-knative-source binary.Bearer API key.
GET/api/v1/admin/cloudevents/repliesAdmin reply-activity dashboard feed.Admin JWT.

POST /api/v1/cloudevents/ingest/{token}

Accepts:

  • Content-Type: application/cloudevents+json: single event, structured mode.
  • Content-Type: application/cloudevents-batch+json: up to 256 events per request.
  • Binary mode via the usual Ce-* headers plus an arbitrary-format body.

Authentication is either:

  • The path {token} (a per-org opaque credential created via org settings), or
  • An OIDC Bearer JWT, if the org has registered an Issuer and Audiences in ingest auth config.

See Knative Eventing → Authentication for the JWT setup.

Responses: 202 Accepted on success, 400 for malformed CloudEvent, 401 for bad auth, 402 if Free tier, 413 if batched array exceeds 256, 429 on rate limit.

GET /api/v1/cloudevents/poll?filter=run.yipyap.alert.*&cursor=<opaque>

Long-polls (up to 30 s) for events matching filter (glob against the CloudEvent type). Returns:

{
"data": [ /* CloudEvents in structured-mode JSON */ ],
"next_cursor": "",
"has_more": false
}

Cursors are stateful on the server: the poll consumer cache tracks your position. Switching to stream mode with the same cursor resumes cleanly.

Plan caps: Pro 30/min/org, Enterprise 60/min/org. Exceeded → 429 with Retry-After.

GET /api/v1/cloudevents/stream?filter=run.yipyap.alert.* (Server-Sent Events).

Each event is emitted as an SSE data: line containing the structured-mode JSON. Heartbeats are sent every 20 s to keep intermediaries from closing the connection.

Concurrency cap: Pro 5 streams/org, Enterprise 10. Opening the 6th (or 11th) stream returns 429 immediately without affecting existing streams.

GET /api/v1/knative/source-config

Returns the recommended mode (auto/poll/stream) and poll cadence for the yipyap-knative-source ContainerSource. The binary calls this on startup and again every refresh_after_seconds:

{
"mode": "stream",
"poll_interval_seconds": 5,
"stream_heartbeat_seconds": 20,
"refresh_after_seconds": 3600
}

No writes are possible; this is a read-only advisor.

GET /api/v1/admin/cloudevents/replies

Lists every state-mutating reply the org has received, whether accepted or rejected (including dispatcher-level rejections: org mismatch, trust-flag missing, rate-limited, unknown alertref).

{
"data": [
{
"id": "01HXAUD...",
"event_id": "reply-01HX...",
"event_type": "run.yipyap.reply.alert.claimed.v1",
"outbound_event_id": "out-01HX...",
"channel_id": "01HXCHAN...",
"source": "https://sre.example.com/",
"outcome": "accepted",
"alert_id": "01HXALERT...",
"received_at": "2026-04-24T17:42:03Z"
},
{
"id": "01HXAUD...",
"event_id": "reply-01HX...",
"event_type": "run.yipyap.reply.alert.escalated.v1",
"outcome": "rejected:trust_required",
"received_at": "2026-04-24T17:43:00Z"
}
],
"next_cursor": "",
"has_more": true
}

Query parameters: outcome (filter by prefix, e.g. rejected:*), event_type, channel_id, alert_id, from, to, limit, cursor.

Retention is tier-aware: Free 7 days, Pro 30 days, Enterprise 365 days.