Hey everyone,
I’m trying to kick off an outbound call on behalf of an agent using the .NET SDK, but I keep hitting a 403 Forbidden error. The docs for the Conversations API say I need the conversation:write scope, which I’ve added to my app’s permissions in the Genesys Cloud admin portal. I’ve also verified the access token has the right claims by decoding it in jwt.io.
Here’s the C# code I’m using to make the request:
var client = new Client("https://api.mypurecloud.com");
var request = new Request("/api/v2/conversations/calls", Method.Post);
request.AddHeader("Authorization", $"Bearer {accessToken}");
request.AddJsonBody(new {
to = new { phoneNumber = "+15550199" },
from = new { phoneNumber = "+15550100" },
routing = new {
queueId = "my-queue-id-here",
skill = new { name = "sales" }
}
});
var response = await client.ExecuteAsync(request);
Console.WriteLine(response.StatusCode); // Returns 403
The weird part is that if I swap the routing object for a direct userId of an agent who is already in a “Available” state, it works fine. But I need to route this to a queue. The error message just says “Forbidden” with no extra details in the body.
Is there a specific permission I’m missing for queue routing? Or maybe the agent needs to be logged in to a specific skill group for this to work? I’ve checked the routing structure against the swagger spec and it looks correct. Any ideas why the queue routing path is failing while the direct agent ID works?
The issue isn’t the scope. It’s the target. You’re hitting /api/v2/conversations/calls which is for creating a conversation object, not initiating the actual call leg. That endpoint requires conversation:write, yes, but it also requires the user to have permission to create calls to that specific number type. If you’re trying to place a call from an agent’s perspective, you shouldn’t be using the generic conversation creation endpoint directly unless you’re building a custom dialer.
For outbound calls, you usually want to use the InitiateOutboundCall method in the SDK or hit /api/v2/outbound/calls if you’re using Predictive/Progressive dialing. But if you just need a simple click-to-call or agent-initiated call, check the ConversationCallApi.
Here is how you structure the request body correctly in C# using the PureCloudPlatformClientV2 SDK. Notice the to object needs the phone number type.
var client = PlatformClientFactory.Instance;
client.Login("your_client_id", "your_client_secret", "https://api.mypurecloud.com");
var callApi = new ConversationCallApi(client);
var to = new PhoneNumber
{
Number = "+15551234567",
Type = "international" // Crucial: "international" or "national"
};
var from = new PhoneNumber
{
Number = "+15559876543", // Your outbound ANI
Type = "international"
};
var callRequest = new CreateConversationCallRequest
{
To = to,
From = from,
WrapupCode = null // Optional
};
try
{
var response = await callApi.PostConversationsCallsAsync(callRequest);
Console.WriteLine($"Call ID: {response.Id}");
}
catch (ApiException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
If you’re still getting 403, check the User’s permissions in Admin. They need conversation:write AND telephony:write if they are initiating from a softphone context. Also, verify the number isn’t blocked by your organization’s call routing settings. Sometimes the error message is misleading.