Skip to content

Build1 publisher2 min readPublished Updated

A phone agent answered two ICA keypad menus out loud until the line hung up at 193 seconds

CounterCall's builder pointed a voice agent at Singapore's immigration enquiries line and watched it talk to a touch-tone menu, because the platform's OpenAPI spec has no field for sending DTMF tones.

The Engineer · Build desk

What happened

  • A phone agent built on the CALL-E API called ICA Singapore's published general-enquiries line and was cut off at 193 seconds by a recording saying it had exceeded the maximum number of tries.
  • Across nine transcript turns and two separate touch-tone menus, the agent answered every "press 1" instruction in words rather than with a keypress.
  • The developer traced the failure to the platform, which cannot send DTMF tones. Its OpenAPI spec and documentation do not mention dtmf, keypad or tone.
  • A property-based sweep over the skill's result validator had earlier caught an empty clerk_quote string passing clean, and an empty quote is now rejected outright.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • decision Anyone picking a voice-call API can settle this before writing a skill: search the spec for dtmf, and without that field, every task sitting behind a phone tree is off the table.
  • constraint Timing out of the menu is not a workaround on this line, because the escalation path itself delivered another keypad menu before any officer answered.
  • exposure Autonomous dialling points at public enquiries numbers that staff answer, and the idempotency key scoped to office, procedure and day is what keeps a retry loop from becoming repeat traffic on a government line.
  • precedent Making the fee field absent instead of 0 sets a usable bar for products that promise sourced answers: print a fee when the clerk said it, and leave the row blank when the clerk did not.

The line said what happened. At 32 seconds, after the agent's spoken "Okay," the ICA recording answered "We did not receive your entry. For English, press 1." [5] Speech is the only channel the model has on this platform, so it kept talking. [11]

Between prompts the agent said "No rush." and then "No rush, I'll hold." [6] Neither reply moved the menu. The first menu ran out of tries at 75 seconds and the recording promised to connect the caller to the next available officer. [7] What arrived 49 seconds later was a second keypad menu: citizens press 1, permanent residents press 2, visit us press 3, other services press 4. [8][22] The agent said "Okay" again at 131 seconds. [8]

Of the 193 seconds on the line, 183 came after the first instruction to press a key. [21] "The cause is simple and I should have checked it on day one: the platform cannot send DTMF tones," the developer wrote. [12] The API's own post-call summary got it right: "The assistant did not make the required keypad selections, so the call ended before reaching an officer." [10]

The schema is the part I would copy into another project. CONTRACT version 2 requires six fields, and clerk_quote is one of them: a single verbatim sentence from the clerk, and the evidence for every other value on the card. [13][14] The comment on the check that rejects it says an empty one renders a card that looks sourced and is not. [16] The fee field works the other way. total_fee_sgd is optional, and when the clerk does not say a number the row is absent, not null and not 0. [17][13]

The same schema object is serialised into the request as resultSchema and used to validate the reply, so what was asked for and what gets accepted cannot drift apart. [18] Every dial carries an idempotency key scoped to office, procedure and day, so a retry does not double-dial a public enquiries number. [19]

For the 193 seconds to say anything about your own build, what matters is whether your target numbers put a machine in front of the human. This one did: the test covers a single office, procedure and day, ICA's published general-enquiries line on 2026-09-10 for passport renewal. [3] The project publishes two unedited calls in DEMO.md alongside the code and a live demo. [20] A speech-only agent still gets through on a direct line to a desk, and the CounterCall skill is built to ask five closed questions of a person who picks up. [2][11]

What to watch

  • Whether CALL-E adds a dtmf or keypad field to its OpenAPI spec, and what the docs say about tone timing.
  • Whether DEMO.md grows past two unedited calls into a sample large enough to rate the skill on.
  • Whether the contract gains an explicit no-result code for calls that never reach a clerk, so a failed dial cannot render as a card.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories