CXone Outbound API returning 400 Bad Request when campaign_id is missing in contact_update request

Hi all,

The Outbound is throwing a 400 error when trying to update a contact that is already associated with a campaign, but the campaign_id is omitted from the request body. It seems the requires the ID even for simple attribute updates.

Repro steps:

  1. Create a contact and assign it to a campaign.
  2. Send a PATCH request to //v1/contacts/{contact_id} with only the custom_fields updated.
  3. The server returns a 400 error instead of ignoring the missing campaign field.

Example payload that fails:

{
 "custom_fields": {
 "customer_tier": "platinum",
 "last_contact_date": "2023-10-25"
 }
}

The response body is:

{
 "error": "Invalid request",
 "message": "campaign_id is required for updates to existing campaign contacts",
 "code": 400
}

This is strange because the documentation implies campaign_id is optional for updates. If the contact is already in a campaign, the system should know which one it is. One edge case is when a contact belongs to multiple campaigns-maybe that is why the is being strict.

I checked the SDK internal request builder and it doesn’t automatically inject the current campaign_id into the update payload. It just sends what is in the request object.

1 Like

Stop trying to omit the ID. The is picky about the state of the record when it’s already linked to a CAMPAIGN.

Just fetch the current CAMPAIGN_ID first and pass it back in the PATCH body. It’s an extra call, but it’s the only way to stop the 400s.

{
 "campaign_id": "12345",
 "custom_fields": {
 "status": "updated"
 }
}

That’s right, and also - the validation logic is strict.

GET /contacts → CAMPAIGN_ID → PATCH /contacts

The requires a full state match for any CAMPAIGN_LINKED record.

{
 "campaign_id": "12345",
 "custom_fields": {
 "ATTR_1": "Value"
 }
}

It’s cleaner to manage these via the ADMIN_UI if bulk updates aren’t required.

1 Like