Skip to content

mv.webhookEndpoints

URLs that receive signed events. These methods are on mv.webhookEndpoints, where mv is your client (see the Node.js SDK). Each one returns the response object and throws when the API answers with an error.

Create a webhook endpoint. Starts sending the selected events to url, signed with a new secret (whsec_…, Standard Webhooks). The response carries the secret: this is the only time it is shown (rotate it to get a new one). Live endpoints need https; private and local addresses are refused.

mv.webhookEndpoints.create(body: WebhookEndpointsCreateData["body"], options?: RequestOptions): Promise<WebhookEndpointsCreateResponse>

POST /webhook_endpoints · API reference

Name Type Required Description
body.url string yes An https URL (http is accepted in test mode). Private and local addresses are refused.
body.enabled_events string[] yes An event type (call.ended), a group (call.*) or "*" for every event. At least one.
body.api_version "2026-11-01" no Render payloads in this API version (default: the current one).
body.description string no
body.max_in_flight integer no Deliveries in flight at once (1–100, default 10).
body.metadata MetadataInput no Up to 50 key/value pairs (keys up to 40 characters, values up to 500) you attach to an object. Returned as sent.
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options.headers["Idempotency-Key"] string no A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

WebhookEndpoint:

Field Type Description
id string A webhook endpoint ID (prefix we_).
object "webhook_endpoint" Always webhook_endpoint.
url string Where events are POSTed.
description string —
enabled_events string[] The event types sent to this endpoint; ["*"] means every event.
status "enabled" | "disabled" | "auto_disabled" auto_disabled: every delivery failed for 72 hours, so sending stopped (and your admins were told). Set status: enabled to resume.
disabled_reason string | null —
disabled_at string | null —
api_version string The API version event payloads are rendered in. legacy: an endpoint moved from the old webhook settings, which keeps getting the previous body ({id, event, createdAt, data}).
campaign_id string | null cmp_… ID.
legacy_headers boolean Also sends the previous X-Webhook-* headers (moved endpoints, for one deprecation cycle).
max_in_flight integer Deliveries in flight to this endpoint at once; more wait their turn.
metadata Metadata Up to 50 key/value pairs (keys up to 40 characters, values up to 500) you attach to an object. Returned as sent.
previous_secret_expires_at string | null While a rotated secret still signs (alongside the new one): until when.
livemode boolean true in live mode, false in test mode.
created string An ISO-8601 timestamp in UTC.
updated string An ISO-8601 timestamp in UTC.
secret string The signing secret (whsec_…). Returned only when the endpoint is created and when its secret is rotated: store it then.
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const webhookEndpoint = await mv.webhookEndpoints.create({
description: "CRM sync",
enabled_events: [
"call.ended",
"call.analyzed",
],
url: "https://hooks.example.com/webhooks",
});
console.log(webhookEndpoint);

Delete a webhook endpoint. Stops all deliveries to the endpoint at once; its queued deliveries are dropped.

mv.webhookEndpoints.delete(id: WebhookEndpointsDeleteData["path"]["id"], options?: RequestOptions): Promise<WebhookEndpointsDeleteResponse>

DELETE /webhook_endpoints/{id} · API reference

Name Type Required Description
id string yes A webhook endpoint ID (we_…).
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options.headers["Idempotency-Key"] string no A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

DeletedWebhookEndpoint:

Field Type Description
id string A webhook endpoint ID (prefix we_).
object "webhook_endpoint" Always webhook_endpoint.
deleted true —
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const deletedWebhookEndpoint = await mv.webhookEndpoints.delete("we_Fr16fYQoriAw3w17jl7hn3");
console.log(deletedWebhookEndpoint);

List webhook endpoints. Your webhook endpoints in this mode, newest first. Signing secrets are never listed.

mv.webhookEndpoints.list(query?: NonNullable<WebhookEndpointsListData["query"]>, options?: RequestOptions): PagedList<WebhookEndpointsListResponse["data"][number], NonNullable<WebhookEndpointsListData["query"]>>

GET /webhook_endpoints · API reference

Name Type Required Description
query.limit integer no How many objects to return, 1–100 (default 20).
query.starting_after string no A cursor (next_cursor) or object ID: return the objects after it (older).
query.ending_before string no A cursor or object ID: return the objects before it (newer).
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

A PagedList: await it for the first page, for await it for every item.

import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
for await (const webhookEndpoint of mv.webhookEndpoints.list()) {
console.log(webhookEndpoint);
}

Replay events to an endpoint. Queues a new delivery to this endpoint for every stored event since since that it subscribes to (optionally only types, or only the events whose deliveries to it never succeeded). At most 10 000 events; narrow the window otherwise. Events keep their ids, so receivers can deduplicate.

mv.webhookEndpoints.replay(id: WebhookEndpointsReplayData["path"]["id"], body: WebhookEndpointsReplayData["body"], options?: RequestOptions): Promise<WebhookEndpointsReplayResponse>

POST /webhook_endpoints/{id}/replay · API reference

Name Type Required Description
id string yes A webhook endpoint ID (we_…).
body.since string yes Replay events created at or after this time (events are kept 30 days).
body.only_failed boolean no Only events whose deliveries to this endpoint never succeeded.
body.types string[] no Only these types (within the endpoint’s own enabled_events).
body.until string no …and up to this time (default: now).
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options.headers["Idempotency-Key"] string no A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

WebhookReplay:

Field Type Description
object "webhook_replay" Always webhook_replay.
endpoint_id string A webhook endpoint ID (prefix we_).
since string An ISO-8601 timestamp in UTC.
until string An ISO-8601 timestamp in UTC.
types string[] —
only_failed boolean —
events_queued integer New deliveries queued (one per event; at most 10000). They keep their event ids, so receivers can deduplicate.
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const webhookReplay = await mv.webhookEndpoints.replay("we_Fr16fYQoriAw3w17jl7hn3", {
only_failed: true,
since: "2026-11-03T00:00:00Z",
});
console.log(webhookReplay);

Retrieve a webhook endpoint.

mv.webhookEndpoints.retrieve(id: WebhookEndpointsRetrieveData["path"]["id"], options?: RequestOptions): Promise<WebhookEndpointsRetrieveResponse>

GET /webhook_endpoints/{id} · API reference

Name Type Required Description
id string yes A webhook endpoint ID (we_…).
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

WebhookEndpoint:

Field Type Description
id string A webhook endpoint ID (prefix we_).
object "webhook_endpoint" Always webhook_endpoint.
url string Where events are POSTed.
description string —
enabled_events string[] The event types sent to this endpoint; ["*"] means every event.
status "enabled" | "disabled" | "auto_disabled" auto_disabled: every delivery failed for 72 hours, so sending stopped (and your admins were told). Set status: enabled to resume.
disabled_reason string | null —
disabled_at string | null —
api_version string The API version event payloads are rendered in. legacy: an endpoint moved from the old webhook settings, which keeps getting the previous body ({id, event, createdAt, data}).
campaign_id string | null cmp_… ID.
legacy_headers boolean Also sends the previous X-Webhook-* headers (moved endpoints, for one deprecation cycle).
max_in_flight integer Deliveries in flight to this endpoint at once; more wait their turn.
metadata Metadata Up to 50 key/value pairs (keys up to 40 characters, values up to 500) you attach to an object. Returned as sent.
previous_secret_expires_at string | null While a rotated secret still signs (alongside the new one): until when.
livemode boolean true in live mode, false in test mode.
created string An ISO-8601 timestamp in UTC.
updated string An ISO-8601 timestamp in UTC.
secret string The signing secret (whsec_…). Returned only when the endpoint is created and when its secret is rotated: store it then.
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const webhookEndpoint = await mv.webhookEndpoints.retrieve("we_Fr16fYQoriAw3w17jl7hn3");
console.log(webhookEndpoint);

Rotate a webhook endpoint’s secret. Creates a new signing secret and returns it (this once). The previous secret keeps signing alongside it for expire_previous_in_hours (default 24), so webhook-signature carries both signatures until your receivers switch.

mv.webhookEndpoints.rotateSecret(id: WebhookEndpointsRotateSecretData["path"]["id"], body?: WebhookEndpointsRotateSecretData["body"], options?: RequestOptions): Promise<WebhookEndpointsRotateSecretResponse>

POST /webhook_endpoints/{id}/rotate_secret · API reference

Name Type Required Description
id string yes A webhook endpoint ID (we_…).
body.expire_previous_in_hours number no How long the previous secret keeps signing alongside the new one (0–72 hours, default 24; 0 stops it at once).
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options.headers["Idempotency-Key"] string no A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

WebhookEndpoint:

Field Type Description
id string A webhook endpoint ID (prefix we_).
object "webhook_endpoint" Always webhook_endpoint.
url string Where events are POSTed.
description string —
enabled_events string[] The event types sent to this endpoint; ["*"] means every event.
status "enabled" | "disabled" | "auto_disabled" auto_disabled: every delivery failed for 72 hours, so sending stopped (and your admins were told). Set status: enabled to resume.
disabled_reason string | null —
disabled_at string | null —
api_version string The API version event payloads are rendered in. legacy: an endpoint moved from the old webhook settings, which keeps getting the previous body ({id, event, createdAt, data}).
campaign_id string | null cmp_… ID.
legacy_headers boolean Also sends the previous X-Webhook-* headers (moved endpoints, for one deprecation cycle).
max_in_flight integer Deliveries in flight to this endpoint at once; more wait their turn.
metadata Metadata Up to 50 key/value pairs (keys up to 40 characters, values up to 500) you attach to an object. Returned as sent.
previous_secret_expires_at string | null While a rotated secret still signs (alongside the new one): until when.
livemode boolean true in live mode, false in test mode.
created string An ISO-8601 timestamp in UTC.
updated string An ISO-8601 timestamp in UTC.
secret string The signing secret (whsec_…). Returned only when the endpoint is created and when its secret is rotated: store it then.
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const webhookEndpoint = await mv.webhookEndpoints.rotateSecret("we_Fr16fYQoriAw3w17jl7hn3", {
expire_previous_in_hours: 24,
});
console.log(webhookEndpoint);

Send a test event. Sends one sample event of type to the endpoint now, signed like a real delivery, and reports how it answered. Samples are not stored and never retried.

mv.webhookEndpoints.test(id: WebhookEndpointsTestData["path"]["id"], body?: WebhookEndpointsTestData["body"], options?: RequestOptions): Promise<WebhookEndpointsTestResponse>

POST /webhook_endpoints/{id}/test · API reference

Name Type Required Description
id string yes A webhook endpoint ID (we_…).
body.type "call.created" | "call.started" | "call.ringing" | "call.answered" | "call.transferred" | "call.ended" | "call.analyzed" | "call.cost_finalized" | … no The event type to send a sample of (default test).
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options.headers["Idempotency-Key"] string no A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

WebhookEndpointTest:

Field Type Description
object "webhook_endpoint_test" Always webhook_endpoint_test.
endpoint_id string A webhook endpoint ID (prefix we_).
event_id string The sample’s id (the webhook-id header). Samples are not stored.
type "call.created" | "call.started" | "call.ringing" | "call.answered" | "call.transferred" | "call.ended" | "call.analyzed" | "call.cost_finalized" | … —
delivered boolean The endpoint answered 2xx.
response_status integer | null The HTTP status it answered (null: no answer, e.g. a timeout or a refused address).
duration_ms integer | null —
error string | null —
response_excerpt string | null The first 2 KB of its answer.
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const webhookEndpointTest = await mv.webhookEndpoints.test("we_Fr16fYQoriAw3w17jl7hn3", {
type: "call.ended",
});
console.log(webhookEndpointTest);

Update a webhook endpoint. Change the URL, the events, the description, the API version or the status. status: enabled resumes an endpoint that was disabled (or auto-disabled after 72 hours of failures).

mv.webhookEndpoints.update(id: WebhookEndpointsUpdateData["path"]["id"], body?: WebhookEndpointsUpdateData["body"], options?: RequestOptions): Promise<WebhookEndpointsUpdateResponse>

PATCH /webhook_endpoints/{id} · API reference

Name Type Required Description
id string yes A webhook endpoint ID (we_…).
body.api_version "2026-11-01" no Render payloads in this API version (default: the current one).
body.description string no
body.enabled_events string[] no
body.max_in_flight integer no Deliveries in flight at once (1–100, default 10).
body.metadata MetadataInput no Up to 50 key/value pairs (keys up to 40 characters, values up to 500) you attach to an object. Returned as sent.
body.status "enabled" | "disabled" no disabled stops deliveries; enabled resumes them (also after an auto-disable).
body.url string no An https URL (http is accepted in test mode). Private and local addresses are refused.
options.headers["MoreVoice-Version"] string no The API version to use for this request. Defaults to the version the API key is pinned to.
options RequestOptions no idempotencyKey, extra headers and an abort signal: see retries and idempotency.

WebhookEndpoint:

Field Type Description
id string A webhook endpoint ID (prefix we_).
object "webhook_endpoint" Always webhook_endpoint.
url string Where events are POSTed.
description string —
enabled_events string[] The event types sent to this endpoint; ["*"] means every event.
status "enabled" | "disabled" | "auto_disabled" auto_disabled: every delivery failed for 72 hours, so sending stopped (and your admins were told). Set status: enabled to resume.
disabled_reason string | null —
disabled_at string | null —
api_version string The API version event payloads are rendered in. legacy: an endpoint moved from the old webhook settings, which keeps getting the previous body ({id, event, createdAt, data}).
campaign_id string | null cmp_… ID.
legacy_headers boolean Also sends the previous X-Webhook-* headers (moved endpoints, for one deprecation cycle).
max_in_flight integer Deliveries in flight to this endpoint at once; more wait their turn.
metadata Metadata Up to 50 key/value pairs (keys up to 40 characters, values up to 500) you attach to an object. Returned as sent.
previous_secret_expires_at string | null While a rotated secret still signs (alongside the new one): until when.
livemode boolean true in live mode, false in test mode.
created string An ISO-8601 timestamp in UTC.
updated string An ISO-8601 timestamp in UTC.
secret string The signing secret (whsec_…). Returned only when the endpoint is created and when its secret is rotated: store it then.
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({
client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),
});
const webhookEndpoint = await mv.webhookEndpoints.update("we_Fr16fYQoriAw3w17jl7hn3", {
enabled_events: [
"call.*",
],
status: "enabled",
});
console.log(webhookEndpoint);