Start recording via API returns 400 Bad Request

Trying to kick off a recording for a voice conversation using the REST API. I’m sending a POST to /api/v2/recordings/voice/{conversationId} with the correct auth token, but it keeps failing.

The body is just {“recordingType”:“ALL”}. I get a 400 response every time. Is there a specific state the conversation needs to be in before this works?

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.