Skip to content
AMD API

Know who answered. In one line of TwiML.

Ten outcomes, not three: human, voicemail, IVR, the new iPhone and Google AI screeners, dead numbers, fax. Decided in under 300 ms for a human and under 800 ms for a machine (in-region), with the reason attached to every call. Keep your carrier, keep your code.

First 5,000 answered calls free every month. No card.

The whole integration
<Response>
  <Connect>
    <Stream url="wss://api.pyai.com/v1/amd/stream">
      <Parameter name="api_key" value="YOUR_PYAI_KEY"/>
      <Parameter name="aggressiveness" value="0.25"/>
      <Parameter name="webhook" value="https://you/amd-events"/>
    </Stream>
  </Connect>
</Response>

That is the migration. The key rides a <Parameter> and is verified before any audio is processed. Decisions push mid-call on the same socket and to your webhook.

Works with what you already dial from

TwilioOne line of TwiML
SignalWireTwilio-format streams
TelnyxTwilio-format streams
PlivoStream bridge
VonageStream bridge
GenesysStream bridge
RingCentralStream bridge
Amazon ConnectKVS bridge

The endpoint speaks Twilio’s Media Streams wire format natively, so platforms that speak it connect directly. Platforms with their own stream format fork call audio to a wss:// bridge that forwards the frames, about a page of server code, authenticated with ?api_key=. All trademarks belong to their owners; listing means protocol compatibility, not endorsement.

<300 ms
human decision, in-region measurement
<800 ms
machine decision, in-region measurement
10
outcome classes, each a different dialer action
$0.004
per answered call after 5,000 free each month
The category shift

An AI answers the phone now. Legacy AMD calls it a human.

iPhone Call Screening and Google Call Screen pick up unknown calls with an on-device assistant before the person does. Person-or-machine detection from 2015 waves that through, your agent pitches into a transcript, and your caller IDs get flagged as spam. AMD returns it as its own class, screening, so your dialer can behave and your numbers stay clean.

Ten outcomes

Every class is a different next move

Three labels force one crude branch. Ten classes let the dialer act: scrub the dead number, respect the screener, let the receptionist through, drop the voicemail after the beep.

human

Connect the agent. Under 300 ms in-region, so the caller never hears dead air.

screening

iPhone or Google AI answered. Say who you are; do not pitch a transcript.

voicemail

Wait for the beep, drop the message, move on.

live_voicemail

The new live-transcribed voicemail. Treat like voicemail, not a person.

ivr

Navigate the tree or route to the right queue.

human_gatekeeper

A receptionist answered. Let them through to a person.

sit_invalid

Dead or disconnected number. Scrub it from the list.

fax

Drop and flag the record.

silence

Nothing on the line. Retry later, do not burn an agent.

unknown

No decisive evidence. Your call: connect or hang up, you set the default.

The receipt

Every decision says why

The reason field quotes what the model heard and when. When a campaign goes sideways at 2am, you read the reason, not a black-box label. answered_by_twilio speaks Twilio's exact vocabulary, so existing routing logic runs unchanged.

Pushed mid-call on the socket and to your webhook
{
  "event": "amd",
  "call_id": "CA7d0…",
  "answered_by": "screening",
  "answered_by_twilio": "machine_start",
  "confidence": 0.96,
  "decision_ms": 720,
  "reason": "screening phrase: 'the person you're calling is using \
a screening service' at 0.6s"
}

FAQ

Which telephony platforms does PyAI AMD work with?

Any platform that can fork call audio to a WebSocket. The endpoint speaks Twilio's Media Streams wire format natively, so Twilio is one line of TwiML, and SignalWire and Telnyx speak the same stream format. Plivo, Vonage, Genesys, and RingCentral fork call audio from their own media streaming features through a thin server-side bridge that forwards the frames; Amazon Connect reaches it the same way via Kinesis Video Streams. Server-side integrations authenticate with ?api_key= on the URL or the pyai-key subprotocol.

How is PyAI AMD billed?

Per answered call. The first 5,000 answered calls each month are free, then $0.004 per answered call. Calls that never get answered are not billed, and AMD is included at no charge when the call already runs on PyAI telephony.

Do I have to change my routing logic to leave Twilio AMD?

No. Every decision carries answered_by_twilio, which maps to Twilio's exact AnsweredBy enum, next to the richer answered_by class. Route on the Twilio field on day one and adopt the ten classes when you are ready.

How fast is the decision?

Under 300 ms for a human and under 800 ms for a machine, measured in-region; not an SLA. Twilio's documented MachineDetection dwell is 2.5 to 4 seconds, so the decision lands well inside the window you already pay carrier seconds for.

Point one call at it. Read the reason.

A free key, one line of TwiML, and the first 5,000 answered calls each month on us. If the decision is not faster and more useful than what you have, keep what you have.

No credit card - OpenAI-compatible - cancel anytime