Trying to spin up a new outbound campaign via the WEM API and keep hitting a 400 Bad Request. The payload looks valid, but the error suggests the skill filter isn’t matching our agent profiles. My team is blocked on the Q3 push and we’ve got a deadline tomorrow. Anyone know if there’s a specific format for the skill IDs in the filter object?
The WEM API is notoriously picky about the skill_id structure in the filter object. It’s not just passing the ID string; you have to wrap it in the specific skill_filter block. If you send a flat array of IDs, the parser throws a 400 because it expects a nested object with an operator field.
Check your payload structure. It usually looks like this:
"filters": [
{
"field": "skill",
"operator": "IN",
"values": ["skill_uuid_1", "skill_uuid_2"]
}
]
Make sure operator is explicitly set to IN or EQUAL. Leaving it out defaults to a strict match that often fails if the agent has multiple skills. Also, double check that the UUIDs are from the Routing Skills endpoint (GET /api/v2/routing/skills), not the WEM-specific skill list. They are different namespaces. Mixing them up is a common trap.
If you are building this in Zapier, use a Code step to map the routing skill IDs into that exact JSON structure before hitting the WEM endpoint. The built-in formatter steps don’t handle nested object creation well for API bodies.
The skill filter structure is correct, but there’s a common gotcha with the operator value. If you’re using has_any or has_all, the API expects the values array to contain the actual skill IDs, not the skill names or external references. Also, double-check that the campaign’s routing queue is actually configured to require those skills. If the queue doesn’t have the skills assigned, the filter validation fails silently with a 400.
Here’s the exact payload shape that works for me in my Node.js middleware when syncing campaigns:
"filters": [
{
"field": "skill",
"operator": "has_all",
"values": [
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"f9e8d7c6-b5a4-3210-fedc-ba0987654321"
]
}
]
Make sure those UUIDs match the skills defined in the routing profile. If you’re still stuck, grab the full request ID from the 400 response and check the platform logs. Often it’s a permission issue on the skill resource itself.
Skill IDs fixed it. Thanks.
The previous advice is spot on, but there’s a specific Java SDK pitfall that often causes this 400 error even when the JSON structure looks correct. The Genesys Cloud Java SDK handles the filter object strictly.
- Don’t construct the JSON manually. Use the
FilterBuilderclass from the platform-client-sdk. It enforces the requiredoperatorandvaluesfields at compile time. - Ensure the skill IDs are Strings, not Longs. The SDK might auto-cast if you’re not careful with the
setValuesmethod. - Verify the agent profile actually has the skill and the skill is active in the specific routing region. The API doesn’t validate against inactive skills, but the WEM engine rejects them during campaign creation.
Here’s how the filter should look in Java:
Filter skillFilter = new Filter();
skillFilter.setField("skill");
skillFilter.setOperator("has_any");
skillFilter.setValues(Arrays.asList("skill-id-1", "skill-id-2"));
campaignRequest.setFilters(Arrays.asList(skillFilter));
If you’re still hitting 400s, check the response body for errorCode. It usually says INVALID_FILTER_CRITERIA if the skill doesn’t exist in the queue context.