> ## Documentation Index
> Fetch the complete documentation index at: https://daily-main.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# didlogic Frame Serializer

> DidlogicFrameSerializer converts audio between Pipecat frames and the didlogic voice-stream WebSocket protocol.

export const CommunityMaintained = ({maintainer, maintainerUrl, repo}) => <Note>
    <strong>Community-maintained integration.</strong> This service is built and
    maintained by{" "}
    <a href={maintainerUrl} target="_blank" rel="noreferrer">
      {maintainer}
    </a>
    . Pipecat does not test or officially support it. Please report issues and
    request changes on the{" "}
    <a href={repo} target="_blank" rel="noreferrer">
      source repository
    </a>
    . Learn more about{" "}
    <a href="/api-reference/server/services/community-integrations">
      community integrations
    </a>
    .
  </Note>;

<CommunityMaintained maintainer="didlogic-cy" maintainerUrl="https://github.com/didlogic-cy" repo="https://github.com/didlogic-cy/pipecat-didlogic" />

## Overview

`DidlogicFrameSerializer` converts audio between Pipecat frames and the
[didlogic](https://didlogic.com/) voice-stream WebSocket protocol, so a Pipecat
bot can take a call on a didlogic number or be the agent leg of an outbound
call. It is used with `FastAPIWebsocketTransport`.

didlogic dials your endpoint, so the bot is the WebSocket server. One protocol
carries both directions of call: inbound, where somebody called a number pointed
at your endpoint, and outbound, placed through the Click2Call API with
`a_type: "stream"`.

<CardGroup cols={2}>
  <Card title="Source Repository" icon="github" href="https://github.com/didlogic-cy/pipecat-didlogic">
    Source code, examples, and issues for the didlogic integration
  </Card>

  <Card title="PyPI Package" icon="cube" href="https://pypi.org/project/pipecat-didlogic/">
    The `pipecat-didlogic` package on PyPI
  </Card>

  <Card title="Protocol Reference" icon="book" href="https://docs.didlogic.com/docs/guides/apps-developer-tools/websocket-calls">
    The WebSocket call protocol this serializer implements
  </Card>

  <Card title="didlogic" icon="phone" href="https://didlogic.com/">
    didlogic telephony platform and account signup
  </Card>
</CardGroup>

## Installation

This is a community-maintained package distributed separately from `pipecat-ai`:

```bash theme={null}
uv add pipecat-didlogic
```

## Prerequisites

### didlogic Account Setup

Before using the didlogic serializer, you need:

1. **didlogic account** with voice streaming enabled. This is enabled per
   account — if the WebSocket destination type is absent from the portal, or the
   API answers `422 a_type_unsupported`, ask support to turn it on.
2. **A publicly reachable `wss://` address.** The platform dials your endpoint
   rather than the other way round, so it has to be reachable from the internet.
3. **One of:** a phone number with its destination set to your `wss://` address,
   for inbound calls; or an API token and SIP account, to place outbound calls
   through Click2Call.

### Required Environment Variables

Nothing is required by the serializer itself — it reads everything it needs off
the socket. The outbound example in the source repository uses:

* `DIDLOGIC_API_TOKEN`: your API token, for placing Click2Call calls
* `DIDLOGIC_SIP_ACCOUNT`: the SIP account the call is billed and routed against
* `PUBLIC_WSS_URL`: the public `wss://` base the platform dials back on
* `DIDLOGIC_STREAM_TOKEN`: optional, sent to your endpoint as
  `Authorization: Bearer <token>` on the WebSocket upgrade

Both examples also use `OPENAI_API_KEY`, `DEEPGRAM_API_KEY` and
`CARTESIA_API_KEY` for the speech and LLM services in the pipeline.

## Configuration

The serializer takes no required arguments. The call id, both numbers and the
direction are read from the `start` message.

<ParamField path="params" type="DidlogicFrameSerializer.InputParams" default="None">
  Serializer configuration. Defaults to `DidlogicFrameSerializer.InputParams()`
  when not provided. See [Input Parameters](#input-parameters) below.
</ParamField>

<ParamField path="call_id" type="Optional[str]" default="None">
  The call's identifier, for a caller that read `start` before building the
  serializer. Left unset, it is learned from `start`.
</ParamField>

<ParamField path="from_number" type="Optional[str]" default="None">
  The calling party, on the same terms as `call_id`.
</ParamField>

<ParamField path="to_number" type="Optional[str]" default="None">
  The called party, on the same terms as `call_id`.
</ParamField>

<ParamField path="direction" type="Optional[str]" default="None">
  `"inbound"` or `"outbound"`, on the same terms as `call_id`.
</ParamField>

### Input Parameters

Configuration passed via the `params` constructor argument using
`DidlogicFrameSerializer.InputParams(...)`.

| Parameter | Type | Default | Description |
| - | - | - | - |
| `didlogic_sample_rate` | `int` | `24000` | The WebSocket wire sample rate. The platform does not negotiate this. |
| `sample_rate` | `Optional[int]` | `None` | Optional override for the Pipecat input sample rate. |
| `auto_hang_up` | `bool` | `True` | Whether an `EndFrame` or `CancelFrame` ends the call by sending `hangup`. |

<Note>
  didlogic uses a fixed media format: PCM16, 24 kHz, mono, base64-encoded inside
  JSON messages, one 10 ms frame per `media` message. Audio sent back may be any
  length. See the [source
  repository](https://github.com/didlogic-cy/pipecat-didlogic) for the
  authoritative, up-to-date list of parameters.
</Note>

## Usage

Wire the serializer into a `FastAPIWebsocketTransport`:

```python theme={null}
from pipecat_didlogic import DidlogicFrameSerializer
from pipecat.transports.websocket.fastapi import (
    FastAPIWebsocketTransport,
    FastAPIWebsocketParams,
)

transport = FastAPIWebsocketTransport(
    websocket=websocket,
    params=FastAPIWebsocketParams(
        audio_in_enabled=True,
        audio_out_enabled=True,
        add_wav_header=False,
        vad_analyzer=SileroVADAnalyzer(),
        serializer=DidlogicFrameSerializer(),
    ),
)
```

Telephony audio carries no WAV header, so `add_wav_header` must be `False`.
Everything else in the pipeline — STT, LLM, TTS — is ordinary Pipecat.

### Waiting for an outbound call to be answered

On an outbound call the platform answers the bot's leg as soon as it has sent
`start`, which is before the person's phone has rung. A bot that greets on
connect talks to a line nobody is on. The `answered` event is what says the far
end picked up, and it reaches the pipeline as an `InputTransportMessageFrame`:

```python theme={null}
from pipecat.frames.frames import InputTransportMessageFrame, LLMRunFrame
from pipecat.processors.frame_processor import FrameProcessor


class GreetWhenAnswered(FrameProcessor):
    async def process_frame(self, frame, direction):
        await super().process_frame(frame, direction)

        if (
            isinstance(frame, InputTransportMessageFrame)
            and frame.message.get("event") == "answered"
        ):
            await self.push_frame(LLMRunFrame())

        await self.push_frame(frame, direction)
```

Place it directly after `transport.input()`. On an inbound call the caller is
already on the line, so the greeting belongs right after the pipeline starts
instead.

Interruptions are handled by sending `clear`, so the platform drops audio it has
buffered but not yet played. DTMF arrives as `InputDTMFFrame`. See the
[source repository](https://github.com/didlogic-cy/pipecat-didlogic) for
complete inbound and outbound examples, including the Click2Call request.

## Compatibility

Tested with `pipecat-ai` 1.12.0. Check the
[source repository](https://github.com/didlogic-cy/pipecat-didlogic) for the
latest tested version and changelog.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.