Skip to content

Overview

Webhooks deliver a POST request to an endpoint you control every time something happens in your workspace — an appointment is booked, a patient record changes, a vitals scan completes.

Every delivery carries the same JSON envelope. Only data differs between events, and each event documents its own shape under Payloads.

  1. Go to Settings > Developers > Webhooks. The Developers section is only visible to users with the Developer role.

  2. Click Webhook (or Create Webhook if you have none yet) and enter your Endpoint URL. It must be a publicly reachable https:// URL — http:// endpoints are rejected, because payloads carry patient data.

  3. On the edit page that opens next, check the Events the webhook should receive. New webhooks are subscribed to the four appointment.* events, and a webhook with nothing selected receives those same four events.

  4. Switch Enabled on and click Save Changes. New webhooks are created disabled, so nothing is delivered until you turn it on.

A workspace can have several webhooks. Each one has its own endpoint, its own event selection and its own enabled state, so you can send appointment events to one service and scan events to another.

{
"id": "ckq7v1w1k0008zqxk7g3l5n2q",
"name": "vitalsScan.complete",
"createdAt": "2026-02-04T09:01:12.000Z",
"business": {
"id": "ckq7v1w1k0001zqxk3f8a9d4t"
},
"data": {
"id": "ckq7v1w1k0006zqxk4r8p2s5w",
"status": "SUCCEEDED"
}
}
Field Type Description
id string Unique identifier for this event delivery.
name string The name of the event, in resource.action format.
createdAt string ISO 8601 timestamp of when the event was recorded by Upvio.
business.id string The business the event belongs to. Always the business that owns the webhook.
data object The event payload. See Payloads.

Every data payload also repeats the business as data.businessId, so it can be read on its own without the envelope.

Deliveries are sent as POST requests with a JSON body and these headers:

Header Value
Content-Type application/json
Accept application/json
User-Agent Upvio Webhooks/1.0

Return any status code below 400 to acknowledge a delivery. Anything from 400 up, along with a connection error or a timeout, is recorded as a failed delivery.

Acknowledge first and do the work afterwards. If your handler calls out to other services before responding, a slow third party turns into a failed Upvio delivery.

// Next.js route handler
export const POST = async (request: Request) => {
const event = await request.json()
// Acknowledge straight away, then process out of band.
await queue.push(event)
return new Response(null, { status: 200 })
}

Every attempt is logged. Open the actions menu next to a webhook in Settings > Developers > Webhooks and select View delivery logs to see its delivery history: the request payload, the response status and body, and how long your endpoint took to reply. This is the fastest way to tell whether a missing event was never sent or was sent and rejected.

Deliveries are not signed, so your endpoint cannot verify them from the request alone. Until signing is available:

  • Keep the URL secret. Include a long, random path segment or query parameter in the endpoint (https://example.com/webhooks/upvio/9f2c…) and reject any request that does not carry it.
  • Do not trust the payload as proof. If a delivery triggers something sensitive, re-read the record from the API before acting on it.
  • Expect duplicates. Deliveries carry the event id; store it and ignore an id you have already handled.
  • Expect unknown events. New event types are added over time. Ignore any name you do not recognize instead of failing the request.