# Manage protected content by API and AI tools

> Read your protected content and its buyers, and change its status, title and access rules through the BCL API or an AI agent over MCP.
>
> Source: https://docs.bcl.my/protected-content-api/

You can manage protected content from your own system or an AI assistant. The BCL API and the BCL MCP server list your content, show who has access, and change a content's status, title and access rules. Creating content, uploading files and linking content to items are done in the dashboard.

## Before you start

You need an API token. Create one under **Platform Setup** → **Integrations**, on the **API Token** tab. See [Create an API token](/api-tokens/).

| Use | Token permissions |
|---|---|
| Read content and buyers by API | **API Read** |
| Change content by API | **API Write** |
| AI agent through MCP | **MCP Read**, and **MCP Write** to make changes |

Send these headers with every API request:

- `Authorization: Bearer <your token>`
- `Accept: application/json`
- A `User-Agent` that names your app, such as `KopiKampung/1.0`. Requests with the default user agent of curl or Python are refused.

The base URL is `https://api.bcl.my/v1`. The API only sees the content of the team the token belongs to.

## API endpoints

These are the protected content endpoints:

| Method and path | What it does | Parameters |
|---|---|---|
| `GET /protected-contents` | Lists your content | `search` (title), `status` (`active`, `inactive`, `all`), `content_type` (`video`, `text`, `file`, `redirect`), `access_type` (`immediate`, `scheduled`, `duration`), `sort_by` (`title`, `created_at`, `updated_at`), `sort_order`, `page`, `per_page` (up to 100, default 15) |
| `GET /protected-contents/{id}` | One content with its settings and stats: buyers, accessible now, total views and downloads | - |
| `GET /protected-contents/{id}/customers` | The buyers who have access | `status` (`active`, `expired`, `revoked`, `all`), `page`, `per_page` |
| `PATCH /protected-contents/{id}/status` | Turns the content on or off | `is_active` (true or false) |
| `PATCH /protected-contents/{id}/title` | Renames the content, and optionally its name in the access email | `title` (required, up to 255 characters), `email_title` |
| `PATCH /protected-contents/{id}/access` | Changes the access rules | `access_type` (required); `scheduled_start_at` (required for `scheduled`), `scheduled_end_at`; `access_duration_days` (required for `duration`); `max_devices` (1 or more); `max_downloads`; `show_on_receipt` |

`{id}` is the content ID from the list, the same code that appears in the content's dashboard address. Each content in the responses has an `access_url`: the content's Access Finder link.

For example, to switch off a content:

```sh
curl -X PATCH "https://api.bcl.my/v1/protected-contents/7XBRVXK4/status" \
  -A "KopiKampung/1.0" \
  -H "Authorization: Bearer $BCL_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}'
```

A successful change returns `"success": true` with the new values. Sending a value that is already set returns HTTP 422, for example "The protected content is already inactive." An unknown ID returns 404 "Protected content not found".

## Things to know

Keep these limits in mind:

- **Access changes apply to new buyers.** Like the dashboard, `PATCH .../access` does not change the dates of people who already have access. Use **Sync Access Dates** on the content's **Customer Access** page afterwards.
- **`max_devices` must be 1 or more by API.** To allow unlimited devices, set **Maximum Devices** to 0 in the dashboard.
- **There is no endpoint to grant or revoke one buyer.** Use **Grant Buyer Access** and the other **Customer Access** actions in the dashboard.

## Use an AI agent (MCP)

The BCL MCP server lets AI assistants such as Claude, ChatGPT or Cursor work with your account. Set it up under **Platform Setup** → **Connect AI Agent**. These tools cover protected content:

| Tool | Needs | Does the same as |
|---|---|---|
| `list_protected_contents` | **MCP Read** | `GET /protected-contents` |
| `get_protected_content` | **MCP Read** | `GET /protected-contents/{id}` |
| `get_protected_content_customers` | **MCP Read** | `GET /protected-contents/{id}/customers` |
| `update_protected_content_status` | **MCP Write** | `PATCH .../status` |
| `update_protected_content_title` | **MCP Write** | `PATCH .../title` |
| `update_protected_content_access` | **MCP Write** | `PATCH .../access` |

You can then ask in plain words, for example "Which Kopi Kampung courses have the most buyers?" or "Turn off the Live Cupping Session content".

## Access links in webhooks and automations

When an order unlocks protected content, the payment webhook lists it under each item's `protected_content`, with the content title, the buyer's access link (`url`) and the `access_finder_url`. Automations have matching variables, so you can send the buyer's access link by WhatsApp. See [Payment form webhook](/webhook-payment-form/).

## Common issues

### Can I create protected content through the API?

Not yet. The API and MCP tools read content and buyers, and change status, title and access settings. Create the content and link it to items in the BCL dashboard.

### Can my system find out who has access to a course?

Yes. Call GET /protected-contents/{id}/customers. It returns each buyer's name, email, phone, order number, status, access dates, views and downloads.

### Can I ask an AI assistant to switch my content off after a promotion ends?

Yes. Connect the assistant to BCL through MCP with a token that has MCP Write, and ask it. It uses the update_protected_content_status tool.
