Skip to Content
GovernanceDestination Policies

Destination Policies

Destination policies control which records may reach a given destination type. A policy is a filter attached to one of your models: when a sync sends that model to that kind of destination, only the records matching the filter are sent, and everything else is withheld before it leaves your warehouse.

How Destination Policies Work

A policy is scoped to two things — a parent model and a destination type — and carries a filter tree describing which records are permitted:

FieldDescription
Parent modelThe model the policy governs. Only models configured as a parent entity can carry a policy.
Destination typeThe kind of destination the policy applies to, such as facebook_ads or salesforce. It applies to every destination of that type, not to one connection.
Filter treeThe criteria a record must match to be sent. Same filter language as an audience.
EnabledWhether the policy is enforced. A disabled policy is ignored entirely.

Together, the model and the destination type are the policy’s identity: one enabled policy governs each model-and-destination-type pair. Creating a second policy for the same pair does not stack another restriction on top — express everything you need for that pair in a single filter tree, combining criteria with and / or groups.

When a sync runs, Zeotap looks for an enabled policy matching that sync’s model and its destination’s type. If it finds one, the policy’s filter is applied to the model’s query before any data is read, so non-matching records are never fetched, never mapped, and never sent. The sync itself still runs and succeeds — it simply carries fewer records.

Because the filter runs inside your warehouse as part of the model query, it can use everything an audience filter can: column values, conditions across related models, computed attributes, and membership of another audience.

A policy filters records, it does not block a sync, alter column values, or throttle how often a sync runs. Those are separate features — see Related Governance Controls below for which one covers each case.

What a Policy Applies To

ScopeBehavior
ModelOnly the parent model named on the policy. Syncs from other models are unaffected, even to the same destination.
Destination typeEvery destination of that type in the workspace. You cannot scope a policy to a single destination connection, to a category such as “advertising”, or to all destinations at once.
Sync kindReverse ETL syncs and audience syncs alike, since both read through the model.
Empty filterA policy whose filter tree is empty adds no criteria and is skipped.

Creating Policies via the UI

  1. Navigate to Governance > Destination Policies in the sidebar
  2. Click Add Destination Policy
  3. Select the parent model the policy governs
  4. Select the destination type it applies to
  5. Build the filter tree describing which records may be sent
  6. Name the policy, optionally describe it, and leave Enabled on to enforce it immediately
  7. Click Save

Policies take effect on the next run of any affected sync. A run already in flight finishes under the rules it started with.

Creating Policies via the API

A policy is scoped to one model and one destination type, and its criteria are a filter tree in the same format as an audience filter. Records that do not match the tree are withheld from that destination type.

# Keep EU customers out of Facebook Ads curl -X POST "$API_BASE_URL/api/v1/workspaces/$WORKSPACE_ID/destination-rules" \ -H "Authorization: Bearer $API_TOKEN" \ -H "X-Workspace-ID: $WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "name": "No EU customers to Facebook Ads", "description": "Withhold EU customer records from Facebook Ads syncs", "parent_model_id": "770e8400-e29b-41d4-a716-446655440000", "destination_type": "facebook_ads", "filter_tree": { "type": "condition", "condition_type": "property", "column": "country", "operator": "not_in", "value": ["DE", "FR", "IT", "ES", "NL"] }, "enabled": true }' # Send only opted-in, verified records to Google Ads curl -X POST "$API_BASE_URL/api/v1/workspaces/$WORKSPACE_ID/destination-rules" \ -H "Authorization: Bearer $API_TOKEN" \ -H "X-Workspace-ID: $WORKSPACE_ID" \ -H "Content-Type: application/json" \ -d '{ "name": "Opted-in and verified only", "parent_model_id": "770e8400-e29b-41d4-a716-446655440000", "destination_type": "google_ads", "filter_tree": { "type": "and", "children": [ { "type": "condition", "condition_type": "property", "column": "marketing_opt_in", "operator": "equals", "value": true }, { "type": "condition", "condition_type": "property", "column": "email_verified", "operator": "equals", "value": true } ] }, "enabled": true }'

See Governance API for the full request and response schemas.

A destination policy answers one question: which records may go to this kind of destination? Three adjacent controls answer the other governance questions people usually ask alongside it.

To do thisUseWhere
Stop a column leaving the warehouse at allSet the column’s sensitivity to BlockedPII Masking
Send a hashed value instead of a raw oneEnable Hash PII (SHA256) on the field mappingPII Masking
Hide a value from operators but still sync itSet the column’s sensitivity to Redacted or Sync OnlyPII Masking
Limit how often one profile is contactedConfigure a per-profile frequency cap for the destination typeGET /api/v1/workspaces/{id}/frequency-caps
Restrict which records a person can seeDefine an access policy and assign it to a groupAccess Policies

The distinction between a destination policy and an access policy is worth keeping straight: an access policy limits what a user can see anywhere in Zeotap, while a destination policy limits what a sync may send, regardless of who set the sync up.

Audit Trail

When a policy is applied to a run, the run’s log records which policy it was and the destination type it applied to. The sync run shows the resulting record counts, so a run that suddenly sends fewer records than expected is usually explained by a policy that was enabled or edited since the previous run.

Changes to policies themselves — creation, edits, enable and disable — are recorded in the workspace audit trail alongside other governance changes. See Data Handling.

Managing Policies

Enabling and Disabling

A policy can be disabled without deleting it. A disabled policy is not looked up at all when a sync runs, so its criteria stop applying immediately — useful for temporarily relaxing a restriction, or for staging a policy before enforcing it.

Because only one enabled policy governs each model-and-destination-type pair, disabling is also how you swap one policy for another on the same pair without a gap in coverage: create the replacement disabled, then disable the old one and enable the new one.

Testing Policies

There is no dry-run mode. To see what a policy will withhold before it takes effect, check the criteria against the same data the policy will read:

  1. Create the policy with enabled: false — it is stored but never consulted during syncs
  2. Build an audience on the same parent model with the same criteria, and preview it or run an estimate. Those are the records the policy would permit; everything else in the model is what it would withhold.
  3. Set enabled: true when the match looks right

Editing a Policy

Edits apply from the next run of any affected sync. Widening a filter does not re-send records that earlier runs withheld — a sync in an incremental mode only sends what has changed since its last run, so records that become newly permitted are picked up when they next change. Trigger a run in a full mode if you need them sent immediately.

Common Patterns

Each pattern below is a single policy on one parent model and one destination type.

PatternFilter tree
Keep EU customers out of an ad platformcountry not in ["DE", "FR", "IT", "ES", "NL"]
Send only marketing-opted-in recordsmarketing_opt_in equals true
Exclude unverified or bounced contactsemail_verified equals true and email_status not equals bounced
Send only customers of a given tiertier in ["gold", "platinum"]
Withhold everyone in a suppression audiencenot in audience Do Not Contact
Send only records with a recent purchasecomputed attribute days_since_last_order less than 90

To keep a column out of a payload entirely, or to send it hashed, use column sensitivity and hash-on-sync rather than a policy — see Related Governance Controls.

API Reference

Every path below is workspace-scoped — {id} is your workspace ID. See Base URL for your instance’s API base URL and Authentication for the required Authorization and X-Workspace-ID headers.

The API path uses the original destination-rules spelling.

# List all destination policies GET /api/v1/workspaces/{id}/destination-rules # Get a single policy GET /api/v1/workspaces/{id}/destination-rules/{ruleId} # Create a policy POST /api/v1/workspaces/{id}/destination-rules # Update a policy PUT /api/v1/workspaces/{id}/destination-rules/{ruleId} # Delete a policy DELETE /api/v1/workspaces/{id}/destination-rules/{ruleId} # List the policies that apply to one destination type GET /api/v1/workspaces/{id}/destination-types/{destType}/rules

See Governance API for full request/response schemas.

Next Steps

Last updated on