We’ve got a Terraform module that provisions Genesys Cloud resources, and part of the validation suite involves programmatically triggering test calls to ensure queue routing works as expected. I’m using the client credentials flow to get a token, then hitting POST /api/v2/conversations/calls with the agent’s user_id in the to array. The response keeps coming back as a 400 with ‘Invalid state’. I’ve double-checked the user status is Available. Is there a specific header I’m missing or does the state need to be reserved first via a separate API call before the actual outbound request goes through?
You’re likely hitting the state check because the user isn’t actually in a state that accepts outbound calls via the API, or the call center isn’t set up for this type of initiation. Being “Available” in the UI doesn’t always mean the API sees them as ready for a grammatic outbound call if their schedule or presence settings are off.
Try checking the user’s current presence state via GET /api/v2/users/{userId}/presence/state. If it returns something other than available or busy (depending on your flow), that’s your blocker.
Also, make sure you’re including the callCenterId in the payload. It’s not optional for outbound calls. Here’s a working curl example that actually triggers a call without the 400 error:
curl -X POST "https://api.mypurecloud.com/api/v2/conversations/calls" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": [
{
"id": "USER_ID_HERE",
"type": "user"
}
],
"callCenterId": "YOUR_CALL_CENTER_ID",
"from": {
"id": "CALLER_ID_OR_ANON",
"type": "callerId"
}
}'
If you’re using Terraform for validation, consider using the genesyscloud_routing_queue resource’s built-in health check instead of firing raw API calls. It’s less ne to state mismatches. The API is strict about the callCenterId matching the user’s assigned call center. If they’re assigned to multiple, pick the one you want to route through. Double-check that too.