D Line API
REST and webhooks for calls, texts, voicemail and your workspace.
Errors
Errors use the HTTP status plus one JSON envelope. Branch on code, show message to people, and quote request_id (also in the DLine-Request-Id header) when you contact support. New codes may be added; handle an unknown code by its type.
{
"error": {
"type": "policy_error",
"code": "recipient_opted_out",
"message": "This number opted out of texts from your workspace.",
"param": "to",
"request_id": "req_01J9ZK3Q4T8N6V2B0C5D7E9F1G",
"doc_url": "https://d-line.app/developers/errors#recipient_opted_out"
}
}Types
| Type | Status | Meaning |
|---|---|---|
invalid_request_error | 400, 404, 409, 410, 413, 422 | The request is malformed, refers to something that does not exist, or conflicts with its current state. Fix the request before retrying. |
authentication_error | 401 | The API key is missing, malformed, revoked or expired. |
permission_error | 403 | The key is valid but may not do this: a missing scope, a feature that is not enabled, or a blocked IP. |
rate_limit_error | 429 | Too many requests. Wait for Retry-After seconds, then retry. |
policy_error | 422 | A compliance rule refused the request (10DLC, opt-outs, quiet hours, fair use). Nothing was created or billed. |
api_error | 5xx | Something failed on our side. Retry with backoff and the same Idempotency-Key. |
Codes
| Code | Status | Type | Meaning |
|---|---|---|---|
unknown_parameter | 400 | invalid_request_error | The body or query has a field the endpoint does not accept (often a typo). `param` names it. |
invalid_parameter | 400 | invalid_request_error | A field has the wrong type or format, for example a number that is not E.164. |
missing_parameter | 400 | invalid_request_error | A required field is missing. |
invalid_cursor | 400 | invalid_request_error | The pagination cursor is malformed, expired or from another workspace. |
invalid_json | 400 | invalid_request_error | The body is not valid UTF-8 JSON. |
idempotency_key_required | 400 | invalid_request_error | This endpoint needs an Idempotency-Key header. |
invalid_recipient | 400 | invalid_request_error | The `to` number is not a valid US or Canadian number, or is known not to receive texts. |
test_number_required | 422 | invalid_request_error | Test keys can only send to the documented magic numbers. |
resource_not_found | 404 | invalid_request_error | No object with this id exists in the workspace. |
recording_not_found | 404 | invalid_request_error | The call has no recording. |
transcript_not_found | 404 | invalid_request_error | The call has no transcript. Request one with POST /calls/{id}/transcript. |
summary_not_found | 404 | invalid_request_error | The call has no AI summary. |
from_number_not_owned | 404 | invalid_request_error | The `from` number is not an active number of this workspace. |
idempotency_key_reused | 409 | invalid_request_error | The Idempotency-Key was already used with a different request body. |
transcript_pending | 409 | invalid_request_error | The transcript is still being processed. Wait for transcript.ready. |
summary_pending | 409 | invalid_request_error | The AI summary is still being processed. Wait for ai_summary.ready. |
consumer_opt_out | 409 | invalid_request_error | The contact opted out themselves (STOP or carrier). Only the contact can lift it by texting START. |
replay_in_progress | 409 | invalid_request_error | A replay is already running for this endpoint. |
recording_deleted | 410 | invalid_request_error | The recording existed but retention removed the audio. |
media_too_large | 413 | invalid_request_error | The upload is over 5 MB, or the media cannot be shrunk to fit carrier limits. |
endpoint_limit_reached | 422 | invalid_request_error | The workspace already has 10 webhook endpoints. |
invalid_webhook_url | 422 | invalid_request_error | The webhook URL is not public HTTPS, or resolves to a private address. |
text_too_long | 422 | invalid_request_error | The text is over 1,600 characters. |
too_many_media | 422 | invalid_request_error | More than 10 media items. |
media_fetch_failed | 422 | invalid_request_error | A `media_urls` entry could not be fetched (not public, timed out, or not a supported type). |
invalid_api_key | 401 | authentication_error | The Authorization header is missing or the key is not valid. |
api_key_expired | 401 | authentication_error | The key passed its expiry date. Create or roll a key in Settings > Developers. |
api_key_revoked | 401 | authentication_error | The key was revoked. |
insufficient_scope | 403 | permission_error | The key lacks the scope this endpoint needs. Roll the key with the extra scope. |
ip_not_allowed | 403 | permission_error | The request came from an IP outside the key's allow-list. |
feature_not_enabled | 403 | permission_error | The workspace plan does not include this feature. |
test_mode_only | 403 | permission_error | This endpoint only accepts test keys. |
registration_required | 422 | policy_error | The number has no approved 10DLC campaign yet. |
registration_pending | 422 | policy_error | The 10DLC campaign is still under carrier review. |
number_not_assigned | 422 | policy_error | The number is not attached to the workspace's 10DLC campaign. |
not_sms_capable | 422 | policy_error | The number cannot send texts. |
billing_hold | 422 | policy_error | Texting is paused on the account (for example an unpaid invoice). |
recipient_opted_out | 422 | policy_error | The recipient is on the workspace opt-out list. |
quiet_hours | 422 | policy_error | Outside the sending window in the recipient's local time. `next_allowed_at` says when to retry. |
fair_use_exceeded | 422 | policy_error | The workspace used its monthly SMS allowance plus the API buffer. |
daily_cap_reached | 422 | policy_error | The campaign's carrier daily cap or the workspace's own cap is used up. |
content_blocked | 422 | policy_error | The content was refused, for example a public URL shortener that carriers filter. |
transcription_allowance_exceeded | 422 | policy_error | The workspace has no transcription minutes left this period. |
rate_limited | 429 | rate_limit_error | Over the request rate for the key or workspace. Honour Retry-After. |
internal_error | 500 | api_error | An unexpected error. Retry with backoff; quote the request id if it persists. |
service_unavailable | 503 | api_error | A dependency is temporarily unavailable. Retry with backoff. |