Skip to main content

Event catalog

Kudos CRM accepts events from this catalog only. A POST with an event_type outside the list returns 422 Unprocessable Entity with code: "event_type_not_in_catalog" — the request is rejected before any tenant data is touched.

This is deliberate. A closed catalog gives both sides a stable contract to test against and prevents one-off payload shapes from accumulating in production.

The 36 types​

Event typeFires whenMaps to CRM
signup.requestedVisitor submits the sign-up formLead created
signup.email_verifiedOTP / email click confirmsLead enriched
signup.qualifiedProducer-side qualification logic passesLead → MQL
signup.approvedOperator approves the new tenantLead → SQL, Deal opens
signup.rejectedOperator rejects the sign-upLead → unqualified
The "Maps to CRM" column is the default — mappings are configurable

What you see above is the default mapping each event triggers. The receiving organization can customize how any event maps to its CRM — which object it upserts, which fields and tags it sets, the pipeline stage and deal economics — per connection, with no code. The set of event types the CRM recognizes out of the box is always available, machine-readable, from the live manifest endpoint:

curl https://api.kudoscrm.com/api/v1/ingest/manifest
# → { "consumer": "crm", "supported_schema_versions": [1], "supported_event_types": [ … ] }

Treat the manifest as the source of truth for the accepted catalog; this page is the human-readable companion.

Envelope​

Every event uses the same outer envelope. The data field carries the per-type payload.

{
"schema_version": 1,
"event_id": "evt_01HZQK7C8R0T8Z2W5N4Y9P3X6V",
"event_type": "subscription.upgraded",
"fired_at": "2026-05-30T08:42:11Z",
"producer": { "name": "kudos", "version": "2.4.0" },
"tenant": {
"external_ref": "kudos_tenant_42",
"name": "Kudos Corp",
"country": "US"
},
"data": { "//": "per-type payload" }
}
FieldTypeRequiredNotes
schema_versionintegeryesMajor envelope version. Current is 1.
event_idstringyesUUIDv7 with evt_ prefix, 25-char base32 body. Idempotency key.
event_typestringyesMust be in the catalog above.
fired_atstringyesRFC 3339 UTC. Wall-clock on the producer at emit time.
producer.namestringyesStable identifier of your product.
producer.versionstringyesYour release version. Aids debugging.
tenant.external_refstringusuallyProducer-side tenant id. Omit only for cross-tenant events (e.g. webhook.ping).
tenant.name / tenant.countrystringnoConvenience for the CRM mapper.
dataobjectyesPer-type payload. Shape is documented per event in the API reference.

Per-type payload examples​

signup.requested
{
"data": {
"lead_email": "[email protected]",
"lead_first_name": "Alex",
"lead_last_name": "Morgan",
"company_name": "Kudos Corp",
"country": "US",
"lead_source": "google_ads",
"utm": { "source": "google", "medium": "cpc", "campaign": "spring_2026" }
}
}
subscription.created
{
"data": {
"subscription_id": "sub_01HZQK7C8R0T8Z2W5N4Y9P3X6V",
"plan_code": "growth_yearly",
"tier": "growth",
"billing_cycle": "yearly",
"currency": "USD",
"mrr_minor": 49900,
"arr_minor": 598800,
"seats": 25,
"starts_at": "2026-05-30T00:00:00Z",
"ends_at": "2027-05-30T00:00:00Z",
"trial": null
}
}
subscription.upgraded
{
"data": {
"subscription_id": "sub_01HZQK…",
"from": { "plan_code": "starter_monthly", "tier": "starter", "mrr_minor": 9900 },
"to": { "plan_code": "growth_yearly", "tier": "growth", "mrr_minor": 49900 },
"delta_mrr_minor": 40000,
"delta_arr_minor": 480000,
"effective_at": "2026-05-30T08:42:11Z"
}
}
payment.succeeded
{
"data": {
"payment_id": "pay_01HZQK…",
"subscription_id":"sub_01HZQK…",
"invoice_id": "inv_01HZQK…",
"amount_minor": 49900,
"currency": "USD",
"method": "card",
"captured_at": "2026-05-30T08:42:11Z"
}
}
tenant.suspended
{
"data": {
"reason_code": "non_payment",
"reason": "Three consecutive failed payments",
"suspended_at": "2026-05-30T08:42:11Z",
"actor": { "kind": "operator", "id": "op_…" },
"retention_until": "2026-08-28T00:00:00Z"
}
}
webhook.ping
{
"data": {
"source": "manual_test_fire",
"fired_by": { "id": "op_…", "email": "[email protected]" }
}
}

Tenant is null on ping events.

The full payload reference for every event is in the API Reference tab (try-it playground per endpoint).

Adding new event types​

We add new event types via the additive rule: a producer that does not know about a new type continues working unchanged. Consumers that do not handle a new type ignore it gracefully. Major version bumps are reserved for breaking changes (renames, removed fields, type changes), and trigger the 180-day deprecation window described on the introduction page.

If you need an event type that is not in the catalog, email [email protected] — we triage every request and tend to land additions within one sprint.