The 400 Bad Request usually isn’t about the conversation state, though the call must be active. It’s almost always a scope or payload structure issue.
First, check your OAuth token. You need recordings:write scope. If you’re using a service account, verify the permissions in Admin > Integrations.
Second, the payload might be too minimal or malformed. The API expects specific fields. Try this explicit JSON structure:
{
"recordingType": "ALL",
"recordingPolicyId": null
}
If you leave recordingPolicyId out entirely, some SDKs or curl versions might send an empty body or malformed JSON. Explicitly setting it to null or omitting it with a strict JSON header helps.
Also, verify the conversationId. It must be the full UUID of the voice conversation, not the participant ID. You can grab it from the GET /api/v2/conversations/voice endpoint.
Here is a working curl example:
curl -X POST "https://api.mypurecloud.com/api/v2/recordings/voice/{conversationId}" \
-H "Authorization: Bearer {your_token}" \
-H "Content-Type: application/json" \
-d '{"recordingType":"ALL"}'
If you still get a 400, check the response body. Genesys Cloud returns a message field that often says “Conversation is not in a recordable state” or “Invalid recording type”.
One gotcha: if the conversation is already recording, you’ll get a 409 Conflict, not a 400. So a 400 means the request itself is invalid.
I’ve seen this happen when the token expires mid-request. Double-check the token’s exp claim.
Also, ensure the user or service account has the “Recordings: Write” permission. Without it, the API returns 403, but sometimes the middleware throws a 400 if the token is malformed.
Try the curl command above. If it works, the issue is in your code’s JSON serialization.