Skip to main content
Contact policies control how often and under what conditions a customer can be contacted. They enforce frequency caps, cooldowns, budget exhaustion, mutual exclusion, and other suppression rules during the filtering stage of a Decision Flow.
See the Contact Policies feature page for UI guidance and conceptual overview.

Base path

/api/v1/contact-policies

List contact policies

GET /api/v1/contact-policies
Returns a paginated list of contact policies, ordered by priority (highest first), then creation date (newest first).

Query parameters

ParameterRequiredTypeDescription
limitNointegerMaximum results per page. Default 25.
cursorNostringCursor for keyset pagination.

Response 200

{
  "data": [
    {
      "id": "cp_001",
      "tenantId": "t_001",
      "name": "Email Weekly Cap",
      "description": "No more than 3 emails per week per customer.",
      "status": "active",
      "scope": "channel",
      "scopeId": "ch_email",
      "ruleType": "frequency_cap",
      "config": {
        "maxContacts": 3,
        "windowDays": 7
      },
      "priority": 80,
      "createdAt": "2026-03-10T12:00:00.000Z",
      "updatedAt": "2026-03-12T09:30:00.000Z"
    }
  ],
  "pagination": {
    "total": 8,
    "limit": 25,
    "hasMore": false,
    "nextCursor": null
  }
}

Create a contact policy

POST /api/v1/contact-policies
Creates a new contact policy. Requires the admin role.

Request body

FieldRequiredTypeDescription
nameYesstring (1-255)Unique policy name.
descriptionNostringPolicy description.
statusNoenumdraft, active (default), paused, archived.
scopeNoenumglobal, offer (default), creative, channel.
scopeIdNostring | nullID of the scoped entity (required when scope is not global).
ruleTypeYesenumOne of the rule types below.
configNoobjectRule-type-specific configuration.
priorityNointeger (0-100)Evaluation priority (higher = evaluated first). Default 50.

Rule types

TypeDescriptionConfig example
frequency_capLimit contacts within a time window.{ "maxContacts": 3, "windowDays": 7 }
cooldownMinimum time between contacts.{ "cooldownHours": 48 }
budget_exhaustedSuppress when budget is depleted.{ "budgetField": "daily_spend" }
outcome_basedSuppress based on past outcomes.{ "outcome": "rejected", "withinDays": 30 }
segment_exclusionExclude an entire segment.{ "segmentId": "seg_do_not_contact" }
time_windowOnly contact during specific hours.{ "startHour": 9, "endHour": 17, "timezone": "America/New_York" }
mutual_exclusionPrevent conflicting offers in the same session.{ "excludeOfferIds": ["off_a", "off_b"] }
cross_channel_capLimit total contacts across all channels.{ "maxContacts": 5, "windowDays": 7 }
allow_overrideWhitelist that bypasses other policies.{ "reason": "VIP exception" }
For time_window rules, the timezone value in config is validated against the IANA timezone database at write time. Invalid timezones are rejected with a 400 error.

Example request

{
  "name": "Email Weekly Cap",
  "description": "No more than 3 emails per week per customer.",
  "scope": "channel",
  "scopeId": "ch_email",
  "ruleType": "frequency_cap",
  "config": {
    "maxContacts": 3,
    "windowDays": 7
  },
  "priority": 80
}

Response 201

Returns the created contact policy object.

Error codes

CodeReason
400Validation error (missing name or ruleType, invalid timezone).
409A contact policy with that name already exists.
415Content-Type is not application/json.

Update a contact policy

PUT /api/v1/contact-policies
Updates an existing contact policy. Only provided fields are changed. Requires the admin role.

Request body

All fields from the create schema are accepted as optional, plus:
FieldRequiredTypeDescription
idYesstringThe policy ID to update.

Example request

{
  "id": "cp_001",
  "config": {
    "maxContacts": 5,
    "windowDays": 7
  }
}

Response 200

Returns the updated contact policy object.

Delete a contact policy

DELETE /api/v1/contact-policies?id={policyId}
Deletes a contact policy by ID. The response includes warnings if the policy is still referenced by any Decision Flow.

Query parameters

ParameterRequiredTypeDescription
idYesstringPolicy ID to delete.

Response 200

{
  "deleted": true,
  "warnings": [
    "Referenced by Decision Flow \"Credit Card NBA\" — it will skip this policy."
  ]
}
Unlike most DELETE endpoints that return 204, this endpoint returns 200 with a body so it can communicate ghost-reference warnings.

Error codes

CodeReason
400Missing id query parameter.

Role requirements

MethodMinimum role
GETviewer
POSTadmin
PUTadmin
DELETEadmin

Contact Policies

Learn more about configuring contact policies in the platform UI.