Data Governance
Configure centralized consent rules that stop event dispatch to destinations based on visitor and event properties. Manage the data-governance record, its categories, and their priority order through the Ours Privacy REST API.
Use this page to configure the centralized consent and routing rules that gate every destination.
Where this fits in the dispatch flow
Configuration changes at any stage take effect once you publish a new version.
Data Governance is the second stage that can drop an event. After Allowed Events decides whether an event is permitted at all, Data Governance evaluates the event against each configured category in priority order. If a category's logic evaluates to TRUE for the event, dispatch is stopped to every destination on that category's destinationIds. Events that don't match any category continue to Mappings and then to the destinations they are allowed to reach.
Write category conditions that evaluate TRUE for opt-out scenarios — the category fires when you want dispatch blocked. Common example: a marketing category whose logic is visitor.consent.rejected_categories Contains "advertising" and whose destinationIds list every ad platform.
Discovering valid property paths
condition.property is a bare dotted path into the event/visitor record being evaluated (no {{...}} — that template syntax is for mapping values, not logic conditions). Use GET /rest/v1/mappings/default-variables to enumerate the canonical platform-provided paths — visitor consent (visitor.consent.accepted_categories, visitor.consent.rejected_categories), event fields (event.event, event.distinct_id, event.time), request context (event.request_context.country, event.request_context.city, ...), and identity fields (visitor.email, visitor.first_name, ...). Custom event properties under event.event_properties.* are caller-defined. A path that doesn't resolve evaluates to undefined and the condition won't fire — typos fail silently.
Consent state is stored as two arrays — accepted_categories and rejected_categories — not as per-category booleans. Use Contains / DoesNotContain against those arrays rather than IsFalsy against a non-existent visitor.consent.marketing.
Account singleton
Each account has at most one data-governance record. GET /rest/v1/data-governance returns either an empty array or a single entity. A second POST returns 409. PATCH the existing record to add categories or toggle isEnabled.
isEnabled: false is the off switch. Categories stay configured but no event is gated. Use this to stage a configuration before going live.
Categories: wholesale replacement and priority renumbering
PATCH /rest/v1/data-governance/{id} follows standard partial-update semantics for name, notes, and isEnabled — only the fields you send are changed.
categories is the documented exception: when you send it, the entire list is replaced. There is no partial-merge for individual categories. The canonical pattern is fetch → modify → PATCH:
# Read the current state
curl "$BASE/rest/v1/data-governance/$ID" \
-H "Authorization: Bearer $TOKEN"
# Modify one category and PATCH the full list back
curl -X PATCH "$BASE/rest/v1/data-governance/$ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"categories": [
{
"name": "Advertising",
"priority": 1,
"destinationIds": ["dest_facebook", "dest_google_ads", "dest_tiktok"],
"logic": {
"condition": {
"property": "visitor.consent.rejected_categories",
"operator": "Contains",
"value": "advertising"
}
}
},
{
"name": "Analytics",
"priority": 2,
"destinationIds": ["dest_amplitude", "dest_mixpanel"],
"logic": {
"condition": {
"property": "visitor.consent.rejected_categories",
"operator": "Contains",
"value": "analytics"
}
}
}
]
}'priority is a sort hint. Send any positive numbers — only their relative order matters. The persisted values come back as a sequential 1..N with no gaps or duplicates, regardless of what you sent.
Stale destination IDs are filtered
Destination ids on categories[].destinationIds that don't exist (deleted, or on another account) are silently dropped at write time. The response echoes the filtered list, so a follow-up GET is not required to confirm what was saved. Pass the ids you currently believe are correct — the server enforces the invariant.
How destination dispatch sees governance
A destination only receives an event if all of these are true:
- An allowed event exists for the inbound event name and lists this destination in
destinationIds. - No data-governance category evaluates TRUE for the event with this destination on its
destinationIds. - A mapping on the destination matches.
Governance can stop one destination while letting the same event through to another, by listing only the gated destination on the category. That's how the standard "stop ad platforms when the visitor rejects the advertising category, keep analytics platforms" pattern is expressed.
Authorization
apiKey Ours Privacy API key
In: header
Query Parameters
Maximum number of items to return. Defaults to 25; values below 1 are clamped to 1 and values above 100 are clamped to 100.
Opaque pagination cursor from pagination.nextCursor in the previous response. Do not decode or modify it. Malformed cursors return 400 Bad Request.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://app.oursprivacy.com/rest/v1/data-governance"{
"entities": [
{
"id": "string",
"name": "string",
"kind": "string",
"isEnabled": true,
"createdAt": "string",
"updatedAt": "string",
"notes": "string",
"categories": [
{
"name": "string",
"description": "string",
"priority": 0,
"destinationIds": [
"string"
],
"logic": {
"AND": [
{}
],
"OR": [
{}
],
"NOT": {},
"condition": {
"property": "string",
"operator": "Is",
"value": "string"
}
}
}
]
}
],
"pagination": {
"nextCursor": "string",
"hasMore": true
}
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}Authorization
apiKey Ours Privacy API key
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://app.oursprivacy.com/rest/v1/data-governance" \ -H "Content-Type: application/json" \ -d '{}'{
"id": "string",
"name": "string",
"kind": "string",
"isEnabled": true,
"createdAt": "string",
"updatedAt": "string",
"notes": "string",
"categories": [
{
"name": "string",
"description": "string",
"priority": 0,
"destinationIds": [
"string"
],
"logic": {
"AND": [
{}
],
"OR": [
{}
],
"NOT": {},
"condition": {
"property": "string",
"operator": "Is",
"value": "string"
}
}
}
]
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}Authorization
apiKey Ours Privacy API key
In: header
Path Parameters
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://app.oursprivacy.com/rest/v1/data-governance/string"{
"id": "string",
"name": "string",
"kind": "string",
"isEnabled": true,
"createdAt": "string",
"updatedAt": "string",
"notes": "string",
"categories": [
{
"name": "string",
"description": "string",
"priority": 0,
"destinationIds": [
"string"
],
"logic": {
"AND": [
{}
],
"OR": [
{}
],
"NOT": {},
"condition": {
"property": "string",
"operator": "Is",
"value": "string"
}
}
}
]
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}Authorization
apiKey Ours Privacy API key
In: header
Path Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X PATCH "https://app.oursprivacy.com/rest/v1/data-governance/string" \ -H "Content-Type: application/json" \ -d '{}'{
"id": "string",
"name": "string",
"kind": "string",
"isEnabled": true,
"createdAt": "string",
"updatedAt": "string",
"notes": "string",
"categories": [
{
"name": "string",
"description": "string",
"priority": 0,
"destinationIds": [
"string"
],
"logic": {
"AND": [
{}
],
"OR": [
{}
],
"NOT": {},
"condition": {
"property": "string",
"operator": "Is",
"value": "string"
}
}
}
]
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}Authorization
apiKey Ours Privacy API key
In: header
Path Parameters
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X DELETE "https://app.oursprivacy.com/rest/v1/data-governance/string"{
"id": "string",
"deleted": true
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}{
"error": "string",
"details": "string"
}How is this guide?

