Appointments
Book an appointment (Tier 2: the customer may be texted)
POST /v1/appointments
- Scope
appointments:write- Tier
- Tier 2 (reaches or unlocks real people)
- Data
- Personal data
- Idempotency
- Idempotency-Key: required
Tier 2. This operation can reach or unlock real people. It needs the scope appointments:write and the account switch tier2_appointment_write_enabled, which is off for every account unless DialerBee turns it on at your request. Until then it answers 403 tier_not_enabled. Daily cap: set before launch.
TIER 2. If the account has appointment confirmations on, the customer is texted that the appointment is booked, and the booking is synced to the account's connected calendar if it has one. Needs the appointments:write scope and the account switch tier2_appointment_write_enabled. Calendar-invite email is not offered, so the request carries no email address. A number in a country the platform does not contact answers 422 blocked_country.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | yes | Your unique value for this logical operation (a UUID is fine). Scoped to your API client, kept 24 hours. (min length 1; max length 255) |
X-Correlation-ID | header | string | no | Your own trace value, logged with the request. Metadata only, never identity. (min length 1; max length 128) |
Request body
The appointment.
JSON: AppointmentCreateRequest
Response
201: The appointment.
| Header | Meaning |
|---|---|
X-Request-ID | The DialerBee request id. Quote it to support. Every response carries X-Request-ID: req_<ULID>, or edge_<32 hex> when the edge answered before the request reached the API. |
Cache-Control | Always no-store. |
Idempotency-Replayed | true when this answer is the stored answer of an earlier request with the same Idempotency-Key. |
ETag | The resource version. Send it back as If-Match. |
Examples
Request example
curl
curl -sS -X POST \
"https://app.dialerbee.com/api/v1/appointments" \
-H "Authorization: Bearer $DIALERBEE_API_KEY" \
-H 'Idempotency-Key: 5f2b7c1e-8a3d-4c6f-9b0e-2d4a6c8e1f3a' \
-H "Content-Type: application/json" \
--data '{
"phone": "+12125550123",
"scheduled_at": "2026-10-01T14:00:00Z",
"duration_minutes": 30,
"timezone": "Asia/Amman",
"service_type": "Consultation",
"contact_name": "Ann Lee",
"notes": "Prefers calls after 5 pm."
}'
Python (SDK)
from dialerbee import DialerBee
db = DialerBee() # reads DIALERBEE_API_KEY from the environment
result = db.appointments.create(
phone="+12125550123",
scheduled_at="2026-10-01T14:00:00Z",
duration_minutes=30,
timezone="Asia/Amman",
service_type="Consultation",
contact_name="Ann Lee",
notes="Prefers calls after 5 pm.",
idempotency_key="5f2b7c1e-8a3d-4c6f-9b0e-2d4a6c8e1f3a",
)
Response example
201
{
"id": "appt_0f8fad5b-d9cb-469f-a165-70867728950e",
"status": "scheduled",
"scheduled_at": "2026-10-01T14:00:00Z",
"timezone": "Asia/Amman",
"duration_minutes": 30,
"service_type": "Consultation",
"contact_name": "Ann Lee",
"phone": "+12125550101",
"email": "[email protected]",
"notes": "Prefers calls after 5 pm.",
"source": "api",
"created_at": "2026-09-29T09:15:00Z",
"updated_at": "2026-09-29T09:20:00Z"
}
Error examples
422 blocked_country
{
"type": "https://docs.dialerbee.com/errors/blocked-country",
"title": "Destination country blocked",
"status": 422,
"detail": "The platform does not contact numbers in this country.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "blocked_country",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C"
}
403 tier_not_enabled
{
"type": "https://docs.dialerbee.com/errors/tier-not-enabled",
"title": "Capability not enabled",
"status": 403,
"detail": "This operation can reach or unlock real people.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "tier_not_enabled",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C"
}
409 outcome_unknown
{
"type": "https://docs.dialerbee.com/errors/outcome-unknown",
"title": "Outcome unknown",
"status": 409,
"detail": "An earlier request with this Idempotency-Key may or may not have taken effect: the platform did not confirm it.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "outcome_unknown",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C"
}
Errors
| Status | Code | Title |
|---|---|---|
| 401 | invalid_api_key | Invalid API key |
| 403 | api_access_disabled | API access disabled |
| 403 | ip_not_allowed | IP address not allowed |
| 403 | insufficient_scope | Not permitted |
| 403 | tier_not_enabled | Capability not enabled |
| 400 | credential_in_url | Credential in URL |
| 400 | credential_in_body | Credential in body |
| 400, 422 | validation_failed | Invalid request |
| 413 | payload_too_large | Payload too large |
| 415 | unsupported_media_type | Unsupported media type |
| 400 | idempotency_key_required | Idempotency-Key required |
| 422 | blocked_country | Destination country blocked |
| 409 | conflict | Request in progress |
| 409 | idempotency_conflict | Idempotency key reused |
| 409 | outcome_unknown | Outcome unknown |
| 429 | rate_limit_exceeded | Too many requests |
| 429 | daily_cap_reached | Daily limit reached |
| 503 | temporarily_unavailable | Temporarily unavailable |
| 503 | upstream_unavailable | Temporarily unavailable |
| 502 | upstream_invalid_response | Upstream error |
| 500 | internal_error | Internal error |
Objects
AppointmentCreateRequest
| Field | Type | Required | Description |
|---|---|---|---|
phone | string (E.164 phone) | yes | A phone number in E.164 form. |
scheduled_at | string (date-time) | yes | |
duration_minutes | integer | no | (min 5; max 480) |
timezone | string | no | IANA time zone, for example Asia/Amman. (max length 64) |
service_type | string | no | (max length 100) |
contact_name | string | no | (max length 200) |
notes | string | no | (max length 1000) |
Appointment
| Field | Type | Required | Description |
|---|---|---|---|
id | string (AppointmentId) | yes | An appointment. appt_ + a lower-case UUID. |
status | string | yes | |
scheduled_at | string (date-time) | yes | |
timezone | string or null | yes | |
duration_minutes | integer | yes | |
service_type | string or null | yes | |
contact_name | string or null | yes | |
phone | string | yes | |
email | string or null | yes | |
notes | string or null | yes | |
source | string | yes | |
created_at | string (date-time) | yes | |
updated_at | string (date-time) | yes |