Consent
Record consent evidence (Tier 2: can make a number callable)
POST /v1/consents
- Scope
consent: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 consent:write and the account switch tier2_consent_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. Structured evidence only: who consented, to which channel, when, captured where, and your own reference to the proof. A bare consent: true is never accepted. Needs the consent:write scope and the account switch tier2_consent_write_enabled.
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 consent evidence.
JSON: ConsentCreateRequest
Response
201: The consent record.
| 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. |
Examples
Request example
curl
curl -sS -X POST \
"https://app.dialerbee.com/api/v1/consents" \
-H "Authorization: Bearer $DIALERBEE_API_KEY" \
-H 'Idempotency-Key: 5f2b7c1e-8a3d-4c6f-9b0e-2d4a6c8e1f3a' \
-H "Content-Type: application/json" \
--data '{
"phone": "+12125550123",
"channel": "voice",
"captured_at": "2026-09-20T10:00:00Z",
"expires_at": "2027-09-20T10:00:00Z",
"source": "customer_crm",
"external_reference": "CRM-CONSENT-1001",
"proof_url": "https://crm.example.com/consents/1001.pdf"
}'
Python (SDK)
from dialerbee import DialerBee
db = DialerBee() # reads DIALERBEE_API_KEY from the environment
result = db.consents.create(
phone="+12125550123",
channel="voice",
captured_at="2026-09-20T10:00:00Z",
expires_at="2027-09-20T10:00:00Z",
source="customer_crm",
external_reference="CRM-CONSENT-1001",
proof_url="https://crm.example.com/consents/1001.pdf",
idempotency_key="5f2b7c1e-8a3d-4c6f-9b0e-2d4a6c8e1f3a",
)
Response example
201
{
"id": "cns_0f8fad5b-d9cb-469f-a165-70867728950e",
"phone": "+12125550123",
"channel": "example",
"status": "active",
"captured_at": "2026-09-20T10:00:00Z",
"expires_at": "2027-09-20T10:00:00Z",
"source": "api",
"external_reference": "CRM-CONSENT-1001",
"created_at": "2026-09-29T09:15:00Z"
}
Error examples
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"
}
400 validation_failed
{
"type": "https://docs.dialerbee.com/errors/validation-failed",
"title": "Invalid request",
"status": 400,
"detail": "The request is not valid.",
"instance": "urn:dialerbee:request:req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"code": "validation_failed",
"request_id": "req_01K6BZ3M9X4T7Q2V8N5R6P1W0C",
"errors": [
{
"pointer": "/leads/1/phone",
"code": "missing"
}
]
}
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 |
| 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
ConsentCreateRequest
Date rules the schema cannot express answer 422 validation_failed, with one errors[] entry per field: captured_at in_future (up to 5 minutes of clock skew is allowed); expires_at in_past, before_captured_at or too_long (more than 730 days after captured_at). Control characters are refused in external_reference and proof_url. Timestamps must be strings with a UTC offset.
| Field | Type | Required | Description |
|---|---|---|---|
phone | string (E.164 phone) | yes | A phone number in E.164 form. |
channel | one of voice, sms | yes | |
captured_at | string (date-time) | yes | When the person gave consent. Not in the future (422 in_future; up to 5 minutes of clock skew is allowed). |
expires_at | string (date-time) | yes | When the consent ends. In the future (422 in_past), after captured_at (422 before_captured_at) and at most 730 days after captured_at (422 too_long). |
source | one of customer_crm, web_form, recorded_call, written | yes | Where the consent was captured. |
external_reference | string | yes | Your reference to the proof in your own system. Printable, with no leading or trailing space; control characters are refused. (min length 1; max length 128) |
proof_url | string (uri) | no | A link to the proof. An https:// URL without credentials (no user name or password in it); control characters are refused. Optional; leave it out rather than send null (null is refused). (max length 2048; https only) |
Consent
| Field | Type | Required | Description |
|---|---|---|---|
id | string (ConsentId) | yes | A consent record. cns_ + a lower-case UUID. |
phone | string (E.164 phone) | yes | A phone number in E.164 form. |
channel | string | yes | |
status | string | yes | |
captured_at | string (date-time) | yes | |
expires_at | string (date-time) | yes | |
source | string | yes | |
external_reference | string | yes | |
created_at | string (date-time) | yes |