AIOZ Stream API Skill
Interact with the AIOZ Stream API — a Web3 decentralized streaming platform — using the user's API key pair.
Base URL: https://api.aiozstream.network/api
Credential Collection
Before performing any API action, Clawbot must collect the user's API credentials if they have not already been provided. Clawbot should prompt the user with two separate open-ended text input fields:
- AIOZ Stream Public Key — Ask: "Please enter your AIOZ Stream Public Key:"
- AIOZ Stream Secret Key — Ask: "Please enter your AIOZ Stream Secret Key:" Rules:
- Use open-ended text input (not dropdowns or multiple choice) so the user can type or paste their actual key values.
- Do not proceed with any API call until both keys have been provided.
- Store them in session as
$AIOZ_PUBLIC_KEYand$AIOZ_SECRET_KEYfor use in all subsequent requests. - Remind the user: "Keep your keys safe — treat them like passwords and consider rotating them after this session."
Authentication
Every request must include these two headers:
stream-public-key: $AIOZ_PUBLIC_KEY
stream-secret-key: $AIOZ_SECRET_KEY
Helper function for all curl calls:
AIOZ_HEADERS=(
-H "stream-public-key: ${AIOZ_PUBLIC_KEY}"
-H "stream-secret-key: ${AIOZ_SECRET_KEY}"
)
How Clawbot Should Respond to Upload Actions
When Clawbot performs any upload or encoding action on behalf of the user, it must use the following response templates exactly. These are not optional — they define how Clawbot communicates status back to the user at every stage.
📤 During Upload — Chunked Upload Progress
While uploading chunks, Clawbot must display a live progress block after each successful chunk:
## 📤 Uploading: {title}
Progress: {bar} {percent}% ({done} of {total} chunks)
| Chunk | Size | MD5 Status | Upload Status |
|-------|--------|------------|---------------|
| 0 | 50 MB | ✅ Valid | ✅ Done |
| 1 | 50 MB | ✅ Valid | ✅ Done |
| 2 | 50 MB | ✅ Valid | ✅ Done |
| 3 | 50 MB | ✅ Valid | ✅ Done |
| 4 | 10 MB | ✅ Valid | ⏳ Uploading |
> ⚠️ Clawbot will only call `/complete` after **all chunks** succeed.
- Replace
{title}with the actual media title. - Replace
{bar}with a Unicode progress bar (e.g.,████████░░). - Replace
{percent},{done},{total}with real values. - Show ✅ for completed chunks, ⏳ for the current one, ❌ for failed ones.
✅ After /media/:id/complete — Upload Complete
When /complete returns successfully, Clawbot must respond with:
## 🎉 Upload Complete!
Your media has been successfully uploaded and is now being processed.
| Field | Value |
|--------------|------------------------|
| **Media ID** | {media_id} |
| **Title** | {title} |
| **Type** | {type} |
| **Status** | `transcoding` |
| **Uploaded** | {timestamp} UTC |
### ⏳ What's Next?
Transcoding is in progress. You will be notified via webhook once encoding is finished.
> Estimated time depends on media length and selected quality presets.
📡 Webhook Response Templates
When Clawbot receives or reports on a webhook event, it must use the matching template below.
file_received
## 📥 File Received
Your file has been received by the server and is queued for transcoding.
| Field | Value |
|---------------|---------------------|
| **Media ID** | {media_id} |
| **Title** | {title} |
| **Event** | `file_received` |
| **Status** | `new` |
| **Timestamp** | {timestamp} UTC |
> Transcoding will begin shortly.
encoding_started
## ⚙️ Encoding Started
Your media is now being transcoded.
| Field | Value |
|---------------|---------------------|
| **Media ID** | {media_id} |
| **Title** | {title} |
| **Event** | `encoding_started` |
| **Status** | `transcoding` |
| **Timestamp** | {timestamp} UTC |
> Please wait while your media is being processed across all selected quality presets.
partial_finished
## 🔄 Partial Quality Ready
One quality preset has finished encoding and is available for streaming.
| Field | Value |
|---------------|---------------------|
| **Media ID** | {media_id} |
| **Title** | {title} |
| **Event** | `partial_finished` |
| **Status** | `transcoding` |
| **Timestamp** | {timestamp} UTC |
> Remaining quality presets are still processing. Full availability coming soon.
encoding_finished
## ✅ Encoding Finished — Media is Live!
| Field | Value |
|---------------|----------------------|
| **Media ID** | {media_id} |
| **Title** | {title} |
| **Event** | `encoding_finished` |
| **Status** | `done` |
| **Timestamp** | {timestamp} UTC |
### 🔗 Your media is ready to stream!
**HLS**
- Stream URL: `https://api.aiozstream.network/api/media/{media_id}/manifest.m3u8`
- Player URL: `https://embed.aiozstream.network/vod/hls/{media_id}`
- Embed: `<iframe src="https://embed.aiozstream.network/vod/hls/{media_id}" width="100%" height="100%" frameborder="0" scrolling="no" allowfullscreen="true"></iframe>`
**DASH**
- Stream URL: `https://api.aiozstream.network/api/media/{media_id}/manifest`
- Player URL: `https://embed.aiozstream.network/vod/dash/{media_id}`
- Embed: `<iframe src="https://embed.aiozstream.network/vod/dash/{media_id}" width="100%" height="100%" frameborder="0" scrolling="no" allowfullscreen="true"></iframe>`
**Other**
- Thumbnail: `https://api.aiozstream.network/api/media/{media_id}/thumbnail?resolution=original`
- MP4: `https://api.aiozstream.network/api/media/{media_id}/mp4`
- Source: `https://api.aiozstream.network/api/media/{media_id}/source`
### 🛠️ Suggested Next Steps
- [ ] Assign a Player Theme → ask Clawbot: "assign a player to my video"
- [ ] Add Chapters → ask Clawbot: "add chapters to my video"
- [ ] Add Subtitles → ask Clawbot: "add subtitles to my video"
- [ ] Add to a Playlist → ask Clawbot: "add my video to a playlist"
- [ ] Review Analytics → ask Clawbot: "show me analytics for my video"
encoding_failed
## ❌ Encoding Failed
Something went wrong during transcoding.
| Field | Value |
|---------------|---------------------|
| **Media ID** | {media_id} |
| **Title** | {title} |
| **Event** | `encoding_failed` |
| **Status** | `fail` |
| **Timestamp** | {timestamp} UTC |
### ⚠️ How to Retry
Clawbot will automatically guide you through the following steps:
1. Delete the failed media object → `DELETE /media/{media_id}`
2. Re-create the media object → `POST /media/create`
3. Check transcode cost before retrying → `GET /media/cost` (verify `is_enough: true`)
4. Re-upload all chunks → `POST /media/:id/part` (one per chunk with MD5)
5. Signal completion → `GET /media/:id/complete`
> Ask Clawbot: "retry my failed upload" to start the process automatically.
🔔 Webhook Event Quick Reference
| Event | Status After | Clawbot Response |
|---|---|---|
file_received | new | 📥 File received, queuing transcode… |
encoding_started | transcoding | ⚙️ Encoding started… |
partial_finished | transcoding | 🔄 Partial quality preset ready |
encoding_finished | done | ✅ Your media is ready to stream! |
encoding_failed | fail | ❌ Encoding failed. Clawbot will guide you through a retry. |
1. VIDEO MANAGEMENT
Create a video object
curl -s -X POST "https://api.aiozstream.network/api/media/create" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"title": "My Video",
"type": "video",
"description": "optional",
"is_public": true,
"tags": ["tag1"],
"metadata": [{"key": "genre", "value": "rock"}],
"qualities": [
{
"resolution": "1080p",
"type": "hls",
"container_type": "mpegts",
"video_config": { "codec": "h264", "bitrate": 5000000, "index": 0 },
"audio_config": { "codec": "aac", "bitrate": 192000, "channels": "2", "sample_rate": 48000, "language": "en", "index": 0 }
}
]
}'
Rules:
typemust be"video"(required)- Supported resolutions:
240p,360p,480p,720p,1080p,1440p,2160p,4320p - Video codecs:
h264(max 4K),h265(max 8K) - ⚠️ H.265 on Apple (Safari/iOS): must use
container_type: "fmp4", NOT"mpegts" - If
qualitiesis omitted, the server applies default encoding
Before creating a video with custom qualities, Clawbot must check transcode cost first:
curl -s "https://api.aiozstream.network/api/media/cost?type=video&duration=60&qualities=360p,1080p" \
"${AIOZ_HEADERS[@]}"
# Returns: { "price": 1.23, "is_enough": true }
# Only proceed if is_enough is true
If is_enough is false, Clawbot must inform the user:
⚠️ Your account balance is insufficient to transcode with the requested quality presets. Please top up your AIOZ wallet before proceeding.
List / Search videos
curl -s -X POST "https://api.aiozstream.network/api/media" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"type": "video",
"limit": 25,
"offset": 0,
"sort_by": "created_at",
"order_by": "desc",
"search": "keyword",
"status": "done",
"tags": "tag1,tag2",
"metadata": {"genre": "rock"}
}'
status options: new, transcoding, done, fail, deleted
Get video detail
curl -s "https://api.aiozstream.network/api/media/${VIDEO_ID}" \
"${AIOZ_HEADERS[@]}"
Upload video (chunked — 50MB–200MB per chunk)
Step 1 — Upload each chunk:
# For each chunk (0-indexed):
CHUNK_INDEX=0
CHUNK_START=0
CHUNK_END=52428799 # end byte (inclusive)
TOTAL_SIZE=104857600
CHUNK_MD5=$(md5sum chunk_file | awk '{print $1}')
curl -s -X POST "https://api.aiozstream.network/api/media/${VIDEO_ID}/part" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Range: bytes ${CHUNK_START}-${CHUNK_END}/${TOTAL_SIZE}" \
-F "file=@chunk_file" \
-F "index=${CHUNK_INDEX}" \
-F "hash=${CHUNK_MD5}"
Step 2 — Signal completion (after ALL chunks uploaded):
curl -s "https://api.aiozstream.network/api/media/${VIDEO_ID}/complete" \
"${AIOZ_HEADERS[@]}"
⚠️ Clawbot must always compute the correct MD5 hash per chunk. Call
/completeonly after all chunks succeed.
Update video info
curl -s -X PATCH "https://api.aiozstream.network/api/media/${VIDEO_ID}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"title": "New Title",
"description": "...",
"is_public": true,
"tags": ["tag1"],
"metadata": [{"key": "k", "value": "v"}],
"player_theme_id": "optional"
}'
Upload video thumbnail
curl -s -X POST "https://api.aiozstream.network/api/media/${VIDEO_ID}/thumbnail" \
"${AIOZ_HEADERS[@]}" \
-F "file=@thumbnail.png"
# File must be .png or .jpg
Delete video
curl -s -X DELETE "https://api.aiozstream.network/api/media/${VIDEO_ID}" \
"${AIOZ_HEADERS[@]}"
2. AUDIO MANAGEMENT
Audio uses the same endpoints as video but with type: "audio". Key differences:
resolutionuses presets:standard,good,highest,lossless- Only
audio_configis needed (novideo_config) - Response does not include
mp4_url
Create an audio object
curl -s -X POST "https://api.aiozstream.network/api/media/create" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"title": "My Podcast",
"type": "audio",
"qualities": [
{
"resolution": "highest",
"type": "hls",
"container_type": "mpegts",
"audio_config": { "codec": "aac", "bitrate": 320000, "channels": "2", "sample_rate": 44100, "language": "en", "index": 0 }
}
]
}'
Calculate audio transcode price
curl -s "https://api.aiozstream.network/api/media/cost?type=audio&duration=60&qualities=highest,standard" \
"${AIOZ_HEADERS[@]}"
All other operations (list, detail, upload part, complete, update, delete) use the same endpoints as video, with AUDIO_ID in place of VIDEO_ID.
3. MEDIA CHAPTERS
Chapters are stored per language in .vtt format. Each (media_id, language) pair holds at most one chapter.
lan accepts BCP 47 tags: en, vi, en-US, fr-CA, etc.
Add chapter
curl -s -X POST "https://api.aiozstream.network/api/media/${MEDIA_ID}/chapters/${LAN}" \
"${AIOZ_HEADERS[@]}" \
-F "file=@chapters.vtt"
List chapters
curl -s "https://api.aiozstream.network/api/media/${MEDIA_ID}/chapters?offset=0&limit=10" \
"${AIOZ_HEADERS[@]}"
Delete chapter
curl -s -X DELETE "https://api.aiozstream.network/api/media/${MEDIA_ID}/chapters/${LAN}" \
"${AIOZ_HEADERS[@]}"
4. MEDIA TRANSCRIPTS (Subtitles / Captions)
Transcripts are .vtt files, one per language per media. Can be set as default for the player.
⚠️ If a transcript for the same primary language already exists, the request will be rejected. Clawbot must inform the user and ask if they want to delete the existing one first.
Add transcript
curl -s -X POST "https://api.aiozstream.network/api/media/${MEDIA_ID}/transcripts/${LAN}" \
"${AIOZ_HEADERS[@]}" \
-F "file=@transcript.vtt"
List transcripts
curl -s "https://api.aiozstream.network/api/media/${MEDIA_ID}/transcripts?offset=0&limit=10" \
"${AIOZ_HEADERS[@]}"
Set default transcript
curl -s -X PATCH "https://api.aiozstream.network/api/media/${MEDIA_ID}/transcripts/${LAN}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{"is_default": true}'
Delete transcript
curl -s -X DELETE "https://api.aiozstream.network/api/media/${MEDIA_ID}/transcripts/${LAN}" \
"${AIOZ_HEADERS[@]}"
If the deleted transcript was the default, the system clears the default. Clawbot must remind the user to set a new default manually.
5. API KEY MANAGEMENT
Create API key
curl -s -X POST "https://api.aiozstream.network/api/api_keys" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"api_key_name": "my key",
"ttl": "100000000",
"type": "full_access"
}'
# type: "full_access" or "only_upload"
# ttl: seconds, max 2147483647
⚠️ The
secretis shown only once. Clawbot must immediately display it to the user and explicitly warn them it cannot be retrieved again.
List API keys
curl -s "https://api.aiozstream.network/api/api_keys?search=name&limit=25&offset=0&sort_by=created_at&order_by=asc" \
"${AIOZ_HEADERS[@]}"
Update API key name
curl -s -X PATCH "https://api.aiozstream.network/api/api_keys/${API_KEY_ID}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{"api_key_name": "new name"}'
Delete API key
curl -s -X DELETE "https://api.aiozstream.network/api/api_keys/${API_KEY_ID}" \
"${AIOZ_HEADERS[@]}"
6. USER INFO
Get current user
curl -s "https://api.aiozstream.network/api/user/me" \
"${AIOZ_HEADERS[@]}"
# Returns: id, first_name, last_name, email, wallet_address, balance, debt, etc.
7. WEBHOOKS
Events available: file_received, encoding_started, partial_finished, encoding_finished, encoding_failed
Create webhook
curl -s -X POST "https://api.aiozstream.network/api/webhooks" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"name": "my webhook",
"url": "https://your-server.com/hook",
"file_received": false,
"encoding_started": true,
"partial_finished": true,
"encoding_finished": true,
"encoding_failed": true
}'
List webhooks
curl -s "https://api.aiozstream.network/api/webhooks?limit=25&offset=0&sort_by=created_at&order_by=asc" \
"${AIOZ_HEADERS[@]}"
Get webhook detail
curl -s "https://api.aiozstream.network/api/webhooks/${WEBHOOK_ID}" \
"${AIOZ_HEADERS[@]}"
Update webhook
curl -s -X PATCH "https://api.aiozstream.network/api/webhooks/${WEBHOOK_ID}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://new-url.com",
"name": "updated name",
"encoding_started": false,
"encoding_finished": true,
"encoding_failed": true,
"partial_finished": true,
"file_received": false
}'
Test / trigger webhook
curl -s -X POST "https://api.aiozstream.network/api/webhooks/check/${WEBHOOK_ID}" \
"${AIOZ_HEADERS[@]}"
Clawbot must use
/webhooks/check/:idto verify a webhook URL is reachable before confirming it to the user.
Delete webhook
curl -s -X DELETE "https://api.aiozstream.network/api/webhooks/${WEBHOOK_ID}" \
"${AIOZ_HEADERS[@]}"
8. PLAYERS
Player themes allow full visual customization of the embedded player.
Color rule: all colors must be rgba(...) format.
Size rule: all sizes must be px format.
Clawbot must validate these before sending to the API and correct them if the user provides hex or named colors.
Create player theme
curl -s -X POST "https://api.aiozstream.network/api/players" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"name": "My Brand Player",
"theme": {
"main_color": "rgba(255, 0, 0, 1)",
"text_color": "rgba(255, 255, 255, 1)",
"control_bar_background_color": "rgba(0, 0, 0, 0.7)",
"menu_background_color": "rgba(30, 30, 30, 1)",
"menu_item_background_hover": "rgba(60, 60, 60, 1)",
"text_track_color": "rgba(255, 255, 255, 1)",
"text_track_background": "rgba(0, 0, 0, 0.5)",
"control_bar_height": "40px",
"progress_bar_height": "4px",
"progress_bar_circle_size": "12px"
}
}'
List player themes
curl -s "https://api.aiozstream.network/api/players?limit=25&offset=0&sort_by=created_at&order_by=asc&search=name" \
"${AIOZ_HEADERS[@]}"
Get player theme detail
curl -s "https://api.aiozstream.network/api/players/${PLAYER_THEME_ID}" \
"${AIOZ_HEADERS[@]}"
Update player theme
curl -s -X PATCH "https://api.aiozstream.network/api/players/${PLAYER_THEME_ID}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"name": "updated name",
"theme": { "main_color": "rgba(0, 128, 255, 1)" },
"controls": {
"enable_api": true,
"enable_controls": true,
"force_autoplay": false,
"hide_title": false,
"force_loop": false
},
"is_default": true
}'
# Setting is_default: true automatically clears is_default on all other players
# CDN propagation may take up to 10 minutes
Clawbot must warn the user: CDN propagation for player theme changes may take up to 10 minutes.
Upload player logo
curl -s -X POST "https://api.aiozstream.network/api/players/${PLAYER_THEME_ID}/logo" \
"${AIOZ_HEADERS[@]}" \
-F "file=@logo.png" \
-F "logo_link=https://yoursite.com"
# JPEG or PNG only, max 100KB, max 200×100px
Delete player logo
curl -s -X DELETE "https://api.aiozstream.network/api/players/${PLAYER_THEME_ID}/logo" \
"${AIOZ_HEADERS[@]}"
Assign player theme to video
curl -s -X POST "https://api.aiozstream.network/api/players/add-player" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{"video_id": "VIDEO_ID", "player_theme_id": "PLAYER_THEME_ID"}'
Delete player theme
curl -s -X DELETE "https://api.aiozstream.network/api/players/${PLAYER_THEME_ID}" \
"${AIOZ_HEADERS[@]}"
# Cannot delete if the player is currently assigned to a video
If the delete fails because the player is assigned to a video, Clawbot must inform the user and ask if they want to unassign it first.
9. ANALYTICS
All analytics endpoints are POST with time range in UNIX timestamps.
Clawbot must always convert human-readable dates provided by the user into UNIX timestamps before constructing requests.
Aggregated metrics (single number)
# metric: play, start, end, impression, watch_time, view
# aggregation: count, rate (play only), total, average, sum
curl -s -X POST "https://api.aiozstream.network/api/analytics/metrics/data/${METRIC}/${AGGREGATION}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"from": 1726001314,
"to": 1726201314,
"filter_by": {
"media_ids": ["id1", "id2"],
"media_type": "video",
"continents": ["AS", "EU"],
"countries": ["VN", "US"],
"device_types": ["computer", "phone"],
"os": ["windows", "android"],
"browsers": ["chrome", "firefox"],
"tags": ["tag1"]
}
}'
Breakdown by dimension
# metric: play, play_rate, start, end, impression, watch_time, retention, view
# breakdown: media-id, media-type, continent, country, device-type, operating-system, browser
curl -s -X POST "https://api.aiozstream.network/api/analytics/metrics/bucket/${METRIC}/${BREAKDOWN}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"from": 1726001314,
"to": 1726201314,
"limit": 100,
"offset": 0,
"sort_by": "metric_value",
"order_by": "desc",
"filter_by": {}
}'
Time series (metrics over time)
# interval: hour, day
curl -s -X POST "https://api.aiozstream.network/api/analytics/metrics/timeseries/${METRIC}/${INTERVAL}" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"from": 1726001314,
"to": 1726201314,
"limit": 100,
"offset": 0,
"sort_by": "metric_value",
"order_by": "desc",
"filter_by": {}
}'
10. PAYMENTS
Get usage statistics
curl -s "https://api.aiozstream.network/api/payment/usage?from=1714232234&to=1824232234" \
"${AIOZ_HEADERS[@]}"
# Returns: storage (bytes), delivery (bytes), transcode (seconds), and their costs
Get top-up history
curl -s "https://api.aiozstream.network/api/payment/top_ups?limit=10&offset=0&orderBy=desc&sortBy=created_at" \
"${AIOZ_HEADERS[@]}"
# transaction_id: on-chain tx hash viewable on AIOZ Explorer
# status: pending, success, failed
Get billing history
curl -s "https://api.aiozstream.network/api/payment/billings?limit=10&offset=0&orderBy=desc" \
"${AIOZ_HEADERS[@]}"
# Returns monthly breakdown: storage, delivery, transcode + costs
11. PLAYLISTS
Playlists use a linked-list structure internally (next_id / previous_id) for item ordering.
Clawbot must always fetch the playlist detail first before moving items to get accurate
next_id/previous_idvalues.
Create playlist
curl -s -X POST "https://api.aiozstream.network/api/playlists/create" \
"${AIOZ_HEADERS[@]}" \
-F "name=My Playlist" \
-F "tags=tag1,tag2" \
-F 'metadata={"key":"val"}'
List playlists
curl -s -X POST "https://api.aiozstream.network/api/playlists" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"limit": 10,
"offset": 0,
"sort_by": "name",
"order_by": "asc",
"search": "playlist name",
"tags": "tag1",
"metadata": {"key": "val"}
}'
Get playlist detail (with video items)
curl -s "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}?sort_by=created_at&order_by=asc" \
"${AIOZ_HEADERS[@]}"
# Omit sort_by/order_by to get items in their custom linked-list order
Update playlist
curl -s -X PATCH "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}" \
"${AIOZ_HEADERS[@]}" \
-F "name=New Name" \
-F "file=@thumbnail.jpg" \
-F "tags=tag1" \
-F 'metadata={"key":"val"}'
# file: optional thumbnail (.jpg, .jpeg, .png)
Add video to playlist
curl -s -X POST "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}/items" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{"video_id": "VIDEO_ID"}'
Move video position in playlist
curl -s -X PUT "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}/items" \
"${AIOZ_HEADERS[@]}" \
-H "Content-Type: application/json" \
-d '{
"current_id": "ITEM_TO_MOVE_ID",
"next_id": "ITEM_THAT_WILL_COME_AFTER",
"previous_id": "ITEM_THAT_WILL_COME_BEFORE"
}'
Positioning reference (current_id is always required):
- Move to top: set only
next_idto the current first item's ID - Move to bottom: set only
previous_idto the current last item's ID - Move between two items: set both
next_idandprevious_id
Remove video from playlist
curl -s -X DELETE "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}/items/${ITEM_ID}" \
"${AIOZ_HEADERS[@]}"
Delete playlist thumbnail
curl -s -X DELETE "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}/thumbnail" \
"${AIOZ_HEADERS[@]}"
Delete playlist
curl -s -X DELETE "https://api.aiozstream.network/api/playlists/${PLAYLIST_ID}" \
"${AIOZ_HEADERS[@]}"
Behavior Guidelines
Clawbot must follow these rules when operating this skill:
- Always include both auth headers (
stream-public-keyandstream-secret-key) on every request, including/user/me. - Chunked uploads: calculate chunk boundaries correctly. Each chunk needs its MD5. Call
/completeonly after all chunks succeed. Display the chunked upload progress template at each step. - Transcode cost check: before creating media with custom qualities, call
/media/costand verifyis_enough: true. Iffalse, block the action and notify the user to top up. - Player colors/sizes: validate that colors are in
rgba(...)format and sizes are inpx. If the user provides hex or named colors, convert them automatically and inform the user. - Analytics timestamps: always convert human-readable dates to UNIX timestamps silently before sending requests.
- Playlist ordering: always fetch playlist detail first to get accurate
next_id/previous_idbefore reordering items. - API key secret: immediately display the
secretto the user in full and warn explicitly that it cannot be retrieved again. - Webhook testing: always use
/webhooks/check/:idto verify a webhook URL is reachable before confirming it to the user. - H.265 on Apple devices: if the user selects
h265withmpegts, automatically warn them and suggest switching tofmp4for Safari/iOS compatibility. - Upload notifications: always use the response templates defined in this skill — never summarize upload events as plain text.
Quick Reference — Endpoints
| Module | Method | Path |
|---|---|---|
| Video | POST | /media/create |
| Video | POST | /media (list) |
| Video | GET | /media/:id |
| Video | GET | /media/cost |
| Video | POST | /media/:id/part |
| Video | GET | /media/:id/complete |
| Video | PATCH | /media/:id |
| Video | POST | /media/:id/thumbnail |
| Video | DELETE | /media/:id |
| Audio | — | (same paths as Video, type=audio) |
| Chapter | POST | /media/:id/chapters/:lan |
| Chapter | GET | /media/:id/chapters |
| Chapter | DELETE | /media/:id/chapters/:lan |
| Transcript | POST | /media/:id/transcripts/:lan |
| Transcript | GET | /media/:id/transcripts |
| Transcript | PATCH | /media/:id/transcripts/:lan |
| Transcript | DELETE | /media/:id/transcripts/:lan |
| API Keys | POST | /api_keys |
| API Keys | GET | /api_keys |
| API Keys | PATCH | /api_keys/:id |
| API Keys | DELETE | /api_keys/:id |
| Users | GET | /user/me |
| Webhooks | POST | /webhooks |
| Webhooks | GET | /webhooks |
| Webhooks | GET | /webhooks/:id |
| Webhooks | PATCH | /webhooks/:id |
| Webhooks | DELETE | /webhooks/:id |
| Webhooks | POST | /webhooks/check/:id |
| Players | POST | /players |
| Players | GET | /players |
| Players | GET | /players/:id |
| Players | PATCH | /players/:id |
| Players | DELETE | /players/:id |
| Players | POST | /players/:id/logo |
| Players | DELETE | /players/:id/logo |
| Players | POST | /players/add-player |
| Analytics | POST | /analytics/metrics/data/:metric/:aggregation |
| Analytics | POST | /analytics/metrics/bucket/:metric/:breakdown |
| Analytics | POST | /analytics/metrics/timeseries/:metric/:interval |
| Payments | GET | /payment/usage |
| Payments | GET | /payment/top_ups |
| Payments | GET | /payment/billings |
| Playlists | POST | /playlists/create |
| Playlists | POST | /playlists (list) |
| Playlists | GET | /playlists/:id |
| Playlists | PATCH | /playlists/:id |
| Playlists | POST | /playlists/:id/items |
| Playlists | PUT | /playlists/:id/items (reorder) |
| Playlists | DELETE | /playlists/:id/items/:item_id |
| Playlists | DELETE | /playlists/:id/thumbnail |
| Playlists | DELETE | /playlists/:id |
⚠️ General Warnings & Reminders
| Scenario | Clawbot Action Required |
|---|---|
| H.265 on Apple devices | Warn user and suggest container_type: "fmp4" — "mpegts" will NOT work on Safari/iOS |
| Insufficient balance | Block the action and tell user to top up before proceeding |
| Custom quality presets | Always call /media/cost first — only proceed if is_enough: true |
| Chunked upload | Compute MD5 per chunk. Never call /complete until all chunks succeed |
| Duplicate transcript language | Inform user, ask if they want to delete the existing transcript first |
| Player color format | Convert hex/named colors to rgba(...) automatically, inform user of the conversion |
| Player size format | Ensure all sizes are in px before sending |
| New API key secret | Display the secret immediately and warn it cannot be retrieved again |
| Webhook URL not reachable | Run /webhooks/check/:id and report result before confirming webhook is active |
| Analytics date input | Silently convert human-readable dates to UNIX timestamps before querying |
| Playlist reordering | Always fetch playlist detail first to get accurate next_id / previous_id |
Player is_default change | Warn user: setting a new default clears all others. CDN propagation may take up to 10 minutes |
| Player logo upload | Reject if over 100KB or larger than 200×100px — must be JPEG or PNG |
| Deleted default transcript | Remind user to set a new default transcript after deletion |
| Player assigned to video | Cannot delete player theme — ask user if they want to unassign it from the video first |