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

Pushes

A push adds and updates every resource it names and touches nothing it does not name: a key absent from the body stays as the app holds it, an events list present replaces the app’s and absent leaves it, purposes present are upserted. It files a new version of every automation and template whose content changed; a key that did not change gets none. The plan names every resource the push would change whose current content was written in the dashboard or over the API as a conflict, and the push is refused over one unless force is set. A push turns nothing on: automation status is untouched. Deleting is always an explicit call.

What a push of these resources would change

Takes the body pushes.create takes, writes nothing, and refuses what that push would refuse. A resource with invalid fields answers validation_failed naming each one in error.issues by its kind, key and field.

Auth: Session token, or an org pipeline key.

Request body

{
"data": {}
}
Field Type Required Constraints
data any yes

Response 200

{
"data": {
"appId": "string",
"entries": [
{
"kind": "automation",
"key": "string",
"change": "added",
"fields": [
"string"
]
}
],
"drift": [
{
"kind": "automation",
"key": "string",
"reason": "not-in-tree"
}
],
"conflicts": [
{
"kind": "automation",
"key": "string",
"updatedAt": "2026-01-15T09:30:00.000Z"
}
],
"events": {
"added": [
"string"
],
"removed": [
"string"
],
"listed": true
},
"purposes": {
"added": [
"string"
],
"changed": [
"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.entries object[] yes
data.entries[] object yes
data.entries[].kind “automation” | “segment” | “template” yes
data.entries[].key string yes
data.entries[].change “added” | “changed” | “unchanged” yes
data.entries[].fields string[] yes
data.drift object[] yes
data.drift[] object yes
data.drift[].kind “automation” | “segment” | “template” yes
data.drift[].key string yes
data.drift[].reason “not-in-tree” | “on-hold” yes
data.conflicts object[] yes
data.conflicts[] object yes
data.conflicts[].kind “automation” | “segment” | “template” | “events” | “purpose” yes
data.conflicts[].key string yes
data.conflicts[].updatedAt string (date-time) yes
data.events object | null yes
data.events.added string[] yes
data.events.removed string[] yes
data.events.listed boolean yes
data.purposes object | null yes
data.purposes.added string[] yes
data.purposes.changed 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.

Push resources to an app

Applies the automations, templates, segments, event list and purposes in the body to the app in one transaction and files a version of every automation and template whose content changed. A resource the body leaves out is left as it is. Refused with conflict when a resource it would change was last written in the dashboard or over the API, unless force is true; refused when an automation’s from address uses a domain your organization has not verified. Resources with invalid fields are refused with validation_failed, which names every one in error.issues by its kind, key and field, and the first in the message, e.g. templates["welcome"].template.subject: a subject is required. A push that prunes (prune: true) takes an organization admin’s session.

Auth: Session token, or an org pipeline key.

Request body

{
"data": {}
}
Field Type Required Constraints
data any yes

Response 201

{
"data": {
"appId": "string",
"versions": [
{
"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"
}
],
"prunedSegments": [
"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.versions object[] yes
data.versions[] object yes
data.versions[].id string yes
data.versions[].orgId string yes
data.versions[].key string yes
data.versions[].kind “automation” | “template” yes
data.versions[].appId string yes
data.versions[].source “push” | “api” yes
data.versions[].moduleDigest string | null yes
data.versions[].manifest object | object yes
data.versions[].protocol integer yes -2147483648 ≤ x ≤ 2147483647
data.versions[].status “compiling” | “ready” | “failed” yes
data.versions[].pushedAt string (date-time) yes
data.versions[].compiledAt string (date-time) | null yes
data.versions[].error string | null yes
data.prunedSegments 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.