POST /api/v2/flows/executions failing with 400

Quick question about launching Architect flows via API. I am using POST /api/v2/flows/executions to trigger a flow from an external webhook. The request returns 400 Bad Request with error_code: invalid_request. The payload includes flow_id and participant_id correctly.

Here is the JSON body: {"flow_id": "abc-123", "participant_id": "user-456"}. The flow exists and is published. I have verified the OAuth token is valid and has flow:execute scope.

Is there a specific format for participant_id required by the endpoint? Or does the flow need an explicit message trigger type to accept external execution?

This looks like a missing required field in your execution payload. The POST /api/v2/flows/executions endpoint is strict about the request body structure, and while flow_id and participant_id are critical, they are not sufficient on their own for a successful execution trigger. You are likely hitting a 400 because the API cannot determine the interaction context or the specific execution type without the flow_execution_id or a properly structured participants array.

In my experience with SCIM syncs and external integrations, developers often overlook that the participants object needs to explicitly define the user’s role (e.g., USER) and their communication channels. If you are triggering this from an external webhook, you also need to ensure your OAuth token has the flow:execution:write scope, not just flow:read.

Here is the corrected JSON payload structure that should resolve the invalid_request error:

{
 "flow_id": "abc-123",
 "participants": [
 {
 "user_id": "user-456",
 "role": "USER",
 "channels": ["voice"]
 }
 ],
 "flow_execution_id": "new-execution-id-here",
 "start_node": "Start"
}

If you are not providing a flow_execution_id, the API might reject it if it expects a unique identifier for tracking. Also, verify that the start_node matches exactly with a node in your published flow. If you are using the Python SDK, the FlowsApi client handles some of this serialization, but constructing the CreateFlowExecutionRequest object manually ensures you don’t miss these nested requirements. Double-check your token scopes in the developer console to ensure flow:execution:write is granted, as this is a common hidden cause for 400s when the payload structure appears correct.

The documentation actually says you need channel_type too. I track these execution errors in Datadog to catch 400s early.

  • Add "channel_type": "web" to payload.
  • Ensure token has flow:execute scope.
  • Verify flow is published.

Try this:

curl -X POST ... -d '{"flow_id":"...","channel_type":"web"}'