Outbound Campaign API 422 on POST /api/v2/outbound/campaigns

Pushed the dialer integration to the client’s staging org using genesys-cloud-sdk-js@3.52.0. Campaign creation endpoint doing jack all. Keeps rejecting the payload with a 422 Unprocessable Entity. Error body just says {“code”:“invalid_request”,“message”:“Invalid contact list reference”}. Rate limiter isn’t tripping either, headers show 14/200 remaining. Multi-org OAuth token’s fresh, it’s got 18 hours left. Console shows the initial GET /api/v2/outbound/contactlists/{id} call succeeds fine, returns 200 with all the fields. Then the POST to campaigns fires and it’s failing right away. Architect flow for the outbound interaction’s published and active. Premium app manifest’s got the outbound:campaign:write permission scoped correctly. Client’s environment runs on v2.89.0. Tried stripping down the JSON to just the campaign name, contact list ID, and wrap-up code. Still hitting the same wall. Dialing rules are set to progressive mode. Nothing in the audit logs explains the rejection. Just keeps bouncing back with the invalid reference error.

The docs state: “The contactListId field must reference an existing, active contact list within the same organization context.” You’re getting a 422 because the SDK is likely sending the UUID string but the outbound campaign API expects the specific contactListId property to be nested correctly under the campaign object, not just passed as a top-level identifier. Also, check if the contact list is actually ACTIVE status. A GET succeeding doesn’t mean it’s usable for dialing if it’s in PAUSED or DELETED state.

Here’s the exact payload structure that works. Note the contactListId placement:

{
 "name": "Q3 Outreach",
 "description": "Automated dialer test",
 "campaignType": "AUTO_DIALER",
 "contactListId": "your-actual-contact-list-uuid-here",
 "wrapUpCode": "your-wrap-up-code-id",
 "enabled": true
}

If you’re using the JS SDK, make sure you’re passing this object to outboundApi.createCampaign and not trying to map fields manually. The SDK handles the serialization. If the list exists in a different org, you’ll need a multi-tenant token with the correct organizationId header. Check the token scope too. It needs outbound:campaign:write.