Quick question about the GetExternalContactAction behavior when invoked via my GraphQL gateway’s data action push.
I am orchestrating a flow that triggers an external lookup for customer profile data based on the initiating phone number. The flow uses the Get External Contact action to query a custom REST endpoint hosted on my gateway. The endpoint accepts a POST request with the msisdn in the body. When I test the endpoint directly via Postman with the same payload, it returns a 200 OK with the expected JSON profile.
However, inside the Architect flow, the action consistently fails with a 404 Not Found status. I have verified the following:
- The URL in the action configuration is correct and includes the trailing slash.
- The HTTP method is set to POST.
- The body mapping uses the expression
{{contact.phoneNumber}}.
- The gateway logs show no incoming requests from the Genesys IP range during flow execution.
Is there a specific header or content-type requirement for this action that is not documented? The default Content-Type seems to be application/x-www-form-urlencoded, but my gateway expects application/json. I tried adding custom headers in the action, but the request never reaches the server. Here is the payload I expect:
{
"msisdn": "+15550199823"
}
The action logs show the request body is empty. How do I force the action to send the JSON payload correctly?
It’s worth reviewing at the request payload structure.
The Guest API requires the msisdn to be nested under a specific contact object, not at the root level.
{
"contact": { "msisdn": "+15550199" }
}
This looks like a payload nesting issue, but the real problem is often how Architect serializes the body before sending it to the external endpoint. The suggestion above regarding the contact object is correct for the standard Guest API, but if you are hitting a custom GraphQL gateway, the schema might expect a flat structure or a different wrapper. In my Electron softphone implementation, I use the platformClient to inspect the raw outbound payload using a custom HTTP interceptor. You need to verify if the GetExternalContactAction is automatically wrapping the msisdn field. If your gateway expects { "msisdn": "+15550199" } but Architect sends { "contact": { "msisdn": "+15550199" } }, the GraphQL resolver will fail to find the variable, resulting in a 404 or null response.
Check the Request Settings in the action configuration. Ensure the Content Type is set to application/json and that you are not manually constructing the body if the action handles it internally. If you are passing the phone number from a previous block, use the expression ${data.phoneNumber} directly in the body definition, but verify the surrounding JSON structure. A quick debug step is to use a tool like ngrok to log the exact incoming request body to your local endpoint. If the msisdn is missing or nested incorrectly, adjust the Body template in Architect to match your GraphQL mutation’s variable definition. For example, if your GraphQL mutation expects query GetUser($msisdn: String!) { user(msisdn: $msisdn) { id } }, your JSON body must be { "msisdn": "${data.phoneNumber}" }, not wrapped in a contact object unless your gateway explicitly requires it.
I normally fix this by validating the protobuf schema. The suggestion above is correct for REST, but GraphQL needs explicit typing.
- Define the input type in your gateway.
- Ensure the Architect data action maps to
input.contact.msisdn.
- Verify OAuth scopes allow outbound calls.
Take a look at at how you are parsing the incoming request body in your Node.js middleware. The 404 often stems from the GraphQL gateway failing to decode the payload because Architect sends it as application/x-www-form-urlencoded by default, not JSON. If your Express server expects JSON, the parser returns an empty object, causing your resolver to throw a not-found error before hitting the database.
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post('/graphql/contact', (req, res) => {
// Architect sends msisdn as a root-level field in form data
const msisdn = req.body.msisdn || req.body.contact?.msisdn;
if (!msisdn) return res.status(404).json({ error: 'No MSISDN' });
// Proceed with GraphQL query...
});
Ensure your middleware handles both formats since Architect’s behavior can vary based on the action configuration.