> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# UCC API

> Manage UCC complaints against your India phone numbers, submit opt-in proof, and receive events on every status change.

<Info title="TL;DR">
  The UCC API helps you manage the complaint workflow described in [UCC Management](/docs/voice/concepts/ucc-management): list and retrieve UCC complaints against your account, submit opt-in proof, and receive an event whenever a complaint is created or its status changes. Available to India data region accounts.
</Info>

This API and the [UCC dashboard](https://cx.plivo.com/phone-numbers/ucc) act on the same records — proof submitted through either one moves the same complaint, and a verdict reached in review shows up in both. Use the API when you want complaint handling wired into your own systems instead of someone watching the Console.

## API Endpoint

```text theme={null}
https://api.plivo.com/v1/Account/{auth_id}/Ucc/
```

All requests use HTTP Basic authentication with your Auth ID and Auth Token. Every response includes an `api_id` for request tracing.

***

## The UCC Complaint Object

A UCC complaint is registered against your account when a carrier reports one of your calls. Each complaint is identified by its `reference_id` and moves through a review lifecycle: `pending` → `in_review` → `accepted` or `rejected`.

### Attributes

<ParamField body="reference_id" type="string">
  Unique reference ID of the complaint, in the format `PUCC-YYYY-NNNNNNNNN`. This is the same reference quoted in Plivo's complaint notification emails and on the UCC dashboard. Use this ID in all endpoint paths.
</ParamField>

<ParamField body="status" type="string">
  Current state of the complaint. One of `pending` (no proof received yet), `in_review` (proof uploaded and under review), `accepted` (proof approved; complaint closed), or `rejected` (proof declined; see `rejection_reason` and resubmit).
</ParamField>

<ParamField body="from_number" type="string">
  Your Plivo number that made the reported call, in E.164 format.
</ParamField>

<ParamField body="to_number" type="string">
  The complainant's phone number, in E.164 format.
</ParamField>

<ParamField body="initiation_date" type="string">
  Date of the reported call, in `YYYY-MM-DD` format, as reported in the carrier's complaint.
</ParamField>

<ParamField body="complaint_category" type="string">
  Category of the complaint as reported by the carrier.
</ParamField>

<ParamField body="call_uuid" type="string">
  Plivo Call UUID of the reported call. Use it to look up the call in your call detail records. Null when the call could not be matched.
</ParamField>

<ParamField body="opt_in_proof" type="string">
  URL of the most recently uploaded opt-in proof. Null until the first upload.
</ParamField>

<ParamField body="rejection_reason" type="string">
  Reason the proof was declined, in plain text. Populated only while `status` is `rejected`; null in every other state.
</ParamField>

<ParamField body="created_at" type="string">
  Timestamp when the complaint was registered, in ISO 8601 UTC.
</ParamField>

<ParamField body="updated_at" type="string">
  Timestamp when the complaint last changed, in ISO 8601 UTC.
</ParamField>

### Example Object

```json theme={null}
{
  "api_id": "aa1e6a4e-31aa-11f1-ab48-d2d6f5435dea",
  "call_uuid": "18830b47-ddda-41ba-b621-f4b4f5524264",
  "complaint_category": "Received spam call in the category: Banking/Insurance/Financial Products/Credit Card",
  "created_at": "2026-07-09T08:04:16Z",
  "from_number": "+911600123456",
  "initiation_date": "2026-07-03",
  "opt_in_proof": "https://media.example.com/ucc-proofs/PUCC-2026-990000051.pdf",
  "reference_id": "PUCC-2026-990000051",
  "rejection_reason": "The consent date is older than 6 months",
  "status": "rejected",
  "to_number": "+919876543210",
  "updated_at": "2026-07-15T09:00:13Z"
}
```

***

## Retrieve a UCC Complaint

Fetch a single complaint by its UCC reference ID.

### HTTP Request

`GET https://api.plivo.com/v1/Account/{auth_id}/Ucc/{reference_id}/`

A `reference_id` that does not exist or belongs to another account returns a `404` error.

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.plivo.com/v1/Account/{auth_id}/Ucc/PUCC-2026-990000051/" \
    -u '<auth_id>:<auth_token>'
  ```
</CodeGroup>

The response is the [UCC Complaint object](#the-ucc-complaint-object) shown above.

***

## List UCC Complaints

Fetch complaints against your account, newest first. Use the filters to poll for open work — for example, all `rejected` complaints that need a new proof.

### HTTP Request

`GET https://api.plivo.com/v1/Account/{auth_id}/Ucc/`

### Request Parameters

<ParamField query="status" type="string">
  Filter by state: `pending`, `in_review`, `accepted`, or `rejected`.
</ParamField>

<ParamField query="from_number" type="string">
  Filter by the Plivo number that made the reported call.
</ParamField>

<ParamField query="created_at" type="string">
  Filter by complaint creation time, in `YYYY-MM-DD HH:MM[:ss[.uuuuuu]]` format. Supports the range variants `created_at__gt`, `created_at__gte`, `created_at__lt`, and `created_at__lte`, with the same behavior as the [List All Calls](/docs/voice/api/calls#list-all-calls) time filters.
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Number of results per page, from 1 to 20.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Number of results to skip, for pagination.
</ParamField>

### Response

<ResponseField name="api_id" type="string">
  Unique identifier for the API request.
</ResponseField>

<ResponseField name="meta" type="object">
  Pagination details: `limit`, `offset`, `total_count`, and relative `next`/`previous` page URLs (null when there is no further page).
</ResponseField>

<ResponseField name="objects" type="array">
  The list of [UCC Complaint objects](#the-ucc-complaint-object) matching the filters.
</ResponseField>

```json theme={null}
{
  "api_id": "b1c2d3e4-58b6-11e1-86da-77300b68f8bb",
  "meta": {
    "limit": 20,
    "next": null,
    "offset": 0,
    "previous": null,
    "total_count": 4
  },
  "objects": [
    {
      "reference_id": "PUCC-2026-990000051",
      "status": "rejected",
      "from_number": "+911600123456",
      "to_number": "+919876543210",
      "initiation_date": "2026-07-03"
    }
  ]
}
```

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.plivo.com/v1/Account/{auth_id}/Ucc/?status=rejected&created_at__gte=2026-07-01" \
    -u '<auth_id>:<auth_token>'
  ```
</CodeGroup>

***

## Submit Opt-In Proof

Upload an opt-in proof file against a complaint. A successful upload moves the complaint to `in_review`. Call this endpoint when a complaint is `pending`, or again after a rejection to resubmit.

### HTTP Request

`POST https://api.plivo.com/v1/Account/{auth_id}/Ucc/{reference_id}/`

Send the request as `multipart/form-data`.

### Request Parameters

<ParamField body="file" type="file" required>
  The opt-in proof document. Allowed types: PDF, PNG, and JPEG, validated by content type. Maximum size: 10 MB.
</ParamField>

The document must show **all three** of the following, or the review declines it:

| Required element               | Details                                                                                                              |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| **Business logo**              | The logo or identity of the business entity that made the call, so the caller's identity can be verified.            |
| **Date of opt-in**             | The date the recipient explicitly opted in to receive calls. Must be within 6 months before the complaint date.      |
| **Complainant's phone number** | The exact number of the person who filed the complaint, confirming the opt-in was obtained for that specific number. |

<Note>
  The API does not validate these three elements when you upload. It checks only the file type and size, then returns `201` and moves the complaint to `in_review`. The contents are assessed later during review — a document missing any of the three is rejected, with the reason in `rejection_reason`. A successful upload is not an accepted proof.
</Note>

<Warning>
  **6-month validity window.** An opt-in acquired more than 6 months before the complaint date is not accepted. Make sure your opt-in collection system records timestamps accurately.
</Warning>

For the full policy, including what happens after a rejection, see [UCC Management](/docs/voice/concepts/ucc-management#1-submit-opt-in-proof).

Uploads are allowed while `status` is `pending` or `rejected`. Uploading against a complaint that is `in_review` or `accepted` returns a `400` error.

### Response

<ResponseField name="api_id" type="string">
  Unique identifier for the API request.
</ResponseField>

<ResponseField name="message" type="string">
  Status of the request.
</ResponseField>

<ResponseField name="reference_id" type="string">
  Reference ID of the complaint the proof was submitted against.
</ResponseField>

<ResponseField name="status" type="string">
  The complaint's new state: `in_review`.
</ResponseField>

<ResponseField name="opt_in_proof" type="string">
  URL of the uploaded proof file.
</ResponseField>

```json theme={null}
{
  "api_id": "c407c522-31a7-11f1-ab48-d2d6f5435dea",
  "message": "proof submitted",
  "reference_id": "PUCC-2026-990000051",
  "status": "in_review",
  "opt_in_proof": "https://media.example.com/ucc-proofs/PUCC-2026-990000051.pdf"
}
```

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.plivo.com/v1/Account/{auth_id}/Ucc/PUCC-2026-990000051/" \
    -u '<auth_id>:<auth_token>' \
    -F "file=@opt-in-record.pdf"
  ```
</CodeGroup>

***

## Callbacks

Configure a callback URL on the [UCC dashboard](https://cx.plivo.com/phone-numbers/ucc) to receive an event whenever a complaint is created against your account or changes state. The URL must use HTTPS, and one URL applies to your whole account.

Plivo sends callbacks as form-encoded POST requests (`Content-Type: application/x-www-form-urlencoded`), signed with the same V3 signature scheme as Voice API callbacks. Validate the signature before trusting the parameters — see [Signature Validation](/docs/voice/concepts/signature-validation).

There are four callbacks, matching the complaint lifecycle. The `Status` parameter identifies which one you received:

| `Status`          | Fired when                                         | Complaint status after |
| ----------------- | -------------------------------------------------- | ---------------------- |
| `created`         | A new complaint is registered against your account | `pending`              |
| `proof_submitted` | You upload a proof, through the API or the Console | `in_review`            |
| `rejected`        | Review declines the proof                          | `rejected`             |
| `accepted`        | Review approves the proof                          | `accepted`             |

### Callback Parameters

<ParamField body="Endpoint" type="string">
  Always `ucc` — identifies the resource type generating the callback.
</ParamField>

<ParamField body="Status" type="string">
  The lifecycle event: `created`, `proof_submitted`, `rejected`, or `accepted`.
</ParamField>

<ParamField body="UCCReferenceID" type="string">
  Reference ID of the complaint. Use it with [Retrieve a UCC Complaint](#retrieve-a-ucc-complaint) for the full record.
</ParamField>

<ParamField body="FromNumber" type="string">
  Your Plivo number that made the reported call, in E.164 format.
</ParamField>

<ParamField body="ToNumber" type="string">
  The complainant's phone number, in E.164 format.
</ParamField>

<ParamField body="InitiationDate" type="string">
  Date of the reported call, in `YYYY-MM-DD` format. Same value as `initiation_date` on the UCC Complaint object.
</ParamField>

<ParamField body="ComplaintCategory" type="string">
  Category of the complaint as reported by the carrier.
</ParamField>

<ParamField body="CallUUID" type="string">
  Plivo Call UUID of the reported call. Empty when the call could not be matched.
</ParamField>

<ParamField body="RejectionReason" type="string">
  Reason the proof was declined, in plain text. Sent only on the `rejected` callback.
</ParamField>

<ParamField body="ResourceCreationTime" type="string">
  When the complaint was registered in Plivo's system, in `YYYY-MM-DD HH:MM:SS.fff +0000 UTC` format. This mirrors the object's `created_at` and is identical across all callbacks for a complaint. It is not the date of the reported call — that's `InitiationDate`.
</ParamField>

<ParamField body="ResourceUpdatedTime" type="string">
  When this status transition fired, in `YYYY-MM-DD HH:MM:SS.fff +0000 UTC` format. This mirrors the object's `updated_at` and changes with every callback.
</ParamField>

### Example Callback

```text theme={null}
Endpoint: ucc
Status: rejected
UCCReferenceID: PUCC-2026-990000051
FromNumber: +911600123456
ToNumber: +919876543210
InitiationDate: 2026-07-03
ComplaintCategory: Received spam call in the category: Banking/Insurance/Financial Products/Credit Card
CallUUID: 18830b47-ddda-41ba-b621-f4b4f5524264
RejectionReason: The consent date is older than 6 months
ResourceCreationTime: 2026-07-09 08:04:16.720 +0000 UTC
ResourceUpdatedTime: 2026-07-15 14:03:27.320 +0000 UTC
```

The `created`, `proof_submitted`, and `accepted` callbacks carry the same parameters without `RejectionReason`.

### Delivery and Retries

* Respond with an HTTP `200` within 5 seconds.
* Plivo retries failed deliveries 3 times, at 60, 120, and 240 seconds.
* Deliveries are at-least-once and unordered. Deduplicate on `UCCReferenceID` + `Status` + `ResourceUpdatedTime`, and reconcile state with [Retrieve a UCC Complaint](#retrieve-a-ucc-complaint) when in doubt.
* Callbacks are the low-latency path, not the only path. Run a daily sweep of `GET /Ucc/?status=rejected&created_at__gte=...` so a missed callback never consumes your [5-business-day response window](/docs/voice/concepts/ucc-management#what-happens-if-i-dont-submit-valid-proof).

***

## Error Codes

| Code  | Description                                                                                                 | Solution                                                    |
| ----- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `400` | Invalid request — for example, uploading proof against an `accepted` complaint, or an unsupported file type | Check the error message; it names the parameter and the fix |
| `401` | Authentication failed                                                                                       | Verify your Auth ID and Auth Token                          |
| `404` | Complaint not found, or it belongs to another account                                                       | Check the `reference_id`                                    |
| `429` | Rate limited                                                                                                | Implement exponential backoff                               |

Error responses use the standard Plivo format:

```json theme={null}
{
  "api_id": "97ceeb52-58b6-11e1-86da-77300b68f8bb",
  "error": "Proof cannot be submitted while the complaint is in accepted state."
}
```

***

## Related Resources

* [UCC Management](/docs/voice/concepts/ucc-management) — the complaint process, deadlines, proof requirements, and escalation rules
* [India Calling Regulations](/docs/voice/concepts/india-calling) — number series rules and TRAI requirements
* [Signature Validation](/docs/voice/concepts/signature-validation) — validating the V3 signature on callbacks
