Added
conversationId in message responses. All messages endpoints now include conversationId in the response body.Group messaging support. GET /v1/messages now supports retrieving group conversation messages via the participants array.Added
Mark a conversation as done.POST /v1/conversations/{conversationId}/mark-as-done removes a conversation from the inbox without sending a message and returns the updated conversation.Mark a conversation as open. POST /v1/conversations/{conversationId}/mark-as-open moves a conversation back to the inbox without sending a message and returns the updated conversation.Added
Group messages.POST /v1/messages now accepts up to 10 phone numbers in the to array, sending a single group message to all recipients at once. Sending to a single recipient is unchanged.Added
Mark a conversation as read.POST /v1/conversations/{conversationId}/mark-as-read clears a conversation’s unread indicator without sending a message and returns the updated conversation.Added
Tasks API. A new set of endpoints for managing tasks is now available.| Method | Endpoint | Description |
|---|---|---|
GET | /v1/tasks | List tasks with cursor-based pagination. |
POST | /v1/tasks | Create a task linked to a phone number, conversation, or activity. |
GET | /v1/tasks/{taskId} | Get a task by ID. |
PUT | /v1/tasks/{taskId} | Update a task’s title and description. |
DELETE | /v1/tasks/{taskId} | Delete a task by ID. |
POST | /v1/tasks/{taskId}/complete | Mark a task as completed. |
POST | /v1/tasks/{taskId}/reopen | Reopen a completed task. |
POST | /v1/tasks/{taskId}/assign | Assign a user to a task. |
POST | /v1/tasks/{taskId}/unassign | Remove a user from a task’s assignees. |
POST | /v1/tasks/{taskId}/change-due-date | Set a task’s due date. |
POST | /v1/tasks/{taskId}/remove-due-date | Clear a task’s due date. |
POST | /v1/tasks/{taskId}/link-conversation | Link a task to a conversation. |
POST | /v1/tasks/{taskId}/unlink-conversation | Unlink a conversation from a task. |
Added
Call lifecycle events. Five call lifecycle events are now supported by the beta webhook API, completing event parity with the legacy webhook system:| Event type | When it fires |
|---|---|
call.ringing | A call started ringing (incoming or outgoing). |
call.answered | A call connected. Also fires when an outgoing call reaches voicemail. |
call.forwarded | An incoming call was forwarded. Includes forwardedFrom and forwardedTo phone numbers. |
call.missed | An incoming call ended without being answered. |
call.voicemail.completed | A voicemail finished processing. Correlate with the source call via resource.callId. |
call.answered, call.forwarded, call.missed, and call.voicemail.completed are new event types with no equivalent in the legacy webhook system.The beta webhook API now covers the full event surface of the legacy system, plus call.answered, call.forwarded, call.missed, and call.voicemail.completed — four event types with no equivalent in legacy. See the beta webhook overview and event payload reference for details.Added
Beta webhook API (open beta). A new webhook API is available in open beta. See the overview and quickstart to get started.Unified create endpoint.POST /webhooks replaces the four legacy create endpoints (/v1/webhooks/messages, /v1/webhooks/calls, /v1/webhooks/call-summaries, /v1/webhooks/call-transcripts). Message, call, and contact event types can be combined in a single subscription. Up to 50 webhooks per workspace.Supported event types at launch.| Event type | When it fires |
|---|---|
message.received | An inbound message was received. |
message.delivered | An outbound message was delivered. |
call.completed | A call ended. Includes final status and duration. |
call.recording.completed | A call recording finished processing. |
call.summary.completed | An AI call summary finished generating. |
call.transcript.completed | A call transcript finished processing. |
contact.updated | A contact was created or updated. |
contact.deleted | A contact was deleted. |
call.ringing, call.answered, call.forwarded, call.missed, call.voicemail.completed) were not yet available at launch — they were added on May 26, 2026.Payload envelope. All events share a common data.resource / data.context / data.links structure. data.resource contains the primary business object; data.context contains routing metadata (phone number, conversation, participants, contact lookup). See Webhook event payloads.Payload versioning. Each subscription pins a payload version at creation via the x-quo-api-version header. Existing subscriptions are unaffected by future version changes. See Versioning policy for the current version.Signing. Deliveries use Standard-Webhooks-compatible headers (webhook-id, webhook-timestamp, webhook-signature) and a whsec_... base64 secret, compatible with the Svix SDK. This scheme is not interchangeable with the legacy OpenPhone-Signature header — update signature verification before routing beta traffic to an existing endpoint. See Validate webhook signatures.Delivery inspection. Send a signed test delivery (POST /webhooks/:id/events/test), browse delivery history and per-attempt responses (GET /webhooks/:id/events, GET /webhooks/:id/events/:eventId), and trigger manual retries (POST /webhooks/:id/events/:eventId/retry). See Webhook API reference.Signing secret rotation. POST /webhooks/:id/rotate issues a new whsec_... key for an existing subscription without changing its event subscriptions or apiVersion.For a side-by-side comparison with the legacy system and a no-downtime migration walkthrough, see Migrating from legacy.Minor Changes
- Adds a property
externalIdto the contact model. AddsexternalIdandsourceas optional parameters to the Create Contact (POST /contacts) request. - Adds
externalIdandsourceas optional parameters to the Update Contact (PATCH /contacts/:id) request. - Added a route to list contacts (
GET /contacts).
Patch Changes
- Fixed an issue where creating or updating a contact with an invalid custom field would result in 500 error. Sending an invalid custom field will now result in a 400 “Invalid Custom Field Item” error.
Patch Changes
- Fixed an issue where paginated endpoints would return a string token for the next page at the end of paginated results. Now, they will correctly return the next page token as
null. - Added a callout that the
totalItemsresult field for the paginated endpoints is not functioning as expected and is not returning the true total items count.
Patch Changes
- Fixes an issue where phone numbers in various routes were expected to be in E164 format, but the format was not being validated correctly.
Patch Changes
- Fixed an issue with list calls (
GET /calls) where sending an empty participants param resulted in a 500 response. Sending an empty participants param will now result in a descriptive 400 response. - Fixes an issue where attempting to send a message to an international number would result in a 500 response if international messaging is not enabled in the workspace. With this fix, the 500 error response changed to a 403 with a descriptive message
- Fixes a bug where the GET call recordings endpoint sometimes returned an empty array.
- Fixes an issue that was preventing some call records from returning successfully from
GET /calls - Fixes an issue where getting a contact by id would result in a 500 instead of a 404 when contact is not found. Now this will respond in a 404 with a descriptive message.
- Fixes an issue where sending a message that contained only whitespace (
' ','\n', etc.) resulted in a 500 error response. Now, this will respond with 400 and a validation error message instead.
Patch Changes
- Fixes an issue with List Calls (
GET /calls) where the user ID applied by default when the user ID parameter was not sent was being set to the workspace owner instead of the phone number owner.
1.0.0
Major Changes
OpenPhone’s Public API v1 release 🚀Changes from the beta version include:- The
sincequery parameter on “list calls” and “list messages” has been deprecated. It used to incorrectly behave as acreatedBefore. Please usecreatedAfterinstead, orcreatedBeforeto maintain current functionality. - The
phoneNumberIdfield for “send text message” has been deprecated. Please usefrominstead. /v0endpoints have been deprecated. Please use/v1instead.