diff --git a/documentation/API_documentation/click-to-dial_API.md b/documentation/API_documentation/click-to-dial_API.md index 59d33d7..b09d638 100644 --- a/documentation/API_documentation/click-to-dial_API.md +++ b/documentation/API_documentation/click-to-dial_API.md @@ -177,12 +177,91 @@ Errors follow the standard format: Reference the [OpenAPI YAML](../../code/API_definitions/click-to-dial.yaml) for exact error codes and descriptions. +#### 4.4.1 422 — Business error codes (Unprocessable Entity) + +When a request is syntactically correct but semantically invalid, the API returns `422 Unprocessable Entity` with a business `code` describing the error. The following 422 business error codes are defined in the OpenAPI spec: + +| Code | Description | +| ---- | ----------- | +| `INVALID_PHONE_NUMBER` | Caller or callee number is not a valid E.164 phone number. | +| `SAME_CALLER_CALLEE` | Caller and callee cannot be the same number. | +| `RECORDING_NOT_SUPPORTED` | Recording is not supported for this call. | +| `CALLER_NOT_AVAILABLE` | Caller number is currently not reachable or not allowed to start a call. | +| `CALLEE_NOT_AVAILABLE` | Callee number is currently not reachable or not allowed to receive a call. | +| `INSUFFICIENT_BALANCE` | The account does not have sufficient balance or quota to start this call. | +| `RESTRICTED_DESTINATION` | The destination number is restricted and cannot be called. | + +Example 422 response: + +```json +{ + "status": 422, + "code": "INVALID_PHONE_NUMBER", + "message": "Caller or callee number is not a valid E.164 phone number." +} +``` + +Note: Additional common CAMARA error responses may be defined in the `CAMARA_common.yaml` referenced by this API's readiness checklist. Always consult the OpenAPI YAML for the authoritative list. + ## CloudEvent delivery notes - Providers MUST send status notifications as CloudEvents in structured mode. The HTTP header must be `Content-Type: application/cloudevents+json`. - The CloudEvent MUST include the attributes: `id`, `source`, `type`, `specversion`, `time`, and `subject` (subject should identify the resource, e.g. `/calls/{callId}`). - The CloudEvent attribute `datacontenttype` MUST be `application/json` for the `data` payload. +The CloudEvent `data` payload for Click-to-Dial `EventCTDStatusChanged` includes `callId`, `caller`, `callee`, `timestamp` and `status` (where `status` is an object with `state` and optional `reason`). Providers MUST set the CloudEvent `subject` to the affected resource (for example `/calls/{callId}`) and set `datacontenttype` to `application/json`. + +Example CloudEvent (structured mode) — `CALL_STATUS_CHANGED_EXAMPLE` from the OpenAPI spec: + +```json +{ + "id": "83a0d986-0866-4f38-b8c0-fc65bfcda452", + "source": "https://api.example.com/click-to-dial", + "subject": "/calls/123e4567-e89b-12d3-a456-426614174000", + "specversion": "1.0", + "datacontenttype": "application/json", + "type": "org.camaraproject.click-to-dial.v0.status-changed", + "time": "2021-12-12T00:00:00Z", + "data": { + "callId": "123e4567-e89b-12d3-a456-426614174000", + "caller": "+12345678", + "callee": "+12345678", + "status": { + "state": "disconnected", + "reason": "hangUp" + }, + "recordingResult": "success", + "callDuration": "1600", + "timestamp": "2017-12-04T18:07:57Z" + } +} +``` + +Providers SHOULD ensure event `id` uniqueness and may retry delivery on transient failures. When delivering events to a `sink` that requires authentication, use the provided `sinkCredential` (e.g., set `Authorization: Bearer ` for `ACCESSTOKEN`). + +## Call flow (sequence diagram) + +The following sequence diagram shows the typical flow when creating a Click-to-Dial session, delivering events, and terminating the call. This is a logical flow; implementers may optimize or parallelise steps. + +```mermaid +sequenceDiagram + participant Client + participant Provider + participant Caller + participant Callee + participant Sink + + Client->>Provider: POST /calls {caller, callee, sink, sinkCredential} + Provider->>Caller: Place outbound call to caller + Provider->>Callee: Place outbound call to callee + Provider-->>Client: 201 Created {callId, status} + Provider->>Sink: CloudEvent (status: initiating) + Provider->>Sink: CloudEvent (status: connected) + Client->>Provider: DELETE /calls/{callId} + Provider->>Sink: CloudEvent (status: disconnected) +``` + + ### 4.5 Policies N/A