API Reference
Complete reference for the Orita Provider Resolution API. All endpoints are prefixed with https://orita.online. Requests and responses use JSON with UTF-8 encoding.
Authentication
All API requests must include an Authorization header with a Bearer token.
Authorization: Bearer orita_live_...Platform API keys begin with orita_live_ and are created in your dashboard settings.
Test keys begin with orita_test_ and have identical capabilities, but do not send real email notifications or trigger live webhooks.
Keep your API keys secret. Never expose them in client-side code or public repositories. Rotate keys immediately if they are compromised.
Resolution API
/api/v2/resolutionsSearch the provider network, apply eligibility rules, verify real-time availability, and return ranked explained options. Hard constraints (license region, insurance plan, language, modality, specialty, age group, panel capacity) exclude providers. Preferences affect ranking only. Returns options valid for 5 minutes.
TTL: Resolution options expire after 5 minutes. Hold: 2 minutes default, 10 minutes maximum.
Authentication
Authorization: Bearer orita_...Headers
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer orita_... | required |
| Idempotency-Key | <unique-string> | required |
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| serviceId | string | required | Event type ID to match against. |
| constraints.languageCodes | { anyOf: string[] } | optional | Hard constraint. Provider must speak at least one listed language. |
| constraints.modalityCodes | { anyOf: string[] } | optional | Hard constraint. Accepted modalities: "virtual" | "in_person". |
| constraints.licenseRegionCodes | { anyOf: string[] } | optional | Hard constraint. Provider must have an active non-expired license in every required region. Unknown license data excludes the provider. |
| constraints.insurancePlanCodes | { anyOf: string[] } | optional | Hard constraint. Provider must accept at least one listed insurance plan. Aliases normalized (e.g. "Blue Cross" → "bcbs"). |
| constraints.ageGroupCodes | { anyOf: string[] } | optional | Hard constraint. Accepted age groups: "adult" | "adolescent" | "child" | "senior". |
| constraints.specialtyCodes | { anyOf: string[] } | optional | Hard constraint. Provider must match at least one specialty. |
| constraints.professionCodes | { anyOf: string[] } | optional | Hard constraint. Provider must match at least one profession code. |
| constraints.acceptsNewClients | boolean | optional | Hard constraint. Only include providers actively accepting new clients. |
| constraints.serviceRegionCodes | { anyOf: string[] } | optional | Hard constraint. Provider must serve at least one required region. |
| preferences.dayParts | string[] | optional | Time-of-day parts for ranking (e.g. ["morning", "afternoon"]). |
| preferences.earliestAvailable | boolean | optional | Rank earliest available slots first. |
| dateRange.from | string (YYYY-MM-DD) | required | Start of the search window. |
| dateRange.to | string (YYYY-MM-DD) | required | End of the search window. Max 14-day span. |
Request Body
{
"serviceId": "svc_01...",
"constraints": {
"languageCodes": { "anyOf": ["es", "en"] },
"modalityCodes": { "anyOf": ["virtual"] },
"acceptsNewClients": true,
"specialtyCodes": { "anyOf": ["anxiety", "cbt"] },
"professionCodes": { "anyOf": ["clinical_psychologist"] }
},
"preferences": {
"dayParts": ["afternoon"],
"earliestAvailable": false
},
"dateRange": {
"from": "2026-08-04",
"to": "2026-08-08"
}
}Response 200
{
"resolutionId": "res_9c1f2a3b4d5e6f70",
"status": "resolved",
"requestId": "req_a1b2c3d4e5f6a7b8",
"organizationId": "org_2m9x1k",
"policy": { "id": "policy_default", "version": 1 },
"providerGraphVersion": 12,
"createdAt": "2026-08-01T13:55:00.000Z",
"expiresAt": "2026-08-01T14:00:00.000Z",
"summary": {
"providersScanned": 12,
"eligibleProviders": 4,
"providersWithVerifiedAvailability": 3,
"optionsReturned": 2,
"evaluatedSlots": 47
},
"options": [
{
"optionId": "opt_7b3d9e1a2c4f5061",
"rank": 1,
"provider": {
"id": "prov_ana_garcia",
"externalId": "sample-provider-ana",
"displayName": "Dr. Ana GarcÃa"
},
"service": {
"id": "evt_therapy_50",
"displayName": "Therapy Session",
"durationMinutes": 50
},
"slot": {
"start": "2026-08-05T18:00:00.000Z",
"end": "2026-08-05T18:50:00.000Z",
"timezone": "America/New_York"
},
"availabilityStatus": "verified_available",
"availabilityCheckedAt": "2026-08-01T13:55:00.000Z",
"score": 100,
"matchedConstraints": [
{ "code": "LANGUAGE_MATCH", "field": "languageCodes", "status": "matched", "required": ["es"], "actual": ["es", "en"], "sourceStatus": "verified" },
{ "code": "MODALITY_MATCH", "field": "modalityCodes", "status": "matched", "required": ["virtual"], "actual": ["virtual"], "sourceStatus": "verified" }
],
"rankingFactors": [
{ "code": "EARLIEST_AVAILABLE", "points": 30 },
{ "code": "PREFERRED_LANGUAGE", "points": 20 }
],
"reason": "Earliest available slot; speaks preferred language (es); accepts virtual visits."
}
],
"exclusionSummary": {
"LANGUAGE_MISMATCH": 5,
"NOT_ACCEPTING_NEW_CLIENTS": 2,
"NO_VERIFIED_AVAILABILITY": 1
},
"warnings": []
}Possible Errors
/api/v2/resolutions/:idRetrieve the current state of a resolution, including all ranked options and expiry.
Authentication
Authorization: Bearer orita_...Response 200
{
"resolutionId": "res_9c1f2a3b4d5e6f70",
"status": "resolved",
"requestId": "req_a1b2c3d4e5f6a7b8",
"organizationId": "org_2m9x1k",
"policy": { "id": "policy_default", "version": 1 },
"providerGraphVersion": 12,
"createdAt": "2026-08-01T13:55:00.000Z",
"expiresAt": "2026-08-01T14:00:00.000Z",
"summary": {
"providersScanned": 12,
"eligibleProviders": 4,
"providersWithVerifiedAvailability": 3,
"optionsReturned": 2,
"evaluatedSlots": 47
},
"options": [ /* same option shape as POST /api/v2/resolutions */ ],
"exclusionSummary": { "LANGUAGE_MISMATCH": 5 },
"warnings": []
}Possible Errors
/api/v2/resolutions/:id/options/:optionId/holdLock a specific option from a resolution while the user confirms. Default TTL is 2 minutes (120 s); maximum is 10 minutes (600 s). Only one hold may be active per resolution at a time.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| ttlSeconds | number | optional | Hold duration in seconds. Default 120, max 600. |
Request Body
{
"ttlSeconds": 120
}Response 200
{
"holdId": "hold_01JZBK...",
"status": "active",
"expiresAt": "2026-08-04T14:47:00Z"
}Possible Errors
/api/v2/resolutions/:id/confirmConfirm an option from a resolution and create a booking. A prior hold is optional but recommended to prevent race conditions; when a holdId is supplied it is validated and a released or expired hold is rejected. Returns the final booking record with status 'confirmed'. Resolution confirmation always returns status 'confirmed' immediately. Direct booking via POST /api/v1/bookings starts as 'pending' until the client confirms by email.
Authentication
Authorization: Bearer orita_...Headers
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer orita_... | required |
| Idempotency-Key | <unique-string> | required |
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| optionId | string | required | The option ID from the resolution to confirm. |
| holdId | string | optional | Hold ID returned by the option-hold endpoint. Optional but recommended. When supplied it is validated; a released or expired hold is rejected. |
| customer.name | string | required | Customer full name. |
| customer.email | string | required | Customer email address. |
| customer.lastname | string | optional | Customer last name (optional). |
| metadata | object | optional | Arbitrary key-value data to attach to the booking. |
Request Body
{
"optionId": "opt_7b3d9e1a2c4f5061",
"holdId": "hold_5d7e9f1a3b2c4e60",
"customer": {
"name": "James Park",
"email": "james@example.com",
"timezone": "America/New_York"
},
"metadata": {
"source": "widget"
}
}Response 200
{
"id": "6dc1b87a-55cb-49cb-93e4-777134fbc341",
"organizationId": "org_2m9x1k",
"resolutionId": "res_9c1f2a3b4d5e6f70",
"optionId": "opt_7b3d9e1a2c4f5061",
"status": "confirmed",
"provider": {
"id": "prov_ana_garcia",
"displayName": "Dr. Ana GarcÃa"
},
"service": {
"id": "evt_therapy_50",
"displayName": "Therapy Session",
"durationMinutes": 50
},
"customer": {
"name": "James Park",
"email": "james@example.com",
"timezone": "America/New_York"
},
"slot": {
"start": "2026-08-05T18:00:00.000Z",
"end": "2026-08-05T18:50:00.000Z",
"timezone": "America/New_York"
},
"createdAt": "2026-08-01T13:55:30.000Z",
"updatedAt": "2026-08-01T13:55:30.000Z"
}Possible Errors
/api/v2/resolutions/:id/options/:optionId/holdRelease an active hold before it expires, freeing the slot for other resolutions. Useful when the user cancels the confirmation flow. A released hold cannot be reinstated; create a new hold if needed.
Authentication
Authorization: Bearer orita_...Response 200
{
"holdId": "hold_01JZBK...",
"status": "released",
"releasedAt": "2026-08-04T14:45:30Z"
}Possible Errors
/api/v2/resolutions/:id/candidatesRetrieve a per-provider eligibility record for every provider evaluated during a resolution. Returns matched, excluded, and unknown providers with the exact constraint fields and values that determined their status. Use this endpoint to debug zero results, unexpected exclusions, or unknown-data gaps.
Authentication
Authorization: Bearer orita_...Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | optional | "matched" | "excluded" | "unknown" — filter by eligibility status. |
| limit | integer | optional | Max results (default 50, max 500). |
| cursor | string | optional | Pagination cursor from previous response. |
Response 200
{
"resolutionId": "res_9c1f2a3b4d5e6f70",
"candidates": [
{
"providerId": "pro_01K...",
"displayName": "Dr. Marcus Lee",
"eligibilityStatus": "excluded",
"exclusions": [
{
"code": "INSURANCE_NOT_ACCEPTED",
"field": "insurancePlanCodes",
"required": ["aetna"],
"actual": ["cigna"],
"sourceStatus": "verified"
}
],
"matchedConstraints": [
{ "code": "LICENSE_REGION_MATCH", "field": "licenseRegionCodes" }
]
},
{
"providerId": "prov_ana_garcia",
"displayName": "Dr. Ana GarcÃa",
"eligibilityStatus": "matched",
"exclusions": [],
"matchedConstraints": [
{ "code": "LANGUAGE_MATCH", "field": "languageCodes" },
{ "code": "MODALITY_MATCH", "field": "modalityCodes" },
{ "code": "INSURANCE_MATCH", "field": "insurancePlanCodes" },
{ "code": "LICENSE_REGION_MATCH", "field": "licenseRegionCodes" }
]
}
],
"summary": {
"total": 12,
"matched": 4,
"excluded": 7,
"unknown": 1
},
"hasMore": false
}Possible Errors
Provider Graph
/api/v2/providersCreate a new professional profile in your provider graph. Requires a platform-level API key.
Authentication
Authorization: Bearer orita_... (platform key)Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| externalId | string | required | Your stable identifier for this provider. Must be unique within the organization. |
| displayName | string | required | Full display name. |
| string | optional | Provider email address. | |
| status | string | optional | "active" | "inactive" | "suspended". Defaults to "active". |
| searchable | boolean | optional | Whether this provider appears in resolution. Defaults to true. |
| professionCode | string | optional | e.g. "clinical_psychologist" |
| specialtyCodes | string[] | optional | Specialty codes. Hard constraint in resolution. |
| languageCodes | string[] | optional | ISO 639-1. Hard constraint in resolution. |
| modalityCodes | string[] | optional | "virtual" or "in_person". Hard constraint. |
| serviceRegionCodes | string[] | optional | Regions the provider serves. Hard constraint. |
| insurancePlanCodes | string[] | optional | Accepted plans. Hard constraint. Aliases normalized. |
| ageGroupCodes | string[] | optional | adult | adolescent | child | senior. Hard constraint. |
| licenseRecords | LicenseRecord[] | optional | License records with regionCode, status, expiresAt, verifiedAt. Hard constraint. |
| acceptsNewClients | boolean | optional | Hard constraint in resolution. |
| timezone | string | optional | IANA timezone (e.g. "America/New_York"). Used for display and scheduling rule evaluation. |
| bio | string | optional | Short professional bio. |
Request Body
{
"externalId": "customer-provider-2841",
"displayName": "Dr. Ana GarcÃa",
"email": "ana@example.com",
"status": "active",
"searchable": true,
"professionCode": "clinical_psychologist",
"specialtyCodes": ["anxiety", "cbt"],
"languageCodes": ["es", "en"],
"modalityCodes": ["virtual"],
"serviceRegionCodes": ["US-NJ"],
"insurancePlanCodes": ["aetna", "cigna"],
"ageGroupCodes": ["adult"],
"licenseRecords": [{ "licenseTypeCode": "psychologist", "regionCode": "US-NJ", "status": "active", "expiresAt": "2027-06-30" }],
"acceptsNewClients": true,
"timezone": "America/New_York"
}Response 200
{
"id": "pro_01K...",
"organizationId": "org_01K...",
"externalId": "customer-provider-2841",
"displayName": "Dr. Ana GarcÃa",
"status": "active",
"searchable": true,
"profileVersion": 1
}Possible Errors
/api/v2/providersList providers in your provider graph. Supports filtering by specialty, language, profession, location, and modality.
Authentication
Authorization: Bearer orita_...Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | optional | Filter by status: "active" | "inactive" |
| searchable | boolean | optional | Filter by searchable status. |
| limit | integer | optional | Max results (default 50). |
Response 200
{
"data": [
{
"id": "pro_01K...",
"organizationId": "org_01K...",
"externalId": "customer-provider-2841",
"displayName": "Dr. Ana GarcÃa",
"status": "active",
"searchable": true,
"professionCode": "clinical_psychologist",
"specialtyCodes": ["anxiety", "cbt"],
"languageCodes": ["es", "en"],
"modalityCodes": ["virtual"],
"insurancePlanCodes": ["aetna"],
"licenseRecords": [],
"profileVersion": 1
}
],
"total": 20,
"hasMore": false
}Possible Errors
/api/v2/servicesCreate a service or session type for a provider. Defines the booking unit used during resolution.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| providerId | string | required | The provider this event type belongs to. |
| title | string | required | Display name of the event type. |
| duration | number | required | Duration in minutes. |
| price | number | optional | Price in smallest currency unit. |
| currency | string | optional | ISO 4217 currency code (e.g. 'EUR'). |
| modality | "virtual" | "in-person" | "both" | optional | Session modality override. |
Request Body
{
"providerId": "prov_01...",
"title": "Initial Consultation",
"duration": 50,
"price": 80,
"currency": "EUR",
"modality": "virtual"
}Response 200
{
"id": "svc_01...",
"providerId": "prov_01...",
"title": "Initial Consultation",
"duration": 50,
"price": 80,
"currency": "EUR",
"modality": "virtual",
"slug": "initial-consultation"
}Possible Errors
/api/v2/calendar-connectionsDefine a recurring availability schedule for a provider. The schedule is used by the resolution engine to find bookable slots.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| providerId | string | required | Provider to assign this schedule to. |
| title | string | optional | Human-readable label for this schedule. |
| timezone | string | required | IANA timezone for all times in this schedule. |
| days | object | required | Per-day config: { enabled: boolean, slots: [{ start, end }] } |
Request Body
{
"providerId": "prov_01...",
"title": "Default",
"timezone": "Europe/Madrid",
"days": {
"monday": {
"enabled": true,
"slots": [{ "start": "09:00", "end": "17:00" }]
},
"tuesday": {
"enabled": true,
"slots": [{ "start": "09:00", "end": "17:00" }]
},
"wednesday": { "enabled": false, "slots": [] },
"thursday": {
"enabled": true,
"slots": [{ "start": "10:00", "end": "18:00" }]
},
"friday": {
"enabled": true,
"slots": [{ "start": "09:00", "end": "14:00" }]
},
"saturday": { "enabled": false, "slots": [] },
"sunday": { "enabled": false, "slots": [] }
}
}Response 200
{
"id": "avail_01...",
"providerId": "prov_01...",
"title": "Default",
"timezone": "Europe/Madrid",
"status": "active"
}Possible Errors
Booking Lifecycle
/api/v1/bookingsCreate a booking directly when the provider and slot are already known, bypassing resolution.
The booking is created with status ‘pending’. The client receives a confirmation email with a link. Status transitions to ‘Confirmada’ after the client clicks the link. Listen for the booking.confirmed webhook event to detect this transition.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| providerId | string | required | Provider to book with. |
| serviceId | string | required | Event type / service. |
| slotId | string | required | Slot ID from availability. |
| attendee | object | required | { name, email, timezone } |
| notes | string | optional | Optional notes from the attendee. |
Request Body
{
"providerId": "prov_01...",
"serviceId": "svc_01...",
"slotId": "c2l0ZXx...",
"attendee": {
"name": "Juan RodrÃguez",
"email": "juan@example.com",
"timezone": "America/New_York"
},
"notes": "First session"
}Response 200
{
"data": {
"id": "6dc1b87a-...",
"status": "pending",
"title": "Therapy Session",
"date": "2026-08-05T15:00:00.000Z",
"end_time": "2026-08-05T16:00:00.000Z",
"tokenToConfirm": "ecc4deb7aa22e7e85b...",
"resolutionId": "res_7812"
}
}Possible Errors
/api/v1/bookingsList all bookings. Paginated. Optionally filter by status.
Authentication
Authorization: Bearer orita_...Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| page | number | optional | Page number (default 1). |
| limit | number | optional | Results per page (default 20). |
| status | "confirmed" | "cancelled" | "completed" | "rescheduled" | optional | Filter by booking status. |
Response 200
{
"bookings": [
{
"bookingId": "6dc1b87a-...",
"status": "confirmed",
"provider": { "name": "Dr. Ana GarcÃa" },
"start": "2026-08-05T15:00:00Z",
"end": "2026-08-05T15:50:00Z"
}
],
"total": 42,
"page": 1,
"limit": 20
}Possible Errors
/api/v1/bookings/:idRetrieve full details of a single booking by ID.
Authentication
Authorization: Bearer orita_...Response 200
{
"bookingId": "6dc1b87a-...",
"status": "confirmed",
"provider": {
"id": "prov_01...",
"name": "Dr. Ana GarcÃa",
"username": "dr-ana-garcia"
},
"service": {
"title": "Initial Consultation",
"duration": 50
},
"attendee": {
"name": "Juan RodrÃguez",
"email": "juan@example.com"
},
"start": "2026-08-05T15:00:00Z",
"end": "2026-08-05T15:50:00Z",
"confirmationUrl": "https://orita.online/b/6dc1b87a-..."
}Possible Errors
/api/v1/bookings/:id/rescheduleMove an existing booking to a new date and time. Cancels the original booking and creates a new one with the same provider, event type, and client.
Production requires separate date (YYYY-MM-DD) and time (HH:MM) fields — not a single ISO datetime. The new booking starts in ‘pending’ status until confirmed by the client.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| date | string | required | New date in YYYY-MM-DD format (e.g. "2026-08-06"). |
| time | string | required | New time in HH:MM format in the provider’s timezone (e.g. "15:00"). |
| notes | string | optional | Optional notes to attach to the rescheduled booking. |
Request Body
{
"date": "2026-08-06",
"time": "15:00",
"notes": "Client requested afternoon slot"
}Response 200
{
"data": {
"id": "6dc1b87a-...",
"status": "pending",
"title": "Therapy Session",
"date": "2026-08-06T19:00:00.000Z",
"end_time": "2026-08-06T20:00:00.000Z"
}
}Possible Errors
/api/v1/bookings/:id/cancelCancel an existing booking. Triggers a booking.cancelled webhook event.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| reason | string | optional | Optional cancellation reason. |
Request Body
{
"reason": "Patient no longer needs appointment"
}Response 200
{
"bookingId": "6dc1b87a-...",
"status": "cancelled",
"cancelledAt": "2026-08-04T09:00:00Z"
}Possible Errors
Direct Scheduling
/api/v1/slotsRetrieve available time slots for a specific provider and event type on a given date. Use this endpoint when you already know which provider and service you want to book, bypassing the resolution engine.
Authentication
Authorization: Bearer orita_...Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| providerId | string | required | Provider ID to fetch slots for. |
| eventTypeId | string | required | Event type (service) ID. |
| date | string (YYYY-MM-DD) | required | Date to fetch available slots for. |
Response 200
{
"slots": [
{
"id": "c2l0ZXx...",
"date": "2026-08-05",
"time": "09:00",
"label": "Tue Aug 5 at 9:00 AM",
"available": true
},
{
"id": "c2l0ZXy...",
"date": "2026-08-05",
"time": "10:00",
"label": "Tue Aug 5 at 10:00 AM",
"available": true
}
],
"total": 8
}Possible Errors
Operations
/api/v2/webhooksRetrieve your current webhook configuration.
Authentication
Authorization: Bearer orita_...Response 200
{
"url": "https://yourapp.com/webhooks/orita",
"events": ["booking.confirmed", "booking.cancelled"],
"active": true,
"createdAt": "2026-01-01T00:00:00Z"
}Possible Errors
/api/v2/webhooksUpdate your webhook URL and the list of events to receive.
Webhook configuration via API is coming soon. Configure your endpoint in the dashboard settings.
Authentication
Authorization: Bearer orita_...Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | required | HTTPS endpoint that will receive webhook POSTs. |
| events | string[] | required | List of event names to subscribe to. |
Request Body
{
"url": "https://yourapp.com/webhooks/orita",
"events": [
"booking.confirmed",
"booking.cancelled",
"booking.rescheduled",
"resolution.resolved"
]
}Response 200
{
"url": "https://yourapp.com/webhooks/orita",
"events": ["booking.confirmed", "booking.cancelled", "booking.rescheduled", "resolution.resolved"],
"active": true
}Possible Errors
/api/v2/webhooksSend a test event to your configured webhook URL to verify delivery.
Synthetic test delivery via API is coming soon. Use the dashboard webhook settings to test.
Authentication
Authorization: Bearer orita_...Request Body
// No body required — sends a test ping eventResponse 200
{
"delivered": true,
"statusCode": 200,
"latencyMs": 142
}Possible Errors
/api/v2/webhooks/deliveriesList recent webhook delivery attempts with HTTP status codes and latency.
Delivery log API is coming soon. Use POST /api/v2/webhooks/:deliveryId/replay to replay a specific delivery.
Authentication
Authorization: Bearer orita_...Response 200
{
"deliveries": [
{
"id": "del_01...",
"event": "booking.confirmed",
"statusCode": 200,
"latencyMs": 132,
"timestamp": "2026-08-05T15:01:00Z",
"success": true
},
{
"id": "del_02...",
"event": "booking.cancelled",
"statusCode": 503,
"latencyMs": 5000,
"timestamp": "2026-08-04T10:00:00Z",
"success": false
}
],
"total": 48
}Possible Errors
/api/v2/webhooks/deliveries/:id/replayReplay a specific webhook delivery attempt. Useful for recovering from failures without waiting for the automatic retry schedule. Requires the Launch plan or higher.
Authentication
Authorization: Bearer orita_... (Launch plan or higher)Request Body
// No body required — pass the delivery ID in the URL pathResponse 200
{
"delivered": true,
"statusCode": 200,
"latencyMs": 118,
"replayedAt": "2026-08-05T16:00:00Z"
}Possible Errors
/api/v2/analyticsRetrieve resolution and booking metrics for your account.
Authentication
Authorization: Bearer orita_...Response 200
{
"resolutions": {
"total": 1240,
"resolved": 1185,
"zeroResults": 55,
"avgEvaluatedSlots": 121
},
"bookings": {
"total": 980,
"confirmed": 930,
"cancelled": 40,
"rescheduled": 10
},
"conversionRate": 0.79,
"period": "last_30_days"
}Possible Errors
Webhook Events
Orita POSTs a signed JSON payload to your configured webhook URL whenever one of the following events occurs.
| Event | Description |
|---|---|
| booking.confirmed | A new booking was confirmed. |
| booking.cancelled | A booking was cancelled. |
| booking.rescheduled | A booking was moved to a new slot. |
| booking.completed | A booking time has passed and it is marked completed. |
| resolution.resolved | A resolution found at least one matching option. |
| resolution.zero_results | A resolution returned no matching options. |
| option.held | An option within a resolution was held. |
| professional.updated | A professional profile was modified. |
Payload Shape
{
"type": "booking.confirmed",
"timestamp": "2026-08-05T15:00:00Z",
"data": { ... }
}Signature Verification
Every webhook request includes an X-Orita-Signature header. Its value is sha256=<hex>, where the hex string is an HMAC-SHA256 of the raw request body signed with your webhook secret.
// Node.js verification example
import crypto from "crypto";
function verifySignature(rawBody: string, signature: string, secret: string) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}Webhook delivery is retried up to 5 times with exponential backoff when your endpoint returns a non-2xx status. Check GET /api/v2/webhooks/deliveries for delivery history.
Error Codes
All errors return a JSON body with an error object. Check the code and message fields for machine-readable and human-readable details.
{
"error": {
"code": "INVALID_DATE_RANGE",
"message": "dateRange.to must be after dateRange.from and within 14 days.",
"status": 400
}
}| Status | Name | Meaning |
|---|---|---|
| 400 | Bad Request | Missing or invalid request parameters. Check the errors array in the response body. |
| 401 | Unauthorized | API key is missing, malformed, or revoked. |
| 404 | Not Found | The requested resource does not exist. |
| 409 | Conflict | State conflict — e.g. slot already taken, idempotency key reused. |
| 410 | Gone | The resource existed but has expired (e.g. a resolution past its expiry). |
| 422 | Unprocessable Entity | Request is syntactically valid but semantically incorrect. |
| 429 | Too Many Requests | Rate limit exceeded. Retry after the Retry-After header value (seconds). |
| 500 | Internal Server Error | Unexpected server error. Contact support if this persists. |
Capability Support Matrix
Every capability marked Yes is live in production v2 and contract-verified. A2A flow (discover → resolve → hold → approval → confirm) is additionally validated by 23/23 conformance tests. SDK and MCP coverage is contract-verified; full end-to-end production testing across all methods is in progress.
| Capability | Stored | Searchable | Hard constraint | Ranking preference |
|---|---|---|---|---|
| Service | Yes | Yes | Yes | No |
| Provider status | Yes | Yes | Yes | No |
| Specialty | Yes | Yes | Yes | Optional |
| Profession | Yes | Yes | Yes | No |
| Language | Yes | Yes | Yes | Yes |
| Modality | Yes | Yes | Yes | No |
| Location | Yes | Yes | Yes | Yes |
| Service region | Yes | Yes | Yes | No |
| License region | Yes | Yes | Yes | No |
| Insurance plan | Yes | Yes | Yes | No |
| Age group | Yes | Yes | Yes | No |
| Accepting new clients | Yes | Yes | Yes | No |
| Availability | Yes | Yes | Yes | Yes |
| Panel capacity | Yes | Yes | Yes | No |
| Provider continuity | Yes | Yes | No | Yes |
| Workload balance | Yes | Yes | No | Yes |
