Consent purposes
Every profile’s consent map answers its own app’s purposes, and every switch that offers one is labelled from here. Two are fixed for every app, the roots marketing and transactional, and turning a root off turns off every name under it. The rest are the names the app’s code declares under purposes in cow.json, such as marketing.newsletter or transactional.weeklyReport, so two apps may each declare a key under their own label. Bare transactional mail, a receipt or a password reset, is not a purpose anyone can withhold: the transactional root turns off only the names under it, never that mail. Purposes are code, like automations and templates, so this resource is read-only: a push is what adds or relabels one, and nothing ever deletes one, because profiles already hold answers against it.
GET /v1/consent-purposes
Section titled “GET /v1/consent-purposes”List the consent purposes an app declares
Auth: Session token.
Query parameters
{ "cursor": "string", "limit": 50, "appId": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
appId |
string | yes | length 0–200 |
Response 200
{ "data": [ { "key": "string", "label": "string", "description": "string" } ], "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[].key |
string | yes | length 0–64 |
data[].label |
string | yes | |
data[].description |
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.
POST /v1/consent-purposes
Section titled “POST /v1/consent-purposes”Declare a consent purpose on an app
Admin only. key is a root, a dot and a camelCase name, like marketing.newsletter or transactional.digest: a marketing name starts off for every profile and a transactional one starts on. Refused when the app already declares the key; change it with consent.purposes.update.
Auth: Session token.
Request body
{ "data": { "key": "string", "label": "string", "description": "string", "appId": "string" }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.key |
string | yes | length 0–64 |
data.label |
string | yes | length 1–50 |
data.description |
string | no | length 1–200 |
data.appId |
string | yes | length 0–200 |
Response 201
{ "data": { "key": "string", "label": "string", "description": "string" }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.key |
string | yes | length 0–64 |
data.label |
string | yes | |
data.description |
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.
PATCH /v1/consent-purposes/{key}
Section titled “PATCH /v1/consent-purposes/{key}”Relabel a consent purpose
Admin only. Changes what the switch is labelled with and the sentence under it; the key, and every answer against it, stay. description: null removes the sentence.
Auth: Session token.
Query parameters
{ "appId": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
appId |
string | yes |
Request body
{ "data": { "label": "string", "description": "string" }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.label |
string | no | length 1–50 |
data.description |
string | null | no |
Response 200
{ "data": { "key": "string", "label": "string", "description": "string" }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.key |
string | yes | length 0–64 |
data.label |
string | yes | |
data.description |
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.
DELETE /v1/consent-purposes/{key}
Section titled “DELETE /v1/consent-purposes/{key}”Delete a consent purpose and every answer to it
Admin only. Refused while a template is sent under the purpose, a broadcast was drafted or sent to it, or people are subscribed to it as a list, naming each. Otherwise the purpose goes, and so does every profile’s answer to it; answersRemoved says how many.
Auth: Session token.
Query parameters
{ "appId": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
appId |
string | yes |
Response 200
{ "data": { "deleted": true, "answersRemoved": 42 }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.deleted |
true | yes | |
data.answersRemoved |
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.