We are trying to programmatically stop a live call recording using PATCH /api/v2/recordings/{recordingId}. The request body contains the standard action payload with the stop command.
The endpoint responds with a 409 Conflict error indicating the recording is not in a startable state. We have verified the recording ID is correct and the status is currently ‘started’.
The code snippet for the request is as follows:
fetch(url, {
method: 'PATCH',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({ action: 'stop' })
});
The 409 usually means the backend thinks the state is already changing or the ID you’re passing isn’t actually a live session recording ID. It’s a common gotcha with the recordings API because recordingId in the PATCH endpoint expects the specific session recording UUID, not the general conversation ID or a finalized recording ID.
Here’s what to check:
- Verify the ID type: Make sure you’re grabbing the
id from the recordings array in the conversation object, specifically where state is started. If you’re using a recordingId that was returned after the call ended, it won’t work for a stop action.
- Check for race conditions: If you’re triggering this from a webhook that fires on
conversation:updated, there might be a slight delay. The backend might still be processing the “start” event. A small retry with exponential backoff often fixes this if it’s a timing issue.
- Use the Conversation API instead: Sometimes it’s cleaner to use
PATCH /api/v2/conversations/{conversationId} with action: "stopRecording". This targets the conversation context directly and might handle state transitions more gracefully than hitting the recordings endpoint directly.
Here’s a quick Node.js snippet using the SDK to stop via the conversation, which tends to be more reliable:
const platformClient = require('genesys-cloud-platform-client');
const stopRecording = async (conversationId) => {
const authSettings = {
clientId: process.env.GC_CLIENT_ID,
clientSecret: process.env.GC_CLIENT_SECRET
};
const oauthClient = new platformClient.AuthClient(authSettings);
await oauthClient.loginClientCredentials();
const conversationApi = new platformClient.ConversationsApi(oauthClient);
try {
// This stops all active recordings on the conversation
await conversationApi.patchConversation(
conversationId,
{ action: 'stopRecording' }
);
console.log('Recording stopped successfully');
} catch (error) {
console.error('Failed to stop recording:', error.response?.data || error.message);
}
};
If you definitely need to use the recordings endpoint, double-check the state field in the GET request for that specific recording ID before attempting the PATCH. The API is strict about the state machine.