Skip to content

Catalog

The tracking plan: catalog entries for event and trait names, each in a governance state (allowed, denied, quarantined, where denied always wins). Ingestion is accept-by-default; rejection has exactly two sources, the deny-list and canonical-trait format validations. With the org’s ingestionPolicy set to strict, unclassified names are held in the quarantine queue instead of applied; promoting a name allow-lists it and backfills its held values. Property and trait types: string, number, boolean, object, array<any>, array<string>, array<number>, array<boolean>, array<object>. Observation infers an array’s item type when its members agree, and array<any> when they do not or the array is empty. All mutations require org:admin.

Register an event name

Auth: Clerk session token.

Request body

{
"data": {
"name": "string",
"properties": {}
}
}
Field Type Required Constraints
data object yes
data.name string yes length 1–200
data.properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> no default {}

Response 201

{
"data": {
"orgId": "string",
"name": "string",
"properties": {
"key": "string"
},
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

List catalog events

Auth: Clerk session token.

Query parameters

{
"cursor": "string",
"limit": 50,
"q": "string",
"state": "allowed"
}
Field Type Required Constraints
cursor string no
limit integer no default 50; 1 ≤ x ≤ 100
q string no length 0–200
state “allowed” | “denied” no

Response 200

{
"data": [
{
"orgId": "string",
"name": "string",
"properties": {
"key": "string"
},
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}
],
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object[] yes
data[] object yes
data[].orgId string yes
data[].name string yes
data[].properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> yes
data[].state “allowed” | “denied” yes
data[].createdAt string (date-time) yes
data[].updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Fetch one catalog event

Auth: Clerk session token.

Response 200

{
"data": {
"orgId": "string",
"name": "string",
"properties": {
"key": "string"
},
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Update a catalog event

Auth: Clerk session token.

Request body

{
"data": {
"properties": {
"key": "string"
}
}
}
Field Type Required Constraints
data object yes
data.properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> yes

Response 200

{
"data": {
"orgId": "string",
"name": "string",
"properties": {
"key": "string"
},
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Allow or deny an event name

Auth: Clerk session token.

Request body

{
"data": {
"state": "allowed"
}
}
Field Type Required Constraints
data object yes
data.state “allowed” | “denied” yes

Response 200

{
"data": {
"orgId": "string",
"name": "string",
"properties": {
"key": "string"
},
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.properties record<string, “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>”> yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Register a trait

Auth: Clerk session token.

Request body

{
"data": {
"name": "string",
"type": "string"
}
}
Field Type Required Constraints
data object yes
data.name string yes length 1–200
data.type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes

Response 201

{
"data": {
"orgId": "string",
"name": "string",
"type": "string",
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

List catalog traits

Auth: Clerk session token.

Query parameters

{
"cursor": "string",
"limit": 50,
"q": "string",
"state": "allowed"
}
Field Type Required Constraints
cursor string no
limit integer no default 50; 1 ≤ x ≤ 100
q string no length 0–200
state “allowed” | “denied” no

Response 200

{
"data": [
{
"orgId": "string",
"name": "string",
"type": "string",
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
}
],
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object[] yes
data[] object yes
data[].orgId string yes
data[].name string yes
data[].type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes
data[].state “allowed” | “denied” yes
data[].createdAt string (date-time) yes
data[].updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Fetch one catalog trait

Auth: Clerk session token.

Response 200

{
"data": {
"orgId": "string",
"name": "string",
"type": "string",
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Update a catalog trait

Auth: Clerk session token.

Request body

{
"data": {
"type": "string"
}
}
Field Type Required Constraints
data object yes
data.type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes

Response 200

{
"data": {
"orgId": "string",
"name": "string",
"type": "string",
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Allow or deny a trait name

Auth: Clerk session token.

Request body

{
"data": {
"state": "allowed"
}
}
Field Type Required Constraints
data object yes
data.state “allowed” | “denied” yes

Response 200

{
"data": {
"orgId": "string",
"name": "string",
"type": "string",
"state": "allowed",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.orgId string yes
data.name string yes
data.type “string” | “number” | “boolean” | “object” | “array<any>” | “array<string>” | “array<number>” | “array<boolean>” | “array<object>” yes
data.state “allowed” | “denied” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Promote a quarantined name into the catalog

Auth: Clerk session token.

Request body

{
"data": {
"kind": "event",
"name": "string"
}
}
Field Type Required Constraints
data object yes
data.kind “event” | “trait” yes
data.name string yes length 1–∞

Response 200

{
"data": {
"promoted": 42
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.promoted integer yes 0 ≤ x ≤ ∞
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.

Deny a quarantined name

Auth: Clerk session token.

Request body

{
"data": {
"kind": "event",
"name": "string"
}
}
Field Type Required Constraints
data object yes
data.kind “event” | “trait” yes
data.name string yes length 1–∞

Response 200

{
"data": {
"dropped": 42
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true
}
}
Field Type Required Constraints
data object yes
data.dropped integer yes 0 ≤ x ≤ ∞
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no

Errors follow the shared envelope and code table.