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

Ingestion

The write path ingests traits and events using an organization API key (Authorization: Bearer <key>). All calls sit behind the organization rate limiter and the billing hard stop, and dedupe retries using Idempotency-Key or messageId. Every call requires the sourceId of an api source, from which Cowliss derives and stamps the app (see Apps tracking). Calls with an unknown or non-API sourceId are rejected, and an inactive one answers source_inactive. Event names starting with system. are rejected because that prefix is reserved for events Cowliss writes itself (see Event patterns).

Create or merge a profile

Auth: Org API key (Authorization: Bearer <key>).

Request body

{
"data": {
"sourceId": "string",
"identifiers": {
"anonymousId": "string"
},
"traits": {},
"consent": {
"marketing.newsletter": true
},
"timestamp": "2026-01-15T09:30:00.000Z",
"messageId": "string"
}
}
Field Type Required Constraints
data object yes
data.sourceId string yes length 1–∞
data.identifiers record<anonymousId | userId | clerkId | email, string> yes
data.traits object no default {}
data.consent record<string, boolean> no
data.timestamp string (date-time) no
data.messageId string no

Response 200

{
"data": {
"id": "string",
"orgId": "string",
"appId": "string",
"sourceId": "string",
"traits": {
"key": {}
},
"consent": {
"key": true
},
"mergedInto": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"identifiers": [
{
"kind": "anonymousId",
"value": "string",
"createdAt": "2026-01-15T09:30:00.000Z"
}
],
"anonymous": 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.sourceId string yes
data.traits record<string, any> yes
data.consent record<string, boolean> yes
data.mergedInto string | null yes
data.createdAt string (date-time) yes
data.updatedAt string (date-time) yes
data.identifiers object[] yes
data.identifiers[] object yes
data.identifiers[].kind “anonymousId” | “userId” | “clerkId” | “email” yes
data.identifiers[].value string yes
data.identifiers[].createdAt string (date-time) yes
data.anonymous 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.

Record one event

Auth: Org API key (Authorization: Bearer <key>).

Request body

{
"data": {
"sourceId": "string",
"identifiers": {
"anonymousId": "string"
},
"event": "string",
"properties": {},
"timestamp": "2026-01-15T09:30:00.000Z",
"messageId": "string"
}
}
Field Type Required Constraints
data object yes
data.sourceId string yes length 1–∞
data.identifiers record<anonymousId | userId | clerkId | email, string> yes
data.event string yes length 1–200
data.properties object no default {}
data.timestamp string (date-time) no
data.messageId string yes length 1–∞

Response 200

{
"data": {
"id": "string",
"orgId": "string",
"appId": "string",
"sourceId": "string",
"profileId": "string",
"event": "string",
"properties": {
"key": {}
},
"timestamp": "2026-01-15T09:30:00.000Z",
"receivedAt": "2026-01-15T09:30:00.000Z",
"messageId": "string",
"client": "string"
},
"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.sourceId string yes
data.profileId string yes
data.event string yes
data.properties record<string, any> yes
data.timestamp string (date-time) yes
data.receivedAt string (date-time) yes
data.messageId string | null yes
data.client string | 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.

Import one source’s calls in one request

Batch writes skip triggers on raw events, but segments still recompute and an automation triggered by segment entry can fire. A failing item is reported in the response and does not fail the rest of the batch.

Auth: Org API key (Authorization: Bearer <key>).

Request body

{
"data": {
"sourceId": "string",
"items": [
{}
]
}
}
Field Type Required Constraints
data object yes
data.sourceId string yes length 1–∞
data.items any[] yes items 1–500

Response 200

{
"data": {
"results": [
{
"ok": true,
"type": "identify",
"id": "string"
}
]
},
"meta": {
"requestId": "string",
"nextCursor": "string",
"hasMore": true,
"warnings": [
{
"code": "string",
"message": "string",
"suggestion": "string"
}
]
}
}
Field Type Required Constraints
data object yes
data.results object | object | object[] 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.

Which app a source id writes into

Auth: Org API key (Authorization: Bearer <key>).

Query parameters

{
"sourceId": "string"
}
Field Type Required Constraints
sourceId string yes length 0–200

Response 200

{
"data": {
"orgId": "string",
"app": {
"id": "string",
"name": "string"
},
"sources": [
{
"id": "string",
"kind": "api",
"name": "string",
"configured": true,
"lastReceivedAt": "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.orgId string yes
data.app object yes
data.app.id string yes
data.app.name string yes
data.sources object[] yes
data.sources[] object yes
data.sources[].id string yes
data.sources[].kind “api” | “clerk” yes
data.sources[].name string yes
data.sources[].configured boolean yes
data.sources[].lastReceivedAt 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.