PATCH /phone/auto_receptionists/{autoReceptionistId}/ivr returns 204 but does not persist any changes

API Endpoint(s)

  • PATCH /v2/phone/auto_receptionists/{autoReceptionistId}/ivr

  • GET /v2/phone/auto_receptionists/{autoReceptionistId}/ivr

Description

I’m trying to configure the IVR menu on an Auto Receptionist programmatically — set the audio_prompt and define key_actions so that pressing 1, 2, 3, etc. routes the caller to specific users, a call queue, or another Auto Receptionist. Goal is to manage IVR config from code rather than the web admin UI.

The PATCH endpoint accepts the request, returns success, but the changes never persist.

Error?

No error returned. The endpoint returns HTTP 204 with an empty body. A subsequent GET on the same endpoint shows the IVR completely unchanged.

The server is parsing the body — sending an invalid caller_enters_no_action.action value correctly returns:

HTTP 400 — "The action value set for if caller enters no action after the prompt played is not correct."

So validation runs. It just silently no-ops on payloads that pass validation.

How To Reproduce

  1. Authentication method / app type: Server-to-Server OAuth app, account-credentials grant. Token includes all phone:*:auto_receptionist*:admin scopes (e.g. phone:write:auto_receptionist_ivr:admin, phone:read:auto_receptionist_ivr:admin). Bearer token verified valid by GET calls on the same endpoint returning correct data.

  2. Request — minimal repro:

PATCH /v2/phone/auto_receptionists/{autoReceptionistId}/ivr?hours_type=business_hours
Host: api.zoom.us
Authorization: Bearer <token>
Content-Type: application/json

Body:

{
  "key_actions": [
    { "key": "1", "action": 2, "target": { "extension_id": "<user-extension-id>" } }
  ]
}

  1. Response:
HTTP/2 204
(empty body)

  1. Verification:
GET /v2/phone/auto_receptionists/{autoReceptionistId}/ivr?hours_type=business_hours

Returns the prior state — the new key: "1" entry is not present.

  1. Variants tested, all silently no-op:

    • With and without ?hours_type=business_hours

    • ?hours_type=closed_hours and ?hours_type=holiday_hours — same 204-no-op

    • Single-key updates and full-replacement payloads

    • Every documented value of key_actions[].action (1, 2, 3, 4, 6, 7, 21, 100, 200)

    • audio_prompt updates with a valid prompt id from GET /phone/users/me/audios

    • PUT and POST on the same path return 405 Method Not Allowed (“Method ‘PUT’ is not supported”) — PATCH really is the only verb

    • PATCH /v2/phone/auto_receptionists/{id} (AR root) — top-level fields like name do persist (verified with rename + GET diff + restore), but a nested ivr / menu / key_actions object on the root endpoint also returns 204 with no validation error and no persistence

    • PATCH /phone/extension/{extensionId}/call_handling/settings/{settingType} for the same Auto Receptionist’s extension — same silent no-op behavior on AR-related settings

    • Refreshed the OAuth token between attempts

  2. What works for comparison:

    • GET on the same endpoint returns correct data

    • Configuring the identical IVR through the Zoom Phone web admin UI works correctly, and the new state is then visible via GET — so the underlying data path is fine, only programmatic writes are dropped

    • The PATCH endpoint does validate input — invalid values return a real 400 with a meaningful message

  3. Sample trace identifiers from no-op PATCH responses (in case they help trace internally):

    • zm-cube-traceid: fec3f9d3e76e740e4750f0ebcf1eb8cd

    • x-zm-trackingid: WEB_5516d382133d6a589a48e7e823a95074

    • Region header: x-zm-region: VA

Has anyone seen this, or is there a known restriction on programmatic IVR writes? If certain Phone tiers don’t support PATCH on this endpoint, returning a 4xx instead of a silent 204 would make the limit much easier to discover.

Thanks.

Confirming this independently three months on, still reproducible as of 2026-08-14. But I have a narrowing result that I think changes the diagnosis.

The endpoint is not wholly broken. It writes some fields and silently drops others.

Testing on an auto receptionist with no phone numbers assigned, same token, same AR, same PATCH /v2/phone/auto_receptionists/{arId}/ivr?hours_type=business_hours, verified by GET after every call:

Field HTTP Persisted?
allow_dialing_by_extension 204 Yes
allow_callers_to_navigate_ivr 204 Yes
audio_prompt (to another valid prompt) 204 No
audio_prompt (reset to Default, id: "") 204 No
key_actions (add a new key) 204 No
key_actions (change an existing key’s target) 204 No
caller_no_input_timeout 204 No

The two that work are both newly added request fields from the 2026-07-20 changelog (“Expand Zoom Phone APIs with new IVR, Call Queue, Fax, and settings fields”). The ones that fail are the older, core fields — audio_prompt and key_actions — which are not mentioned in that changelog at all.

That pattern suggests the newer fields were wired into a working write path while the original ones were left behind, rather than the endpoint being disabled.

This rules out the tier-limitation theory raised earlier in this thread. If programmatic IVR writes were gated by Phone tier, allow_dialing_by_extension would not persist either. It does, on the same account, same token, same request.

Other things ruled out

  • Scopes/permissions. PATCH /v2/phone/auto_receptionists/{arId} on the base resource persists correctly with the same token on the same AR (changed timezone, verified by GET, reverted).
  • hours_type targeting. PATCH sent with explicit ?hours_type=business_hours and read back with the same value; all three hours types checked afterwards. No difference.
  • Prompt validity/context. The prompt ID I set is actively in use as the IVR greeting on other auto receptionists in the same account. And resetting to Default (""), which cannot be context-restricted, also no-ops.
  • Request schema. A deliberately wrong field name (key_action, singular) returns 400 {"code":300,"message":"Request Body should be a valid JSON object."}, so the body is being parsed. Correctly-named fields are accepted and discarded.

Tracking IDs

Both 204, nothing persisted:

  • x-zm-trackingid: WEB_a18ab699635bab97066dcdcf1fff6a29audio_prompt set to another valid prompt
  • x-zm-trackingid: WEB_9ff537805bb262eb8d29c298d3b79fdaaudio_prompt reset to Default

zm-cube-traceid: e550181c8b487a74957dec0d1fa2c90b · x-zm-region: VA2 · Server-to-Server OAuth, Business plan, multi-site enabled. Happy to share the account ID privately.

Ask

Could someone from Zoom confirm whether audio_prompt and key_actions are still supported request fields on this endpoint? Given the July changelog added new fields here without touching these two, it would help to know whether they were deliberately deprecated, or missed.

And separately, regardless of root cause — a 204 that discards the write is a silent-failure mode. Anything checking the response code, which is the normal thing to do, believes the change applied. I would echo the earlier request in this thread that an unsupported write return 4xx.

Impact

This blocks a menu change across 22 production auto receptionists. The web portal works, so the fallback is doing it by hand 22 times, which is exactly the kind of repetitive change an API should be handling.