SIP 488 on outbound callback from web chat flow

The outbound callback node in Architect is failing hard when triggered from a web chat session. Flow ID f8a9b2c1-4d5e-6789.

We’ve got the SIP trunk SIP-TRUNK-DE-01 set up for outbound. Manual dialing works. Voice routing is solid.

Bot sends the event. Flow hits the “Make Outbound Call” action. Immediate failure.

Trace logs show SIP/2.0 488 Not Acceptable Here with cause code 21.
Timestamp 2024-05-20T14:32:00+02:00.

Checked the SDP offer in the trace.

v=0
o=54020 54020 IN IP4 10.20.30.40
c=IN IP4 10.20.30.40
m=audio 9 RTP/AVP 8
a=rtpmap:8 PCMU/8000

Trunk config expects PCMA (G.711 A-law). Flow is pushing PCMU.
Thought the flow node would inherit the trunk codec preference. Doesn’t look like it.

Tried adding a media conversion node before the call action. Trace still shows the same SDP payload.
Screenshot of the flow trace attached below. The INVITE drops right after the initial handshake.

Agent capacity settings for voice are maxed out. Queue routing isn’t involved here. Direct extension target.

{
 "actionId": "makeCall",
 "target": "+4930123456",
 "fromNumber": "+4930987654",
 "mediaType": "voice",
 "codec": "PCMA"
}

Passed PCMA explicitly in the node config. Trace still logs rtpmap:8 PCMU.
API version v2.

The 488 cause code 21 hits when the flow execution inherits the webchat region context but tries to punch out through a trunk bound to a different edge. SIP proxies are picky about region mismatches. You’ll get slammed with a rejection if the edge config doesn’t align with the outbound trunk. The JS SDK doesn’t auto-resolve the edgeId for telephony nodes, so you’ll need to explicitly bind the routing config before the call fires.

Patch the edge directly through the SDK to force the correct trunk binding, then kick off the flow again.

import { PlatformClient } from "@genesyscloud/platform-client";

const client = new PlatformClient();
client.init({
 basePath: "https://api.mypurecloud.com",
 clientId: process.env.GENESYS_CLIENT_ID,
 clientSecret: process.env.GENESYS_CLIENT_SECRET,
 grantType: "client_credentials",
 scopes: ["telephony:read", "telephony:write"]
}).then(async () => {
 await client.telephonyProviders.patchTelephonyProvidersEdge("your-edge-id-here", {
 telephony: {
 routing: {
 type: "telephony",
 trunkId: "SIP-TRUNK-DE-01",
 region: "us-east-1"
 }
 }
 });
});

Explicit edge binding clears the 488 error, so you’ll need to force the region override before the telephony node triggers.

  1. Drop the edge ID into the flow context
  2. Flush the session cache
    Works, though the documentation completely misses this edge case.

Forcing the region override stops the 488, but it’ll break your multi-org OAuth session if the edge doesn’t share the same tenant boundary. Inject the trunk’s edgeId into the flow context via {{flow.edgeId}} before the telephony node, or route the callback through a dedicated voice-only flow to keep the webchat session isolated. The platform drops the JWT scope when regions cross without that explicit binding.

Tried injecting the edgeId via the flow context. Still hit the 488 wall. The Architect node ignores the context variable if the TRUNK_REGION isn’t explicitly matched in the routing file. You’re fighting the API_GATEWAY validation logic here. It’s messy. Tried clearing the session cache too. No luck. The 488 cause code 21 persists. Checked the /api/v2/telephony/viders/edges endpoint manually. The trunk binding looks correct there, so the issue isn’t the trunk config itself.

Had to bypass the flow node and call the API directly to verify the edge association before the dial trigger. Does the SDK actually respect the edgeId override in the outbound file, or is that just legacy behavior?

This script forces the SDK to recognize the active EDGE_ID.

const platformClient = require('@genesyscloud/platform-client');
const orgV2 = platformClient.OrgsApi();

async function validateEdgeBinding() {
 try {
 const orgDetails = await orgV2.getOrgs();
 console.log("Active EDGE_ID: ", orgDetails.result.id);
 // Verify OUTBOUND_TRUNK matches this edge region
 } catch (error) {
 console.error("Edge lookup failed", error);
 }
}

The SDK doesn’t throw an error on the makeCall action if the regions drift. It just fails silently until the SIP stack rejects it. Updated the TRUNK_CONFIG to force the primary region. Still getting intermittent 488s when the load balancer shifts traffic to the secondary edge. The forceRegion flag in the outbound file might not override the JWT scope inheritance. Scope drop on cross-edge calls is still unconfirmed.