Files
api/services/nginx/app/modules/bird/bird.md
T

5.6 KiB

Bird Module

This module provides Bird API integration for voice calls and number management.

Endpoints

Voice calls

  • POST /bird/voice/calls

    • Permission: modules_bird_voice_calls_create
    • Required: workspaceId, channelId
    • Body: passthrough to Bird call create API (except workspaceId and channelId).
  • GET /bird/voice/calls

    • Permission: modules_bird_voice_calls_list
    • Required query: workspaceId, channelId
    • Query params are passed through to Bird.
  • GET /bird/voice/calls/{id}

    • Permission: modules_bird_voice_calls_get
    • Required query: workspaceId, channelId
  • POST /bird/voice/calls/{id}/hangup

    • Permission: modules_bird_voice_calls_hangup
    • Required: workspaceId, channelId
  • POST /bird/voice/calls/test-outbound

    • Permission: modules_bird_voice_calls_test_outbound
    • Required: workspaceId, channelId
    • Places an outbound call to the fixed test number +45 42 33 11 28 (+4542331128), polls call state, and sends hangup when state is accepted or ongoing.
    • Optional tuning params:
      • pollIntervalSeconds (default 2)
      • maxPollSeconds (default 30)
      • hangupCause
  • POST /bird/voice/calls/webhook/inbound

    • Permission: modules_bird_voice_call_webhooks_trigger
    • Stateful inbound IVR webhook for phone-controlled department gates.
    • On the initial request, the webhook accepts the live inbound call through Bird before returning the first gather command.
    • Supports both request formats:
      • Native-flow mode: top-level { callId, channelId, workspaceId } for the initial fetch, then { callId, channelId, workspaceId, keys } for selections.
      • Compatibility mode: { payload, request, waitConditions }, which returns a raw Bird callCommand gather envelope.
    • Uses department_gates rows with config.type=PHONE_CALL as the source of truth for which departments and entrance/exit gates are offered.
    • Department menu order follows departments.order_priority.
    • Supports multi-digit department selections such as 10#.
    • Always prompts for both department selection and gate selection, even when only one valid option exists.
    • Uses compact gate numbering:
      • both gates available: 1=entrance, 2=exit
      • entrance only: 1=entrance
      • exit only: 1=exit

Bird Flow Builder setup

  • Preferred native-flow setup:
    • Voice trigger
    • Answer call
    • Async HTTP request (initial IVR state fetch)
    • Gather digits from a call
    • Async HTTP request (submit selected keys)
    • If the second HTTP response returns completed=false, run another Gather digits from a call with the returned prompt and gather settings.
    • If the second HTTP response returns completed=true, end the flow or optionally say the returned message.
  • The caller must be connected in Bird before the HTTP webhook step runs. If the flow omits Answer call, the inbound call can keep ringing until Bird times it out.
  • Initial HTTP step:
    • URL: https://api.truckwash.io:4433/bird/voice/calls/webhook/inbound
    • Content type: application/json
    • Body:
{
  "callId": "{{callId}}",
  "channelId": "{{channelId}}",
  "workspaceId": "{{workspaceId}}"
}
  • Example native-flow response:
{
  "requestId": "request-123",
  "callId": "4015cf84-8028-46a1-a0d9-9213e5bf4f09",
  "status": "gather",
  "completed": false,
  "stage": "department_select",
  "prompt": "Choose department. Press 1 for Roskilde. Press 2 for Demo.",
  "gather": {
    "input": "dtmf",
    "maxNumKeys": 1,
    "endKey": "#",
    "timeout": 30,
    "retries": 3,
    "say": {
      "locale": "en-US",
      "voice": "female",
      "text": "Choose department. Press 1 for Roskilde. Press 2 for Demo."
    }
  }
}
  • Use the initial HTTP step output to configure Gather digits from a call:
    • Prompt/text from prompt or gather.say.text
    • maxNumKeys, endKey, timeout, and retries from gather
    • TTS locale and voice from gather.say
  • Selection HTTP step:
    • POST the same callId, channelId, and workspaceId plus the gathered digits as keys.
    • Example body:
{
  "callId": "{{callId}}",
  "channelId": "{{channelId}}",
  "workspaceId": "{{workspaceId}}",
  "keys": "{{gatheredKeys}}"
}
  • Bird's current Voice API examples use BCP-47 locales such as en-US and TTS voices such as female/male. Avoid undocumented values like alice.
  • Compatibility mode:
    • The webhook still supports the older { payload, request, waitConditions } contract and returns a raw 202 Accepted Bird callCommand gather envelope.
    • That mode is not suitable for Bird Flow Builder Async HTTP request, because Bird treats the response as data rather than executing the returned call command.

Numbers

  • GET /bird/numbers

    • Permission: modules_bird_numbers_list
    • Optional query: workspaceId (if not configured)
    • Query params are passed through to Bird.
  • GET /bird/numbers/{id}

    • Permission: modules_bird_numbers_get
    • Optional query: workspaceId (if not configured)
  • DELETE /bird/numbers/{id}

    • Permission: modules_bird_numbers_delete
    • Optional query/body: workspaceId (if not configured)
    • Releases/deletes a number if supported by Bird account policy.

Logging

Bird requests are logged through logs_o with module bird, including:

  • Request start (BIRD_HTTP_REQUEST)
  • Response status (BIRD_HTTP_RESPONSE)
  • API or transport errors (BIRD_HTTP_ERROR, BIRD_HTTP_CURL_ERROR)
  • Test outbound flow events (BIRD_TEST_OUTBOUND_CALL_*)

Notes

  • Bird credentials and base URL are configured in Bird module config.
  • Route handlers enforce workspace/channel requirements before outbound API calls.