> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes.

# detect_machine

> Detect whether the other end of the call is a machine (fax, voicemail, etc.) or a human, using AMD and fax detection.

[variables]: #variables

[statuscallbacks]: #statuscallbacks

A detection method that combines AMD (Answering Machine Detection) and fax detection.
Detect whether the user on the other end of the call is a `machine` (fax, voicemail, etc.) or a `human`.
The detection event(s) will be sent to the specified `status_url` as a POST request, and the current detection state
or final result will also be saved in the `detect_result` [variable][variables].

## **Properties**

**`detect_machine`** `object` — required

An object that accepts the following properties.

---

**`detect_machine.detect_message_end`** `boolean` — default: false

If `true`, stops detection on beep / end of voicemail greeting.

---

**`detect_machine.detectors`** `string` — default: amd,fax

Comma-separated string of detectors to enable. **Valid Values:** `amd`, `fax`

---

**`detect_machine.end_silence_timeout`** `number` — default: 1.0

How long to wait for voice activity to finish (in seconds).

---

**`detect_machine.initial_timeout`** `number` — default: 4.5

How long to wait for initial voice activity before giving up (in seconds).

---

**`detect_machine.machine_ready_timeout`** `number` — default: value of the end\_silence\_timeout parameter

How long to wait for voice activity to finish before firing the READY event (in seconds).

---

**`detect_machine.machine_voice_threshold`** `number` — default: 1.25

The number of seconds of ongoing voice activity required to classify as MACHINE.

---

**`detect_machine.machine_words_threshold`** `integer` — default: 6

The minimum number of words that must be detected in a single utterance before classifying the call as MACHINE.

---

**`detect_machine.status_url`** `string`

The HTTP(S) URL to deliver detector events to. Learn more about [status callbacks][statuscallbacks].

---

**`detect_machine.timeout`** `number` — default: 30.0

The maximum time to run the detector (in seconds).

---

**`detect_machine.tone`** `string` — default: CED

The tone to detect. Only the remote side tone will be received. (`CED` or `CNG`) Used for fax detection.

---

**`detect_machine.wait`** `boolean` — default: true

If `false`, the detector will run asynchronously and `status_url` must be set. If `true`, the detector will wait for detection to complete before moving to the next SWML instruction.

---

## **Variables**

The following variables are available after the `detect_machine` method is executed and detection is complete.
You can reference these variables in your SWML script utilizing the `${variable}` syntax.

**`detect_result`** `machine | human | fax | unknown | detecting | error`

The lowercase SWML variable value for the current detection state or final result.
Callback lifecycle events such as `READY`, `NOT_READY`, and `finished` are never assigned to this variable.

---

**`detect_machine_beep`** `true | false`

Whether a beep was detected. `true` if detected.

---

**`detect_ms`** `integer`

The number of milliseconds the detection took.

---

## **StatusCallbacks**

> **Status callbacks are advisory**
>
> Status callbacks are asynchronous, best-effort HTTP notifications: delivery can be delayed or fail silently — if your server is unreachable, the callback simply never arrives. Don't gate time-critical or business-critical actions solely on receiving one. Confirm state via the REST API before acting, or use a transport with visible failure modes — see [Status callback reliability](/docs/platform/webhooks#status-callback-reliability).

A POST request will be sent to `status_url` with a JSON payload like the following:

**`event_type`** `string`

The type of event, always `calling.call.detect` for this method.

---

**`event_channel`** `string`

The channel for the event, includes the SWML session ID.

---

**`timestamp`** `number`

Unix timestamp (float) when the event was generated.

---

**`project_id`** `string`

The project ID associated with the call.

---

**`space_id`** `string`

The Space ID associated with the call.

---

**`params`** `object`

An object containing detection-specific parameters.

---

**`params.control_id`** `string`

The control ID for this detect operation.

---

**`params.detect`** `object`

Detection result details (see subfields below).

---

**`detect.type`** `string`

The type of detection. **Valid values:** `machine` or `fax`.

---

**`detect.params.event`** `string`

The detector event value in the status callback payload.

Detection outcome values are `HUMAN`, `MACHINE`, and `UNKNOWN`.
Lifecycle marker values are `READY`, `NOT_READY`, and `finished`.
`READY`, `NOT_READY`, and `finished` only appear in callback payloads and are not valid `${detect_result}` values.
The lowercase `finished` value is intentional.

---

**`detect.params.beep`** `boolean`

Present and set to `true` when a beep was detected. Absent when no beep has been detected.

---

**`params.call_id`** `string`

The call ID.

---

**`params.node_id`** `string`

The node handling the call.

---

**`params.segment_id`** `string`

The segment ID for this part of the call.

---

### Raw JSON example

```json
{
  "event_type": "calling.call.detect",
  "event_channel": "swml:be38xxxx-8xxx-4xxxx-9fxx-bxxxxxxxxx",
  "timestamp": 1745332535.668522,
  "project_id": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "space_id": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "params": {
    "control_id": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "detect": {
      "type": "machine",
      "params": {
        "event": "MACHINE",
        "beep": true
      }
    },
    "call_id": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "node_id": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "segment_id": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  }
}
```

---

## **Examples**

### Play the detection result

#### YAML

```yaml
version: 1.0.0
sections:
  main:
    - detect_machine:
        status_url: 'https://example.com/detect-events'
        timeout: 20
    - play:
        url: 'say:Detection result: ${detect_result}'
```

#### JSON

```json
{
  "version": "1.0.0",
  "sections": {
    "main": [
      {
        "detect_machine": {
          "status_url": "https://example.com/detect-events",
          "timeout": 20
        }
      },
      {
        "play": {
          "url": "say:Detection result: ${detect_result}"
        }
      }
    ]
  }
}
```

### Conditional actions based on the detection result

#### YAML

```yaml
version: 1.0.0
sections:
  main:
    - play:
        url: "say: Welcome to the machine detection test."
    - detect_machine:
        status_url: "https://webhook.site/5c8abf82-b8c7-41c8-b5d6-b32a40068109"
        detectors: "amd,fax"
        wait: true
    - cond:
        - when: detect_result == 'machine'
          then:
            - play:
                url: "say: You are a machine, goodbye."
            - hangup: {}
        - when: detect_result == 'human'
          then:
            - play:
                url: "say: You are a human, hello."
            - hangup: {}
        - when: detect_result == 'fax'
          then:
            - play:
                url: "say: You are a fax, goodbye."
            - hangup: {}
        - else:
            - play:
                url: "say: Unable to determine if you are a human, machine, or fax, goodbye. Result was ${detect_result}"
            - hangup: {}
```

#### JSON

```json
{
  "version": "1.0.0",
  "sections": {
    "main": [
      {
        "play": {
          "url": "say: Welcome to the machine detection test."
        }
      },
      {
        "detect_machine": {
          "status_url": "https://webhook.site/5c8abf82-b8c7-41c8-b5d6-b32a40068109",
          "detectors": "amd,fax",
          "wait": true
        }
      },
      {
        "cond": [
          {
            "when": "detect_result == 'machine'",
            "then": [
              {"play": {"url": "say: You are a machine, goodbye."}},
              {"hangup": {}}
            ]
          },
          {
            "when": "detect_result == 'human'",
            "then": [
              {"play": {"url": "say: You are a human, hello."}},
              {"hangup": {}}
            ]
          },
          {
            "when": "detect_result == 'fax'",
            "then": [
              {"play": {"url": "say: You are a fax, goodbye."}},
              {"hangup": {}}
            ]
          },
          {
            "else": [
              {"play": {"url": "say: Unable to determine if you are a human, machine, or fax, goodbye. Result was ${detect_result}"}},
              {"hangup": {}}
            ]
          }
        ]
      }
    ]
  }
}
```