Skip to main content
An Agent is Egma’s record of one of your voice agents. It holds the agent’s name, its project membership, and a history of every test run and simulation ever conducted against it. A Connection is how Egma actually reaches that agent when a simulation starts — it carries the provider credentials, the reach type, and everything else the simulator needs to place a call or exchange messages.

Agents

Register an agent once and Egma assigns it a stable agt_ identifier. That identifier ties together everything that runs against that agent: test suites, individual runs, simulation traces, and verdict history. You never need to re-register after an update to your agent’s prompt or tooling — the identifier stays the same. Registering is idempotent by design. If you run egma connect a second time for the same vendor agent, Egma looks up the existing registration rather than creating a duplicate. The registration field in the response tells you exactly what happened: This makes it safe to run from CI pipelines or after a network failure — you will never end up with two agent records for one vendor agent.

Connections

A Connection defines the path from Egma to your agent. One agent can have multiple connections, each representing a different way to reach it. This is useful when you want to test the same agent over both a text channel and a phone line.

Connection types

Retell

Connects via the Retell API. Requires a Retell API key and a Retell agent ID. Egma seals the key on arrival and uses it only when placing simulation calls.

LiveKit

Connects to a LiveKit agent by joining a room in your own LiveKit project. Requires a LiveKit URL, API key, and API secret. Optionally accepts an agent name if your worker registers one.

Reach types

Each connection has a reach type that determines what kind of conversation Egma simulates:

text

Egma exchanges messages directly with your agent. No phone call, nothing dialled. Tests your prompt, reasoning logic, and tool integrations.

phone

Egma places a real SIP call to one of your agent’s phone numbers. Tests everything the text reach tests, plus your speech stack, TTS/STT providers, and the telephone network path.
Running the same test over both a text connection and a phone connection is the sharpest diagnostic Egma offers. A test that passes on text and fails on phone tells you the prompt is fine and the speech stack is not.

Credential sealing

Credentials you provide when creating a connection — API keys, secrets — are encrypted immediately on arrival and never stored in plaintext. After creation, they are not readable through any Egma API. The response returns only a credentials_hint (the last four characters of the key) so you can confirm a rotation landed without seeing the credential itself. This is enforced structurally: the sealed field is absent from every read response shape, not merely blanked. There is no serializer path that could accidentally expose it.

Registering via the CLI

The fastest way to register an agent is with egma connect. Run it inside your voice agent repository:
The wizard asks for your provider API key (input is masked), lists the agents on your account, and asks which reach type to create. For phone connections, it lists the numbers routed to the agent and asks you to pick one. To run non-interactively (for CI or a coding agent), supply the key and options without a terminal:

Registering via the API

You can also register directly with POST /api/agents. Include the connection inline in the same request:
To attach a second connection to an existing agent, use POST /api/agents/:agentId/connections with the same connection body.
A connection is only ever reachable through its agent. There is no /api/connections root. To list the connections on an agent, use GET /api/agents/:agentId.

One agent, multiple connections

Having multiple connections on one agent keeps all run history unified. You do not need separate agents for “text testing” and “phone testing” — they are the same agent reached two different ways, and Egma tracks their results together.
Each run names a specific connection_id, so results from each reach type stay distinct in your history.