Skip to content
Cowliss is in beta: features and pricing may change.

Apps

An app is the attribution unit for one product: it carries no kind, configuration, or credential of its own, and each event and profile carries its appId. Inbound pipes into an app are sources created under it, and all of an app’s sources land on the same profiles. This includes the first-party api source created with the app, which the SDK and HTTP path write through. Routes that address a source by its own id (including the public webhook receiver) are on the Sources page. See the Apps and sources guide.

Create an app

Auth: Session token.

Request body

{
"data": {
"name": "string"
}
}
Field Type Required Constraints
data object yes
data.name string yes length 1–100

Response 201

{
"data": {
"id": "string",
"orgId": "string",
"name": "string",
"publicName": "string",
"returnUrl": "string",
"unsubscribeUrlTrait": "string",
"status": "active",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"archivedAt": "2026-01-15T09:30:00.000Z",
"events": [
"string"
],
"eventsSource": "push",
"sourceCount": 42,
"lastReceivedAt": "2026-01-15T09:30:00.000Z",
"automationCount": 42,
"templateCount": 42
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.id string yes
data.orgId string yes
data.name string yes
data.publicName string | null yes
data.returnUrl string | null yes
data.unsubscribeUrlTrait string | null yes
data.status “active” | “archived” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
data.archivedAt string (date-time) | null yes
data.events string[] | null yes
data.eventsSource “push” | “api” yes
data.sourceCount integer yes
data.lastReceivedAt string (date-time) | null yes
data.automationCount integer yes
data.templateCount integer yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

List apps

Auth: Session token.

Query parameters

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

Response 200

{
"data": [
{
"id": "string",
"orgId": "string",
"name": "string",
"publicName": "string",
"returnUrl": "string",
"unsubscribeUrlTrait": "string",
"status": "active",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"archivedAt": "2026-01-15T09:30:00.000Z",
"events": [
"string"
],
"eventsSource": "push",
"sourceCount": 42,
"lastReceivedAt": "2026-01-15T09:30:00.000Z",
"automationCount": 42,
"templateCount": 42
}
],
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object[] yes
data[] object yes
data[].id string yes
data[].orgId string yes
data[].name string yes
data[].publicName string | null yes
data[].returnUrl string | null yes
data[].unsubscribeUrlTrait string | null yes
data[].status “active” | “archived” yes
data[].createdAt string (date-time) yes
data[].updatedAt string (date-time) yes
data[].archivedAt string (date-time) | null yes
data[].events string[] | null yes
data[].eventsSource “push” | “api” yes
data[].sourceCount integer yes
data[].lastReceivedAt string (date-time) | null yes
data[].automationCount integer yes
data[].templateCount integer yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Every live app’s health

Each live app the caller reaches, with its six checks and its health (as apps.health.get), plus its events and deliveries in the last 24 hours, an hourly series of events over 7 days, its failed rate, its last event and its last push. Problems first, then the busiest. One response, not a page.

Auth: Session token, or an org pipeline key.

Response 200

{
"data": {
"apps": [
{
"appId": "string",
"name": "string",
"sourceId": "string",
"health": "fail",
"checks": [
{
"code": "events_arriving",
"status": "pass",
"label": "string",
"detail": "string",
"prompt": "string",
"names": [
"string"
]
}
],
"events24h": 42,
"hourly": [
42
],
"deliveries24h": 42,
"failedRate": 42,
"lastEventAt": "2026-01-15T09:30:00.000Z",
"lastPushAt": "2026-01-15T09:30:00.000Z"
}
]
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.apps object[] yes
data.apps[] object yes
data.apps[].appId string yes
data.apps[].name string yes
data.apps[].sourceId string | null yes
data.apps[].health “fail” | “warn” | “setting_up” | “quiet” | “healthy” yes
data.apps[].checks object[] yes
data.apps[].checks[] object yes
data.apps[].checks[].code “events_arriving” | “key_scoped” | “code_pushed” | “sending_domain” | “automations_on” | “events_listed” | “signup_sender” yes
data.apps[].checks[].status “pass” | “warn” | “fail” | “not_used” yes
data.apps[].checks[].label string yes
data.apps[].checks[].detail string yes
data.apps[].checks[].prompt string | null yes
data.apps[].checks[].names string[] no
data.apps[].events24h integer yes 0 ≤ x ≤ ∞
data.apps[].hourly integer[] yes
data.apps[].deliveries24h integer yes 0 ≤ x ≤ ∞
data.apps[].failedRate number | null yes
data.apps[].lastEventAt string (date-time) | null yes
data.apps[].lastPushAt string (date-time) | null yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Whether an app is set up and healthy

Seven checks, each with a stable code, a status (pass, warn, fail or not_used), a label and a detail line, and for a check that does not pass, a prompt an agent can act on: events_arriving (an event in the last 6 hours, or the app is quiet), key_scoped (the last 24 hours of events were signed by keys that reach only this app), code_pushed (the last build of every automation and template succeeded), sending_domain (every domain an automation sends from is verified), automations_on (no automation is on hold), events_listed (every name seen since the last push is in cow.json) and signup_sender (an app with a list has the default sender its signup confirm emails leave from). health rolls them up: fail, then warn, then setting_up (no event ever), quiet or healthy.

Auth: Session token, or an org pipeline key.

Response 200

{
"data": {
"appId": "string",
"name": "string",
"sourceId": "string",
"health": "fail",
"checks": [
{
"code": "events_arriving",
"status": "pass",
"label": "string",
"detail": "string",
"prompt": "string",
"names": [
"string"
]
}
],
"events24h": 42,
"hourly": [
42
],
"deliveries24h": 42,
"failedRate": 42,
"lastEventAt": "2026-01-15T09:30:00.000Z",
"lastPushAt": "2026-01-15T09:30:00.000Z"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.appId string yes
data.name string yes
data.sourceId string | null yes
data.health “fail” | “warn” | “setting_up” | “quiet” | “healthy” yes
data.checks object[] yes
data.checks[] object yes
data.checks[].code “events_arriving” | “key_scoped” | “code_pushed” | “sending_domain” | “automations_on” | “events_listed” | “signup_sender” yes
data.checks[].status “pass” | “warn” | “fail” | “not_used” yes
data.checks[].label string yes
data.checks[].detail string yes
data.checks[].prompt string | null yes
data.checks[].names string[] no
data.events24h integer yes 0 ≤ x ≤ ∞
data.hourly integer[] yes
data.deliveries24h integer yes 0 ≤ x ≤ ∞
data.failedRate number | null yes
data.lastEventAt string (date-time) | null yes
data.lastPushAt string (date-time) | null yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Fetch one app

Auth: Session token.

Response 200

{
"data": {
"id": "string",
"orgId": "string",
"name": "string",
"publicName": "string",
"returnUrl": "string",
"unsubscribeUrlTrait": "string",
"status": "active",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"archivedAt": "2026-01-15T09:30:00.000Z",
"events": [
"string"
],
"eventsSource": "push",
"sourceCount": 42,
"lastReceivedAt": "2026-01-15T09:30:00.000Z",
"automationCount": 42,
"templateCount": 42
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.id string yes
data.orgId string yes
data.name string yes
data.publicName string | null yes
data.returnUrl string | null yes
data.unsubscribeUrlTrait string | null yes
data.status “active” | “archived” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
data.archivedAt string (date-time) | null yes
data.events string[] | null yes
data.eventsSource “push” | “api” yes
data.sourceCount integer yes
data.lastReceivedAt string (date-time) | null yes
data.automationCount integer yes
data.templateCount integer yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Rename or archive an app, set what recipients see of it, or its event list

Admin only. Archiving is permanent: an archived app cannot be unarchived or modified. Renaming changes the display name only; the app id never changes. publicName is what recipients see the app called on the pages an unsubscribe link opens, in place of name, and returnUrl (https only) is where those pages link back to. An empty string or null clears either. unsubscribeUrlTrait names a profile trait holding the recipient’s own unsubscribe URL, which a marketing email then links to in place of Cowliss’s unsubscribe; that URL answers GET with a page offering the change and makes it only on the one-click POST (see Partners). An empty string or null clears it. events replaces the app’s event list (the names it sends, as in cow.json), and null turns the list off; a later push that names a different list asks before overwriting it.

Auth: Session token.

Request body

{
"data": {
"name": "string",
"status": "archived",
"publicName": "string",
"returnUrl": "string",
"unsubscribeUrlTrait": "string",
"events": [
"string"
]
}
}
Field Type Required Constraints
data object yes
data.name string no length 1–100
data.status “archived” no
data.publicName string | null no
data.returnUrl string | null no
data.unsubscribeUrlTrait string | null no
data.events string[] | null no

Response 200

{
"data": {
"id": "string",
"orgId": "string",
"name": "string",
"publicName": "string",
"returnUrl": "string",
"unsubscribeUrlTrait": "string",
"status": "active",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"archivedAt": "2026-01-15T09:30:00.000Z",
"events": [
"string"
],
"eventsSource": "push",
"sourceCount": 42,
"lastReceivedAt": "2026-01-15T09:30:00.000Z",
"automationCount": 42,
"templateCount": 42
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.id string yes
data.orgId string yes
data.name string yes
data.publicName string | null yes
data.returnUrl string | null yes
data.unsubscribeUrlTrait string | null yes
data.status “active” | “archived” yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
data.archivedAt string (date-time) | null yes
data.events string[] | null yes
data.eventsSource “push” | “api” yes
data.sourceCount integer yes
data.lastReceivedAt string (date-time) | null yes
data.automationCount integer yes
data.templateCount integer yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

What an app’s automations and templates are doing

Auth: Session token, or an org pipeline key.

Response 200

{
"data": {
"appId": "string",
"keys": [
{
"kind": "automation",
"key": "string",
"latestVersion": {
"id": "string",
"orgId": "string",
"key": "string",
"kind": "automation",
"appId": "string",
"source": "push",
"moduleDigest": "string",
"manifest": {
"key": "string",
"tags": {},
"trigger": {
"event": "string"
},
"purpose": "string",
"enrollment": {
"cooldown": "string"
},
"description": "string",
"from": "string",
"definition": {
"trigger": {
"event": "string"
},
"purpose": "marketing",
"from": "string",
"tags": {},
"description": "string",
"enrollment": {
"cooldown": "string"
},
"steps": [
{
"id": "string",
"type": "sleep",
"duration": "string"
}
]
},
"spine": [
{
"name": "sleep",
"detail": "string",
"timeout": "string",
"steps": [],
"otherwise": []
}
],
"bundle": "string"
},
"protocol": 42,
"status": "compiling",
"pushedAt": "2026-01-15T09:30:00.000Z",
"compiledAt": "2026-01-15T09:30:00.000Z",
"error": "string"
},
"status": "on",
"liveExecutions": 42
}
],
"warnings": [
"string"
]
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.appId string yes length 0–200
data.keys object[] yes
data.keys[] object yes
data.keys[].kind “automation” | “template” yes
data.keys[].key string yes
data.keys[].latestVersion object | null yes
data.keys[].latestVersion.id string yes
data.keys[].latestVersion.orgId string yes
data.keys[].latestVersion.key string yes
data.keys[].latestVersion.kind “automation” | “template” yes
data.keys[].latestVersion.appId string yes
data.keys[].latestVersion.source “push” | “api” yes
data.keys[].latestVersion.moduleDigest string | null yes
data.keys[].latestVersion.manifest object | object yes
data.keys[].latestVersion.protocol integer yes -2147483648 ≤ x ≤ 2147483647
data.keys[].latestVersion.status “compiling” | “ready” | “failed” yes
data.keys[].latestVersion.pushedAt string (date-time) yes
data.keys[].latestVersion.compiledAt string (date-time) | null yes
data.keys[].latestVersion.error string | null yes
data.keys[].status “on” | “off” | “paused” | null yes
data.keys[].liveExecutions integer yes
data.warnings string[] yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

An app’s broadcast look and default sender

The app’s Brand: the logo, colours and font every broadcast, the signup confirm email and the hosted signup and unsubscribe pages render with, the postal address under a broadcast’s footer, the from and replyTo a new broadcast takes when it names none (and the from the confirm email leaves from), and the language of the confirm email and the hosted pages (en, fr, ro or es; English when unset). logoWidth and logoHeight are the logo’s pixel size, read by the API; the logo renders at that size, scaled down to fit 200 by 64. Empty until an admin sets them.

Auth: Session token.

Response 200

{
"data": {
"logoUrl": "https://example.com/hooks/cowliss",
"colors": {
"background": "string",
"text": "string",
"heading": "string",
"link": "string",
"button": "string",
"buttonText": "string"
},
"font": "string",
"logoWidth": 42,
"logoHeight": 42,
"postalAddress": "string",
"from": "string",
"replyTo": "[email protected]",
"language": "en"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.logoUrl string (uri) no length 0–2048
data.colors object no
data.colors.background string no
data.colors.text string no
data.colors.heading string no
data.colors.link string no
data.colors.button string no
data.colors.buttonText string no
data.font string no
data.logoWidth integer no
data.logoHeight integer no
data.postalAddress string no length 1–300
data.from string no length 0–200
data.replyTo string (email) no length 0–320
data.language “en” | “fr” | “ro” | “es” no
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Set an app’s broadcast look and default sender

Admin only. Replaces the whole of it: a field left out is cleared. from must be on a verified sending domain. logoWidth and logoHeight are ignored: the API keeps them while logoUrl is unchanged, reads them from an uploaded logo, and otherwise fetches a changed logoUrl once and reads them from the image, refusing it unless it is a png, jpg, webp or gif at a public address.

Auth: Session token.

Request body

{
"data": {
"logoUrl": "https://example.com/hooks/cowliss",
"colors": {
"background": "string",
"text": "string",
"heading": "string",
"link": "string",
"button": "string",
"buttonText": "string"
},
"font": "string",
"logoWidth": 42,
"logoHeight": 42,
"postalAddress": "string",
"from": "string",
"replyTo": "[email protected]",
"language": "en"
}
}
Field Type Required Constraints
data object yes
data.logoUrl string (uri) no length 0–2048
data.colors object no
data.colors.background string no
data.colors.text string no
data.colors.heading string no
data.colors.link string no
data.colors.button string no
data.colors.buttonText string no
data.font string no
data.logoWidth integer no
data.logoHeight integer no
data.postalAddress string no length 1–300
data.from string no length 0–200
data.replyTo string (email) no length 0–320
data.language “en” | “fr” | “ro” | “es” no

Response 200

{
"data": {
"logoUrl": "https://example.com/hooks/cowliss",
"colors": {
"background": "string",
"text": "string",
"heading": "string",
"link": "string",
"button": "string",
"buttonText": "string"
},
"font": "string",
"logoWidth": 42,
"logoHeight": 42,
"postalAddress": "string",
"from": "string",
"replyTo": "[email protected]",
"language": "en"
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.logoUrl string (uri) no length 0–2048
data.colors object no
data.colors.background string no
data.colors.text string no
data.colors.heading string no
data.colors.link string no
data.colors.button string no
data.colors.buttonText string no
data.font string no
data.logoWidth integer no
data.logoHeight integer no
data.postalAddress string no length 1–300
data.from string no length 0–200
data.replyTo string (email) no length 0–320
data.language “en” | “fr” | “ro” | “es” no
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Upload a logo for an app’s broadcasts

Admin only. Stores the image and answers with the https url it is served at; pass that to apps.look.set as logoUrl, which this does not do itself. content is the image base64-encoded: a png, jpg, webp or gif (told by its bytes, never by a name or a declared type; svg is refused) of at most 1 MB. Every upload gets a new address, so replacing a logo never shows the old one from a cache. Answers dependency_unavailable where uploads are not set up.

Auth: Session token.

Request body

{
"data": {
"content": "string"
}
}
Field Type Required Constraints
data object yes
data.content string (base64) yes length 1–∞

Response 201

{
"data": {
"url": "https://example.com/hooks/cowliss",
"width": 42,
"height": 42
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.url string (uri) yes
data.width integer yes
data.height integer yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

Add a source to an app

Admin only. An api source takes a name, unique among the app’s active sources; an app may hold any number of them. A clerk source is named after its kind, and an app holds one active at a time.

Auth: Session token.

Request body

{
"data": {
"kind": "api",
"name": "string",
"config": {}
}
}
Field Type Required Constraints
data one of yes
data〈api〉 object yes
data〈api〉.kind “api” yes
data〈api〉.name string yes length 1–100
data〈api〉.config object no default {}
data〈clerk〉 object yes
data〈clerk〉.kind “clerk” yes
data〈clerk〉.config object no default {}
data〈clerk〉.config.signingSecret string no length 1–∞

Response 201

{
"data": {
"id": "string",
"orgId": "string",
"appId": "string",
"kind": "api",
"name": "string",
"config": "string",
"lastReceivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"deactivatedAt": "2026-01-15T09:30:00.000Z",
"status": "active",
"configured": true
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.id string yes
data.orgId string yes
data.appId string yes
data.kind “api” | “clerk” yes
data.name string yes
data.config string | number | boolean | null | record<string, any> | any[] yes
data.lastReceivedAt string (date-time) | null yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
data.deactivatedAt string (date-time) | null yes
data.status “active” | “inactive” yes
data.configured boolean yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.

List an app’s sources

Auth: Session token.

Query parameters

{
"cursor": "string",
"limit": 50
}
Field Type Required Constraints
cursor string no
limit integer no default 50; 1 ≤ x ≤ 100

Response 200

{
"data": [
{
"id": "string",
"orgId": "string",
"appId": "string",
"kind": "api",
"name": "string",
"config": "string",
"lastReceivedAt": "2026-01-15T09:30:00.000Z",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"deactivatedAt": "2026-01-15T09:30:00.000Z",
"status": "active",
"configured": true
}
],
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object[] yes
data[] object yes
data[].id string yes
data[].orgId string yes
data[].appId string yes
data[].kind “api” | “clerk” yes
data[].name string yes
data[].config string | number | boolean | null | record<string, any> | any[] yes
data[].lastReceivedAt string (date-time) | null yes
data[].createdAt string (date-time) yes
data[].updatedAt string (date-time) yes
data[].deactivatedAt string (date-time) | null yes
data[].status “active” | “inactive” yes
data[].configured boolean yes
meta object no
meta.requestId string no
meta.nextCursor string | null no
meta.hasMore boolean no
meta.warnings object[] no
meta.warnings[] object no
meta.warnings[].code string yes
meta.warnings[].message string yes
meta.warnings[].suggestion string no

Errors follow the shared envelope and code table.