# Uscreen API

> Every Uscreen endpoint on Cotlet: inputs, JSON Schema, cURL, Python and Node.js examples and an example response for each call.

Source: https://cotlet.dev/docs/api/uscreen

Docs sections: [Get started](https://cotlet.dev/docs.md) · [REST API](https://cotlet.dev/docs/api.md) · [MCP](https://cotlet.dev/docs/mcp.md) · [SDKs & CLI](https://cotlet.dev/docs/sdks.md) · [Integrations](https://cotlet.dev/docs/integrations.md)

15 endpoints for Uscreen. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/uscreen`
- Connects with: Your own Uscreen admin account (store owner, or a team member who can open Content, Marketing and Community)
- Integration page: https://cotlet.dev/integrations/uscreen-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_videos` | read | Videos in your library with status, categories and release date. |
| `get_video` | read | One video: title, description, tags, categories, publication status and the collections it is in. |
| `list_collections` | read | Collections with status, categories and number of videos. |
| `get_collection` | read | A collection with its playlist in order: videos, dividers and drip days. |
| `list_live_events` | read | Live events with start time, streaming method and status. |
| `get_content_analytics` | read | Views, watch time and completion for videos, live events or collections in a period. |
| `list_community_channels` | read | Channels of your community with ID, name and whether they are public or private. |
| `upload_video` | write | Upload a video file from a URL. It is saved unpublished and processed by Uscreen. |
| `update_video` | write | Change the title, description, tags or categories of a video. |
| `publish_video` | write | Publish a video now or schedule its release, optionally emailing members. |
| `create_collection` | write | New collection from uploaded videos, saved unpublished. |
| `set_collection_playlist` | write | Replace the playlist of a collection: video order, dividers and drip days. |
| `create_live_event` | write | Create a live event; for RTMP it returns the stream URL and stream key. |
| `create_coupon` | write | New coupon code with a discount, target, limits and expiry. |
| `create_community_post` | write | Post as you in a community channel, now or at a set time. |

## List videos

`POST https://cotlet.dev/api/v1/uscreen/list_videos`

Access: read.

Returns videos with their publication status, categories and, for scheduled videos, the release date. A video that is still processing is marked as such. Uscreen processes a new upload for 10 minutes to 72 hours. Videos without a category are listed but stay out of the catalog.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `status` | enum | no | published, unpublished or scheduled. Empty: all. |
| `search` | string | no | Match on title. |
| `limit` | integer | no | Maximum videos to return. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/list_videos \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("uscreen", "list_videos")
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'list_videos');
```

**CLI**

```bash
cotlet call uscreen list_videos
```

### Example response

```json
{
  "videos": [
    {
      "video_id": "2390417",
      "title": "Mobility Basics 1: Ankles",
      "status": "unpublished",
      "category_ids": [
        "48211"
      ],
      "processing": false
    },
    {
      "video_id": "2390418",
      "title": "Mobility Basics 2: Hips",
      "status": "scheduled",
      "release_at": "2026-11-02T07:00:00-05:00",
      "category_ids": [
        "48211"
      ],
      "processing": false
    }
  ],
  "next_cursor": null
}
```

## Get video

`POST https://cotlet.dev/api/v1/uscreen/get_video`

Access: read.

Returns the details shown on the video page in Uscreen. If the video is scheduled, it includes the release date and whether it shows as Coming Soon. It also lists the collections that contain the video, because one video can sit in several.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `video_id` | string | yes | Video ID from list_videos. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/get_video \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video_id":"video_8c41d2"}'
```

**Python**

```python
result = client.call("uscreen", "get_video", {"video_id":"video_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'get_video', {"video_id":"video_8c41d2"});
```

**CLI**

```bash
cotlet call uscreen get_video --data '{"video_id":"video_8c41d2"}'
```

### Example response

```json
{
  "video_id": "2390417",
  "title": "Mobility Basics 1: Ankles",
  "description": "A 12 minute ankle mobility routine.",
  "status": "unpublished",
  "category_ids": [
    "48211"
  ],
  "tags": [
    "mobility",
    "beginner"
  ],
  "collection_ids": [
    "118204"
  ]
}
```

## List collections

`POST https://cotlet.dev/api/v1/uscreen/list_collections`

Access: read.

Returns each collection with its publication status, categories and video count. A collection appears in the catalog only when it is published and has a category.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `search` | string | no | Match on title. |
| `limit` | integer | no | Maximum collections to return. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/list_collections \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("uscreen", "list_collections")
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'list_collections');
```

**CLI**

```bash
cotlet call uscreen list_collections
```

### Example response

```json
{
  "collections": [
    {
      "collection_id": "118204",
      "title": "Mobility Basics",
      "status": "unpublished",
      "category_ids": [
        "48211"
      ],
      "video_count": 2
    }
  ],
  "next_cursor": null
}
```

## Get collection

`POST https://cotlet.dev/api/v1/uscreen/get_collection`

Access: read.

Returns the playlist in the order viewers see it, with section dividers and the drip delay of each video. It also returns the collection access, gated or free, because drip only works on gated collections.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `collection_id` | string | yes | Collection ID from list_collections. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/get_collection \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"collection_id":"collection_8c41d2"}'
```

**Python**

```python
result = client.call("uscreen", "get_collection", {"collection_id":"collection_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'get_collection', {"collection_id":"collection_8c41d2"});
```

**CLI**

```bash
cotlet call uscreen get_collection --data '{"collection_id":"collection_8c41d2"}'
```

### Example response

```json
{
  "collection_id": "118204",
  "title": "Mobility Basics",
  "status": "unpublished",
  "access": "gated",
  "items": [
    {
      "divider": "Week 1"
    },
    {
      "video_id": "2390417",
      "title": "Mobility Basics 1: Ankles",
      "drip_days": 0
    },
    {
      "divider": "Week 2"
    },
    {
      "video_id": "2390418",
      "title": "Mobility Basics 2: Hips",
      "drip_days": 7
    }
  ]
}
```

## List live events

`POST https://cotlet.dev/api/v1/uscreen/list_live_events`

Access: read.

Returns each live event with its start time, streaming method (Live Studio, RTMP or Zoom), publication status and whether preregistration is on. It never returns a stream key; create_live_event does that once.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `search` | string | no | Match on title. |
| `limit` | integer | no | Maximum events to return. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/list_live_events \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("uscreen", "list_live_events")
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'list_live_events');
```

**CLI**

```bash
cotlet call uscreen list_live_events
```

### Example response

```json
{
  "events": [
    {
      "event_id": "77310",
      "title": "Thursday Q&A",
      "start_at": "2026-11-05T18:00:00-05:00",
      "method": "rtmp",
      "status": "published",
      "preregistration": true
    }
  ],
  "next_cursor": null
}
```

## Get content analytics

`POST https://cotlet.dev/api/v1/uscreen/get_content_analytics`

Access: read.

Returns the totals for the period and one row per item, most views first, matching the Content Analytics reports in Uscreen. Video rows include viewers, watch time and completion rate. Live event rows include preregistered, attendees and replays. Offline viewing is not tracked by Uscreen, so it is not counted.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `report` | enum | yes | videos, live_events or collections. |
| `from` | date | yes | First day of the period. |
| `to` | date | yes | Last day of the period. |
| `limit` | integer | no | Items to return, most views first. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/get_content_analytics \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"report":"videos","from":"2026-10-01","to":"2026-10-01"}'
```

**Python**

```python
result = client.call("uscreen", "get_content_analytics", {"report":"videos","from":"2026-10-01","to":"2026-10-01"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'get_content_analytics', {"report":"videos","from":"2026-10-01","to":"2026-10-01"});
```

**CLI**

```bash
cotlet call uscreen get_content_analytics --data '{"report":"videos","from":"2026-10-01","to":"2026-10-01"}'
```

### Example response

```json
{
  "report": "videos",
  "from": "2026-10-01",
  "to": "2026-10-31",
  "totals": {
    "views": 1840,
    "viewers": 612
  },
  "rows": [
    {
      "video_id": "2390417",
      "title": "Mobility Basics 1: Ankles",
      "views": 412,
      "viewers": 301,
      "total_watch_time": "71h 20m",
      "completion_rate": "64%"
    },
    {
      "video_id": "2390418",
      "title": "Mobility Basics 2: Hips",
      "views": 366,
      "viewers": 280,
      "total_watch_time": "58h 05m",
      "completion_rate": "59%"
    },
    {
      "video_id": "2390422",
      "title": "Warm-up Flow",
      "views": 301,
      "viewers": 254,
      "total_watch_time": "40h 10m",
      "completion_rate": "71%"
    }
  ]
}
```

## List community channels

`POST https://cotlet.dev/api/v1/uscreen/list_community_channels`

Access: read.

Returns every channel the signed-in admin can see, including private ones. Channel names are lowercase, with hyphens or underscores instead of spaces. The default general channel is always public.

### Parameters

No parameters.

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/list_community_channels \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("uscreen", "list_community_channels")
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'list_community_channels');
```

**CLI**

```bash
cotlet call uscreen list_community_channels
```

### Example response

```json
{
  "channels": [
    {
      "channel_id": "ch_general",
      "name": "general",
      "visibility": "public"
    },
    {
      "channel_id": "ch_announcements",
      "name": "announcements",
      "visibility": "public"
    }
  ]
}
```

## Upload video

`POST https://cotlet.dev/api/v1/uscreen/upload_video`

Access: write.

Cotlet downloads the file and uploads it to Content > Videos, then sets the video to Unpublished. Uscreen then transcodes it, which takes 10 minutes to 72 hours depending on size, bit rate and format; the response says processing until it is ready. Files over 8 Mbps or outside MP4 with H.264 can cause playback problems or slow processing. It reaches no one, because the video stays unpublished until publish_video, so it runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `file_url` | string | yes | Public or signed URL of an MP4 file, H.264, 16:9 recommended. |
| `title` | string | yes | Video title. |
| `description` | string | no | Shown on the video page. |
| `category_ids` | string[] | no | Categories it appears under. Without one it stays out of the catalog. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/upload_video \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_url":"https://example.com","title":"title"}'
```

**Python**

```python
result = client.call("uscreen", "upload_video", {"file_url":"https://example.com","title":"title"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'upload_video', {"file_url":"https://example.com","title":"title"});
```

**CLI**

```bash
cotlet call uscreen upload_video --data '{"file_url":"https://example.com","title":"title"}'
```

### Example response

```json
{
  "video_id": "2390417",
  "title": "Mobility Basics 1: Ankles",
  "status": "unpublished",
  "processing": true,
  "category_ids": [
    "48211"
  ]
}
```

## Update video

`POST https://cotlet.dev/api/v1/uscreen/update_video`

Access: write.

Changes only the fields you send and returns the previous values, so one more call restores them. Tags replace the whole tag list. A published video shows the new text to members at once. It runs without asking because it sends nothing to anyone and one call undoes it.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `video_id` | string | yes | Video ID from list_videos. |
| `fields` | object | yes | Any of title, description, tags, category_ids. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/update_video \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video_id":"video_8c41d2","fields":"fields"}'
```

**Python**

```python
result = client.call("uscreen", "update_video", {"video_id":"video_8c41d2","fields":"fields"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'update_video', {"video_id":"video_8c41d2","fields":"fields"});
```

**CLI**

```bash
cotlet call uscreen update_video --data '{"video_id":"video_8c41d2","fields":"fields"}'
```

### Example response

```json
{
  "video_id": "2390417",
  "updated": [
    "title",
    "tags"
  ],
  "previous": {
    "title": "Ankles",
    "tags": [
      "mobility"
    ]
  }
}
```

## Publish or schedule video

`POST https://cotlet.dev/api/v1/uscreen/publish_video`

Access: write. Confirm: waits for the user's OK before it runs.

Sets Visibility to Published, or to Scheduled when release_at is given. Uscreen releases at the time in your store time zone (Settings > General), so Cotlet converts the offset you send. The video needs a category to appear in the catalog, and it stays out of the catalog until Uscreen finishes processing it. With send_email, the broadcast reaches every member with access. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `video_id` | string | yes | Video ID from list_videos. |
| `release_at` | datetime | no | ISO 8601 with offset. Empty: publish now. |
| `send_email` | boolean | no | Email all members with access when it goes live. Default: false. |
| `show_coming_soon` | boolean | no | Show it as Coming Soon in the catalog until release. Default: true. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/publish_video \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video_id":"2390417","release_at":"2026-11-02T07:00:00-05:00","send_email":true,"show_coming_soon":true}'
```

**Python**

```python
result = client.call("uscreen", "publish_video", {"video_id":"2390417","release_at":"2026-11-02T07:00:00-05:00","send_email":True,"show_coming_soon":True})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'publish_video', {"video_id":"2390417","release_at":"2026-11-02T07:00:00-05:00","send_email":true,"show_coming_soon":true});
```

**CLI**

```bash
cotlet call uscreen publish_video --data '{"video_id":"2390417","release_at":"2026-11-02T07:00:00-05:00","send_email":true,"show_coming_soon":true}'
```

### Example response

```json
{
  "video_id": "2390417",
  "status": "scheduled",
  "release_at": "2026-11-02T07:00:00-05:00",
  "show_coming_soon": true,
  "send_email": true
}
```

## Create collection

`POST https://cotlet.dev/api/v1/uscreen/create_collection`

Access: write.

Creates the collection in Content > Collections and adds the videos to its playlist. It stays unpublished, so it reaches no one, and it runs without asking; publish it in Uscreen when it is ready. Uscreen advises keeping a collection under 50 videos. Pricing and access keep their defaults, so check them before you publish.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `title` | string | yes | Collection title. |
| `description` | string | no | Shown on the collection home page. |
| `video_ids` | string[] | no | Videos to add, in order. They must already be uploaded. |
| `category_ids` | string[] | no | Categories it appears under. Without one it stays out of the catalog. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/create_collection \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"title"}'
```

**Python**

```python
result = client.call("uscreen", "create_collection", {"title":"title"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'create_collection', {"title":"title"});
```

**CLI**

```bash
cotlet call uscreen create_collection --data '{"title":"title"}'
```

### Example response

```json
{
  "collection_id": "118204",
  "title": "Mobility Basics",
  "status": "unpublished",
  "video_count": 2,
  "category_ids": [
    "48211"
  ]
}
```

## Set collection playlist

`POST https://cotlet.dev/api/v1/uscreen/set_collection_playlist`

Access: write.

Replaces the whole playlist with the order you send and returns the previous one, so one more call restores it. Drip delays are days after a viewer first opens the collection, and Uscreen unlocks each video about every 2 hours after that delay. It is rejected if drip_days is set on a collection with free access. It runs without asking because members only see a change once the collection is published.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `collection_id` | string | yes | Collection ID from list_collections. |
| `items` | object[] | yes | Ordered list of { video_id, drip_days } or { divider: "Week 1" }. drip_days needs Gated access. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/set_collection_playlist \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"collection_id":"118204","items":[{"divider":"Week 1"},{"video_id":"2390417","drip_days":0},{"divider":"Week 2"},{"video_id":"2390418","drip_days":7}]}'
```

**Python**

```python
result = client.call("uscreen", "set_collection_playlist", {"collection_id":"118204","items":[{"divider":"Week 1"},{"video_id":"2390417","drip_days":0},{"divider":"Week 2"},{"video_id":"2390418","drip_days":7}]})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'set_collection_playlist', {"collection_id":"118204","items":[{"divider":"Week 1"},{"video_id":"2390417","drip_days":0},{"divider":"Week 2"},{"video_id":"2390418","drip_days":7}]});
```

**CLI**

```bash
cotlet call uscreen set_collection_playlist --data '{"collection_id":"118204","items":[{"divider":"Week 1"},{"video_id":"2390417","drip_days":0},{"divider":"Week 2"},{"video_id":"2390418","drip_days":7}]}'
```

### Example response

```json
{
  "collection_id": "118204",
  "title": "Mobility Basics",
  "status": "unpublished",
  "access": "gated",
  "playlist_items": 4,
  "videos": 2,
  "dividers": 2
}
```

## Create live event

`POST https://cotlet.dev/api/v1/uscreen/create_live_event`

Access: write. Confirm: waits for the user's OK before it runs.

Creates the event in Content > Live Streaming. For rtmp the response includes the stream URL and the stream key once; paste both into OBS or similar software, and keep the key private. Live Studio and RTMP events count against your plan's live streaming hours. Purchase and access options stay at their defaults, so check them before the event. Published events are visible to members, and with preregistration on, the event shows a countdown. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `title` | string | yes | Event title. |
| `start_at` | datetime | yes | ISO 8601 with offset. |
| `method` | enum | yes | live_studio, rtmp or zoom. |
| `description` | string | no | Shown on the event page. |
| `category_ids` | string[] | no | Categories it appears under. Without one it stays out of the catalog. |
| `preregistration` | boolean | no | Let viewers register before it starts. Default: false. |
| `live_chat` | boolean | no | Turn on live chat. Default: false. |
| `publish` | boolean | no | Set Visibility to Published. Default: false, saved unpublished. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/create_live_event \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Thursday Q&A","start_at":"2026-11-05T18:00:00-05:00","method":"rtmp","live_chat":true,"preregistration":true,"publish":true}'
```

**Python**

```python
result = client.call("uscreen", "create_live_event", {"title":"Thursday Q&A","start_at":"2026-11-05T18:00:00-05:00","method":"rtmp","live_chat":True,"preregistration":True,"publish":True})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'create_live_event', {"title":"Thursday Q&A","start_at":"2026-11-05T18:00:00-05:00","method":"rtmp","live_chat":true,"preregistration":true,"publish":true});
```

**CLI**

```bash
cotlet call uscreen create_live_event --data '{"title":"Thursday Q&A","start_at":"2026-11-05T18:00:00-05:00","method":"rtmp","live_chat":true,"preregistration":true,"publish":true}'
```

### Example response

```json
{
  "event_id": "77310",
  "title": "Thursday Q&A",
  "start_at": "2026-11-05T18:00:00-05:00",
  "method": "rtmp",
  "status": "published",
  "preregistration": true,
  "live_chat": true,
  "stream_url": "rtmp://live.example.com/app",
  "stream_key": "sk_example_4f9a21"
}
```

## Create coupon

`POST https://cotlet.dev/api/v1/uscreen/create_coupon`

Access: write. Confirm: waits for the user's OK before it runs.

Creates the coupon in Marketing > Coupons. The code and the discount cannot be changed afterwards; a wrong code means deleting the coupon and creating a new one. The expiry only stops new redemptions and leaves discounts already applied. It changes what members pay, so it asks first. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `code` | string | yes | Letters and numbers only, no spaces. |
| `discount_type` | enum | yes | fixed or percentage. |
| `value` | number | yes | Percent off, or the fixed amount in the currency the coupon is denominated in. |
| `applies_to` | enum | yes | all_products, subscription, bundles or content. |
| `offer_ids` | string[] | no | Plans, bundles or content it applies to. Not used with all_products. |
| `duration` | enum | no | Subscription coupons only: once, forever or repeating. Default: once. |
| `duration_periods` | integer | no | Billing periods, when duration is repeating. |
| `expires_on` | date | no | Last day the code can be redeemed. |
| `redemption_limit` | integer | no | Most users who can redeem it. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/create_coupon \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"code","discount_type":"fixed","value":1,"applies_to":"all_products"}'
```

**Python**

```python
result = client.call("uscreen", "create_coupon", {"code":"code","discount_type":"fixed","value":1,"applies_to":"all_products"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'create_coupon', {"code":"code","discount_type":"fixed","value":1,"applies_to":"all_products"});
```

**CLI**

```bash
cotlet call uscreen create_coupon --data '{"code":"code","discount_type":"fixed","value":1,"applies_to":"all_products"}'
```

### Example response

```json
{
  "coupon_id": "55102",
  "code": "SPRING30",
  "discount": "30% off",
  "applies_to": "subscription",
  "duration": "once",
  "expires_on": "2027-04-30",
  "redemption_limit": 200,
  "status": "active"
}
```

## Create community post

`POST https://cotlet.dev/api/v1/uscreen/create_community_post`

Access: write. Confirm: waits for the user's OK before it runs.

Posts from your admin account in the channel you name, now or scheduled. Members who can see the channel see it in the feed. Large images can take a while and may time out after about a minute. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `channel_id` | string | yes | Channel ID from list_community_channels. |
| `body` | string | yes | Post text. |
| `image_url` | string | no | Attach one image by URL: jpeg, png, webp or gif. |
| `publish_at` | datetime | no | ISO 8601 with offset. Empty: post now. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/uscreen/create_community_post \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel_id":"channel_8c41d2","body":"body"}'
```

**Python**

```python
result = client.call("uscreen", "create_community_post", {"channel_id":"channel_8c41d2","body":"body"})
```

**Node.js**

```js
const result = await cotlet.call('uscreen', 'create_community_post', {"channel_id":"channel_8c41d2","body":"body"});
```

**CLI**

```bash
cotlet call uscreen create_community_post --data '{"channel_id":"channel_8c41d2","body":"body"}'
```

### Example response

```json
{
  "post_id": "p_90417",
  "channel_id": "ch_announcements",
  "status": "published"
}
```
