400 on POST /api/v2/conversations/calls - malformed participant address?

Just noticed that my Newman runs are failing on POST /api/v2/conversations/calls with a 400 Bad Request. The error payload says Malformed participant address even though the to value is a valid tel:+15551234567 string.

{
 "to": {
 "phoneNumber": "tel:+15551234567",
 "type": "phone"
 },
 "from": {
 "phoneNumber": "tel:+18005550199",
 "type": "phone"
 }
}

Checked the endpoint docs and the schema looks right. Is there a hidden format requirement for the to object in the request body?

You need to check the scope.

  • ensure conversation:call:write is present.
  • verify the from number is actually configured as an outbound route in your org.
  • check the apiVersion header matches the tenant version.

You need to verify that the from address you’re passing actually matches a configured outbound route or user number in your org. The 400 error often hides behind scope issues, but if the scope is good, the platform rejects the call because it can’t route the origin.

“Malformed participant address”

This usually means the phoneNumber value in the from object doesn’t exist in your Genesys Cloud configuration. Even if conversation:call:write is present, the API validates the resource before attempting the call.

Here’s how I handle this in Go. I always pre-validate the outbound route or user number before firing the POST.

// Validate the 'from' number exists in org config
func validateOutboundNumber(client *platformclientv2.Client, number string) error {
 outboundRoutingAPI := platformclientv2.NewOutboundRoutingApiwithClient(client)
 routes, _, err := outboundRoutingAPI.PostOutboundRoutesGet()
 if err != nil {
 return fmt.Errorf("failed to fetch routes: %w", err)
 }

 for _, route := range *routes.Entities {
 // Check if the number is in the route's numbers list
 if route.Numbers != nil {
 for _, n := range *route.Numbers {
 if n.Number == number {
 return nil // Found it
 }
 }
 }
 }
 return fmt.Errorf("outbound number %s not found in any route", number)
}

If that passes, check your Content-Type. It must be application/json. Newman sometimes defaults to text/plain if the header isn’t explicitly set in the collection.

Also, ensure the tel: prefix is consistent. Some older SDK versions strip it, causing a mismatch. I’ve seen this break calls where the route expects +1555... but the payload sends tel:+1555....

Double check your apiVersion header too. If it’s missing, the platform uses the tenant default, which might have stricter validation rules enabled.

The root cause here is the from object missing the id field when using a user-initiated call flow, even if the phone number looks valid.

“Malformed participant address”

you gotta include the user or outbound route id in that object, otherwise the platform rejects it.