# Changelog

> What changed across the Amomic-AI platform and public API, newest first, with links to the documentation for each release.

Source: https://docs.amomic.in/operate/changelog

---

Changes that affect customers or people building against the public API, newest first. A paragraph that starts with **API** changes something your own code can observe: an endpoint, an event, a scope or an error reason.

## 2026-10-15 — A suspended workspace stops everything

**Suspension now stops every channel, not just calls and API keys.** While a workspace is suspended for an unpaid plan invoice, web chat visitors get a neutral *the assistant isn't available right now* reply, including in conversations already open. Incoming WhatsApp messages are saved to the inbox, but the agent doesn't reply and no *typing…* is shown. Nothing is sent on WhatsApp, and outbound and click-to-call calls are refused. Incoming calls still hear the out-of-service line and are recorded without being charged. Campaigns, call-backs and appointment reminders are held rather than failed, and a staff WhatsApp reply on a ticket is held with a line saying why. Billing keeps working, and paying the invoice resumes everything on its own: held work carries on and nobody is skipped or messaged twice. Your customers are never told why. See [When a payment fails](/operate/plan-changes#when-a-payment-fails), [Tickets](/console/tickets#did-the-reply-reach-the-customer), [WhatsApp](/channels/whatsapp#how-an-inbound-message-reaches-your-agent), [Web chat](/channels/web-chat#when-your-workspace-is-out-of-allowance) and [Voice](/channels/voice).

**API** — `workspace_suspended` can now also come back as `412 failed_precondition` on a WhatsApp send and on a campaign launch or resume, not only on a call. Over the API a suspended workspace's key is normally refused first with `403 workspace_suspended`, as before. See [Errors](/api/errors#messages).

## 2026-10-15 — Retries, typing, admin-only channel changes and invoice details

**API** — a request sent with an `Idempotency-Key` that fails (any `4xx` or `5xx`) now releases the key, so a retry with the same key runs fresh instead of answering `409 idempotency_in_progress` for 24 hours. A stored success still replays, and a duplicate sent while the first request is running still gets the `409`. A `5xx` can come after a message or call went out, so confirm before you retry one. See [After an error response, retry with the same key](/api/idempotency#after-an-error-response-retry-with-the-same-key).

**No typing indicator when the agent won't reply.** On WhatsApp, *typing…* is no longer shown on an **Off** number, when your workspace is out of conversation allowance, or while WhatsApp is paused on your plan. It was already hidden while the agent has stepped back. Read receipts still follow **Mark incoming messages as read**. See [Reply modes](/channels/whatsapp-reply-modes#assigned-agent-read-receipts-and-typing).

**Channel changes are for owners and admins.** Changing a WhatsApp number's settings, submitting business verification, and requesting, attaching or releasing phone numbers are now refused for members. See [Workspaces & roles](/concepts/workspace#the-three-roles) and [Numbers & KYC](/channels/phone-numbers).

**Pay asks for what the invoice needs.** When a payment needs a **Registered name** or **Billing address** (₹50,000 or more, or a GSTIN on file), the **Add credits** and plan dialogs now show the fields and say why, instead of leaving **Pay** disabled with no explanation. See [Invoices & tax](/operate/invoices-and-tax#tax-details) and [Credits](/operate/credits).

**Duesly keeps recording payments after you disconnect Razorpay.** Payment links sent before the disconnect still settle their payments automatically; new dues get UPI instructions. See [Duesly](/apps/duesly#razorpay-webhook).

## 2026-10-13 — Meera's voice on calls

**Meera sounds the way her preview does.** The Support desk voice **Meera** has a warmer tone on the line and plays a little louder. Her sample in the voice picker was re-recorded through the same phone line, so what you hear before you save is what callers hear. See [Voice](/channels/phone-workspace#voice).

## 2026-10-11 — Pause with /stop, outcomes on incoming calls, open sign-up

**Pause the agent on one WhatsApp chat.** On a number that stays on your WhatsApp Business app, send `/stop` in a customer's chat from your phone and the agent stays out of that chat until you send `/continue`, or someone chooses **Resume AI now** in the inbox. See [Pause with /stop](/channels/whatsapp-pause).

**Outcomes on incoming calls.** Each phone number can carry its own questions. The agent helps the caller first and asks where it fits, and every call is read afterwards. The number gets an outcome dashboard, and each call shows what was learned. See [Outcomes on incoming calls](/console/call-outcomes).

**API** — `call.outcome` now also fires for incoming calls, with `direction: "inbound"`, and `GET /calls/{call_id}` returns the same reading as `result`. See [Call outcomes](/api/call-outcomes#reading-the-result).

**Anyone can sign up.** The early-access gate is gone. Create an account, verify your email and create your organization without an invitation. See [Create your account](/start/create-account).

**Tips & features.** A new section in the sidebar holds short walkthroughs of recent features, and the newest one plays on Home. See [Home](/console/home#keep-moving-and-tips-features).

**Billing counts more fairly.** A customer's reply to a campaign message is billed once, as part of the campaign's conversation, and a message blocked before it was sent is never billed. **Usage by touchpoint** counts a voice call once instead of twice. See [Usage by touchpoint](/build/deployments#usage-by-touchpoint) and [What credits pay for](/operate/credits#what-credits-pay-for).

**Fewer false payment alarms.** Billing no longer says a payment is due before a renewal has actually failed, and a USD plan payment is announced only once its checkout has finished. See [When a payment fails](/operate/plan-changes#when-a-payment-fails).

## 2026-10-09 — Plan changes, trials and a new Billing page

**The Billing page was rebuilt.** A status rail at the top shows what needs attention first, then your plan, your next payment, prepaid credits, usage this cycle, the plans, and tax details and invoices. Plan and credit warnings elsewhere in the console lead straight to it. See [Billing](/console/billing).

**Upgrades, downgrades and trials.** An upgrade starts as soon as the payment clears, and unused days on your old paid plan come back as credits. A downgrade is previewed first, listing what will stop for your workspace, and is scheduled for the end of the period you paid for; you can undo it until then. A trial given by Amomic-AI ends without charging you, and you can change plan during one. See [Upgrades, downgrades & trials](/operate/plan-changes).

**Moving to Free winds down voice and WhatsApp.** Your WhatsApp number and phone numbers stop answering. Phone numbers are held for 7 days before they are released, so an upgrade in that time brings them back. See [The 7-day hold](/operate/plan-changes#the-7-day-hold).

**API** — while a channel is wound down, `POST /messages` and `POST /calls` are refused with `412` and `details.reason` of `channel_dormant`. See [What is actually enforced](/operate/limits#what-is-actually-enforced).

## 2026-10-08 — Support desk voices you can choose

**Six named voices on Support desk.** Aarohi, Meera, Nandini, Vikram, Kabir and Arjun, each with a sample recorded through the same phone line and office room a caller hears. The agent's Hindi follows the voice's gender, so when you save, the console checks that the agent's name fits the voice and offers to change it. See [Voice](/channels/phone-workspace#voice).

## 2026-10-06 — Call outcomes

**Decide what every campaign call brings back.** Call batches have a new **Outcome** step in the wizard: the fields to capture and what counts as success. Each call is read after it ends. The campaign gets an outcome dashboard and a CSV export, and each call an outcome card. See [Call outcomes & dashboard](/campaigns/outcomes) and [The call outcome card](/console/calls#the-call-outcome-card).

**API** — `POST /calls` accepts a capture, `GET /calls/{call_id}` returns the reading as `result`, and the new `call.outcome` webhook pushes it, usually within a minute of `call.ended`. That makes twenty event types. Campaign outcomes are at `GET /campaigns/{campaign_id}/outcomes` (`campaigns:read`) and `GET /campaigns/{campaign_id}/outcomes.csv` (`campaigns:write`). See [Call outcomes](/api/call-outcomes) and [Event reference](/webhooks/events#call-outcome).

## 2026-10-05 — Your workspace's time zone

**Pick the time zone at sign-up and change it in Settings.** Campaign sending windows, live support hours, Duesly reminders and customer call-backs follow it, and agents know the business's local time when a customer asks the time or says "tomorrow". See [Settings](/console/settings#organization) and [Quiet hours](/campaigns/scheduling#quiet-hours).

**API** — a campaign created without a schedule time zone, pace or window takes them from your workspace's campaign defaults. See [Workspace defaults](/campaigns/scheduling#workspace-defaults).

## 2026-10-04 — How a call sounds, and call-backs at the time the caller asked

**More control over how a number sounds.** Choose how callers hear the recording notice: in the agent's greeting, or as an automated announcement first. Turn on **Natural hesitations**, set the office background sound to one of five room levels, and accept the offer to translate the opening line when you change the greeting language. See [How it sounds on this number](/channels/phone-workspace#how-it-sounds-on-this-number).

**Call-backs land when the caller said.** "Tomorrow at 11" is booked for 11, a new time moves the open call-back instead of adding another, and nothing is booked until a time is agreed. See [Customer-requested call-backs](/console/calls#customer-requested-call-backs).

## 2026-10-03 — More than one organization, and new house voices

**One person, several organizations.** Each browser tab works in its own organization, so two tabs can show two workspaces side by side. The organization menu lists invitations to **Accept** or **Decline**, opens any organization in a new tab, and creates a new one. You can leave an organization from Settings. See [More than one workspace](/concepts/workspace#more-than-one-workspace) and [Invitations to other organizations](/console/team#invitations-to-other-organizations).

**Standard and Expressive have a new house voice.** Both engines speak with the **Amomic-AI default voice**, a warm Indian-English delivery tuned for support. If a caller asks for another language the call allows, the agent switches to it. See [Voice](/channels/phone-workspace#voice) and [Switching language mid-call](/channels/voice-languages#switching-language-mid-call).

## 2026-09-28 — Version history, the number workspace, call script variables

**Agent version history.** Each version shows what changed as red and green differences, with settings, tools and knowledge shown as switches and chips. Compare any two versions, or roll back to an earlier one. Saved edits still reach customers straight away; versions are your history and your way back. See [Versions & rollback](/build/versions).

**Each phone number has its own workspace.** One place for a number's agent, opening line, engine, voice, room sound, recording and call length, like a WhatsApp sender's. See [Manage a number](/channels/phone-workspace).

**Number search matches digits anywhere.** A search finds the digits in any position of the number, not only at the start. See [Search and request a number](/channels/phone-numbers#in-india-search-and-request-a-number).

**Call scripts per recipient.** In a call batch, each call gets its own row of the uploaded file. Insert columns as variable chips, type `@` to pick one, use **@all** for everything, or let AI write the script. A script that uses the name is refused when the file has no name column. See [Call scripts & variables](/campaigns/call-scripts).

## 2026-09-25 — The Support desk engine

**A third conversation engine for phone calls.** **Support desk** sounds like a real person at your support desk: relaxed, natural and easy to talk to. It is best for Hindi and Indian-language helplines, offers female and male voices, and has an office background sound you can switch on or off per number. See [Conversation engine](/channels/phone-workspace#conversation-engine).

## 2026-09-24 — Video headers and numbers outside India

**WhatsApp templates with a video header.** Compose, preview and send templates that open with a video. See [Video headers](/channels/whatsapp-templates#video-headers).

**Phone numbers outside India.** A workspace outside India asks our team for a number from **Channels → Phone**, and we set it up with you. See [Outside India: ask our team for a number](/channels/phone-numbers#outside-india-ask-our-team-for-a-number).

## 2026-09-23 — Who the customer is, and quieter WhatsApp agents

**Customer details captured across channels.** The name, phone and email a customer gives on web chat, WhatsApp or a call are kept with their contact, and Live support shows them with a **View contact** link. See [The queue](/console/human-handoff#the-queue) and [Where contacts come from](/console/contact-memory#where-contacts-come-from).

**The WhatsApp agent can stay out of a message.** If your instructions say to leave a kind of message alone, the agent declines to reply instead of sending an apology. Greetings and thanks still get a short reply, and several messages sent in quick succession get one answer. See [Instructions](/build/agents#instructions).

**Photos show in the inbox.** Images and voice notes appear in the transcript even when the agent didn't answer them, including on numbers that stay on the WhatsApp Business app. See [Reading a transcript](/console/inbox#reading-a-transcript).

## 2026-09-16 — Smart reply mode

**Smart mode.** The agent answers everyone, then steps back from a conversation when someone on your team replies, for a quiet period you choose. The inbox shows when the agent has stepped back and lets you hand the conversation back early. See [Smart](/channels/whatsapp-reply-modes#smart) and [When the agent has stepped back](/console/inbox#when-the-agent-has-stepped-back).

**Longer instructions.** An agent's instructions hold 40,000 characters, up from 4,000, with a counter. See [Instructions](/build/agents#instructions).

**Conversations open on the newest message.** A long thread opens at the bottom; scroll up for earlier messages. See [Reading a transcript](/console/inbox#reading-a-transcript).

**API** — `message.echo`: on a number that stays on the WhatsApp Business app, a message your team sends, edits or deletes from the app is delivered to your endpoint. That makes nineteen event types. See [`message.echo`](/webhooks/events#message-echo).

## 2026-09-12 — Keep your number on the WhatsApp Business app, and stop the agent for one person

**Keep using the WhatsApp Business app.** When you connect a number you can keep it on the WhatsApp Business app on your phone. Your team replies from the phone while the agent works alongside, and both sides of the conversation are kept in the inbox. See [Choose how the number connects](/channels/whatsapp#step-2-choose-how-the-number-connects).

**Choose when the agent replies.** Each WhatsApp number has a reply mode, and the console shows who else can send from the number. With the agent **Off** you can also choose not to keep those conversations. See [Reply modes](/channels/whatsapp-reply-modes).

**Stop the agent replying to someone.** Switch the agent off for one contact and it never replies to them on WhatsApp; your team still can. See [Stop the agent replying to someone](/console/contact-memory#stop-the-agent-replying-to-someone).

**Your country, not India by default.** Sign-up asks where the business is. Phone fields start with your country's code, and a number typed without one is read as a number from your country. See [Settings](/console/settings#organization).

**Messages your team sends from the app aren't billed.** They, and threads nobody had a conversation in, don't use a conversation. See [What credits pay for](/operate/credits#what-credits-pay-for).

## 2026-09-09 — Your currency, GST invoices and credit notes

**Bill in your workspace's currency.** A workspace is billed in rupees or US dollars, and every price, credit and invoice uses that currency. See [Your workspace currency](/operate/credits#your-workspace-currency).

**GST invoices.** INR workspaces get a GST invoice for every payment, downloadable from Billing. Add your GSTIN in **Tax details** or at checkout; it is optional. Refunds come with a credit note, and checkout shows the price, the tax and the total before you pay. See [Invoices & tax](/operate/invoices-and-tax).

## 2026-09-07 — Ticket replies that reach the customer

**See whether a reply arrived.** Each staff reply on a ticket shows whether it reached the customer. A reply to a customer who has been quiet for more than 24 hours on WhatsApp goes out through the approved ticket update template. See [Did the reply reach the customer?](/console/tickets#did-the-reply-reach-the-customer)

**Reply settings.** Choose which WhatsApp number ticket replies leave from, see the state of each template on it, submit Amomic-AI's templates for approval, or substitute one of your own approved templates. See [Reply settings](/console/ticket-settings#reply-settings).

**The ticket header shows the customer's contact details,** and the support workspaces fit smaller screens. See [Reading a ticket](/console/tickets#reading-a-ticket).

**API** — `ticket.replied` fires when a staff reply is added to a ticket and carries `delivery_state`, including `held` while a reply waits. That makes eighteen event types. See [`ticket.replied`](/webhooks/events#ticket-replied).

## 2026-09-02 — Availability ends with the shift

**Going available lasts until your shift ends.** The availability switch in Live support turns itself off at the end of your live-hours window, so nobody is left looking available overnight. See [Go available](/console/human-handoff#go-available).

## 2026-08-31 — Activity across channels

**A contact's whole history in one place.** Each contact lists their conversations, calls, tickets and appointments, newest first, and pages through long histories instead of stopping at 50. See [Activity across channels](/console/contact-memory#activity-across-channels).

## 2026-08-29 — Appointment webhooks, the retrieval tester, removing a sender

**Three new webhook events.** `appointment.booked`, `appointment.rescheduled`, and `appointment.cancelled`, bringing the catalogue to seventeen. All three were subscribable before this release but never delivered anything; an endpoint already ticked for them starts receiving deliveries now, with no action needed.

**A reschedule reports the new appointment, not a moved one.** Rescheduling books the replacement as a new appointment, so `appointment_id` on `appointment.rescheduled` is an id your system has not seen and the original is in `previous_appointment_id`. A handler that upserts on `appointment_id` alone will end up with the customer booked twice. No separate `appointment.booked` fires for the replacement. See [Event reference](/webhooks/events#appointment-booked-appointment-rescheduled-appointment-cancelled).

**The attendee is not in the payload.** No name, phone, or email leaves in a webhook body, and there is still no public appointments REST API to fetch them back — the `appointments:read` and `appointments:write` scopes remain accepted but have no routes behind them.

**See why the knowledge base returned what it did.** The retrieval tester shows each matching passage with how it was found and how it scored, so you can tell a wording problem from a missing answer. See [The retrieval tester](/build/knowledge-retrieval#the-retrieval-tester).

**Remove a WhatsApp sender.** A connected number can now be disconnected from its sender workspace. See [Remove (disconnect) a sender](/channels/whatsapp#remove-disconnect-a-sender).

**The webhook picker names every event in plain words.** See [The Developers page](/console/developers#add-an-endpoint).

## 2026-08-28 — Live support shifts, plan limits, and editing a source

**Hand each waiting customer to one person at a time.** Live support can offer a customer to one named responder, with a countdown, before moving on. The queue can ring until someone answers, you can paste an image into a reply, and a supervisor's tracker shows who is available, each person's shifts day by day, and how quickly customers were looked after. See [Hand each customer to one person at a time](/console/human-handoff#hand-each-customer-to-one-person-at-a-time) and [The tracker](/console/human-handoff#the-tracker).

**Plan limits are enforced, with warning first.** A plan's conversation allowance is counted, you are warned before it runs out, and a campaign send counts as one conversation, paid from the plan's allowance before your credits. Billing shows a used-up allowance as used up, and says so plainly when a plan includes none of a meter. See [Plans & limits](/operate/limits) and [Usage this cycle](/console/billing#usage-this-cycle).

**Phone numbers are charged when you request them.** The first month comes from your credits when you send the request, and is refunded if the number cannot be set up. See [What a number costs](/channels/phone-numbers#what-a-number-costs).

**Edit a knowledge source in place.** Change a source's settings without deleting and re-adding it. See [Edit a source](/build/knowledge#edit-a-source).

**One person, one lead.** Repeat submissions of the web chat lead form from the same person are linked to one contact. See [Duplicate submissions](/channels/web-chat-leads#duplicate-submissions).

**Fixes.** The web chat widget keeps scrolling and keeps its pointer on sites with smooth scrolling or a custom cursor, and Analytics counts voice calls and minutes correctly per touchpoint. See [Analytics](/console/analytics).

## 2026-08-20 — WhatsApp voice conversations

**Voice notes are understood and answered in kind.** A customer can send a WhatsApp voice note and the agent transcribes it before running the same knowledge, tool, booking, ticket, and memory path as typed text. It replies with a playable WhatsApp voice note plus the normal written answer, so links and buttons remain usable. Audio files are understood but answered in text; reactions carry the message they refer to instead of being treated as unsupported media. See [Set up WhatsApp](/channels/whatsapp#what-the-agent-can-read).

## 2026-08-17 — Customer memory

**Returning customers do not have to start from zero.** Agents can recall a compact, contact-level memory across voice, WhatsApp, and web chat. The Contacts panel separates staff notes from facts picked up after conversations, shows which temporary facts fade, and lets an admin disable recall, delete one item, or forget everything while retaining the conversation history. Memory remains private to the authorised conversation and console surfaces. See [Contacts and customer memory](/console/contact-memory).

## 2026-08-16 — Campaign reports and image templates

**Campaign failures now answer “why?”.** Reports group failures by the actual reason and scope, show the fix and whether retrying can help, preserve provider codes on each recipient, and add delivery timelines and voice outcome/talk-time reporting. Account-wide WhatsApp sending blocks also appear on the channel and prevent a launch that cannot work. See [Campaigns](/campaigns/overview#following-a-running-campaign) and [Campaign troubleshooting](/campaigns/troubleshooting#provider-errors).

**WhatsApp templates can use image headers.** The composer uploads and crops the review image, the preview uses the confirmed crop, and later sends attach the saved image automatically. A campaign with a missing required image is blocked before launch. See [Image headers](/channels/whatsapp-templates#image-headers).

## 2026-08-15 — Appointments, channel personas, and call follow-ups

**Appointments and booking calendars.** Teams can define opening hours, capacity, notice, buffers, closed dates, reminders, and calendar sync; agents can check live availability and safely book across voice, WhatsApp, and web chat. Moving and cancelling are separately controlled. See [Appointments and calendars](/console/appointments).

**Per-channel agent personas.** Phone, WhatsApp, and web chat can override the default purpose or instructions without needing duplicate agents. See [Per-channel persona](/build/agents#per-channel-persona).

**Call records tell the full story.** Talk time begins at answer, campaign and ticket origins stay attached, ticket calls are metered, customers can ask the voice agent for a call-back, and call campaigns can schedule one extra attempt after no answer. See [Calls and call-backs](/console/calls).

**Gradual campaign delivery is the default.** Campaigns ramp toward an upper per-minute limit, with an explicit full-speed option for urgent sends. See [Pace](/campaigns/scheduling#pace).

## 2026-08-12 — Campaigns and the app platform

**Campaigns on the API.** Nine endpoints for reaching a list of people once, and the same guardrails the console is held to. Create produces a **draft** — nothing is sent — then `evaluate` reports the exact recipient count and every exclusion, and `launch` starts it.

| Method | Path |
|---|---|
| `POST` | `/api/v1/campaigns` |
| `GET` | `/api/v1/campaigns` |
| `GET` | `/api/v1/campaigns/{campaign_id}` |
| `POST` | `/api/v1/campaigns/{campaign_id}/evaluate` |
| `POST` | `/api/v1/campaigns/{campaign_id}/launch` |
| `POST` | `/api/v1/campaigns/{campaign_id}/pause` |
| `POST` | `/api/v1/campaigns/{campaign_id}/resume` |
| `POST` | `/api/v1/campaigns/{campaign_id}/cancel` |
| `GET` | `/api/v1/campaigns/{campaign_id}/recipients` |

See [Campaigns API](/api/campaigns) and [Sending rules](/campaigns/sending-rules).

**Two new scopes, and read is separate from write.** `campaigns:read` and `campaigns:write`. Unlike tickets, these are split: a write here reaches thousands of people at once, so a reporting integration should not hold a credential that can start a broadcast. `campaigns:read` is granted by nothing automatically; new keys stay read-only on conversations and agents as before. See [Scopes](/api/scopes).

**A dry-run that tells you whether a launch would be refused.** `POST /campaigns/{id}/evaluate` runs every guardrail and returns the findings — each with a machine-readable `code`, a `severity`, a `fix`, and a `docs` URL — without sending anything. Refusals from `launch` carry the same `details.reason` and `details.docs` pair, so a 412 in your logs points at the page that explains it.

**Resume never duplicates.** Every recipient is an individual record claimed transactionally before it is sent, so nobody already messaged can be messaged again — by a resume, a retry, or two of your servers calling at once.

**Apps: Duesly.** An installable app inside Campaigns that collects recurring payments over WhatsApp. Four endpoints for integrating an existing billing system: add a customer to a recurring plan, list them, read what is owed, and record a payment collected outside the gateway.

| Method | Path |
|---|---|
| `POST` | `/api/v1/apps/duesly/subscribers` |
| `GET` | `/api/v1/apps/duesly/subscribers` |
| `GET` | `/api/v1/apps/duesly/dues` |
| `POST` | `/api/v1/apps/duesly/dues/{due_id}/paid` |

Scoped under `campaigns:*` — an app is part of Campaigns, not a product of its own. See [Duesly API](/api/apps-duesly) and [the Duesly guide](/apps/duesly).

**Five new webhook events.** `campaign.launched`, `campaign.completed`, `payment.due_created`, `payment.paid`, and `payment.declined`, bringing the catalogue to fourteen. `campaign.completed` carries counters rebuilt from the recipient records, so they are exact rather than a running projection. There is deliberately no per-recipient event — a campaign to forty thousand people would mean forty thousand deliveries to your endpoint. See [Event reference](/webhooks/events).

**Idempotency on the two creates.** `POST /campaigns` and `POST /apps/duesly/subscribers` honour `Idempotency-Key`. `launch` does not need one — `expected_version` is a stronger guard — and `mark paid` is idempotent by state: a payment that is already paid returns `409` rather than overwriting a settled amount.

**Email campaigns are not available.** Requesting `channel: "email"` returns `412` with `email_not_available` rather than accepting a campaign that would never send.

## 2026-08-01 — Public API and webhooks

The public developer platform shipped. Everything below became available on `/api/v1` on this date.

**A REST API for your own systems.** Thirteen endpoints covering the operations your team already performed in the console: send a WhatsApp message, place and end an AI call, read conversations and transcripts, create and read tickets, upsert contacts, and discover which agents and channels a workspace has.

| Method | Path |
|---|---|
| `GET` | `/api/v1/ping` |
| `GET` | `/api/v1/channels` |
| `POST` | `/api/v1/messages` |
| `POST` | `/api/v1/calls` |
| `GET` | `/api/v1/calls/{call_id}` |
| `POST` | `/api/v1/calls/{call_id}/hangup` |
| `GET` | `/api/v1/conversations` |
| `GET` | `/api/v1/conversations/{conversation_id}` |
| `GET` | `/api/v1/conversations/{conversation_id}/messages` |
| `GET` | `/api/v1/agents` |
| `POST` | `/api/v1/contacts` |
| `POST` | `/api/v1/tickets` |
| `GET` | `/api/v1/tickets/{ticket_id}` |

See [API overview](/api/overview).

**API keys with scopes.** Keys took the form `amk_live_…` or `amk_test_…`, authenticated with either `Authorization: Bearer` or `X-Api-Key`, and were stored as a SHA-256 hash with the secret revealed exactly once. Six scopes — `messages:send`, `calls:write`, `conversations:read`, `contacts:write`, `tickets:write`, `agents:read` — partitioned what a key could do, and new keys were created read-only. See [Authentication](/api/authentication) and [Scopes](/api/scopes).

**Rolling with a 24-hour grace window.** Rolling a key minted a replacement with the same name, scopes, and rate limit while the previous key kept authenticating for 24 hours, so a secret could be rotated without a deploy window. Revoking stayed immediate and permanent.

**Signed webhooks.** Nine event types — `message.received`, `message.status`, `conversation.started`, `conversation.ended`, `call.started`, `call.ended`, `ticket.created`, `ticket.updated`, and `lead.created` — pushed activity to an endpoint you own, signed with a timestamped HMAC over the raw body. Delivery was at-least-once with a four-attempt retry ladder, and an endpoint that failed fifteen consecutive events was disabled with the reason recorded. See [Getting events](/webhooks/overview).

**Outbound AI calling.** `POST /api/v1/calls` had an agent place a call and hold the conversation, returning as soon as the destination was ringing. The caller-ID number selected which agent spoke, a `purpose` string shaped the opening line, and guards refused a self-dial, a number the workspace did not own, or a number with no agent deployed to it. A ceiling of ten concurrent calls per workspace applied. See [Outbound calls](/channels/outbound-calls).

**Idempotency on every request that spends money.** `POST /messages`, `POST /calls`, and `POST /tickets` honoured an `Idempotency-Key` header for 24 hours. A retry replayed the original response; the same key with a different body was refused rather than silently sending twice. See [Idempotency](/api/idempotency).

**Rate limiting.** 120 requests per key per minute, counted in a fixed one-minute window, with `X-RateLimit-Limit` and `X-RateLimit-Remaining` on successful responses. See [Rate limits](/api/rate-limits).

**A published OpenAPI document.** `GET /api/v1/openapi.json` was served without authentication and covered the public surface only.

**A per-workspace request log.** Every `/api/v1` call made with a valid key was recorded against the workspace that made it and kept for seven days. **Developers → Logs** shows the newest 50: time, method and path, key name, status with its error code, and duration.

![The Request log on the Developers page, listing recent API requests with time, method and path, key name, status with error codes, and duration](https://docs.amomic.in/screens/developers/logs.light.webp)

*The request log. Failed calls are listed alongside successful ones, which is what makes it useful.*

## How this changelog is maintained

**Entries are added when something changes for integrators.** A new endpoint, a new event type, a new scope, a change in behaviour you could observe from your own code — those get a dated entry here.

**Backwards-compatible additions may ship without an entry.** A new field on a response, a new `details.reason` on an existing error, a new optional request parameter, a new value in an enum-like field. These are covered by the compatibility rules in [API versioning](/operate/versioning), and client code written to those rules absorbs them without a deploy. Not every one of them appears here.

**Breaking changes would arrive as a new API version rather than a silent change.** Removing or renaming a field, changing a type, changing the error code for an existing condition, tightening validation — none of those happen inside `/api/v1`. If one ever became necessary, it would be published as a new versioned namespace alongside this one.

This page records what has shipped. It is not a roadmap.
