# Access Rules List
Source: https://docs.tenbyte.io/api-reference/access-rules/access-rules-list
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions/{distributionID}/access-rules
# Create New Access
Source: https://docs.tenbyte.io/api-reference/access-rules/create-new-access
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/access-rules
# Delete Access Rule
Source: https://docs.tenbyte.io/api-reference/access-rules/delete-access-rule
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json delete /distributions/{distributionID}/access-rules/{accessRuleID}
# Update Access Rule
Source: https://docs.tenbyte.io/api-reference/access-rules/update-access-rule
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json put /distributions/{distributionID}/access-rules/{accessRuleID}
# Analytics
Source: https://docs.tenbyte.io/api-reference/analytics/analytics
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /analytics
# Attach Disk
Source: https://docs.tenbyte.io/api-reference/block-storage/attach-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/storage/attach
Attaches a disk to a virtual machine. Location-specific endpoint.
# Create Disk
Source: https://docs.tenbyte.io/api-reference/block-storage/create-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /storage/disks
Creates a new block storage disk. Can be empty, a copy of an OS base image, an existing disk, or a snapshot. Location-specific endpoint.
# Delete Disk
Source: https://docs.tenbyte.io/api-reference/block-storage/delete-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /storage/disks/{disk_uuid}
Delete a disk and all its snapshots. All data will be lost irrecoverably. Location-specific endpoint.
# Detach Disk
Source: https://docs.tenbyte.io/api-reference/block-storage/detach-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/storage/detach
Detaches a disk from a virtual machine. Location-specific endpoint.
# Get Disk
Source: https://docs.tenbyte.io/api-reference/block-storage/get-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/disks/{disk_uuid}
Get one disk. Location-specific endpoint.
# List Disks
Source: https://docs.tenbyte.io/api-reference/block-storage/list-disks
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/disks
List user's disks. Location-specific endpoint.
# Modify Disk Info
Source: https://docs.tenbyte.io/api-reference/block-storage/modify-disk-info
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /storage/disks/{disk_uuid}
Modify meta-data of a disk. Location-specific endpoint.
# Cache Rules Details
Source: https://docs.tenbyte.io/api-reference/cache-rules/cache-rules-details
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions/{distributionID}/cache-rules/{cacheRuleID}
# Cache Rules List
Source: https://docs.tenbyte.io/api-reference/cache-rules/cache-rules-list
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions/{distributionID}/cache-rules
# Create Cache Rules
Source: https://docs.tenbyte.io/api-reference/cache-rules/create-cache-rules
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/cache-rules
# Delete Cache Rules
Source: https://docs.tenbyte.io/api-reference/cache-rules/delete-cache-rules
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json delete /distributions/{distributionID}/cache-rules/{cacheRuleID}
# Update Cache Rules
Source: https://docs.tenbyte.io/api-reference/cache-rules/update-cache-rules
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json put /distributions/{distributionID}/cache-rules/{cacheRuleID}
# Assign Certificate To Distribution
Source: https://docs.tenbyte.io/api-reference/distributions/assign-certificate-to-distribution
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json put /distributions/{distributionID}/certificates/{certificateID}
# Create Distribution
Source: https://docs.tenbyte.io/api-reference/distributions/create-distribution
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions
Creates a new CDN distribution for a customer. This API allows configuration of caching behavior, domain mapping, and origin server settings.
# Delete A Distribution
Source: https://docs.tenbyte.io/api-reference/distributions/delete-a-distribution
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json delete /distributions/{distributionID}
# Get A Distribution Detail
Source: https://docs.tenbyte.io/api-reference/distributions/get-a-distribution-detail
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions/{distributionID}
# Get Distribution List
Source: https://docs.tenbyte.io/api-reference/distributions/get-distribution-list
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions
🔍 Filtering
You can filter by the following fields:
- `id`
- `name`
- `cname`
- `domain`
- `status`
- `domain_type`
- `cache_strategy`
- `organization_id`
- `certificate_id`
- `enable_ssl`
- `is_redirect_http_to_https`
- `is_http2`
- `is_http3`
- `is_cname_valid`
- `is_acme_challenge_valid`
- `le_issue`
- `created_at`
- `updated_at`
Operators
Operator Description
--------------- ------------------------------------------
`eq` Equals
`ne` Not equals
`like` Contains (case insensitive)
`not-like` Does not contain
`starts-with` Starts with
`ends-with` Ends with
`gt` Greater than
`gte` Greater than or equal
`lt` Less than
`lte` Less than or equal
`in` In list (comma-separated)
`not-in` Not in list
`null` Is null
`not-null` Is not null
`between` Between two values (comma-separated)
`not-between` Not between two values (comma-separated)
Example Filters
filter[name][starts-with]=cdn-
filter[status][in]=active,disabled
filter[enable_ssl][eq]=true
filter[created_at][between]=2025-01-01,2025-08-01
------------------------------------------------------------------------
Sorting
---------------------------------------------------------------------------
Parameter Description
----------- ---------------------------------------------------------------
`sort` Sort fields. Prefix with `-` for descending. Allowed:
`created_at`, `updated_at`, `name`, `status`, `domain_type`,
`cache_strategy`, `domain`, `cname`
---------------------------------------------------------------------------
Example Sorts
sort=-created_at
sort=name
sort=-created_at,name
------------------------------------------------------------------------
📌 Example Requests
1. Prefix search + newest first
GET /v1/distributions?filter[name][starts-with]=cdn-&sort=-created_at
2. Status + type + alphabetical
GET /v1/distributions?filter[status][in]=active,disabled&filter[domain_type][eq]=system&sort=name
3. Created date range
GET /v1/distributions?filter[created_at][between]=2025-01-01,2025-08-01&sort=-created_at
4. SSL-only
GET /v1/distributions?filter[enable_ssl][eq]=true
------------------------------------------------------------------------
✅ Success Response
Status: 200 OK
{
"success": true,
"count": 2,
"data": [
{
"id": "uuid",
"name": "cdn-example",
"status": "active",
"domain_type": "system",
"enable_ssl": true,
"created_at": "2025-02-01T12:00:00Z",
"updated_at": "2025-02-10T12:00:00Z"
}
]
}
------------------------------------------------------------------------
❌ Error Response
Status: 400 Bad Request
{
"success": false,
"message": "Invalid filter query",
"errors": {
"filter": "Unsupported field or operator"
}
}
# Patch Distribution
Source: https://docs.tenbyte.io/api-reference/distributions/patch-distribution
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json patch /distributions/{distributionID}
# Revoke SSL
Source: https://docs.tenbyte.io/api-reference/distributions/revoke-ssl
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json patch /distributions/{distributionID}/revoke-ssl
# Toggle WebP
Source: https://docs.tenbyte.io/api-reference/distributions/toggle-webp
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json patch /distributions/{distributionID}/toggle-webp
This API is to toggle WebP Configuration.
API consumer must send `enable_webp`: `true` or `false`
# Update A Distribution
Source: https://docs.tenbyte.io/api-reference/distributions/update-a-distribution
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json put /distributions/{distributionID}
# Assign Firewall to VM
Source: https://docs.tenbyte.io/api-reference/firewall/assign-firewall-to-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/firewalls/{firewallUuid}/vms
Associates a firewall with a specific virtual machine. Location-specific endpoint.
# Create Firewall
Source: https://docs.tenbyte.io/api-reference/firewall/create-firewall
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/firewalls
Creates a new firewall with a given set of rules. See Representation and validation for FirewallRule object structure. Location-specific endpoint.
# Delete Firewall
Source: https://docs.tenbyte.io/api-reference/firewall/delete-firewall
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/firewalls/{firewallUuid}
Deletes a specified firewall. Location-specific endpoint.
# List Firewalls
Source: https://docs.tenbyte.io/api-reference/firewall/list-firewalls
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/firewalls
Retrieves a list of firewalls for the current user. Location-specific endpoint.
# Unassign Firewall from VM
Source: https://docs.tenbyte.io/api-reference/firewall/unassign-firewall-from-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/firewalls/{firewallUuid}/vms
Removes the association between a firewall and a virtual machine. Location-specific endpoint.
# Update Firewall
Source: https://docs.tenbyte.io/api-reference/firewall/update-firewall
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json put /network/firewalls/{firewallUuid}
Updates an existing firewall configuration. Location-specific endpoint.
# Assign Floating IP
Source: https://docs.tenbyte.io/api-reference/floating-ip/assign-floating-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/ip_addresses/{public_ipv4_address}/assign
Assign floating IP. Accepted values of assigned_to_resource_type: virtual_machine, service, load_balancer. Location-specific endpoint.
# Create Floating IP
Source: https://docs.tenbyte.io/api-reference/floating-ip/create-floating-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/ip_addresses
Create new floating IP. Location-specific endpoint.
# Delete Floating IP
Source: https://docs.tenbyte.io/api-reference/floating-ip/delete-floating-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/ip_addresses/{public_ipv4_address}
Delete floating IP. Location-specific endpoint.
# Get Floating IP
Source: https://docs.tenbyte.io/api-reference/floating-ip/get-floating-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/ip_addresses/{public_ipv4_address}
Get floating IP. Location-specific endpoint.
# List Floating IPs
Source: https://docs.tenbyte.io/api-reference/floating-ip/list-floating-ips
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/ip_addresses
List floating IPs. Can be filtered by billing_account_id and vm_uuid. Location-specific endpoint.
# Un-assign Floating IP
Source: https://docs.tenbyte.io/api-reference/floating-ip/un-assign-floating-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/ip_addresses/{public_ipv4_address}/unassign
Un-assign floating IP. Location-specific endpoint.
# Update Floating IP
Source: https://docs.tenbyte.io/api-reference/floating-ip/update-floating-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /network/ip_addresses/{public_ipv4_address}
Update floating IP. Location-specific endpoint.
# Bulk Delete Folder
Source: https://docs.tenbyte.io/api-reference/folder/bulk-delete-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/folders/bulk
Deletes multiple folders from a specific library in a single request.
This operation permanently removes the selected folders and all their nested subfolders and files (if any).
# Bulk Move Folder
Source: https://docs.tenbyte.io/api-reference/folder/bulk-move-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/folders/bulk/move
Moves multiple folders to a new parent folder within the same library in a single operation.
This endpoint is useful for reorganizing folder structures efficiently without making multiple API calls.
# Create Folder
Source: https://docs.tenbyte.io/api-reference/folder/create-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/folders
Create a new folder in this library.
Folders are used to organize video assets.
# Delete Folder
Source: https://docs.tenbyte.io/api-reference/folder/delete-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/folders/{folderId}
Deletes a specific folder from a given library. This action permanently removes the folder.
# Get Folder Details
Source: https://docs.tenbyte.io/api-reference/folder/get-folder-details
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/folders/{folderId}
Retrieve detailed information about a specific folder.
# List Folders
Source: https://docs.tenbyte.io/api-reference/folder/list-folders
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/folders
Retrieves a list of all folders within a specified library.
# Move Folder
Source: https://docs.tenbyte.io/api-reference/folder/move-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/folders/{folderId}/move
Moves a folder to a new parent location within the same library.
# Update Folder
Source: https://docs.tenbyte.io/api-reference/folder/update-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/folders/{folderId}
Modify an existing folder’s information such as name.
# Health check
Source: https://docs.tenbyte.io/api-reference/health/health-check
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json get /health
# Ping
Source: https://docs.tenbyte.io/api-reference/health/ping
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json get /ping
# Get Headers
Source: https://docs.tenbyte.io/api-reference/http-headers/get-headers
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions/{distributionID}/headers
# Http Headers
Source: https://docs.tenbyte.io/api-reference/http-headers/http-headers
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/headers
# Get CDN servers IP addresses
Source: https://docs.tenbyte.io/api-reference/ip-addresses-list/get-cdn-servers-ip-addresses
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /cdn/public-ip-list
Retrieves all IP addresses of CDN servers that can be used to pull content from your origin.
The list is updated periodically. We recommend monitoring its relevance automatically — for example, with a script that keeps your IP ACLs up to date — rather than tracking changes manually.
The response format can be controlled with the `format` query parameter or the `Accept` header. By default the response is returned as JSON.
# Create Library
Source: https://docs.tenbyte.io/api-reference/library/create-library
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries
Create a new video library within your Tenbyte account.
Libraries are used to organize video assets, folders, and related webhooks.
# Delete Library
Source: https://docs.tenbyte.io/api-reference/library/delete-library
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}
Delete an existing video library from your Tenbyte account.
This action permanently removes the library along with all associated folders, videos, and webhooks.
# Get Library Details
Source: https://docs.tenbyte.io/api-reference/library/get-library-details
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}
Retrieve detailed information about a specific library, including its metadata, visibility, and storage usage.
# Library Metrics
Source: https://docs.tenbyte.io/api-reference/library/library-metrics
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/metrics
Fetch usage and performance metrics for a specific library.
Returns total video count, total storage used (in bytes), and combined video duration in seconds.
# List Libraries
Source: https://docs.tenbyte.io/api-reference/library/list-libraries
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries
Retrieve a paginated list of all libraries associated with your account.
You can filter by visibility or creation date.
# Update Library
Source: https://docs.tenbyte.io/api-reference/library/update-library
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}
Modify an existing library’s information such as name, description, or visibility.
Use PATCH for partial updates.
# List Locations
Source: https://docs.tenbyte.io/api-reference/locations/list-locations
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /config/locations
Returns list of available locations (data centres). Use the location slug in the URL path after version number to target a specific location: /v1/{slug}/.
# Create Migrations
Source: https://docs.tenbyte.io/api-reference/migration-jobs/create-migrations
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/migration-jobs
# Validate Credentials
Source: https://docs.tenbyte.io/api-reference/migration-jobs/validate-credentials
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/migration-jobs/validate
# Add load balancer forwarding rule
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/add-load-balancer-forwarding-rule
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/load_balancers/{load_balancer_uuid}/forwarding_rules
Add new port forwarding rule to load balancer. Location-specific endpoint.
# Add load balancer target
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/add-load-balancer-target
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/load_balancers/{load_balancer_uuid}/targets
Add new target to load balancer. Location-specific endpoint.
# Change billing account on load balancer
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/change-billing-account-on-load-balancer
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json put /network/load_balancers/{load_balancer_uuid}/billing_account
Change Billing Account that load balancer is assigned to. Location-specific endpoint.
# Create load balancer
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/create-load-balancer
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/load_balancers
Create new load balancer. Location-specific endpoint.
# Delete load balancer
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/delete-load-balancer
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/load_balancers/{load_balancer_uuid}
Delete load balancer. Location-specific endpoint.
# Drop load balancer rule
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/drop-load-balancer-rule
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/load_balancers/{LB_UUID}/forwarding_rules/{RULE_UUID}
Drop port rule from load balancer. Location-specific endpoint.
# Get user load balancer by UUID
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/get-user-load-balancer-by-uuid
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/load_balancers/{load_balancer_uuid}
Get user load balancer by UUID. Location-specific endpoint.
# List user load balancers
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/list-user-load-balancers
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/load_balancers
Get list of load balancers owned by user. Location-specific endpoint.
# Rename load balancer
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/rename-load-balancer
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /network/load_balancers/{load_balancer_uuid}
Rename load balancer. Location-specific endpoint.
# Unlink load balancer target
Source: https://docs.tenbyte.io/api-reference/network-load-balancer/unlink-load-balancer-target
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/load_balancers/{LB_UUID}/targets/{TARGET_UUID}
Unlink target from load balancer. Location-specific endpoint.
# Create Bucket
Source: https://docs.tenbyte.io/api-reference/object-storage/create-bucket
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json put /storage/bucket
Create an S3 object storage bucket. Bucket names must be globally unique across all users.
# Delete Bucket
Source: https://docs.tenbyte.io/api-reference/object-storage/delete-bucket
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /storage/bucket
Delete an S3 object storage bucket. Only empty buckets can be deleted via this API.
# Delete key
Source: https://docs.tenbyte.io/api-reference/object-storage/delete-key
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /storage/user/keys
Delete an S3 key.
# Generate key
Source: https://docs.tenbyte.io/api-reference/object-storage/generate-key
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /storage/user/keys
Generate a new S3 key pair. Returns the list of all keys.
# Get Bucket
Source: https://docs.tenbyte.io/api-reference/object-storage/get-bucket
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/bucket
Get bucket information.
# Get keys
Source: https://docs.tenbyte.io/api-reference/object-storage/get-keys
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/user/keys
Returns all user S3 keys.
# Get S3 user
Source: https://docs.tenbyte.io/api-reference/object-storage/get-s3-user
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/user
Get S3 user info, including access and secret keys. User and keys will be generated if they do not exist already.
# List Buckets
Source: https://docs.tenbyte.io/api-reference/object-storage/list-buckets
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/bucket/list
List user's buckets. Optionally filter by billing account.
# Modify Bucket
Source: https://docs.tenbyte.io/api-reference/object-storage/modify-bucket
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /storage/bucket
Modify a bucket's billing account.
# S3 API Info
Source: https://docs.tenbyte.io/api-reference/object-storage/s3-api-info
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /storage/api/s3
Returns S3 API URL.
# Create Origins
Source: https://docs.tenbyte.io/api-reference/originsupstreams-manage/create-origins
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/origins
# Get Origins List
Source: https://docs.tenbyte.io/api-reference/originsupstreams-manage/get-origins-list
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /distributions/{distributionID}/origins
# API Overview
Source: https://docs.tenbyte.io/api-reference/overview
Everything you need to start using the Tenbyte API — authentication, requests, responses, limits, errors, webhooks, and SDKs.
# Tenbyte API Overview
The **Tenbyte API** provides a single, developer-friendly interface to manage **Cloud**, **CDN**, **Vidinfra**, and **Image Optimization** services.
You can use it to automate infrastructure, media pipelines, and delivery with predictable, REST-based endpoints.
***
## 🌍 Base URL
All API requests use the same base URL:
```bash theme={null}
https://api.tenbyte.io/v1/
```
Each service has its own subpath:
| Service | Base Path | Example |
| ------------ | ----------- | --------------------------------------------- |
| **CDN** | `/cdn` | `https://api.tenbyte.io/v1/cdn/distributions` |
| **Vidinfra** | `/vidinfra` | `https://api.tenbyte.io/v1/vidinfra/videos` |
| **Cloud** | `/cloud` | `https://api.tenbyte.io/v1/cloud/instances` |
***
## 🔐 Authentication
Tenbyte APIs use **API Key Authentication** to authorize requests.
Every API call must include an `x-api-key` header containing your API key.
You can generate and manage API keys in your **Tenbyte Console → Organization → API Keys**.
***
### 🪪 Example Authorization Header
```bash theme={null}
-H "x-api-key: YOUR_API_KEY"
```
```bash theme={null}
curl -X GET https://api.tenbyte.io/v1/cdn/distributions \
-H "x-api-key: YOUR_API_KEY"
```
### 🧱 Authentication Errors
| HTTP Code | Error | Description |
| --------- | -------------- | --------------------------------------------------------------------- |
| **401** | `unauthorized` | API key is missing, expired, or invalid. |
| **403** | `forbidden` | The provided API key does not have access to the requested resource. |
| **429** | `rate_limited` | Too many requests have been sent with this key. Wait before retrying. |
***
### ⚠️ Important
> * **Never expose your API keys** in public repositories, client-side code, or browser environments.
> * Always **store API keys securely** using environment variables or your platform’s secret manager.
> * **Rotate keys periodically** and immediately revoke compromised keys.
> * If you need multiple environments (e.g., staging, production), create **separate API keys** for each.
> * Monitor key activity in the **Tenbyte Console → API Logs** to detect unauthorized usage.
***
## 🤖 Using the API with AI agents
Prefer to drive the Tenbyte API from an AI agent? Install the official [Tenbyte skill](https://github.com/tenbytehq/tenbyte-skill):
```bash theme={null}
npx skills add tenbytehq/tenbyte-skill
```
Set your key as the `TENBYTE_API_KEY` environment variable and the agent can call the API on your behalf.
***
## 🧩 Pagination
Tenbyte API responses for list endpoints are **paginated** to help manage large data sets efficiently.
Use query parameters to control the number of items per page and navigate between pages.
| Parameter | Description | Example |
| --------- | -------------------------- | ----------- |
| `limit` | Number of results per page | `?limit=20` |
| `page` | Page number to retrieve | `?page=2` |
***
### 🧠 Example Request
```bash theme={null}
GET https://api.tenbyte.io/v1/libraries?limit=20&page=1 \
-H "x-api-key: TENBYTE_API_KEY"
```
# Get App Catalog images
Source: https://docs.tenbyte.io/api-reference/parameters/get-app-catalog-images
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /config/vm_images/app_catalog
Returns list of App Catalog images and corresponding versions for the platform Compute section.
# Get Plain OS images
Source: https://docs.tenbyte.io/api-reference/parameters/get-plain-os-images
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /config/vm_images/plain_os
Returns list of plain Virtual Machines images and corresponding versions for the platform Compute section.
# List bootable media images
Source: https://docs.tenbyte.io/api-reference/parameters/list-bootable-media-images
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /config/boot_images
Returns list of available bootable ISO images.
# VM images list
Source: https://docs.tenbyte.io/api-reference/parameters/vm-images-list
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /config/vm_images
Returns list of VM images and corresponding versions for the platform Compute section.
# VM parameters
Source: https://docs.tenbyte.io/api-reference/parameters/vm-parameters
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /api/parameters/vm
Describes VM creation parameters and their expected and allowed values.
# Create Player
Source: https://docs.tenbyte.io/api-reference/player-themes/create-player
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/players
Create a player for your video, and customise it.
# Delete Player
Source: https://docs.tenbyte.io/api-reference/player-themes/delete-player
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/players/{playerId}
Deletes a specific video player from a library. This operation permanently removes the player and its configuration.
# List Players Themes
Source: https://docs.tenbyte.io/api-reference/player-themes/list-players-themes
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/players
Retrieves a list of all video players within a specific library. Supports pagination, filtering, and sorting to efficiently manage and browse multiple players.
# Mark Player As Default
Source: https://docs.tenbyte.io/api-reference/player-themes/mark-player-as-default
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/players/{playerId}/mark-as-default
Marks a specific video player as the default player for a library.
The default player will be automatically used when embedding or displaying videos from this library if no specific player is selected.
# Player Details
Source: https://docs.tenbyte.io/api-reference/player-themes/player-details
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/players/{playerId}
Retrieves detailed information about a specific video player within a library.
This includes player configuration, associated videos, playback settings, and any customization options.
# Update Player
Source: https://docs.tenbyte.io/api-reference/player-themes/update-player
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/players/{playerId}
Updates the configuration or metadata of a specific video player within a library.
This endpoint allows partial updates, so only the fields provided in the request are modified.
# Create Prefetch
Source: https://docs.tenbyte.io/api-reference/prefetch/create-prefetch
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/prefetches
# Change network name
Source: https://docs.tenbyte.io/api-reference/private-networks/change-network-name
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /network/network/{network_uuid}
Change network name. Location-specific endpoint.
# Change network to default
Source: https://docs.tenbyte.io/api-reference/private-networks/change-network-to-default
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json put /network/network/{network_uuid}/default
Change network to default. Other private networks will be changed to non-default. Location-specific endpoint.
# Create a private network
Source: https://docs.tenbyte.io/api-reference/private-networks/create-a-private-network
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /network/network
Creates a new private network with specified descriptive name. If the first network of the user, it is set as default. Location-specific endpoint.
# Delete network
Source: https://docs.tenbyte.io/api-reference/private-networks/delete-network
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /network/network/{network_uuid}
Delete network. The network can be deleted if it does not contain any resources and it is not default. Location-specific endpoint.
# Get network data
Source: https://docs.tenbyte.io/api-reference/private-networks/get-network-data
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/network/{network_uuid}
Get network data. Location-specific endpoint.
# List Networks
Source: https://docs.tenbyte.io/api-reference/private-networks/list-networks
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /network/networks
List user networks with resources. Location-specific endpoint.
# Create Purge
Source: https://docs.tenbyte.io/api-reference/purge/create-purge
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/purges
# Get Security Settings
Source: https://docs.tenbyte.io/api-reference/security/get-security-settings
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/security
Retrieve the current security settings for a specific library, including access controls and privacy configurations.
# Update Security Settings
Source: https://docs.tenbyte.io/api-reference/security/update-security-settings
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/security
Update a library’s security configurations such as access level, allowed domains, or token-based restrictions.
# Create New SSL
Source: https://docs.tenbyte.io/api-reference/ssl-certificate-manage/create-new-ssl
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /certificates
# Delete Certificate
Source: https://docs.tenbyte.io/api-reference/ssl-certificate-manage/delete-certificate
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json delete /certificates/{certificateID}
# Get Certificate
Source: https://docs.tenbyte.io/api-reference/ssl-certificate-manage/get-certificate
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /admin/certificates/{certificateID}
# Get Certificate List
Source: https://docs.tenbyte.io/api-reference/ssl-certificate-manage/get-certificate-list
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /certificates
# Get Certificate Stats
Source: https://docs.tenbyte.io/api-reference/ssl-certificate-manage/get-certificate-stats
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json get /certificates/stats
# Request For Let's Encrypt SSL
Source: https://docs.tenbyte.io/api-reference/ssl-certificate-manage/request-for-lets-encrypt-ssl
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/request-ssl
# Create stream
Source: https://docs.tenbyte.io/api-reference/streams/create-stream
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json post /streams
# Delete stream
Source: https://docs.tenbyte.io/api-reference/streams/delete-stream
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json delete /streams/{streamId}
Stops stream if live. Removes stream key. Does not delete recordings.
# Get stream
Source: https://docs.tenbyte.io/api-reference/streams/get-stream
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json get /streams/{streamId}
# List streams
Source: https://docs.tenbyte.io/api-reference/streams/list-streams
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json get /streams
# Reset stream key
Source: https://docs.tenbyte.io/api-reference/streams/reset-stream-key
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json post /streams/{streamId}/reset-key
Old key invalid immediately. Disconnects active stream if live.
# Restart stream
Source: https://docs.tenbyte.io/api-reference/streams/restart-stream
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json post /streams/{streamId}/restart
Restarts the transcoding process on the transcoder service. Sets status to `starting`. Fails if stream is already live.
# Stop stream
Source: https://docs.tenbyte.io/api-reference/streams/stop-stream
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json post /streams/{streamId}/stop
Force-disconnects the encoder. Stream object stays, can go live again.
# Create Subtitle
Source: https://docs.tenbyte.io/api-reference/subtitle/create-subtitle
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/videos/{videoId}/subtitles
Upload a new subtitle file for a specific video.
# Delete Subtitle
Source: https://docs.tenbyte.io/api-reference/subtitle/delete-subtitle
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/videos/{videoId}/subtitles/{subtitleId}
Remove a subtitle file from a specific video.
# Get Subtitle
Source: https://docs.tenbyte.io/api-reference/subtitle/get-subtitle
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/{videoId}/subtitles/{subtitleId}
Retrieve details of a specific subtitle, including language, title, and file path.
# List Subtitle
Source: https://docs.tenbyte.io/api-reference/subtitle/list-subtitle
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/{videoId}/subtitles
Retrieve all subtitles associated with a specific video.
# Update Subtitle
Source: https://docs.tenbyte.io/api-reference/subtitle/update-subtitle
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/videos/{videoId}/subtitles/{subtitleId}
Update subtitle information such as title, language, or file path.
# Create Token
Source: https://docs.tenbyte.io/api-reference/token/create-token
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/token
Create new token and register it at API Gateway.
# Delete Token
Source: https://docs.tenbyte.io/api-reference/token/delete-token
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /user-resource/token
Delete API token.
# List Tokens
Source: https://docs.tenbyte.io/api-reference/token/list-tokens
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/token/list
List user API tokens.
# Update Token
Source: https://docs.tenbyte.io/api-reference/token/update-token
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /user-resource/token
Update API token options.
# Create Transcoding Profile
Source: https://docs.tenbyte.io/api-reference/transcoding-profiles/create-transcoding-profile
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/transcoding/profiles
Create a new transcoding profile with video, audio, and AI settings
# Delete Transcoding Profile
Source: https://docs.tenbyte.io/api-reference/transcoding-profiles/delete-transcoding-profile
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/transcoding/profiles/{profileId}
Delete a transcoding profile.
# Get Transcoding Profile
Source: https://docs.tenbyte.io/api-reference/transcoding-profiles/get-transcoding-profile
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/transcoding/profiles/{profileId}
Retrieve detailed configuration of a profile
# List Transcoding Profiles
Source: https://docs.tenbyte.io/api-reference/transcoding-profiles/list-transcoding-profiles
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/transcoding/profiles
List all transcoding profiles for a library
# Mark Default Transcoding Profile
Source: https://docs.tenbyte.io/api-reference/transcoding-profiles/mark-default-transcoding-profile
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/transcoding/profiles/{profileId}/default
Set a specific transcoding profile as the default for the library, making it the primary profile used for future video processing.
# Update Transcoding Profile
Source: https://docs.tenbyte.io/api-reference/transcoding-profiles/update-transcoding-profile
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/transcoding/profiles/{profileId}
Retrieve detailed configuration of a profile
# Create SSH Key
Source: https://docs.tenbyte.io/api-reference/user/create-ssh-key
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/ssh_keys
Create a new SSH public key. The public_key is immutable once created.
# Delete SSH Key
Source: https://docs.tenbyte.io/api-reference/user/delete-ssh-key
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /user-resource/ssh_keys/{uuid}
Delete an SSH key by UUID.
# Get User Info
Source: https://docs.tenbyte.io/api-reference/user/get-user-info
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/user
Authenticated user can request data-model for themselves.
# List SSH Keys
Source: https://docs.tenbyte.io/api-reference/user/list-ssh-keys
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/ssh_keys
List all SSH public keys associated with the authenticated user.
# Modify Profile Info
Source: https://docs.tenbyte.io/api-reference/user/modify-profile-info
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /user-resource/user/profile
Authenticated user can modify their own profile data.
# Update SSH Key Name
Source: https://docs.tenbyte.io/api-reference/user/update-ssh-key-name
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /user-resource/ssh_keys/{uuid}
Rename an existing SSH key. Only metadata (name) can be changed.
# Validate Acme DNS challenge endpoint
Source: https://docs.tenbyte.io/api-reference/verifications/validate-acme-dns-challenge-endpoint
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/validate-acme-challenge
# Validate distribution cname endpoint
Source: https://docs.tenbyte.io/api-reference/verifications/validate-distribution-cname-endpoint
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json post /distributions/{distributionID}/validate-cname
# List Chapter
Source: https://docs.tenbyte.io/api-reference/video-chapter/list-chapter
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/{videoId}/chapters
Retrieve all chapters associated with a specific video, including their titles, timestamps, and descriptions.
# Upsert Chapter
Source: https://docs.tenbyte.io/api-reference/video-chapter/upsert-chapter
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/videos/{videoId}/chapters
Create or update a chapter within a video.
If the chapter exists, it will be updated; otherwise, a new one will be created.
# Abort Multipart Upload
Source: https://docs.tenbyte.io/api-reference/video-multipart-upload/abort-multipart-upload
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/uploads/s3/multipart/{uploadId}
Abort an in-progress multipart upload and delete partial data.
# Complete Multipart Upload
Source: https://docs.tenbyte.io/api-reference/video-multipart-upload/complete-multipart-upload
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/uploads/s3/multipart/{uploadId}/complete
Finalize the upload and merge parts.
# Get Part Upload URL
Source: https://docs.tenbyte.io/api-reference/video-multipart-upload/get-part-upload-url
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/uploads/s3/multipart/{uploadId}/{partNumber}
Generate pre-signed URL for uploading a specific part
# Initialize Multipart Upload
Source: https://docs.tenbyte.io/api-reference/video-multipart-upload/initialize-multipart-upload
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/uploads/s3/multipart
Start a multipart upload session for a large video.
Vidinfra validates the file type and returns an uploadId for the client to upload chunks directly to S3.
# List Uploaded Parts
Source: https://docs.tenbyte.io/api-reference/video-multipart-upload/list-uploaded-parts
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/uploads/s3/multipart/{uploadId}
List all parts uploaded so far.
# Delete Thumbnail
Source: https://docs.tenbyte.io/api-reference/video-thumbnails/delete-thumbnail
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/videos/{videoId}/thumbnails/{fileName}
Remove an existing thumbnail from a video.
# Set Thumbnail
Source: https://docs.tenbyte.io/api-reference/video-thumbnails/set-thumbnail
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/videos/{videoId}/thumbnails/set
Set a specific image as the active or default thumbnail for a video.
# Upload Thumbnail
Source: https://docs.tenbyte.io/api-reference/video-thumbnails/upload-thumbnail
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/videos/{videoId}/thumbnails
Upload a new thumbnail image for a specific video.
# Bulk Move Videos to Folder
Source: https://docs.tenbyte.io/api-reference/video/bulk-move-videos-to-folder
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/videos/bulk-move
Moves multiple videos to a new folder or location within the same library in a single operation.
# Create Video
Source: https://docs.tenbyte.io/api-reference/video/create-video
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/videos
Uploads video directly under a library.
# Delete Video
Source: https://docs.tenbyte.io/api-reference/video/delete-video
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/videos/{videoId}
Deletes a specific video from a library. This action permanently removes the video and its associated data (e.g., files, thumbnails, metadata).
# Get Video By Custom ID
Source: https://docs.tenbyte.io/api-reference/video/get-video-by-custom-id
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/custom/{customFiled}/{customId}
Retrieves a list of videos within a library filtered by a custom field.
This endpoint is useful when videos are associated with external systems or identifiers (e.g., project ID, user ID, category tag).
# Get Video Details
Source: https://docs.tenbyte.io/api-reference/video/get-video-details
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/{videoId}
Retrieves detailed information about a specific video within a given library.
This includes its metadata, processing status, playback URLs, and associations (e.g., folder, tags, visibility).
# List Videos
Source: https://docs.tenbyte.io/api-reference/video/list-videos
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos
Retrieves a list of all videos within a specific library.
Supports filtering, pagination, and sorting to allow efficient browsing of video content.
# Pull Video
Source: https://docs.tenbyte.io/api-reference/video/pull-video
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/videos/pull
Uploads video directly under a library.
# Search Videos
Source: https://docs.tenbyte.io/api-reference/video/search-videos
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/search
Performs a search for videos within a library based on keywords, metadata, tags, or other searchable fields.
# Update Video
Source: https://docs.tenbyte.io/api-reference/video/update-video
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json patch /libraries/{libraryId}/videos/{videoId}
Updates metadata or visibility settings for a specific video within a library.
This endpoint allows partial updates, meaning only the provided fields will be modified.
# Video Timelines
Source: https://docs.tenbyte.io/api-reference/video/video-timelines
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/videos/{videoId}/timelines
Retrieve the timeline of events for a specific video.
Returns a chronological list of processing stages (such as queued, processing, transcoding, completed) with titles, descriptions, and timestamps for each event.
# Add Disk
Source: https://docs.tenbyte.io/api-reference/vm/add-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/storage
Create and add a disk device of specified capacity to a virtual machine. Location-specific endpoint.
# Boot a rescue or installation media
Source: https://docs.tenbyte.io/api-reference/vm/boot-a-rescue-or-installation-media
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/boot_iso_media
Launches the VM with a live OS image attached as a cd-rom device for booting. Mode is enabled for a single launch only. Location-specific endpoint.
# Change Password
Source: https://docs.tenbyte.io/api-reference/vm/change-password
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /user-resource/vm/user
Set a new password for an existing user on the virtual machine. The VM must be running. Location-specific endpoint.
# Clone VM
Source: https://docs.tenbyte.io/api-reference/vm/clone-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/clone
Clone existing virtual machine. Location-specific endpoint.
# Create Replica
Source: https://docs.tenbyte.io/api-reference/vm/create-replica
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/replica
Create replica from block storage. Location-specific endpoint.
# Create VM
Source: https://docs.tenbyte.io/api-reference/vm/create-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm
Create a new virtual machine. billing_account_id is optional if using an API token restricted to one billing account. Location-specific endpoint.
# Delete Attached Disk
Source: https://docs.tenbyte.io/api-reference/vm/delete-attached-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /user-resource/vm/storage
Disconnects and completely removes a disk device from a virtual machine. Data will be irrecoverably lost. Primary/boot disks cannot be deleted. Location-specific endpoint.
# Delete Replica
Source: https://docs.tenbyte.io/api-reference/vm/delete-replica
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /user-resource/vm/replica
Delete replica by uuid. Location-specific endpoint.
# Delete VM
Source: https://docs.tenbyte.io/api-reference/vm/delete-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /user-resource/vm
Delete virtual machine. Location-specific endpoint — optionally prefix path with /{slug}/.
# Get VM Info
Source: https://docs.tenbyte.io/api-reference/vm/get-vm-info
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/vm
Get virtual machine data. Location-specific endpoint.
# List Replicas
Source: https://docs.tenbyte.io/api-reference/vm/list-replicas
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/vm/replica
Get virtual machine storage replica list. Location-specific endpoint.
# List VM resource pools
Source: https://docs.tenbyte.io/api-reference/vm/list-vm-resource-pools
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/host_pool/list
Get a list of pools available for running compute resources. Location-specific endpoint.
# List VMs
Source: https://docs.tenbyte.io/api-reference/vm/list-vms
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json get /user-resource/vm/list
Get virtual machine list. Location-specific endpoint.
# Modify Disk
Source: https://docs.tenbyte.io/api-reference/vm/modify-disk
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /user-resource/vm/storage
Modify virtual machine disk capacity. New disk size cannot be smaller than current size. Location-specific endpoint.
# Modify VM
Source: https://docs.tenbyte.io/api-reference/vm/modify-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json patch /user-resource/vm
Currently only name, vcpu and ram can be changed. vcpu and ram can only be changed when the machine is in stopped state. Location-specific endpoint.
# Rebuild from Replica
Source: https://docs.tenbyte.io/api-reference/vm/rebuild-from-replica
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/rebuild
Discard virtual machine's current storage state and restore it from the specified replica. Location-specific endpoint.
# Reinstall VM
Source: https://docs.tenbyte.io/api-reference/vm/reinstall-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/reinstall
Discard virtual machine's current storage state and overwrite it with an OS base image. Location-specific endpoint.
# Release Public IP
Source: https://docs.tenbyte.io/api-reference/vm/release-public-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json delete /user-resource/vm/ip/public
DEPRECATED — see Floating IP for the updated API. Release a virtual machine's public IPv4 address. Location-specific endpoint.
# Reserve Public IP
Source: https://docs.tenbyte.io/api-reference/vm/reserve-public-ip
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/ip/public
DEPRECATED — see Floating IP for the updated API. Reserve and assign a public IP address for a virtual machine. Location-specific endpoint.
# Start VM
Source: https://docs.tenbyte.io/api-reference/vm/start-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/start
Start virtual machine. Location-specific endpoint.
# Stop VM
Source: https://docs.tenbyte.io/api-reference/vm/stop-vm
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/stop
Stop a virtual machine. By default tries a graceful ACPI shutdown. Use force=True to immediately cut power. Location-specific endpoint.
# Toggle Auto Backup
Source: https://docs.tenbyte.io/api-reference/vm/toggle-auto-backup
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cloud-api.json post /user-resource/vm/backup
Toggle automatic backups for virtual machine. Location-specific endpoint.
# Get a Single Delivery
Source: https://docs.tenbyte.io/api-reference/webhook-deliveries/get-a-single-delivery
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/webhooks/{endpointId}/events/{deliveryId}
Retrieve detailed information about a specific webhook delivery attempt, including the request body, response payload, timestamps, and retry count.
# List Deliveries for a Specific Endpoint
Source: https://docs.tenbyte.io/api-reference/webhook-deliveries/list-deliveries-for-a-specific-endpoint
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/webhooks/{endpointId}/events
Retrieve the webhook delivery history for a specific endpoint.
Useful for debugging delivery failures for a particular integration.
# Retry a Webhook Delivery
Source: https://docs.tenbyte.io/api-reference/webhook-deliveries/retry-a-webhook-delivery
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/webhooks/{endpointId}/events/{deliveryId}
Trigger a replay of a webhook delivery event.
Tenbyte re-sends the original payload to the same or a custom target URL.
Useful for testing fixed integrations or manually resending failed events.
# Create Webhook Endpoint
Source: https://docs.tenbyte.io/api-reference/webhook-endpoints/create-webhook-endpoint
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /libraries/{libraryId}/webhooks/endpoints
Register a new webhook endpoint to receive event notifications from this library.
Each endpoint can subscribe to one or more event types.
# Delete Webhook Endpoint
Source: https://docs.tenbyte.io/api-reference/webhook-endpoints/delete-webhook-endpoint
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json delete /libraries/{libraryId}/webhooks/endpoints/{endpointId}
Permanently delete or deactivate a webhook endpoint.
After deletion, Vidinfra will stop sending events to this endpoint.
# Get Webhook Endpoint by ID
Source: https://docs.tenbyte.io/api-reference/webhook-endpoints/get-webhook-endpoint-by-id
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/webhooks/endpoints/{endpointId}
Retrieve detailed information about a specific webhook endpoint, including its URL, subscribed events, status, and last delivery timestamps.
# List Webhook Endpoints
Source: https://docs.tenbyte.io/api-reference/webhook-endpoints/list-webhook-endpoints
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json get /libraries/{libraryId}/webhooks/endpoints
Retrieve a list of all webhook endpoints configured for a given library.
Supports pagination and optional filtering (e.g., by status or event type).
# Update Webhook Endpoint
Source: https://docs.tenbyte.io/api-reference/webhook-endpoints/update-webhook-endpoint
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json put /libraries/{libraryId}/webhooks/endpoints/{endpointId}
Update an existing webhook endpoint.
You can modify its description, event subscriptions, or status (active, paused, disabled).
# Transcoding Webhook
Source: https://docs.tenbyte.io/api-reference/webhook/transcoding-webhook
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/openapi.json post /webhooks/transcoding/vidinfra
Triggered automatically during the video transcoding process to notify your system about status updates.
Sends video details such as ID, processing status, duration, and file sizes for real-time tracking or post-processing actions.
# Transcoder status callback
Source: https://docs.tenbyte.io/api-reference/webhooks/transcoder-status-callback
https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/livestream-api.json post /webhooks/transcoder
Internal endpoint called by the transcoder service when a stream's
status changes. Authenticated via shared secret in `X-Webhook-Secret`
header, not JWT/API key.
On receive: updates stream status, creates audit event, and dispatches
a signed webhook to the customer's configured `webhook_url` (if set).
# Changelog
Source: https://docs.tenbyte.io/changelog
Product updates from Tenbyte Ltd.
### CDN — Purge By Pattern
#### FIXED
• **Purge By Pattern** — Occasionally Purged everything instead of the requested pattern.
### CDN - WAAP Integration
#### ADDED
• **WAAP (Web Application & API Protection)** — Combines signatures with behavioral analytics and machine learning to catch zero-day exploits and abnormal traffic sequences
### Live Streaming — VP9 & Opus Support
The encoder now supports two additional codecs for live streams, giving teams more flexibility in how they deliver video.
#### ADDED
• **VP9 video encoding** — a modern, open codec well-suited for browser-based delivery. Supports two rate-control modes: `capped-crf` (default, quality-capped) and `cbr` (constant bitrate, ideal for strict bandwidth budgets). VP9 streams are delivered in fMP4 format\
• **Opus audio encoding** — the recommended audio companion for VP9 ladders, using variable bitrate at 48 kHz for efficient, high-quality audio\
• **Reference VP9 + Opus configuration** — a ready-to-use 5-tier ladder (240p to 1080p) included out of the box, following Google's live encoding recommendations
#### IMPROVED
• Low-latency tuning on the default H.264 configuration — glass-to-glass delay reduced to approximately 4–5 seconds typical
### Live Streaming — Bug Fixes
#### FIXED
• **Pull ingest stalling on UDP sources** — pull connections to UDP sources occasionally stalled silently after several hours without dropping the stream or triggering reconnection\
• **H.265 streams not playing in Safari** — H.265 renditions were being served to Safari clients that do not support HEVC, causing playback failures. Codec capability detection now correctly filters renditions per client\
• **Mixed-codec ladder missing renditions in DASH manifest** — DASH manifests for streams with both H.264 and H.265 renditions were occasionally omitting the H.264 tiers\
• **Pull reconnect not honouring retry interval** — the configured retry interval was being ignored on the second reconnect attempt, causing aggressive reconnect loops\
• **Source health status stuck on "Connecting"** — pull ingest connections that stabilised successfully were occasionally reporting a stale "Connecting" status in the dashboard
### Live Streaming — Pull Ingest
Tenbyte can now connect to an existing stream source directly, removing the need to push from the encoder side.
#### ADDED
• **Pull ingest** — provide a source URL and Tenbyte initiates and maintains the ingest connection, supporting SRT, RTMP, and UDP sources\
• **Automatic reconnection** — pull ingest connections recover automatically if the source becomes temporarily unavailable, with configurable retry intervals\
• **Source health monitoring** — real-time visibility into pull connection status and source bitrate from the dashboard and API\
• **Pull + push fallback** — configure a pull source with a push ingest URL as fallback, so streams switch automatically if the pull source drops
### Vidinfra Player
A focused quality pass on the Vidinfra Player across desktop and mobile.
#### ADDED
• Volume and muted state persistence across videos\
• Double-click to toggle fullscreen on desktop\
• Comprehensive keyboard shortcuts and accessibility features\
• Compact control bar layout optimised for screens under 300px wide\
• Dark backdrop on the mobile settings panel for improved readability
#### IMPROVED
• Click-to-play behaviour on desktop browsers\
• Controls auto-hide timing for a cleaner viewing experience\
• Context menu redesigned with dedicated About and Keyboard Shortcuts views\
• Mobile tap controls for more reliable play/pause toggling\
• Mobile seek bar with a larger touch target and more accurate scrubbing\
• Centred play button, loading spinner, and seek buttons within the visible video area\
• Controls positioning in portrait fullscreen mode on mobile
#### FIXED
• Memory leaks from timers not being cleaned up properly on mobile devices\
• Settings panel being cut off in iframes and constrained mobile viewports\
• iOS-specific issues with controls animation and fullscreen centring\
• All seek intervals normalised to 10 seconds for consistent navigation\
• Mute and volume controls now function independently of each other
### Live Streaming — H.265 Encoding
H.265 is now available as an encoding option for streams requiring better quality at lower bitrates.
#### ADDED
• **H.265 (HEVC) encoding** — configure renditions to use H.265 for significantly improved compression efficiency over H.264 at equivalent quality\
• **H.265 rendition ladder** — a reference multi-rendition configuration for H.265 streams included out of the box\
• **Mixed-codec ladders** — H.264 and H.265 renditions can coexist in the same stream for broad device compatibility
#### FIXED
• **SRT reconnect loop on encoder restart** — restarting the encoder mid-stream occasionally caused the ingest endpoint to loop in a reconnect state rather than cleanly accepting the new connection\
• **SRT encrypted streams dropping frames** — streams using AES-256 encryption were intermittently dropping frames under high bitrate loads
### Cloud — T2 Object Storage
Introduced T2 Object Storage — Tenbyte's new generation of highly scalable, durable object storage for unstructured data.
#### WHAT'S NEW
• **S3-compatible API** — drop-in compatibility for existing tooling, SDKs, and workflows\
• **High durability** — data replicated across multiple availability zones\
• **Improved throughput** — optimised for media file ingest, backups, and large-scale data workloads\
• **Lifecycle policies** — automate object expiration and data transition rules\
• **Access control** — bucket-level and object-level permissions with fine-grained policies\
• Available immediately under Tenbyte Cloud → Storage
### Live Streaming — RTSP Ingest & Protocol Improvements
Expanded ingest protocol support and fixed a long-standing SRT reliability issue on Linux.
#### ADDED
• **RTSP ingest** — pull live feeds directly from IP cameras and hardware encoders. Supports TCP and UDP transport, with automatic fallback between them\
• **UDP MPEG-TS ingest** — accept broadcast contribution feeds over UDP, useful for satellite links and professional broadcast equipment\
• **`--protocols` flag** — lists which ingest protocols (RTMP, SRT, RTSP, UDP) are available in the running binary, making it easy to verify your setup\
• **HE-AAC audio support (opt-in)** — enables HE-AAC v1 and HE-AAC v2 for efficient, high-quality audio at low bitrates
#### FIXED
• **SRT ingest on Linux** — SRT streams were silently unavailable in Linux builds despite the protocol being enabled, causing `srt://` sources to fail at runtime. Now resolved and verified automatically before each release\
• **RTMP probe stall** — streams from certain RTMP servers occasionally stalled during the initial connection phase, causing the encoder to loop in reconnect. Resolved by aligning with standard behaviour across all major RTMP servers
### Vidinfra — Real-time Analytics and introducing DRM Features
#### ADDED
• **DRM & access control** — Widevine, FairPlay, and PlayReady with token-signed playback URLs
• **Analytics** — play counts, geographic distribution, and bandwidth usage per video
### Live Streaming — SRT Ingest
SRT is now supported as a second ingest protocol alongside RTMP, offering lower latency and built-in packet recovery.
#### ADDED
• **SRT ingest** — send live streams to Tenbyte via SRT from any compatible encoder including OBS, vMix, and hardware devices\
• **Caller & listener modes** — SRT connections can be initiated from either the encoder or the Tenbyte ingest endpoint\
• **Stream encryption** — optional AES-128 and AES-256 passphrase encryption on SRT streams for secure contribution\
• **Latency tuning** — configurable SRT latency parameter to balance delay against packet recovery on lossy networks
### Tenbyte Live Streaming — Live Broadcast Infrastructure
• **Push ingest** — RTMP and SRT from OBS, vMix, or any hardware encoder
• **Multi-rendition transcoding** — simultaneous quality tiers with adaptive-bitrate HLS and DASH output\
• **H.264 encoding** — industry-standard codec with configurable quality, bitrate, and GOP settings\
• **AAC audio** — high-quality audio encoding across all stream tiers\
• **Linear & live-event modes** — 24/7 always-on channels or one-time scheduled broadcasts\
• **Custom rendition ladder** — full control over resolution, codec, bitrate, and frame rate\
• **CMAF packaging** — fMP4 segments compatible with both HLS and DASH players, with clean VOD fallback on stream end\
• **CDN-ready origin URLs** — HLS/DASH output ready for CDN distribution\
• **Webhook events** — signed POST notifications for every stream lifecycle event\
• **API-first** — create, update, start, and stop streams programmatically
### Vidinfra — Video Platform Enhancements
#### ADDED
• **DRM multi-key support** — assign different encryption keys per rendition (Widevine, FairPlay, PlayReady) for tiered content protection\
• **Clip & trim API** — programmatically extract clips from an ingested video without re-uploading the source file\
• **Webhook retry policy** — configurable retry count and backoff for failed webhook deliveries\
• **Per-video analytics** — play rate, buffering ratio, and completion rate now available at the individual video level
#### IMPROVED
• Shorter transcoding wait times for videos under 2 minutes, processed via a dedicated fast-path queue\
• Signed URLs now support optional IP binding for tighter access control\
• Player SDK bundle size reduced by 18% through dependency trimming
#### FIXED
• Audio/video sync drift on videos encoded at 59.94 fps\
• Chapter markers not rendering correctly in Safari 17
### CDN - Access Rules & Signed URLs
#### ADDED
• **Real-time analytics** — bandwidth, requests, cache-hit ratio, and response class breakdown
### CDN — Image Optimisation Now Generally Available
#### ADDED
• Automatic format negotiation: serves WebP or AVIF where the browser supports it, falls back to JPEG/PNG\
• On-the-fly resize, crop, and quality control via URL query parameters\
• Responsive image transformations cached at the edge — no repeated origin requests\
• Multi-CDN failover improvements — weighted fallback rules and per-path CDN pinning now supported
### Vidinfra — Video Hosting & Delivery
End-to-end video infrastructure for developers and media teams.
• **Ingest & transcoding** — upload via API or dashboard; automatic multi-rendition encoding to HLS and MPEG-DASH\
• **Adaptive bitrate** — per-device quality ladder with intelligent client-side rendition selection\
• **Global delivery** — smart-routing multi-CDN engine with a 99.99% availability target\
• **DRM & access control** — Widevine, FairPlay, and PlayReady with token-signed playback URLs\
• **Player SDK** — embeddable player with customisable controls, themes, and branding\
• **Webhooks** — real-time lifecycle events for upload, encoding, and delivery stages\
• **Analytics** — play counts, geographic distribution, and bandwidth usage per video
### CDN - Access Rules & Signed URLs
#### ADDED
• **Access rules** — country, IP, referrer, and token-gate policies per path\
• **Signed URLs** — time-limited token authentication for protected content
### Tenbyte CDN — Global Content Delivery
• **Distributions** — configure CDN endpoints mapped to HTTP, S3, or custom origins\
• **Smart routing** — anycast with continuous health checks routing each request to the nearest healthy edge\
• **Multi-CDN** — intelligent failover across multiple CDN providers for maximum availability\
• **Cache rules** — per-path TTL, query-string handling, and compression settings
• **Header rules** — add or remove request and response headers at the edge\
• **Purge** — invalidate cached content by exact path or pattern, processed in under 500 ms globally
• **REST API & webhooks** — full programmatic control over distributions, rules, and purge events
### Tenbyte Cloud — Infrastructure Platform
• **Virtual Machines** — scalable compute instances on enterprise-grade hardware for application hosting and media workloads\
• **Object Storage** — scalable, cost-effective storage for media files, backups, and large datasets\
• **Virtual Private Cloud (VPC)** — custom IP ranges, subnets, and security group rules\
• **DDoS protection** — platform-level mitigation with guaranteed service continuity\
• **Snapshots & Backups** — scheduled and on-demand snapshots for compute instances and volumes\
• **Monitoring & Analytics** — resource utilisation dashboards with alerting\
• **99.98% uptime SLA** — high-availability architecture across all core services\
• **24/7 support** — migration, setup, and troubleshooting assistance
# Create Your Tenbyte Account
Source: https://docs.tenbyte.io/docs/account/account-creation
This page walks you through creating a **Tenbyte account**, giving you access to the dashboard and core services. The setup is simple and requires only basic information to get started.
## What you need
Before you start, make sure you have access to the following:
* An email address that can receive messages
* A password you want to use
* The verification code sent to your inbox
Completing these steps is enough to open the dashboard for the first time.
***
## Sign up for a account
* To sign up for Tenbyte services, go to the Tenbyte website and select **Get Started** on the Tenbyte [**home page**](https://beta.tenbyte.io/)
* Click **Sign-up** to create your account. A new page will open.
* **Enter Your Name**: Provide your first name and last name so your account can be personalized.
* **Add Your Email Address**: Enter a valid email address.
* **Create a Password**: Set a secure password that meets the following requirements:
* At least 8 characters long
* Includes one uppercase letter
* Includes one special character
* Once all fields are filled, click **Continue** to create your account and move to the next step.
* A **one-time password (OTP)** will be delivered to your email so you can verify your account.
* Once you have confirmed your otp, you will be able to access your **Tenbyte dashboard**.
***
## Use Social Sign-Up
If you prefer a faster setup, you can sign up using:
1. Google
2. GitHub
This lets you access Tenbyte without creating a separate password.
Once you’re signed in, you can take a moment to review your profile details, set your organization information, and check your active sessions. You’ll also be able to access the main services like Cloud, CDN, Object Storage, and Vidinfra whenever you’re ready.
# Account Settings
Source: https://docs.tenbyte.io/docs/account/index
Manage your profile details, access controls, and security settings from a single, centralized page.
1. [Account Creation](/docs/account/account-creation): Learn how to open a new Tenbyte account and set up your initial dashboard access.
2. [Profile Settings](/docs/account/profile-settings): Update your name, email, and other information linked to your Tenbyte account.
3. [Session Management](/docs/account/session-management): View active logins, check connected devices, and remove any session you no longer want to keep active.
# User Profile Settings
Source: https://docs.tenbyte.io/docs/account/profile-settings
Update your personal information, manage login details, and control account preferences in your Tenbyte profile.
## What you need
Before updating your profile, make sure you have:
* Access to the email linked to your Tenbyte account
* A new password ready if you plan to change it
* The image file you want to use as your profile picture
***
## User Profile Settings
* Click your profile icon in the left sidebar. When the dropdown menu opens, choose **Account** to access your **user settings**.
* The **User section** allows you to manage your personal information, update login details, and perform critical account actions. Follow the steps below to update your profile.
### Update Account Information
* In the **Account Information** section, you can edit your basic profile details.
1. **Name**: Enter or update your first name and last name.
2. **Email Address**: Your email address is shown here for authentication purposes.
If you signed in using a social provider like Google or GitHub, this field shows the associated login email.
3. **Profile Picture**: Click **Upload image** to add or change your profile picture.
### Create or Update Your Password
* If you signed in using a social login, you may not have a password yet. Use the **Create a Password** section to set one.
1. **New Password**: Enter a new password. It must meet Tenbyte’s security rules (minimum 8 characters).
2. **Confirm New Password**: Re-enter the same password to verify it.
Setting a password enables direct email-based login alongside your social provider.
### Manage Critical Account Actions
* The **Danger Zone** contains irreversible actions.
* **Account Deletion**: Click **Delete Account** to permanently remove your Tenbyte account. A confirmation step will appear to ensure you understand the impact.
This action cannot be undone and will delete all associated data.
# Session Management
Source: https://docs.tenbyte.io/docs/account/session-management
Monitor active login sessions, review connected devices, and terminate unauthorized access to protect your Tenbyte account security.
## Current Sessions
* This section shows the device you are currently using to access your Tenbyte account.
For each active session, you will see:
1. Device Type (e.g., Desktop)
2. IP Address
3. Activation Time (when the session started)
This helps you confirm that the current login session is valid and expected.
***
## Other Sessions
The **Other Sessions** section lists all additional devices that are signed in to your account.
Each entry displays:
1. Device name
2. IP address
3. Last active timestamp
4. Terminate button
If you see a session you don’t recognize, you can **click Terminate** to immediately revoke access for that device.
***
## Ending a Session
To **remove a session** find the session under **Other Sessions** and click **Terminate**. The device will be logged out instantly.
# Cache Hit Ratio
Source: https://docs.tenbyte.io/docs/cdn/analytics/cache-hit-ratio
Measure cache efficiency — the headline metric for CDN performance and origin cost. Includes diagnosis and tuning playbook.
Cache hit ratio (CHR) is the single most important CDN metric. It's the share of requests served straight from the edge cache, with no origin round-trip. High CHR means lower latency, lower origin load, and a smaller bill.
## How it's calculated
```
cache_hit_ratio = cache_hits / (cache_hits + cache_misses)
```
A `MISS` becomes a `HIT` after the first request fills the cache. A path that's only ever requested once is always a `MISS` and drags CHR down — that's normal for long-tail content.
## What "good" looks like
| Workload | Healthy CHR | Investigate |
| --------------------------- | ----------- | --------------- |
| Static assets (`/static/*`) | 95–99% | \< 90% |
| Image library | 90–98% | \< 85% |
| HLS / DASH VOD | 90–97% | \< 85% |
| Mixed (HTML + API + assets) | 75–90% | \< 65% |
| API-heavy (short TTL) | 30–70% | wildly variable |
Don't chase a single number — chase trend stability per path class.
## Read the chart
| Element | Meaning |
| ------------ | ------------------------------------------------------------------- |
| Main % | Hit ratio over the window. |
| Trend line | Rolling CHR — sudden drops point at deploys, purges, or noisy keys. |
| Comparison % | Change vs prior period. |
## Pull via API
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/analytics/cache?from=2026-05-01T00:00:00Z&to=2026-05-09T00:00:00Z" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
```
```json theme={null}
{
"hits": 41510234,
"misses": 3501112,
"hit_ratio": 0.922,
"series": [
{"ts": "2026-05-01T00:00:00Z", "hit_ratio": 0.94}
]
}
```
## Diagnose a low CHR
```mermaid theme={null}
flowchart TD
LOW[Low CHR] --> Q1{Origin sends Cache-Control: private?}
Q1 -- yes --> R1[Override via cache rule: Ignore Origin No Cache]
Q1 -- no --> Q2{Query string varies per request?}
Q2 -- yes --> R2[Enable Ignore Query String in Cache Key]
Q2 -- no --> Q3{Vary header fragmenting cache?}
Q3 -- yes --> R3[Strip / narrow Vary via response header rule]
Q3 -- no --> Q4{TTL too short?}
Q4 -- yes --> R4[Bump expiration on cache rule]
Q4 -- no --> Q5[Long-tail content requested once]
Q5 --> R5[Likely fine — accept]
```
## Tuning playbook
1. **Spot the bad prefix.** Filter analytics by URL prefix; find the prefix dragging overall CHR down.
2. **Inspect a sample path.** `curl -sSI "$CDN_HOST/the/path"` and look at `cache-control`, `vary`, and the cache rule that matches.
3. **Apply the right fix:**
* Origin sends `private` / `no-store` → enable **Ignore Origin No Cache** on the [cache rule](/docs/cdn/distributions/cache-rules).
* Query string is noisy → enable **Ignore Query String in Cache Key**.
* `Vary: User-Agent` fragments cache → strip or narrow via [response header rule](/docs/cdn/distributions/headers).
* TTL too short → bump expiration time.
4. **Validate.** Wait for the cache to rewarm, then check CHR per path.
## Common false alarms
* **CHR drops right after a [purge](/docs/cdn/purge/purge-by-pattern).** Expected — every purged path becomes a MISS until refilled. Watch for recovery within minutes.
* **CHR drops on launch day.** New paths haven't filled the cache yet. Don't tune; wait.
* **Low CHR on auth callbacks / per-user JSON.** These are correctly uncacheable. Exclude them from your "should be cached" baseline.
## Operational tips
* **Track per-path-class CHR**, not a single distribution-wide number — averages hide problems.
* **Alert on slope, not value.** A 10-point drop in 5 minutes is incident-worthy; a slowly drifting baseline calls for tuning, not paging.
* **Pair with origin metrics.** Origin CPU spikes that line up with CHR drops confirm causation.
* **Cache hit ratio + bandwidth** answers "is this CDN paying off?" — the higher CHR, the more leverage.
# CDN Analytics Overview
Source: https://docs.tenbyte.io/docs/cdn/analytics/overview
Track bandwidth, requests, cache hit ratio, and error classes for your Tenbyte CDN distribution. Pull the same data via API for your own dashboards.
The Analytics tab shows real-time and historical metrics for a distribution. Use it to validate cache tuning, monitor traffic, and catch error spikes early.
## Metrics at a glance
```mermaid theme={null}
flowchart LR
EDGE[Edge PoPs] -->|access logs| AGG[Aggregation pipeline]
AGG --> DASH[Console dashboard]
AGG --> API[Analytics API]
AGG --> WEBHOOK[Alert webhooks]
```
| Metric | Why it matters | Page |
| -------------------- | ------------------------------------------------------ | -------------------------------------------------------- |
| **Traffic served** | Bandwidth out — drives bill and capacity planning. | [Traffic served](/docs/cdn/analytics/traffic-reports) |
| **Requests served** | Volume — sizes infra and tracks adoption. | [Requests served](/docs/cdn/analytics/request-served) |
| **Cache hit ratio** | Efficiency — high HIT% = low origin cost and latency. | [Cache hit ratio](/docs/cdn/analytics/cache-hit-ratio) |
| **Response classes** | Health — non-2xx counts catch outages and bad deploys. | [Response classes](/docs/cdn/analytics/response-classes) |
## Healthy baselines
| Metric | Good | Investigate |
| ------------------------ | ---------------- | ------------------------ |
| Cache hit ratio (static) | ≥ 95% | \< 90% |
| Cache hit ratio (mixed) | ≥ 80% | \< 70% |
| 4xx rate | \< 1% of total | sustained > 2% |
| 5xx rate | \< 0.1% of total | any sustained spike |
| Traffic week-over-week | within ±20% | sudden 2× without launch |
These are starting points; tune to your workload.
## Pull metrics via API
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/analytics?from=2026-05-01T00:00:00Z&to=2026-05-09T00:00:00Z" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
```
Common response fields:
```json theme={null}
{
"bandwidth_bytes": 12834567890,
"requests": 4501234,
"cache_hit_ratio": 0.92,
"responses": {"2xx": 4456012, "3xx": 12000, "4xx": 33000, "5xx": 222}
}
```
See the [CDN API reference](/api-reference/cdn) for the canonical endpoint and filters.
## Wire into your stack
| Destination | How |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| **Grafana** | Use the Tenbyte API as a JSON datasource; chart `bandwidth_bytes`, `requests`, `cache_hit_ratio`. |
| **Datadog** | Cron a small lambda that pulls the API and pushes custom metrics. |
| **Slack alerts** | Configure webhook on response-class spike via the distribution settings. |
| **Spreadsheet** | Pipe daily totals to a CSV for finance / capacity reporting. |
## Operational tips
* **Compare deploys, not days.** A weekday/weekend baseline beats raw deltas.
* **Alert on ratios, not absolutes.** Traffic doubles, errors stay flat — that's healthy growth, not an incident.
* **Drill in by path.** Filter by URL prefix to find the noisy 4xx contributor before it becomes a 5xx.
* **Pair with origin metrics.** Edge `5xx` plus origin `5xx` = origin issue; edge `5xx` only = networking or config.
# Requests Served
Source: https://docs.tenbyte.io/docs/cdn/analytics/request-served
Track the number of HTTP requests the CDN handled. Spot traffic patterns, abuse, and bot activity.
Requests Served counts every HTTP request the CDN processed — cache hits, cache misses, errors, and OPTIONS preflights all included.
## What it tells you
* Total request volume in the selected window.
* How that compares to the previous period.
* Hourly / daily distribution — peaks, troughs, anomalies.
## How to read the chart
| Element | Meaning |
| ----------- | ------------------------------------ |
| Main number | Total requests (M / B suffix). |
| Percentage | Delta vs the prior identical window. |
| Sparkline | Time-series — find spikes and dips. |
## Pull via API
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/analytics/requests?from=2026-05-01T00:00:00Z&to=2026-05-09T00:00:00Z&granularity=hour" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
```
Response (truncated):
```json theme={null}
{
"total_requests": 45012345,
"series": [
{"ts": "2026-05-01T00:00:00Z", "requests": 1923456},
{"ts": "2026-05-01T01:00:00Z", "requests": 1876543}
]
}
```
## Requests vs traffic
A high request count with low [traffic](/docs/cdn/analytics/traffic-reports) means tiny payloads (API JSON, manifests). A high traffic with low requests means big objects (video, downloads). Watch both ratios.
| Ratio | Workload |
| ---------------------------- | ---------------------------------------------------- |
| Many requests, low bytes/req | API-style or HLS manifest. |
| Few requests, high bytes/req | Video / downloads / large images. |
| Both high | Mixed-purpose distribution — scope per-path metrics. |
## Spot abuse
Sudden request spikes without a corresponding traffic spike usually mean:
* **Bot scraping** — same small object hit thousands of times.
* **Cache busting** — random query strings forcing every request to be unique.
* **Probing** — `404` flood from a vulnerability scanner.
Drill into [response classes](/docs/cdn/analytics/response-classes) and consider an IP or country [access rule](/docs/cdn/distributions/access-rules/overview).
## Operational tips
* **Group by path.** The top 10 paths by request count usually drive the bulk of origin traffic.
* **Watch off-hours.** Sustained traffic at 03:00 local is rarely human.
* **Combine with cache-hit ratio.** High request count + low HIT% = origin pain. Tune cache rules.
* **Alert on rate change**, not raw totals — easier to write portable thresholds.
# Response Classes
Source: https://docs.tenbyte.io/docs/cdn/analytics/response-classes
Track non-2xx HTTP responses (4xx and 5xx) on your distribution. Includes diagnosis flow and per-class playbooks.
Response Classes breaks down HTTP status codes the CDN returned to clients. The non-2xx panel surfaces problems — bad URLs, blocked traffic, origin failures — before users complain.
## Status code map
| Class | Meaning | Common causes |
| ------- | ------------ | ---------------------------------------------------------------------- |
| **2xx** | Success | Healthy traffic. |
| **3xx** | Redirect | HTTP→HTTPS, canonical-URL redirects. |
| **4xx** | Client error | `404` for missing assets, `403` from access rules, `429` rate-limited. |
| **5xx** | Server error | Origin down, TLS handshake failed, edge timeout. |
## How to read the panel
| Element | Meaning |
| ----------------- | --------------------------------------------------------- |
| 4xx counter | Count of client-side errors in the window. Yellow series. |
| 5xx counter | Count of server-side errors. Red series. |
| Time-series chart | Distribution over time — find spikes. |
## Pull via API
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/analytics/responses?from=2026-05-01T00:00:00Z&to=2026-05-09T00:00:00Z&granularity=hour" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
```
```json theme={null}
{
"totals": {"2xx": 4456012, "3xx": 12000, "4xx": 33000, "5xx": 222},
"series": [
{"ts": "2026-05-01T00:00:00Z", "2xx": 1923000, "4xx": 1500, "5xx": 12}
]
}
```
## Diagnose a 4xx spike
```mermaid theme={null}
flowchart TD
SPIKE[4xx spike] --> Q1{What status?}
Q1 -- 404 --> R1[Check recent deploys Asset paths changed?]
Q1 -- 403 --> R2[Token / referrer / IP / country rule blocking]
Q1 -- 429 --> R3[Origin rate-limiting or edge throttling abuse]
Q1 -- other --> R4[Inspect raw access logs for top URLs]
```
| Status | Likely cause | Action |
| ------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `404` | Stale URLs after a deploy, broken `` `srcset`, robots probing. | Audit recent deploys, fix references, consider a `404` cache rule. |
| `403` | [Access rule](/docs/cdn/distributions/access-rules/overview) blocked the request. | Inspect rule logs; verify intended audience can pass. |
| `401` | Origin rejected an auth-protected path. | Check upstream credentials. |
| `405` | Method not allowed. | Origin or rule disallows verb (often `OPTIONS` preflight). |
| `429` | Rate limit hit. | Check origin throttling and edge protection settings. |
## Diagnose a 5xx spike
```mermaid theme={null}
flowchart TD
SPIKE5[5xx spike] --> Q1{Origin healthy?}
Q1 -- no --> R1[Origin outage Roll back / scale up]
Q1 -- yes --> Q2{Edge → origin TLS OK?}
Q2 -- no --> R2[Cert expired or SNI mismatch]
Q2 -- yes --> Q3{Edge timing out?}
Q3 -- yes --> R3[Origin slow or far from edge]
Q3 -- no --> R4[Open a support ticket with purge_id / window]
```
| Status | Likely cause | Action |
| ------ | ---------------------------------------------------- | ----------------------------------------------------------------- |
| `502` | Origin unreachable, dropped connection, TLS failure. | Check origin health and certs. |
| `503` | Origin overloaded or returning `Retry-After`. | Scale origin; consider edge `Retry-After` aware caching. |
| `504` | Edge timed out waiting for origin. | Investigate origin latency; raise timeouts only as a last resort. |
## Operational tips
* **Alert on rate, not absolute count.** `5xx > 0.1% of requests for 5 min` beats a fixed threshold across distributions of different size.
* **Correlate with deploys.** Most 4xx spikes are deploys with stale paths; first action on a spike is "what shipped?"
* **Cache `404`s briefly.** A short TTL on `404` cuts origin load during a probe storm. Configure via [cache rules](/docs/cdn/distributions/cache-rules).
* **Watch the edge → origin TLS expiry.** A silent cert renewal failure shows up as `502`.
* **Combine with [Cache hit ratio](/docs/cdn/analytics/cache-hit-ratio).** Falling CHR + rising 5xx = origin couldn't keep up with the cold-start spike.
# Traffic Served
Source: https://docs.tenbyte.io/docs/cdn/analytics/traffic-reports
Track bandwidth delivered through the CDN, spot trends, and pull totals via API for billing and capacity reports.
Traffic Served measures the bytes the CDN sent to clients in a given window. It drives your bandwidth bill and signals whether traffic patterns are shifting under you.
## What it tells you
* Total bytes delivered to end users.
* Period-over-period change (today vs yesterday, week vs week).
* Trend lines that surface launches, viral spikes, and outages.
## How to read the chart
| Element | Meaning |
| ----------- | -------------------------------------------------------- |
| Main number | Total bytes (KB / MB / GB / TB) for the selected window. |
| Percentage | Change vs the prior identical window. Positive = growth. |
| Sparkline | Distribution over time — find spikes and dips. |
## Pull via API
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/analytics/traffic?from=2026-05-01T00:00:00Z&to=2026-05-09T00:00:00Z&granularity=hour" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
```
Response (truncated):
```json theme={null}
{
"total_bytes": 1283456789012,
"series": [
{"ts": "2026-05-01T00:00:00Z", "bytes": 5012345678},
{"ts": "2026-05-01T01:00:00Z", "bytes": 5234567890}
]
}
```
See the [CDN API reference](/api-reference/cdn) for filters (`granularity`, per-PoP breakdown).
## Common patterns
| Pattern | What it usually means |
| ------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Steady daytime peaks | Healthy — track week-over-week ratio. |
| Sudden spike with low cache-hit ratio | Origin will feel it. Check [cache hit ratio](/docs/cdn/analytics/cache-hit-ratio) and rule TTLs. |
| Spike with stable hit ratio | Real traffic growth. Capacity-plan origin. |
| Sustained drop | DNS issue, broken deploy, or upstream redirect bypassing the CDN. |
## Cost levers
* **Raise cache hit ratio.** Higher HIT% = same user-facing bytes, less origin egress.
* **Compress text.** Enable Gzip / Brotli in [cache rules](/docs/cdn/distributions/cache-rules).
* **Right-size images.** Use [Image Optimizer](/docs/cdn/distributions/image-optimizer) with `format=auto` and capped widths.
* **Cap query-string variants.** A noisy cache key duplicates the same bytes.
## Operational tips
* **Daily totals to finance.** Pipe API totals into your billing spreadsheet or BI tool.
* **Per-path breakdowns.** Use the path filter to find the top 10 bandwidth consumers; cache or compress them harder.
* **Alert on rate, not total.** A 5× hourly spike is more actionable than absolute totals.
# Tenbyte CDN FAQs
Source: https://docs.tenbyte.io/docs/cdn/cdn-faqs
Operational, developer, and billing questions about Tenbyte CDN.
Quick answers grouped by topic. For deeper guidance, follow the linked pages or the [API reference](/api-reference/cdn).
## General
### What is Tenbyte CDN?
A global content delivery network with anycast routing, edge caching, image optimization, signed URLs, and a REST API. Edge nodes serve cached responses close to the user; origin only sees cache misses.
### How does it speed up my site?
Three levers: shorter network distance (edge PoP near user), cached responses (no origin round-trip on hits), and HTTP/2 + HTTP/3 multiplexing.
### What protocols are supported?
HTTP/1.1, HTTP/2, and HTTP/3 (QUIC) on the client side. Origin pulls support HTTP/1.1 and HTTP/2.
## Caching
### What is the default cache TTL?
The edge respects your origin's `Cache-Control: max-age` and `Expires` headers. To override, configure a [cache rule](/docs/cdn/distributions/cache-rules).
### Why do I keep seeing `x-cache: MISS`?
Common causes:
* Origin sends `Cache-Control: no-store`, `private`, or `max-age=0`.
* Each request has a unique query string and cache-key includes the query.
* Different `Vary` headers fragment the cache.
* Object exceeds the max cacheable size.
Inspect the response with `curl -I` and check the cache rule for the path.
### How do I bust the cache after a deploy?
Use [Purge by Pattern](/docs/cdn/purge/purge-by-pattern) for a path or wildcard, or [Purge All](/docs/cdn/purge/purge-all). Both are available via the API:
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"paths": ["/static/*"]}'
```
## Security
### Is my content secure?
TLS 1.2/1.3, optional WAF, [token-authenticated signed URLs](/docs/cdn/distributions/access-rules/token-authentication), and IP / referrer / country rules. DDoS mitigation runs at the edge.
### How do I protect a private path?
Layer it: token authentication for time-limited URLs, plus referrer or IP rules so a leaked URL still can't be replayed from arbitrary networks. See [Access rules](/docs/cdn/distributions/access-rules/overview).
### Where do I rotate the signing secret?
Per access rule, in the console. Walk through the [rotation runbook](/docs/cdn/distributions/access-rules/token-authentication#rotating-the-secret) before swapping in production.
## Operations
### How do I monitor traffic?
[Analytics](/docs/cdn/analytics/overview) — bandwidth, request count, cache-hit ratio, and response-class breakdown. Pull the same metrics from the API for your dashboards.
### Can I run multi-region or multi-CDN?
Yes. Tenbyte CDN routes to the healthiest edge automatically. For multi-CDN setups, point one CNAME per provider and use a steering DNS (Route 53, NS1) for failover.
### What happens during a regional outage?
Traffic shifts to the next-best PoP via anycast and health checks. Origin is only contacted on cache miss, so cached content keeps serving.
## API and automation
### Where is the API reference?
[CDN API reference](/api-reference/cdn). The OpenAPI spec is published at `https://raw.githubusercontent.com/vidinfra/open-api-docs/refs/heads/main/cdn-openapi.json`.
### How do I authenticate API calls?
Bearer token in the `Authorization` header. Generate one in **Organization → API Keys**:
```bash theme={null}
curl -H "Authorization: Bearer $TENBYTE_API_TOKEN" https://api.tenbyte.io/cdn/distributions
```
### Are there rate limits?
Yes. Standard accounts get a generous per-minute quota that's enough for normal automation. Bulk imports or large purge fan-outs should batch and back off on `429`.
### Are webhooks supported?
Yes — for purge completion, certificate events, and traffic alerts. Configure in the distribution settings.
## Billing
### How is Tenbyte CDN billed?
Pay-as-you-go on bandwidth and requests. No minimums, no long-term commitment. See [Billing](/docs/cloud/billing/billing).
### Does cache miss traffic cost more?
Egress from origin to edge is metered separately. Tuning cache rules to raise hit ratio is the cheapest way to lower bills.
### Are purges billed?
Purges themselves are free. The next request after a purge is a cache miss and counts as origin egress.
## Support
24/7 support via console chat and email. Critical incidents get priority routing.
# Upload a Custom SSL Certificate
Source: https://docs.tenbyte.io/docs/cdn/certificates/custom-certificates
Upload a TLS certificate, private key, and intermediate chain in PEM format. Includes verification commands and rotation flow.
Use a custom certificate when you need EV / OV identity, a wildcard, an internal CA, or a cert your security team manages. You upload PEM-format material and the edge installs it.
For free DV certs, use [Let's Encrypt](/docs/cdn/certificates/lets-encrypt) — it auto-renews.
## Prerequisites
* Custom domain CNAMEs to your distribution.
* Cert files in **PEM** format:
* Server certificate (with `BEGIN CERTIFICATE` / `END CERTIFICATE` lines).
* Private key (with `BEGIN PRIVATE KEY` / `END PRIVATE KEY`).
* Intermediate / chain (one or more PEM blocks concatenated).
* Cert covers the hostname (CN or SAN match).
## Validate locally before uploading
```bash theme={null}
# 1. Subject and SANs cover the hostname
openssl x509 -in cert.pem -noout -subject -ext subjectAltName
# 2. Cert and key match
openssl x509 -in cert.pem -noout -modulus | openssl md5
openssl rsa -in key.pem -noout -modulus | openssl md5
# both md5 hashes must be identical
# 3. Chain validates
openssl verify -CAfile chain.pem cert.pem
# cert.pem: OK
# 4. Expiry
openssl x509 -in cert.pem -noout -dates
```
If any step fails, fix locally before uploading — the upload form does the same checks.
## Upload via console
| Field | Value |
| --------------- | --------------------------------------------------------------------- |
| **Label** | Internal name (`prod-2026-wildcard`). Include year for easy rotation. |
| **Certificate** | Paste the server cert PEM. |
| **Private Key** | Paste the private key PEM. |
| **Chain** | Paste intermediate certs PEM (root not required). |
Tenbyte validates the cert/key match and chain order. On success, attach the cert to your distribution from the **SSL** tab.
## Upload via API
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/certificates" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg label 'prod-2026-wildcard' \
--arg cert "$(cat cert.pem)" \
--arg key "$(cat key.pem)" \
--arg chain "$(cat chain.pem)" \
'{label: $label, certificate: $cert, private_key: $key, chain: $chain}')"
```
Attach to a distribution:
```bash theme={null}
curl -X PUT "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/ssl" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "custom", "certificate_id": "cert_..."}'
```
See the [CDN API reference](/api-reference/cdn) for canonical fields.
## Verify
```bash theme={null}
openssl s_client -connect cdn.yoursite.com:443 -servername cdn.yoursite.com /dev/null | openssl x509 -noout -subject -issuer -dates
```
Confirm `subject` matches your domain and `notAfter` is the expected date.
## Rotation runbook
Custom certs do **not** auto-renew. You must replace before `notAfter`.
| When | Action |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| 30 d before expiry | Calendar reminder fires. Order / generate new cert. |
| 14 d before expiry | Upload new cert via console / API. **Do not detach the old one yet.** |
| 7 d before expiry | Switch the distribution's SSL config to the new `certificate_id`. Verify: `openssl s_client` and SSL Labs. |
| Immediately after | Watch [response classes](/docs/cdn/analytics/response-classes) for unexpected 5xx — rare but possible if the new chain is wrong. |
| Old cert expired | Delete the old cert from the certificate store. |
Never replace a private key on a hot endpoint without a tested rollback. Keep the previous cert + key around for at least one rollback window.
## Common formats and conversions
| You have | Convert to PEM |
| --------------------- | ------------------------------------------------------------------------------------------- |
| `.pfx` / `.p12` | `openssl pkcs12 -in cert.pfx -nodes -out combined.pem`, then split into cert / key / chain. |
| `.cer` (DER) | `openssl x509 -inform DER -in cert.cer -out cert.pem` |
| Private key encrypted | `openssl rsa -in key.pem -out key.pem` (writes unencrypted — handle carefully). |
| Chain order wrong | Concatenate as: leaf → intermediate(s) → (omit root). |
## Troubleshooting
| Symptom | Fix |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Upload rejected — `cert/key mismatch` | The key doesn't match this cert. Re-export both from the same source. |
| Upload rejected — `chain incomplete` | Add the issuing intermediate(s). Test with `openssl verify -CAfile chain.pem cert.pem`. |
| Browser shows `NET::ERR_CERT_AUTHORITY_INVALID` | Chain missing or out of order. Reconcatenate leaf → intermediates. |
| `notAfter` already passed at upload | Generate / order a new cert; you can't upload an expired one. |
| Wildcard cert not matching subdomain | Wildcard covers one level only — `*.example.com` doesn't match `a.b.example.com`. Use a multi-SAN cert. |
## Related
* [SSL Overview](/docs/cdn/certificates/ssl-overview) — pick the right cert type.
* [SSL settings](/docs/cdn/distributions/ssl) — attach the cert and toggle protocols.
* [Headers](/docs/cdn/distributions/headers) — add HSTS once HTTPS is verified.
# Let's Encrypt SSL
Source: https://docs.tenbyte.io/docs/cdn/certificates/lets-encrypt
Automated, free TLS certificates for custom domains via Let's Encrypt. Auto-renews ~30 days before expiry.
Let's Encrypt issues free, domain-validated TLS certificates that auto-renew. It's the right default for any custom domain on Tenbyte CDN.
## When to use Let's Encrypt
* You have a custom domain (`cdn.yoursite.com`) on a Tenbyte CDN distribution.
* Domain Validation (DV) is sufficient — no green-bar EV / OV needed.
* You want zero-touch renewal.
For EV / OV / wildcard / internal CA, see [Custom certificates](/docs/cdn/certificates/custom-certificates).
## How it works
```mermaid theme={null}
sequenceDiagram
participant Y as You
participant T as Tenbyte
participant LE as Let's Encrypt
participant DNS as Public DNS
Y->>T: Pick "Let's Encrypt" SSL
T->>LE: Certificate request
LE->>T: ACME challenge
T->>DNS: Place validation record
LE->>DNS: Verify control of domain
LE->>T: Issue cert
T->>T: Install at edge
Y->>T: Status: Active
```
Renewal runs automatically about 30 days before `notAfter`.
## Prerequisites
* Custom domain configured on the distribution. See [SSL settings](/docs/cdn/distributions/ssl).
* A DNS CNAME from your domain to the distribution hostname:
```text theme={null}
cdn.yoursite.com. 300 IN CNAME your-distribution.tenbytecdn.com.
```
* DNS resolves publicly — Let's Encrypt verifies from the public internet.
Verify before requesting:
```bash theme={null}
dig +short cdn.yoursite.com CNAME
# cdn.yoursite.com. CNAME your-distribution.tenbytecdn.com.
```
## Issue the certificate
1. Open the distribution → **SSL** tab.
2. Choose **Let's Encrypt**.
3. Click **Issue certificate**.
4. Status moves through: `Pending validation` → `Issuing` → `Active`.
Most certs issue within a minute. If it stalls in `Pending`, the DNS isn't pointing at the distribution yet — wait for the TTL to expire and try again.
## Verify
```bash theme={null}
openssl s_client -connect cdn.yoursite.com:443 -servername cdn.yoursite.com /dev/null | openssl x509 -noout -subject -issuer -dates
```
Expected:
```text theme={null}
subject=CN = cdn.yoursite.com
issuer=C = US, O = Let's Encrypt, CN = R3
notBefore=May 9 00:00:00 2026 GMT
notAfter=Aug 7 23:59:59 2026 GMT
```
## Renewal
| Event | What happens |
| --------------------------- | ---------------------------------------------------- |
| \~30 days before `notAfter` | Tenbyte requests a renewal automatically. |
| Validation succeeds | New cert is hot-swapped at the edge — zero downtime. |
| Validation fails | Webhook + console alert fires. |
You don't need to do anything. If renewal fails, the most common cause is the DNS CNAME was changed or removed.
## Limitations
* **DV only.** No organizational identity in the cert.
* **No wildcards by default.** Use a custom cert if you need `*.yoursite.com`.
* **Public DNS only.** Internal-only domains can't validate; use a custom cert from your internal CA.
* **Rate limits.** Let's Encrypt limits per registered domain (50 certs / week / domain). Plenty for production but worth knowing for spin-up scripts.
## Troubleshooting
| Symptom | Fix |
| -------------------------------------- | --------------------------------------------------------------------------------------------- |
| Stuck at `Pending validation` | DNS not resolving to the distribution. `dig +short` and confirm. |
| Stuck at `Issuing` | Let's Encrypt rate limit hit, or transient ACME outage. Retry after 1 h. |
| Cert active but browser shows mismatch | DNS resolves to the wrong distribution, or you changed the hostname after issuing — re-issue. |
| Renewal failed alert | Confirm CNAME still points at the distribution. Re-issue if it changed. |
## Related
* [SSL Overview](/docs/cdn/certificates/ssl-overview) — pick the right cert type.
* [SSL settings](/docs/cdn/distributions/ssl) — toggle HTTPS redirect, HTTP/2, HTTP/3.
* [Custom certificates](/docs/cdn/certificates/custom-certificates) — bring your own.
# SSL Certificates Overview
Source: https://docs.tenbyte.io/docs/cdn/certificates/ssl-overview
How TLS works on Tenbyte CDN — the three certificate types, when to use each, and renewal expectations.
Every Tenbyte CDN distribution serves over TLS. You pick how the certificate is provisioned: a free Tenbyte cert, automated Let's Encrypt, or a custom cert you upload. This page explains the trade-offs; the per-type pages walk through setup.
## TLS at the edge
```mermaid theme={null}
sequenceDiagram
participant U as User
participant E as Tenbyte edge
participant O as Origin
U->>E: ClientHello (SNI: cdn.yoursite.com)
E->>U: Cert + ServerHello
U->>E: Encrypted request
E->>O: TLS handshake (origin-side)
O->>E: Encrypted response
E->>U: Encrypted response
```
Two TLS sessions exist: client ↔ edge (using the cert on this page) and edge ↔ origin (using your origin's cert). They are independent.
## Choose a certificate type
| Type | Cost | Auto-renew | Best for |
| ------------------------------------------------------------ | ------------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------- |
| **Tenbyte SSL (Free)** | Free | Yes | The system-generated `*.tenbytecdn.com` host. Zero setup. |
| **[Let's Encrypt](/docs/cdn/certificates/lets-encrypt)** | Free | Yes (\~30 days before expiry) | Custom domains where you control DNS. |
| **[Custom SSL](/docs/cdn/certificates/custom-certificates)** | Whatever you paid your CA | **No** — you renew | EV / OV certs, wildcards across many subdomains, internal CA, certs your security team manages. |
## Decision flow
```mermaid theme={null}
flowchart TD
Q1{Custom domain?} -- no --> TENBYTE[Use Tenbyte SSL]
Q1 -- yes --> Q2{Bring your own cert?}
Q2 -- no --> LE[Use Let's Encrypt]
Q2 -- yes --> CUSTOM[Upload Custom SSL]
```
## What's included regardless of type
* **TLS 1.2 + 1.3** with modern cipher suites.
* **HTTP/2** and **HTTP/3 (QUIC)** offered when negotiated.
* **OCSP stapling** for fast revocation checks.
* **SNI** for multi-tenant edge routing.
## Operational checklist
* [ ] Custom domain CNAMEs to your distribution.
* [ ] Cert covers the exact hostname (no wildcard surprises).
* [ ] HTTPS redirect is on for production traffic. See [SSL settings](/docs/cdn/distributions/ssl).
* [ ] HSTS configured via [response headers](/docs/cdn/distributions/headers) once you're sure all subdomains are HTTPS.
* [ ] Custom certs: calendar reminder set 30 days before `notAfter`.
## Verify a cert
```bash theme={null}
openssl s_client -connect cdn.yoursite.com:443 -servername cdn.yoursite.com /dev/null | openssl x509 -noout -subject -issuer -dates
```
For a deeper grade, run [SSL Labs](https://www.ssllabs.com/ssltest/).
## Related
* [SSL configuration](/docs/cdn/distributions/ssl) — pick the type and toggle HTTP/2/3 / redirects.
* [Custom certificates](/docs/cdn/certificates/custom-certificates) — upload PEM, manage chain, renew.
* [Let's Encrypt](/docs/cdn/certificates/lets-encrypt) — automated DV cert flow.
# Country Access Policy
Source: https://docs.tenbyte.io/docs/cdn/distributions/access-rules/country-access-policy
Allow or deny CDN requests based on the requester country.
Restrict who can fetch content based on the requester's country. Useful for licensing, regional rollouts, and compliance.
## Allow by default
All countries are allowed unless you list exceptions to deny.
## Deny by default
All countries are blocked unless you list specific countries to allow.
## When to use this
* License a video catalog only to specific markets.
* Block traffic from regions outside your business footprint.
* Stage a regional launch before going global.
Country detection uses the requester IP. VPN traffic resolves to the VPN exit country, not the user's true location.
# IP Access Policy
Source: https://docs.tenbyte.io/docs/cdn/distributions/access-rules/ip-access-policy
Allow or deny CDN requests by IP address or CIDR range.
Control distribution access at the network level. Allow or deny individual IPs or full CIDR ranges.
## Modes
* **Allow by default** — anyone can access; you list IPs/ranges to block.
* **Deny by default** — access blocked; you list IPs/ranges that may pass.
## CIDR notation
Use CIDR to express ranges in a single line.
| Notation | Meaning |
| ---------------- | ----------------------------- |
| `203.0.113.42` | Single host |
| `203.0.113.0/24` | 256 addresses (one /24 block) |
| `10.0.0.0/8` | All `10.x.x.x` addresses |
## When to use this
* Restrict an internal staging origin to your office IP range.
* Block known abusive IPs while keeping the rest open.
* Limit a partner-only feed to their egress IPs.
# Access Rules Overview
Source: https://docs.tenbyte.io/docs/cdn/distributions/access-rules/overview
Set up access control for your Tenbyte CDN distribution with country, IP, referrer, and token-based restrictions.
Access rules let you control who can fetch content from your Tenbyte CDN distribution. Each rule scopes a set of policies (country, IP, referrer, and token authentication) to a path prefix or regex pattern, so different parts of your distribution can have different protections.
## How access rules work
* A distribution can have multiple access rules.
* Each rule targets a URL pattern (prefix or regex).
* Within a rule, you can enable any combination of the four policies below.
* Requests that match the pattern must satisfy every enabled policy on that rule.
| Policy | Use case |
| ------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [Country Access Policy](/docs/cdn/distributions/access-rules/country-access-policy) | Geo-block or geo-allow regions |
| [IP Access Policy](/docs/cdn/distributions/access-rules/ip-access-policy) | Allow or block specific IPs / CIDR ranges |
| [Referrer Access Policy](/docs/cdn/distributions/access-rules/referrer-access-policy) | Stop hotlinking from other domains |
| [Token Authentication](/docs/cdn/distributions/access-rules/token-authentication) | Issue time-limited signed URLs for protected content |
## General Info
The **General Info** section defines the rule name, type, and matching pattern.
* **Rule Name** — unique identifier for the rule.
* **Rule Type** — how the match pattern is interpreted:
1. **Prefix** — applies to URLs that begin with the pattern.
2. **Regex** — applies to URLs matching the regular expression.
* **Match Pattern** — the path or pattern the rule applies to.
Spaces are not allowed, the pattern cannot start with `*`, and it must start with `/`.
## Create an access rule
1. Open **CDN** → **Distributions** → select your distribution.
2. Go to **Access Rules** → **Add Access Rules**.
3. Fill in **Rule Name**, **Rule Type**, and **Match Pattern**.
4. Toggle on the policies you want to enforce and configure each.
5. Click **Create Access Rules**.
# Referrer Access Policy
Source: https://docs.tenbyte.io/docs/cdn/distributions/access-rules/referrer-access-policy
Allow or deny CDN requests based on the HTTP Referer header to prevent hotlinking.
Control which sites can embed or link to your CDN content based on the HTTP `Referer` header.
## Modes
* **Allow by default** — every referrer can fetch content; list domains to block.
* **Deny by default** — only domains in your allowlist can fetch content.
Add allowed or blocked domains under **Specify Domain(s)**.
## When to use this
* Stop other sites from hotlinking your images, videos, or downloads.
* Pin your video player to a known set of partner sites.
The `Referer` header is sent by the client and can be spoofed or stripped. For high-value content, combine referrer rules with [Token Authentication](/docs/cdn/distributions/access-rules/token-authentication).
# Token Authentication
Source: https://docs.tenbyte.io/docs/cdn/distributions/access-rules/token-authentication
Protect CDN content with time-limited signed URLs. Includes signing examples, curl tests, player integration, and operational guidance.
Token authentication protects content with **time-limited signed URLs**. Each URL carries an MD5-based token plus an expiry timestamp; the CDN edge validates both before serving the file. Links expire on schedule and cannot be tampered with — the secret never leaves your server.
Use it for HLS / DASH streams, private downloads, embedded video players, and any media you want gated behind your application's auth.
## Request flow
```mermaid theme={null}
sequenceDiagram
participant U as User
participant A as Your app (server)
participant C as Tenbyte CDN edge
participant O as Origin
U->>A: Request resource (after auth)
A->>A: Sign URL with secret + expiry
A-->>U: Signed URL (md5, expires)
U->>C: GET signed URL
C->>C: Recompute hash, check expires
alt token valid
C->>O: Fetch (or serve from cache)
O-->>C: Bytes
C-->>U: 200 OK
else token bad / expired
C-->>U: 403 Forbidden
end
```
The secret stays on your server. Clients only ever see the finished signed URL.
## Enable token authentication
1. Open **CDN** → **Distributions** → select your distribution.
2. Go to **Access Rules** → **Add Access Rules** (or open an existing rule).
3. Set the **Match Pattern** to the path you want to protect (for example `/videos/*`).
4. Toggle **Token Authentication** on.
5. Click **Generate Token** to mint a **Secret Token**, then **Copy Token**.
6. Click **Create Access Rules** to save.
Token authentication is configured **per access rule**, not globally. Each rule has its own secret, so you can scope tokens to a path prefix and rotate them independently.
Treat the secret like a database password. Store it in your secret manager (AWS Secrets Manager, GCP Secret Manager, Vault, Doppler, etc.), inject it via environment variable, and never commit it to a repo or expose it in client-side code.
## URL anatomy
```
https://.tenbytecdn.com/?md5=&expires=
```
| Part | Source | Notes |
| ---------------- | -------------------------- | --------------------------------------------------------------------------------------------------- |
| `` | Your distribution hostname | Can be a custom domain CNAMEd to the distribution. |
| `` | Path to the asset | Must start with `/`. Must match the access rule's **Match Pattern**, otherwise the rule is skipped. |
| `md5` | Computed token | URL-safe base64 of the MD5 hash. No `+`, `/`, or `=`. |
| `expires` | Unix timestamp (seconds) | After this, the edge returns `403`. |
## Signing algorithm
1. Build the string `{expires}{path} {secret}` — note the **single space** before the secret.
2. MD5 hash with **raw binary** output (16 bytes), not hex.
3. Base64-encode the binary hash.
4. Make the base64 URL-safe: replace `+` → `-`, `/` → `_`, strip `=` padding.
5. Append `?md5={token}&expires={unix_timestamp}` to the CDN URL.
## Configuration
Drive everything from environment variables — never hard-code the secret.
```bash .env theme={null}
TENBYTE_CDN_HOST=https://your-distribution.tenbytecdn.com
TENBYTE_CDN_SECRET=replace-with-secret-from-console
TENBYTE_CDN_TTL=1800
```
| Variable | Description | Example |
| -------------------- | ----------------------------------------- | ------------------------------------------ |
| `TENBYTE_CDN_HOST` | Distribution hostname (no trailing slash) | `https://your-distribution.tenbytecdn.com` |
| `TENBYTE_CDN_SECRET` | Secret token from the access rule | injected at runtime |
| `TENBYTE_CDN_TTL` | Token lifetime in seconds | `1800` (30 min) |
## Generate signed URLs
Reference implementations live in the [tenbyte-cdn-signed-url-example](https://github.com/vidinfra/tenbyte-cdn-signed-url-example) repo. Pick a language, copy the function, swap your config.
```php PHP theme={null}
str:
"""Build a signed Tenbyte CDN URL.
cdn_host: distribution host, e.g. "https://xxx.tenbytecdn.com"
path: resource path, must start with "/"
secret: CDN secret token (server-side only)
ttl: token lifetime in seconds (default 1800)
"""
expires = int(time.time()) + ttl
link = f"{expires}{path} {secret}".encode()
digest = hashlib.md5(link).digest()
token = base64.b64encode(digest).decode()
token = token.replace("+", "-").replace("/", "_").rstrip("=")
return f"{cdn_host.rstrip('/')}{path}?md5={token}&expires={expires}"
if __name__ == "__main__":
print(tenbyte_signed_url(
os.environ["TENBYTE_CDN_HOST"],
"/videos/sample/index.m3u8",
os.environ["TENBYTE_CDN_SECRET"],
int(os.environ.get("TENBYTE_CDN_TTL", 1800)),
))
```
```lua Lua theme={null}
-- Standalone Lua: requires "md5" and "lbase64" from luarocks.
-- OpenResty: see ngx variant below.
local md5_lib = require("md5")
local base64 = require("base64")
local function tenbyte_signed_url(cdn_host, path, secret, ttl)
ttl = ttl or 1800
local expires = os.time() + ttl
local link = expires .. path .. " " .. secret
local raw = md5_lib.sum(link)
local token = base64.encode(raw)
token = token:gsub("%+", "-"):gsub("/", "_"):gsub("=", "")
cdn_host = cdn_host:gsub("/+$", "")
return string.format("%s%s?md5=%s&expires=%d", cdn_host, path, token, expires)
end
print(tenbyte_signed_url(
os.getenv("TENBYTE_CDN_HOST"),
"/videos/sample/index.m3u8",
os.getenv("TENBYTE_CDN_SECRET"),
tonumber(os.getenv("TENBYTE_CDN_TTL")) or 1800
))
```
```lua OpenResty theme={null}
-- Drop-in for OpenResty / Nginx with lua-nginx-module.
-- No luarocks needed.
local function tenbyte_signed_url(cdn_host, path, secret, ttl)
ttl = ttl or 1800
local expires = ngx.time() + ttl
local link = expires .. path .. " " .. secret
local token = ngx.encode_base64(ngx.md5_bin(link))
token = token:gsub("%+", "-"):gsub("/", "_"):gsub("=", "")
cdn_host = cdn_host:gsub("/+$", "")
return string.format("%s%s?md5=%s&expires=%d", cdn_host, path, token, expires)
end
```
## Verify with curl
Mint a URL, hit the edge, expect `200`:
```bash theme={null}
SIGNED_URL="$(node js/index.js)" # or php/go/python equivalent
curl -sSI "$SIGNED_URL" | head -1
# HTTP/2 200
```
Negative tests — both should return `403`:
```bash theme={null}
# Tampered path (token won't match)
curl -sSI "${SIGNED_URL/index.m3u8/secret.m3u8}" | head -1
# Expired
curl -sSI "${SIGNED_URL/expires=*/expires=1}" | head -1
```
## Use the URL in a player
The signed URL is a normal HTTPS URL — drop it into any player. For HLS streams, sign the manifest only; segments inherit the rule as long as the **Match Pattern** covers them.
```html HTML5 video theme={null}
```
```javascript hls.js theme={null}
import Hls from "hls.js";
const res = await fetch("/api/stream/123"); // your backend signs the URL
const { url } = await res.json();
const video = document.querySelector("video");
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
} else {
video.src = url; // Safari / native HLS
}
```
## Operations
### Choosing a TTL
| Workload | Suggested TTL | Why |
| ----------------- | ------------- | ---------------------------------------------------------------------- |
| Image / thumbnail | 60–300 s | Short request, easy to re-sign on retry. |
| Private download | 5–15 min | Long enough for a slow connection, short enough to limit URL sharing. |
| HLS / DASH live | 1–4 h | Must outlast the session: full playback + ABR switches + pause/resume. |
| HLS VOD | 2–6 h | Should cover the longest expected viewing session in one URL. |
Set TTL ≥ longest possible playback session. If a viewer pauses past the expiry, the next segment fetch returns `403` and the player stalls.
### Clock skew
`expires` is compared against the edge's wall clock. Servers signing URLs should run NTP. If your sign host drifts ahead, the edge sees a token that is "already expired"; if it drifts behind, tokens live longer than expected. A skew of ±60 seconds is usually invisible — anything more is a config issue.
### Rotating the secret
The console only stores **one** active secret per access rule. Rotation is a hard cutover, so do it at low traffic and keep a short overlap by issuing short-TTL tokens leading up to the swap.
```text theme={null}
T-1h Drop new sign-time TTL to 5 min so old tokens age out fast
T-0 Click Regenerate, copy new secret
T-0+s Push new secret to your secret manager / app config
T-0+m Restart / reload signing services
T+5m Old tokens fully expired — back to normal TTL
```
### Multiple environments
Use **one access rule per environment** with its own secret and a path prefix that namespaces traffic — for example `/prod/*` and `/staging/*`. That way a leaked staging secret cannot sign production URLs.
### Logging and observability
* Log the **path** you signed and **expires** value, never the secret or the full signed URL — query strings often end up in access logs.
* Track edge `403` rate per access rule. A spike usually means clock skew, expired tokens, or a bug in your signer.
* For incident triage, keep the signing function pure (input in, URL out) so you can replay it offline against suspect timestamps.
## Security checklist
* [ ] Secret stored in a secret manager, injected via env var.
* [ ] Signing happens **only** on the server. No browser code, no mobile-client embedded secrets.
* [ ] Per-environment access rules with distinct secrets.
* [ ] TTL is the shortest value your workload tolerates.
* [ ] Rotation runbook documented and tested.
* [ ] Application auth gates the signer endpoint — never let an unauthenticated request mint a URL.
* [ ] Combine with [Referrer](/docs/cdn/distributions/access-rules/referrer-access-policy), [IP](/docs/cdn/distributions/access-rules/ip-access-policy), or [Country](/docs/cdn/distributions/access-rules/country-access-policy) policies for defense in depth.
## Troubleshooting
| Problem | Fix |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `403 Forbidden` on a fresh URL | Path doesn't match the rule's **Match Pattern**, or your sign host's clock is ahead of the edge. Check `date -u` and the rule pattern. |
| Token works in PHP but not Go / Node / Python | MD5 must be **raw binary** before base64, not the hex string. |
| URL contains `+` or `/` and breaks | Apply the URL-safe base64 step (`+` → `-`, `/` → `_`). |
| Trailing `=` in token causes `403` | Strip all `=` padding. |
| Manifest plays, segments `403` | Access rule pattern only covers the manifest. Broaden the pattern (e.g. `/videos/*`) so segment paths match. |
| Works in `curl` but not the browser | Browser cached an old manifest. Bust cache or use a fresh signed URL. |
| Intermittent `403` near expiry | TTL too short for the session. Bump TTL or re-sign on player error. |
# Manage Cache Rules
Source: https://docs.tenbyte.io/docs/cdn/distributions/cache-rules
Set per-path TTLs, control cache-key behavior, and override origin no-cache headers. Includes curl checks and TTL recipes.
Cache rules tell the edge how long to keep a response and what counts as the same response. A high cache-hit ratio is the cheapest way to lower origin load and improve P95 latency.
## How the edge cache works
```mermaid theme={null}
flowchart LR
REQ[Request] -->|build cache key| KEY[path + query + Vary]
KEY -->|lookup| CACHE{In cache?}
CACHE -->|HIT, fresh| OUT[Serve cached]
CACHE -->|MISS or stale| ORIGIN[Fetch origin]
ORIGIN --> STORE[Store with TTL]
STORE --> OUT
```
The edge stores responses keyed by URL (and selected headers / query params). On the next request for the same key, it serves the cached copy until TTL expires.
## General Info
| Field | Notes |
| ------------------- | ----------------------------------------------------------- |
| **Rule Name** | Internal label. |
| **Rule Type** | `Prefix` (URL starts with) or `Regex` (full pattern match). |
| **Match Pattern** | Must start with `/`. No spaces. No leading `*`. |
| **Expiration Time** | TTL in the cache. |
## Rule Configurations
| Toggle | Effect | Use when |
| ------------------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
| **Ignore Origin Server No Cache** | Cache the response even if origin sends `Cache-Control: no-cache` / `private`. | Origin you don't fully control still sends `private` for cacheable assets. |
| **Ignore Client No Cache** | Ignore `Cache-Control: no-cache` from the client. | Block clients from forcing origin fetches (DDoS-ish). |
| **Never Cache** | Bypass cache entirely. | Per-user dashboards, auth callbacks, anything tied to identity. |
| **Ignore Query String in Cache Key** | Drop `?...` when computing the cache key. | Tracking-only params (`utm_*`, `fbclid`) — same content, many URLs. |
| **Gzip Compression** | Serve compressed responses to clients that send `Accept-Encoding`. | Text-heavy assets (HTML, CSS, JS, JSON, SVG). |
Enabling **Ignore Query String in Cache Key** on a path with legitimate variant query strings (e.g. `?w=400` for image resize) collapses every variant to the same cache entry. Scope the rule to a precise prefix.
## TTL recipes
| Asset | Cache-Control | Expiration | Notes |
| --------------------------------------------- | ------------------------------------- | ---------------------- | -------------------------------------- |
| Hashed JS / CSS / fonts (`/static/abc123.js`) | `public, max-age=31536000, immutable` | 1 y | Filename changes invalidate naturally. |
| Images (versioned by path) | `public, max-age=2592000` | 30 d | Refresh on path change. |
| HTML entry point | `public, max-age=60, must-revalidate` | 60 s | Fast deploys, low risk of stale shell. |
| API GET (idempotent) | `public, max-age=10` | 10 s | Tiny TTL still flattens spikes. |
| User-specific JSON | n/a (Never Cache) | n/a | Privacy + correctness. |
| HLS / DASH segment | `public, max-age=10` | match segment duration | Live streams: TTL ≤ segment duration. |
| HLS manifest | `public, max-age=2` | 2 s | Refreshes ABR ladder updates. |
## Verify cache behavior
```bash theme={null}
# 1. Warm the cache
curl -sSI "$CDN_HOST/static/main.js" >/dev/null
# 2. Confirm HIT and inspect TTL
curl -sSI "$CDN_HOST/static/main.js" \
| grep -iE 'http/|x-cache|cache-control|age'
```
Expected:
```text theme={null}
HTTP/2 200
cache-control: public, max-age=31536000, immutable
x-cache: HIT
age: 42
```
`age` is seconds since the edge cached this object. When `age` approaches `max-age`, the next request triggers a revalidation.
## Cache key tuning
By default the cache key is `host + path + sorted query string`. You typically want to drop:
* **Tracking params** — `utm_*`, `fbclid`, `gclid`. They don't change the response.
* **Session-style params** — only on truly static assets.
Use a regex rule with **Ignore Query String in Cache Key** on the static prefix only.
## Compression
Tenbyte CDN supports Gzip (and increasingly Brotli) at the edge. Enable on text-based MIME types only — already-compressed binary (images, video, archives) gains nothing.
```bash theme={null}
curl -sSI -H "Accept-Encoding: gzip" "$CDN_HOST/static/main.js" \
| grep -i content-encoding
# content-encoding: gzip
```
## Manage via API
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/cache-rules" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "static-assets-1y",
"rule_type": "prefix",
"match_pattern": "/static/",
"expiration_seconds": 31536000,
"ignore_origin_no_cache": true,
"ignore_query_string_in_key": true,
"gzip_compression": true
}'
```
See the [CDN API reference](/api-reference/cdn) for canonical fields.
## Operational tips
* **Tune by hit ratio.** [Cache hit ratio](/docs/cdn/analytics/cache-hit-ratio) below 80% on static content usually means a noisy query string or wrong TTL.
* **Stale-while-revalidate where supported.** Origin can emit `Cache-Control: max-age=60, stale-while-revalidate=86400` for a smooth deploy story.
* **Don't `Never Cache` everything.** Even short TTLs (5–10 s) blunt traffic spikes hard.
* **Purge before changing TTL down.** A long-cached object stays cached for the original TTL — cut TTL **and** [purge](/docs/cdn/purge/purge-by-pattern) to roll out.
* **Watch `Vary`.** Origin returning `Vary: User-Agent` fragments the cache by browser. Strip or narrow at the edge.
## Troubleshooting
| Symptom | Likely cause |
| ----------------------------------- | ------------------------------------------------------------------------------------ |
| `x-cache: MISS` every request | Origin sends `Cache-Control: private` / `no-store`, or **Never Cache** is on. |
| `x-cache: HIT` but stale content | TTL too long. Purge the path and lower the rule's TTL. |
| Cache entries explode for one URL | Cache key includes a noisy query string. Enable Ignore Query String for that prefix. |
| Compressed response missing on text | Gzip not enabled or origin already returned `Content-Encoding: identity`. |
# Create a CDN Distribution
Source: https://docs.tenbyte.io/docs/cdn/distributions/create-distribution
Create a Tenbyte CDN distribution from the console or API. Covers domain setup, cache strategy, origin types, and host header config.
A **distribution** is the CDN endpoint your users hit. It maps a hostname to one or more origins, applies cache and access rules, and serves traffic from edge PoPs.
## Prerequisites
* A reachable origin (HTTPS hostname, IP, or S3-compatible bucket).
* DNS access if you plan to use a custom domain (you'll add a CNAME).
* An API token if creating distributions from CI/CD.
## Steps
Use a clear, environment-prefixed name (`prod-web`, `staging-images`). Names show up in audit logs and metrics.
System-generated for quick tests, custom domain for production.
Static, VOD, livestream, or dynamic — sets sensible TTL defaults you can override later.
Hostname, IP, or S3-compatible bucket.
Custom Host header for virtual-hosted origins.
`curl -I` the distribution domain and confirm a `200`.
## Domain type
| Option | When to use |
| -------------------- | ---------------------------------------------------------------------------------------------------- |
| **System Generated** | Quick test, internal tools, or when DNS isn't ready. Tenbyte gives you a `.tenbytecdn.com` host. |
| **Custom** | Production. Add `cdn.yoursite.com` and CNAME it to the system-generated host. |
For a custom domain, create a DNS record like:
```text theme={null}
cdn.yoursite.com. 300 IN CNAME your-distribution.tenbytecdn.com.
```
Issue an SSL cert in [SSL](/docs/cdn/distributions/ssl) before going live.
## Cache strategy
| Strategy | Default TTL profile | Use for |
| -------------- | ------------------------------------- | ------------------------- |
| **Static** | Long TTL, full cache | Images, JS, CSS, fonts |
| **VOD** | Segmented cache, large object support | MP4, HLS / DASH on-demand |
| **Livestream** | Short TTL, frequent refresh | HLS / DASH live segments |
| **Dynamic** | Minimal cache | API responses, SSR pages |
The strategy seeds defaults; you can still add fine-grained [cache rules](/docs/cdn/distributions/cache-rules) per path.
## Origin
The origin is the upstream the CDN pulls from on cache miss. Pick one of two types.
### Hostname origin
* **Origin Label** — internal name.
* **Hostname / IP** — must be reachable over HTTPS or HTTP.
### S3-compatible origin
* **Origin Label** — internal name.
* **Hostname** — endpoint of the S3-compatible service (e.g. `s3.amazonaws.com`, `s3.us-east-1.amazonaws.com`, `nyc3.digitaloceanspaces.com`).
* **Access Key ID** / **Secret Access Key** — credentials with read access to the bucket.
* **Bucket** — bucket name.
* **Region** — bucket region.
Use a **read-only** IAM user/key. Never reuse a key with write or delete permissions. Rotate the key periodically — Tenbyte's signed-fetch logic handles rotation transparently if you update both fields together.
Verify the origin can be read with the same credentials:
```bash theme={null}
aws s3 ls "s3://my-bucket/" \
--endpoint-url "https://s3.us-east-1.amazonaws.com" \
--region us-east-1
```
## Advanced settings
The **Host header** is what the origin sees in `Host:`. Set it explicitly when:
* Your origin uses virtual hosting (multiple sites on one IP).
* The origin's TLS cert is issued for a specific hostname.
* A reverse proxy or load balancer routes by Host.
| Field | Example |
| ----- | --------------------- |
| Key | `Host` |
| Value | `origin.yoursite.com` |
## Verify the distribution
```bash theme={null}
export CDN_HOST="https://your-distribution.tenbytecdn.com"
curl -sSI "$CDN_HOST/" | grep -iE 'http/|x-cache|server'
```
Expected:
```text theme={null}
HTTP/2 200
x-cache: MISS # first request
server: tenbyte-cdn
```
Repeat the call. `x-cache` should flip to `HIT`.
## Create via API
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/distributions" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "prod-web",
"domain_type": "system",
"cache_strategy": "static",
"origin": {
"type": "hostname",
"label": "origin-prod",
"hostname": "origin.yoursite.com"
}
}'
```
See the [CDN API reference](/api-reference/cdn) for the full schema and updated field names.
## Common pitfalls
| Symptom | Cause |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `502 Bad Gateway` from CDN | Origin unreachable, wrong port, or TLS cert mismatch. Check origin from outside your network. |
| `403` from S3 origin | Credentials missing `s3:GetObject` on the bucket / prefix. |
| Wrong content served | Custom Host header missing — virtual host routing on origin picks the default vhost. |
| `x-cache: MISS` every request | Origin sends `Cache-Control: no-store` or `private`. Override via [cache rules](/docs/cdn/distributions/cache-rules). |
# Distribution Overview
Source: https://docs.tenbyte.io/docs/cdn/distributions/distribution-overview
Inspect distribution status, hostname, configuration, and lifecycle metadata from the console or API.
The **Overview** tab is your at-a-glance status for a single distribution: hostname, current state, when it was created, and basic config you can edit in place.
## Open the distribution
From the CDN workspace, click **Action → Manage** on the row for your distribution.
The detail dashboard opens. Pick **Overview** in the left sidebar.
## Distribution details
| Field | What it means |
| ----------------- | -------------------------------------------------------------------------------------- |
| **Domain** | The CDN hostname (system-generated or your custom one). Click **Copy Domain** to copy. |
| **Status** | Lifecycle state — see the table below. |
| **Created On** | Distribution creation timestamp. |
| **Last Modified** | Timestamp of the most recent config change (cache rules, headers, origin, etc.). |
### Status values
| Status | Meaning | Action |
| -------------- | ------------------------------- | ---------------------------------------------------- |
| `Provisioning` | Edge config is rolling out. | Wait — usually under a minute. Don't switch DNS yet. |
| `Deployed` | Active everywhere. | Safe to send traffic. |
| `Updating` | A config change is propagating. | Existing traffic is unaffected. |
| `Disabled` | Distribution is paused. | The hostname returns `503` until re-enabled. |
## Configuration
| Field | Notes |
| --------------------- | ------------------------------------------------------------------ |
| **Distribution Name** | Internal label. Changing this does not affect the public hostname. |
| **Description** | Free-text. Use it for owner / team / runbook links. |
## Inspect via API
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq '{name, domain, status, last_modified}'
```
Expected:
```json theme={null}
{
"name": "prod-web",
"domain": "your-distribution.tenbytecdn.com",
"status": "Deployed",
"last_modified": "2026-05-09T10:42:11Z"
}
```
Wire this into a healthcheck so deploys block on `Deployed`.
## Quick health checks
```bash theme={null}
# 1. Edge reachable?
curl -sSI "https://$CDN_HOST/" | head -1
# 2. TLS valid?
openssl s_client -connect "$CDN_HOST:443" -servername "$CDN_HOST" /dev/null | openssl x509 -noout -subject -dates
# 3. HTTP/2 / HTTP/3 negotiated?
curl -sS --http2 -o /dev/null -w '%{http_version}\n' "https://$CDN_HOST/"
```
See [SSL](/docs/cdn/distributions/ssl) and [Headers](/docs/cdn/distributions/headers) for tuning.
# Configure HTTP Headers
Source: https://docs.tenbyte.io/docs/cdn/distributions/headers
Control Host, CORS, request, and response headers at the edge. Includes security header recipes and curl verification.
Header rules let you rewrite, add, or strip HTTP headers at the edge — without touching your origin. Use them for routing (Host), browser policy (CORS, security headers), and observability (request tagging).
## Header types
| Type | Direction | Common use |
| ------------------- | -------------- | ----------------------------------------- |
| **Host header** | Edge → origin | Virtual hosting, SNI matching. |
| **CORS** | Edge → browser | Allow cross-origin XHR / fetch. |
| **Request header** | Edge → origin | Tag requests, forward auth tokens. |
| **Response header** | Edge → browser | Cache-control, security, custom branding. |
## Host header
Toggle **Host Header** on, then set:
| Field | Example |
| --------- | -------------------- |
| **Key** | `Host` |
| **Value** | `origin.example.com` |
Set this when your origin uses virtual hosting or its TLS cert is for a name other than the distribution hostname.
## CORS headers
Toggle **CORS Headers** on. Pick:
* **`*`** — allow any origin (fine for fully public assets).
* **Specify Origin** — allowlist a domain (e.g. `https://app.yoursite.com`). The CDN echoes that exact origin in `Access-Control-Allow-Origin` only when the request matches.
Don't use `*` for any URL that requires credentials (cookies, `Authorization` header). Browsers block credentialed cross-origin requests against `*`. Use a specific origin.
Verify with curl:
```bash theme={null}
curl -sSI -H "Origin: https://app.yoursite.com" "$CDN_HOST/api/data" \
| grep -i 'access-control'
```
Expected:
```text theme={null}
access-control-allow-origin: https://app.yoursite.com
access-control-allow-methods: GET, POST, OPTIONS
```
## Request headers
Toggle **Request Header** on, click **Add Header**, then set name + value. The header is added to every origin fetch.
Use cases:
* **Tagging** — `X-Edge-Pop: ` for log correlation.
* **Auth forwarding** — pin an `Authorization: Bearer ...` for a private origin.
* **Routing** — `X-Tenant: prod` so a multi-tenant origin picks the right backend.
```text theme={null}
Add Header → "X-CDN-Source": "tenbyte"
```
## Response headers
Two actions:
| Action | Effect |
| -------- | ----------------------------------------------------------------- |
| **Add** | Append a header on the way out (overrides origin if same name). |
| **Hide** | Strip a header from the response (e.g. `Server`, `X-Powered-By`). |
### Security header recipe
A reasonable baseline for static / SPA distributions:
| Header | Value |
| --------------------------- | ---------------------------------------------- |
| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains; preload` |
| `X-Content-Type-Options` | `nosniff` |
| `X-Frame-Options` | `DENY` |
| `Referrer-Policy` | `strict-origin-when-cross-origin` |
| `Permissions-Policy` | `geolocation=(), camera=(), microphone=()` |
| `Content-Security-Policy` | App-specific; start with `default-src 'self'`. |
Verify:
```bash theme={null}
curl -sSI "$CDN_HOST/" | grep -iE 'strict-transport|x-content|x-frame|referrer|permissions|content-security'
```
### Hide leaky headers
```text theme={null}
Hide → "Server"
Hide → "X-Powered-By"
```
These leak origin software versions. Strip them at the edge.
## Response cache headers
Add `Cache-Control` at the edge to override or supplement origin headers:
| Asset class | `Cache-Control` |
| ---------------- | ------------------------------------- |
| Hashed JS / CSS | `public, max-age=31536000, immutable` |
| HTML entry point | `public, max-age=60, must-revalidate` |
| Private API JSON | `private, no-store` |
For path-specific TTLs, prefer [Cache rules](/docs/cdn/distributions/cache-rules) — they affect the **edge cache**, while a `Cache-Control` response header instructs the **browser**.
## Manage via API
```bash theme={null}
curl -X PUT "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/headers" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"host": {"enabled": true, "value": "origin.example.com"},
"cors": {"enabled": true, "origin": "https://app.yoursite.com"},
"response_add": [
{"name": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains"},
{"name": "X-Content-Type-Options", "value": "nosniff"}
],
"response_hide": ["Server", "X-Powered-By"]
}'
```
See the [CDN API reference](/api-reference/cdn) for the canonical schema.
## Troubleshooting
| Symptom | Fix |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| CORS preflight fails (`OPTIONS` returns no headers) | Add `OPTIONS` to allowed methods, or enable CORS Headers. |
| Browser blocks credentialed request | Replace `*` with a specific origin and add `Access-Control-Allow-Credentials: true` via response header. |
| Origin gets wrong vhost | Host header missing or wrong. |
| Security header missing on some paths | Header rules apply distribution-wide; check for cache-poisoned responses cached before the rule was added — purge the path. |
# Manage your CDN Origins
Source: https://docs.tenbyte.io/docs/cdn/distributions/origins
Connect a hostname or S3-compatible bucket as your distribution origin. Includes connectivity checks, IAM scoping, and failure modes.
The **origin** is the upstream Tenbyte CDN pulls from on cache miss. You can attach a hostname/IP or an S3-compatible bucket. The edge then caches the response per your rules.
## Origin types
| Type | When to use |
| ------------- | ------------------------------------------------------------------------------------------------------ |
| **Hostname** | Web servers, app servers, load balancers, anywhere reachable by HTTP(S). |
| **S3 Bucket** | AWS S3, Cloudflare R2, DigitalOcean Spaces, Tenbyte T2 Object Storage, MinIO — anything S3-compatible. |
## Hostname origin
| Field | Notes |
| ---------------- | ------------------------------------------------------------------- |
| **Origin Label** | Internal identifier for logs and dashboards. |
| **Domain / IP** | FQDN (`origin.example.com`) or IP. The edge talks HTTPS by default. |
Verify reachability before saving:
```bash theme={null}
curl -sSI "https://origin.example.com/healthz"
# expect 200 OK
```
If the origin uses virtual hosting or has a TLS cert for a different name, set a custom **Host header** in [Headers](/docs/cdn/distributions/headers).
## S3-compatible origin
| Field | Example |
| ----------------------- | ---------------------------------------------- |
| **Origin Label** | `prod-assets-s3` |
| **Endpoint / Hostname** | `s3.us-east-1.amazonaws.com` |
| **Access Key ID** | from your IAM user / service account |
| **Secret Access Key** | injected once, stored encrypted |
| **Bucket** | bucket name only, no path |
| **Region** | bucket region (`us-east-1`, `eu-west-1`, etc.) |
### Endpoint cheat sheet
| Provider | Endpoint |
| --------------------- | --------------------------------------- |
| AWS S3 (regional) | `s3..amazonaws.com` |
| Cloudflare R2 | `.r2.cloudflarestorage.com` |
| DigitalOcean Spaces | `.digitaloceanspaces.com` |
| Backblaze B2 (S3 API) | `s3..backblazeb2.com` |
| Tenbyte T2 | `s3.tenbyte.io` |
| MinIO | your MinIO host |
### Least-privilege IAM
Use a **read-only** key scoped to the bucket / prefix you're serving. Example AWS policy:
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
```
### Verify before saving
```bash theme={null}
aws s3 ls "s3://my-bucket/" \
--endpoint-url "https://s3.us-east-1.amazonaws.com" \
--region us-east-1
aws s3api get-object \
--bucket my-bucket --key index.html \
--endpoint-url "https://s3.us-east-1.amazonaws.com" \
--region us-east-1 /tmp/out.html
```
If both work locally with the same key, the CDN will work too.
## Update origins
After editing fields, click **Update Origins**.
Distribution status flips to `Updating` until the new config rolls out (usually under a minute).
## Manage via API
```bash theme={null}
# Read current origin
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/origins" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
# Replace origin
curl -X PUT "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/origins" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "s3",
"label": "prod-assets-s3",
"hostname": "s3.us-east-1.amazonaws.com",
"bucket": "my-bucket",
"region": "us-east-1",
"access_key_id": "AKIA...",
"secret_access_key": "..."
}'
```
See [CDN API reference](/api-reference/cdn) for the exact field names.
## Rotate S3 keys safely
1. Create a new key pair on the IAM user (so two keys are active).
2. Update the origin via the console or API with the new key.
3. Confirm `x-cache: HIT` and a clean `MISS → HIT` transition for a fresh path.
4. Deactivate / delete the old key in IAM.
## Failure modes
| Symptom | Likely cause |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `502 Bad Gateway` from CDN | Origin unreachable, port closed, TLS handshake failure. |
| `403` from S3 origin | Key missing `s3:GetObject` or bucket policy denies. |
| `404` for a known object | Bucket name wrong, region mismatch, or path includes the bucket prefix twice. |
| Origin returns content but CDN serves nothing | Origin sent `Cache-Control: private` and `Never Cache` is also set. Check [cache rules](/docs/cdn/distributions/cache-rules). |
| Wrong vhost served | Host header missing — configure it in [Headers](/docs/cdn/distributions/headers). |
# SSL Management
Source: https://docs.tenbyte.io/docs/cdn/distributions/ssl
Issue or upload SSL certificates, configure SNI, force HTTPS, and enable HTTP/2 / HTTP/3 on your distribution.
Every Tenbyte CDN distribution serves over TLS. You pick how the cert is provisioned and tune protocol-level options like SNI, redirects, and HTTP/2 / HTTP/3.
## SSL types
| Type | DNS validation | Best for |
| ---------------------- | -------------------------------------- | ----------------------------------------------------------- |
| **Tenbyte SSL (Free)** | Automatic | System-generated `*.tenbytecdn.com` host. Zero setup. |
| **Let's Encrypt** | Domain validation via HTTP-01 / DNS-01 | Custom domains where you control DNS. Free, auto-renews. |
| **Custom SSL** | You manage | Bring-your-own cert (EV, wildcard, internal CA, multi-SAN). |
## Provision a certificate
### Tenbyte SSL (free)
Auto-issued for the system-generated hostname. Nothing to configure.
### Let's Encrypt
1. Pick **Let's Encrypt** as the SSL type.
2. Confirm the custom domain CNAMEs to your distribution:
```bash theme={null}
dig +short cdn.yoursite.com CNAME
# cdn.yoursite.com. CNAME your-distribution.tenbytecdn.com.
```
3. Click **Issue certificate**. Validation runs automatically.
4. Status moves from `Pending` → `Active` once issued. Auto-renewal handles future cycles.
### Custom SSL
Upload an existing cert. See [Custom Certificates](/docs/cdn/certificates/custom-certificates) for the full upload flow and PEM format.
## Verify the cert
```bash theme={null}
openssl s_client -connect cdn.yoursite.com:443 -servername cdn.yoursite.com /dev/null | openssl x509 -noout -subject -issuer -dates
```
Expected output:
```text theme={null}
subject=CN = cdn.yoursite.com
issuer=C = US, O = Let's Encrypt, CN = R3
notBefore=May 9 00:00:00 2026 GMT
notAfter=Aug 7 23:59:59 2026 GMT
```
For browsers, hit the URL and check the lock icon. SSL Labs (`https://www.ssllabs.com/ssltest/`) gives you a deeper grade.
## Additional SSL settings
| Setting | What it does | When to use |
| ------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------- |
| **SNI Hostname** | Sent during the TLS handshake. | Set if your origin's TLS cert doesn't match the distribution hostname. |
| **Redirect HTTP → HTTPS** | Sends `301` for any plain-HTTP request. | Always on for production. |
| **HTTP/2** | Multiplexed connections. | Always on — universally supported. |
| **HTTP/3 (QUIC)** | UDP-based transport, faster on lossy networks. | On for end-user-facing distributions; off if you have strict-firewall users. |
### Verify the protocol
```bash theme={null}
# HTTP/2
curl --http2 -o /dev/null -sS -w 'HTTP version: %{http_version}\n' "https://cdn.yoursite.com/"
# HTTP/3
curl --http3 -o /dev/null -sS -w 'HTTP version: %{http_version}\n' "https://cdn.yoursite.com/"
```
## Renewal and rotation
| Cert type | Renewal |
| ------------- | ------------------------------------------------------------------------------------ |
| Tenbyte SSL | Automatic. No action needed. |
| Let's Encrypt | Automatic, \~30 days before expiry. Failures emit a webhook. |
| Custom SSL | **You** are responsible. Watch `notAfter` and upload the new cert before it expires. |
For custom certs, set a calendar reminder 30 days before `notAfter` and a hard alert 7 days before.
## Operational tips
* **Mixed-content audits** — once HTTPS redirect is on, scan your site for `http://` asset URLs.
* **HSTS** — add `Strict-Transport-Security` via [response headers](/docs/cdn/distributions/headers) only after you're sure all subdomains are HTTPS.
* **Cipher / version** — Tenbyte CDN serves TLS 1.2 and 1.3 with modern cipher suites. Older clients (XP, ancient Android) won't connect.
* **Origin TLS** — the edge talks TLS to your origin too. If you use a self-signed cert, mark the origin as such; otherwise the cert must validate.
## Troubleshooting
| Symptom | Fix |
| --------------------------- | ----------------------------------------------------------------------------------------- |
| Cert stuck at `Pending` | DNS not resolving to the distribution. Confirm CNAME and wait for TTL to expire. |
| Browser shows cert mismatch | SNI Hostname misconfigured, or DNS resolves to a different distribution. |
| Origin handshake fails | Set the SNI Hostname to match the origin's cert CN. |
| Mixed-content warnings | Your HTML still references `http://...` assets. Update or rely on protocol-relative URLs. |
| HTTP/3 not negotiated | Client or network blocks UDP/443. Falls back to HTTP/2 silently. |
# Android and iOS
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/android-ios
Generate optimized image URLs in native mobile apps. Java, Kotlin, Swift examples with width and DPR awareness.
Native mobile apps benefit even more from image optimization than web — bandwidth is precious on mobile networks. Tenbyte transforms work over plain HTTP, so any networking library (OkHttp, URLSession, Glide, Coil, SDWebImage, Kingfisher) just works.
## Pattern
Compute a URL from the view's dimensions and the device's pixel density, then hand the URL to your image loader.
```text theme={null}
https://your-distribution.tenbytecdn.com/photo.jpg?width=&dpr=&format=auto&q=80
```
## Android (Java)
```java theme={null}
public String buildImageUrl(View view, String baseImageUrl, float density) {
int width = view.getWidth() - view.getPaddingLeft() - view.getPaddingRight();
int dpr = Math.round(density);
return baseImageUrl
+ (baseImageUrl.contains("?") ? "&" : "?")
+ "width=" + width
+ "&dpr=" + dpr
+ "&format=auto&q=80";
}
```
Usage with Glide:
```java theme={null}
String url = buildImageUrl(imageView, "https://your-distribution.tenbytecdn.com/photo.jpg",
getResources().getDisplayMetrics().density);
Glide.with(context).load(url).into(imageView);
```
## Android (Kotlin)
```kotlin theme={null}
fun buildImageUrl(view: View, baseImageUrl: String, density: Float): String {
val width = view.width - view.paddingLeft - view.paddingRight
val dpr = density.toInt().coerceAtLeast(1)
val sep = if (baseImageUrl.contains("?")) "&" else "?"
return "$baseImageUrl${sep}width=$width&dpr=$dpr&format=auto&q=80"
}
```
Usage with Coil:
```kotlin theme={null}
val url = buildImageUrl(imageView, "https://your-distribution.tenbytecdn.com/photo.jpg",
resources.displayMetrics.density)
imageView.load(url)
```
## iOS (Swift)
```swift theme={null}
public func buildImageUrl(view: UIImageView, baseImageUrl: String) -> String {
let width = Int(round(view.frame.width - view.layoutMargins.left - view.layoutMargins.right))
let dpr = Int(UIScreen.main.scale)
let sep = baseImageUrl.contains("?") ? "&" : "?"
return "\(baseImageUrl)\(sep)width=\(width)&dpr=\(dpr)&format=auto&q=80"
}
```
Usage with SDWebImage:
```swift theme={null}
let url = buildImageUrl(view: imageView,
baseImageUrl: "https://your-distribution.tenbytecdn.com/photo.jpg")
imageView.sd_setImage(with: URL(string: url))
```
Usage with Kingfisher:
```swift theme={null}
imageView.kf.setImage(with: URL(string: url))
```
## iOS (SwiftUI)
```swift theme={null}
import SwiftUI
struct TenbyteImage: View {
let baseURL: String
let width: CGFloat
var body: some View {
let dpr = Int(UIScreen.main.scale)
let url = "\(baseURL)?width=\(Int(width))&dpr=\(dpr)&format=auto&q=80"
return AsyncImage(url: URL(string: url))
}
}
```
## Tips
* **Compute width after layout.** Calling before layout returns 0. Use `viewDidLayoutSubviews` (UIKit) / `onAppear` (SwiftUI) / view-tree observers (Android).
* **Round to design tokens.** A `123 px` request and a `124 px` request are two different cache entries. Snap widths to `[160, 320, 480, 720, 1080]` etc.
* **DPR clamp.** `dpr ≥ 4` rarely helps; clamp to `min(actualDpr, 3)`.
* **Pre-fetch hero images** during splash / loading for fast first paint.
* **Pair with library cache.** Glide/Coil/SDWebImage/Kingfisher all cache by URL — Tenbyte's cache + their disk cache = great offline UX.
## Verify
Run the app and inspect the request URL in your debugger or proxy (Charles, Proxyman):
```text theme={null}
GET https://your-distribution.tenbytecdn.com/photo.jpg?width=300&dpr=3&format=auto&q=80
```
Response should be `content-type: image/webp` on Android (and `image/heic` or `image/webp` on iOS depending on negotiation).
## Operational tips
* **Don't ship the secret in the app.** If you use [Token Authentication](/docs/cdn/distributions/access-rules/token-authentication), sign URLs server-side and hand them to the app via your API. Never embed the secret in the binary.
* **Long TTLs.** Image paths should have multi-month TTLs in [cache rules](/docs/cdn/distributions/cache-rules) — saves origin egress and helps offline scenarios.
# Astro
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/astro
Use Tenbyte Image Optimization in Astro with a small wrapper component and the Tenbyte JS SDK.
Use Tenbyte Image Optimization in Astro to deliver lighter images with zero build-time work. Drop in a small component and the Tenbyte JS SDK; the SDK rewrites `data-src` to optimized Tenbyte URLs at runtime.
## Prerequisites
* Astro 3+.
* A Tenbyte distribution with [Image Optimizer enabled](/docs/cdn/distributions/image-optimizer).
* The Tenbyte CDN hostname for your account.
## 1. Create the wrapper component
```astro src/components/TenbyteImage.astro theme={null}
---
const { src, alt = "", style = "", ...rest } = Astro.props;
---
```
The SDK looks for `data-src` and rewrites it on load.
## 2. Load the Tenbyte SDK in your layout
```astro src/layouts/BaseLayout.astro theme={null}
```
Replace `images.yoursite.com` with the domain where your master images live, and `your-distribution.tenbytecdn.com` with your Tenbyte hostname.
## 3. Use it in pages
```astro src/pages/index.astro theme={null}
---
import BaseLayout from "../layouts/BaseLayout.astro";
import TenbyteImage from "../components/TenbyteImage.astro";
---
```
## Pre-applied transforms
You can put query params directly in `src` — they're preserved through the rewrite:
```astro theme={null}
```
Or compose params per breakpoint with a small helper:
```astro src/lib/img.ts theme={null}
export function tenbyteUrl(src: string, params: Record = {}) {
const u = new URL(src);
for (const [k, v] of Object.entries(params)) u.searchParams.set(k, String(v));
if (!u.searchParams.has("format")) u.searchParams.set("format", "auto");
if (!u.searchParams.has("q")) u.searchParams.set("q", "80");
return u.toString();
}
```
```astro theme={null}
---
import { tenbyteUrl } from "../lib/img";
---
```
## Verify
```bash theme={null}
curl -sS http://localhost:4321 | grep -oE '(data-src|src)="[^"]*tenbytecdn\.com[^"]+"' | head -3
```
After the SDK loads in the browser, `data-src` becomes `src`. Inspect with DevTools → Network to see the actual request URL.
## Tips
* **Always `loading="lazy"`** below the fold.
* **Cap widths** — only request widths your design uses.
* **`format=auto`** — let the edge pick WebP / AVIF.
* **SSR works** — output is plain ``. The SDK runs only on the client.
* **Static builds work** — Tenbyte still handles transforms at request time.
## Troubleshooting
| Symptom | Fix |
| -------------------------- | ---------------------------------------------------------------------------------------- |
| Images don't load | SDK script blocked / not loaded. Check Network tab; confirm `tenbyte.min.js` is fetched. |
| Original src is requested | The host in `src` doesn't match `TENBYTE_CONFIG.hosts[0].current`. |
| Wrong dimensions on Retina | Pass `dpr=2` or rely on `srcset` widths. |
# Image Optimization Integration Guides
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/index
Plug Tenbyte Image Optimization into your framework or platform — Next.js, Nuxt, Astro, React Native, native mobile, Shopify.
Tenbyte Image Optimization works with any framework or platform via URL-based transforms. These guides show the cleanest setup per stack — usually a custom loader, component, or theme tweak.
## How transforms work
```mermaid theme={null}
flowchart LR
APP[Your app] -->|| EDGE[Tenbyte edge]
EDGE -->|cache miss| FETCH[Fetch master from origin]
FETCH -->|transform| VARIANT[Resize / convert / compress]
VARIANT -->|cache + serve| BROWSER[Browser]
```
Append query params, the edge does the rest. Each variant is cached independently after the first miss.
## Common params
| Param | Values | Purpose |
| --------------- | ----------------------------------------------- | ------------------- |
| `width` / `w` | px | Resize. |
| `height` / `h` | px | Resize. |
| `format` / `fm` | `auto`, `webp`, `avif`, `jpeg`, `png` | Format conversion. |
| `quality` / `q` | `1–100` | Compression. |
| `dpr` | `1`, `2`, `3` | Device pixel ratio. |
| `fit` | `cover`, `contain`, `fill`, `inside`, `outside` | Resize behavior. |
See [Image Optimizer](/docs/cdn/distributions/image-optimizer) for the full param list and examples.
## Pick your stack
* [**Next.js**](/docs/cdn/image-optimization/integration-guide/nextjs) — custom loader for the built-in `` component.
* [**Nuxt**](/docs/cdn/image-optimization/integration-guide/nuxt) — Tenbyte provider for ``.
* [**Astro**](/docs/cdn/image-optimization/integration-guide/astro) — drop-in `` component plus client SDK.
* [**React Native**](/docs/cdn/image-optimization/integration-guide/react-native) — replace `` with `TenbyteScaledImage`.
* [**Android / iOS**](/docs/cdn/image-optimization/integration-guide/android-ios) — generate URLs from view dimensions.
* [**Shopify**](/docs/cdn/image-optimization/integration-guide/shopify) — Liquid snippet that rewrites Shopify CDN URLs.
Don't see your stack? The transforms are pure HTTP query params — any HTTP client can use them. Open a support ticket if you want a bespoke guide.
## Verify any integration
```bash theme={null}
curl -sSI "https://your-distribution.tenbytecdn.com/photo.jpg?width=400&format=webp" \
| grep -iE 'content-type|content-length|x-cache'
```
Expected:
```text theme={null}
content-type: image/webp
content-length: 18432
x-cache: HIT
```
If `content-type` doesn't change to your requested format, the master file probably wasn't fetched yet (first request is a miss) or [Image Optimizer is off](/docs/cdn/distributions/image-optimizer).
## Dev-friendly checklist
* [ ] Master image is high-quality JPEG or PNG. Don't upscale.
* [ ] `format=auto` everywhere — covers AVIF / WebP / JPEG fallback.
* [ ] Cap `width` to the breakpoints your design system actually uses.
* [ ] Long TTL on image paths (see [cache rules](/docs/cdn/distributions/cache-rules)).
* [ ] Lazy-load below-the-fold (`loading="lazy"` or framework-equivalent).
* [ ] Test on real devices — `dpr=2` matters for Retina screens.
# Next.js
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/nextjs
Use Tenbyte Image Optimization with the Next.js Image component via a custom loader. Works with App Router and Pages Router.
Next.js (v10+) ships a built-in `` component. Plug Tenbyte into it with a custom loader — a few lines of config, no extra dependencies.
## Prerequisites
* Next.js 10+ (App Router or Pages Router).
* A Tenbyte distribution with [Image Optimizer enabled](/docs/cdn/distributions/image-optimizer).
* The Tenbyte CDN hostname for your account: `your-distribution.tenbytecdn.com`.
## Setup
```javascript utils/imageloader.js theme={null}
export default function tenbyteLoader({ src, width, quality }) {
// Rewrite known origin domains to Tenbyte CDN; pass everything else through unchanged.
if (src.includes(process.env.NEXT_PUBLIC_IMAGE_ORIGIN)) {
const url = new URL(src);
url.hostname = process.env.NEXT_PUBLIC_TENBYTE_HOST;
url.searchParams.set("w", width);
url.searchParams.set("q", quality || 80);
url.searchParams.set("format", "auto");
return url.toString();
}
return `${src}?w=${width}&q=${quality || 80}&format=auto`;
}
```
```javascript next.config.js theme={null}
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
loader: "custom",
loaderFile: "./utils/imageloader.js",
},
};
module.exports = nextConfig;
```
```bash .env.local theme={null}
NEXT_PUBLIC_IMAGE_ORIGIN=images.yoursite.com
NEXT_PUBLIC_TENBYTE_HOST=your-distribution.tenbytecdn.com
```
## Use the Image component
```jsx theme={null}
import Image from "next/image";
export default function Hero() {
return (
);
}
```
Next.js will call `tenbyteLoader` for each `srcset` width, generating URLs like:
```text theme={null}
https://your-distribution.tenbytecdn.com/hero.jpg?w=1200&q=80&format=auto
https://your-distribution.tenbytecdn.com/hero.jpg?w=640&q=80&format=auto
```
## Verify
```bash theme={null}
# In the rendered HTML, inspect the srcset
curl -sS http://localhost:3000 | grep -oE 'tenbytecdn\.com[^"]+' | head -3
```
Should look like:
```text theme={null}
your-distribution.tenbytecdn.com/hero.jpg?w=640&q=80&format=auto
your-distribution.tenbytecdn.com/hero.jpg?w=1080&q=80&format=auto
your-distribution.tenbytecdn.com/hero.jpg?w=1920&q=80&format=auto
```
## Tips
* **Set `sizes`** — without it, Next.js requests the largest variant for every screen.
* **Use `priority`** sparingly — only for above-the-fold images. It bypasses lazy-loading.
* **Whitelist domains** — `images.yoursite.com` should be in `images.remotePatterns` if you're on App Router with stricter checks.
* **Avoid `unoptimized`** — that disables the loader and ships the master file. The whole point of Tenbyte is to skip that.
* **Cap quality at 80** — visual difference vs 90 is negligible, bytes drop a lot.
## Reference
[Next.js Image documentation](https://nextjs.org/docs/app/api-reference/components/image#loader)
# Nuxt
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/nuxt
Use Tenbyte Image Optimization in Nuxt via the @nuxt/image module and the tenbyte provider.
Nuxt's `@nuxt/image` module supports custom providers. Configure Tenbyte once and use `` (or ``) anywhere in your app — Nuxt handles `srcset`, lazy loading, and sizing.
## Prerequisites
* Nuxt 3 with `@nuxt/image` installed:
```bash theme={null}
npm install @nuxt/image
```
* A Tenbyte distribution with [Image Optimizer enabled](/docs/cdn/distributions/image-optimizer).
* Your Tenbyte CDN hostname.
## Configure the provider
```ts nuxt.config.ts theme={null}
export default defineNuxtConfig({
modules: ["@nuxt/image"],
image: {
provider: "tenbyte",
tenbyte: {
baseURL: "https://your-distribution.tenbytecdn.com",
},
},
});
```
## Use ``
```vue theme={null}
```
Nuxt resolves `src` against `baseURL` and emits a `srcset` with multiple widths. `modifiers` map to Tenbyte transform query params.
## Use `` for advanced fallbacks
```vue theme={null}
```
`` emits a `` with multiple `` elements — one per format — for browsers that need explicit fallbacks.
## Verify
```bash theme={null}
# Render the page and inspect generated URLs
curl -sS http://localhost:3000 | grep -oE 'tenbytecdn\.com[^"]+' | head -3
```
Expected URLs include your transforms:
```text theme={null}
your-distribution.tenbytecdn.com/sea.jpeg?w=320&q=80&format=auto
your-distribution.tenbytecdn.com/sea.jpeg?w=640&q=80&format=auto
your-distribution.tenbytecdn.com/sea.jpeg?w=800&q=80&format=auto
```
## Tips
* **Use `sizes`** — without it, Nuxt picks the largest width for every breakpoint.
* **Pin `quality`** in `modifiers` — keeps bundle output deterministic.
* **`format: 'auto'`** — lets the edge negotiate WebP / AVIF based on the browser's `Accept` header.
* **Lazy-load by default** — Nuxt's default. Override with `loading="eager"` only above the fold.
* **Cache long.** Set a long TTL on `/path/to/images/*` via [cache rules](/docs/cdn/distributions/cache-rules); each variant is independent.
## Reference
[@nuxt/image documentation](https://image.nuxt.com/)
# React Native
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/react-native
Drop-in component that fetches optimized images sized for the device pixel ratio.
React Native apps benefit hard from image optimization — every saved byte is one less over a flaky mobile connection. This guide adds a `TenbyteScaledImage` component that picks the right size and DPR at runtime.
## Prerequisites
* React Native project up and running.
* A Tenbyte distribution with [Image Optimizer enabled](/docs/cdn/distributions/image-optimizer).
* Master images served from a known origin host (e.g. `images.yoursite.com`).
## Component
```jsx components/TenbyteImage.js theme={null}
import React, { useMemo, useState } from "react";
import { Image, PixelRatio, StyleSheet } from "react-native";
import PropTypes from "prop-types";
const TENBYTE_CONFIG = {
hosts: [
{ current: "images.yoursite.com", tenbyte: "your-distribution.tenbytecdn.com" },
],
};
function extractHostname(url) {
let h = url.includes("//") ? url.split("/")[2] : url.split("/")[0];
return h.split(":")[0].split("?")[0];
}
export default function TenbyteScaledImage({ style, source, quality = 80, format = "auto", ...rest }) {
const flat = useMemo(() => StyleSheet.flatten(style) || {}, [style]);
if (typeof flat.width !== "number" && typeof flat.height !== "number") {
throw new Error("TenbyteScaledImage requires width or height in style");
}
const [size] = useState({ width: flat.width, height: flat.height });
const match = TENBYTE_CONFIG.hosts.find(
(h) => h.current === extractHostname(source.uri)
);
let url = match ? source.uri.replace(match.current, match.tenbyte) : source.uri;
const sep = url.includes("?") ? "&" : "?";
const dpr = PixelRatio.get();
url += `${sep}width=${flat.width || ""}&dpr=${dpr}&q=${quality}&format=${format}`;
return ;
}
TenbyteScaledImage.propTypes = {
source: PropTypes.object.isRequired,
style: PropTypes.object,
quality: PropTypes.number,
format: PropTypes.string,
};
```
## Use it
```jsx App.js theme={null}
import React from "react";
import { StyleSheet, View } from "react-native";
import TenbyteScaledImage from "./components/TenbyteImage";
export default function App() {
return (
);
}
const styles = StyleSheet.create({
container: { paddingTop: 50 },
});
```
## What you get
* **Right size per device.** `width` matches the rendered view; the edge resizes the master.
* **Retina-correct.** `dpr` covers `@2x` / `@3x` displays without shipping multiple assets.
* **Format auto.** Server picks WebP / AVIF when supported.
## Verify
Run the app and look at the network panel (Flipper / React Native Debugger):
```text theme={null}
GET https://your-distribution.tenbytecdn.com/photo.jpg?width=200&dpr=2&q=80&format=auto
```
`content-type: image/webp` (or `avif` on supporting platforms).
## Tips
* **Pass numeric widths**, not `"100%"`. The component needs a px value.
* **Cap at design tokens.** Use a small set of widths (`64`, `128`, `256`, `512`, `1024`) so the cache stays warm.
* **Pre-fetch hero images** with `Image.prefetch(uri)` for instant first paint.
* **Pair with `FastImage`** if you need disk caching or priority hints — wrap `FastImage` instead of `Image`.
* **Lazy-list images** — `` or `` only render visible rows; that's free lazy-loading.
## Troubleshooting
| Symptom | Fix |
| --------------------------------------------- | ---------------------------------------------------------------------- |
| `TenbyteScaledImage requires width or height` | Add `width` or `height` to `style`. |
| Wrong host in URL | `TENBYTE_CONFIG.hosts[0].current` doesn't match the source host. |
| Blurry on Retina | Ensure `dpr=2` (or 3) is in the URL — check `PixelRatio.get()` return. |
# Shopify
Source: https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/shopify
Route Shopify product images through Tenbyte CDN for faster storefronts. Includes theme settings, snippet, and srcset example.
Shopify hosts your product images on `cdn.shopify.com`. By proxying that origin through Tenbyte CDN, you get on-the-fly resizing, format conversion, and faster regional delivery without changing how you upload products.
## How the integration works
```mermaid theme={null}
flowchart LR
THEME[Shopify theme tenbyte.liquid] -->|rewrite URL| TENBYTE[your-distribution.tenbytecdn.com]
TENBYTE -->|cache miss| SHOPIFY[cdn.shopify.com]
SHOPIFY -->|original image| TENBYTE
TENBYTE -->|optimized variant| BROWSER[Browser]
```
The `tenbyte.liquid` snippet rewrites Shopify CDN URLs to Tenbyte URLs and appends transform params.
## Prerequisites
* A Shopify store with theme edit access.
* A Tenbyte distribution with [Image Optimizer enabled](/docs/cdn/distributions/image-optimizer).
* **Backup your theme** before editing — Online Store → Themes → "..." → Download theme file.
## 1. Add Shopify as an origin
In your Tenbyte distribution → **Origins** → **Add Origin**:
| Field | Value |
| ----------- | ------------------------- |
| Origin Name | `Origin-Shopify` |
| Type | Hostname |
| Domain / IP | `https://cdn.shopify.com` |
Save. Your Tenbyte CDN domain can now fetch and optimize Shopify-hosted images.
## 2. Add Tenbyte settings to the theme
In Shopify Admin → **Online Store → Themes**, find your theme, click **"..." → Edit code**.
Open `Config/settings_schema.json`, scroll to the bottom, and append this block. Save.
```json settings_schema.json theme={null}
{
"name": "Tenbyte",
"settings": [
{
"type": "paragraph",
"content": "Tenbyte Image Optimization. See https://docs.tenbyte.io/docs/cdn/image-optimization/integration-guide/shopify"
},
{
"type": "checkbox",
"id": "enableTenbyte",
"label": "Enable Tenbyte"
},
{
"type": "text",
"id": "tenbyteUrl",
"label": "Tenbyte URL endpoint",
"info": "Your Tenbyte distribution. Example: https://your-distribution.tenbytecdn.com/"
},
{
"type": "text",
"id": "tenbyteShopifyCdnUrl",
"label": "Shopify CDN domain",
"info": "Leave as //cdn.shopify.com unless you have a proxy in place."
}
]
}
```
## 3. Create the `tenbyte.liquid` snippet
In **Snippets**, create `tenbyte.liquid` and paste:
```liquid tenbyte.liquid theme={null}
{% capture TENBYTE %}
{% if settings.enableTenbyte %}
{% for i in (1..1) %}
{% unless src or settings.tenbyteUrl != blank %}
{{ src }}{% break %}
{% endunless %}
{% assign cdnUrl = settings.tenbyteShopifyCdnUrl | strip %}
{% unless src contains cdnUrl %}
{{ src }}{% break %}
{% endunless %}
{% assign tenbyteUrl = settings.tenbyteUrl | strip %}
{% assign filters = 'w,h,q,fm,fit,dpr,format,quality,bri,con,sat,sharp,blur,auto' | split:',' %}
{% assign imgWithQuerystring = "?" %}
{% if src contains '?' %}{% assign imgWithQuerystring = '' %}{% endif %}
{% for _filter in filters %}
{% if [_filter] %}
{% assign imgWithQuerystring = imgWithQuerystring | append:_filter | append:'=' | append:[_filter] | append:'&' %}
{% endif %}
{% endfor %}
{% assign modifySrc = src | split:'?' | first | append:"?" %}
{% assign newSrc = modifySrc | strip | replace:cdnUrl,tenbyteUrl | append:imgWithQuerystring %}
{% endfor %}
{{ newSrc | default:src }}
{% else %}
{{ src }}
{% endif %}
{% endcapture %}{{ TENBYTE | strip | replace:' ' | strip_newlines }}
```
## 4. Enable Tenbyte in theme settings
**Online Store → Themes → Customize**. In the left panel, open the **Tenbyte** section under General settings:
| Field | Value |
| -------------------- | ------------------------------------------- |
| Enable Tenbyte | ✓ |
| Tenbyte URL endpoint | `https://your-distribution.tenbytecdn.com/` |
| Shopify CDN domain | `//cdn.shopify.com` |
## 5. Update theme image renders
Replace direct image renders with the snippet. The before/after pattern:
**Before:**
```liquid theme={null}
{{ product.featured_image }}
```
**After:**
```liquid theme={null}
{% assign feat_img_url = product.featured_image | image_url %}
{% render 'tenbyte', src: feat_img_url, w: 600 %}
```
### Responsive `srcset` example
```liquid theme={null}
{% assign feat_img_url = product.featured_image | image_url %}
```
## Verify
1. Open a product page.
2. View source / inspect element.
3. Confirm image URLs go to `your-distribution.tenbytecdn.com` instead of `cdn.shopify.com`.
4. In DevTools Network, check `content-type: image/webp` on supported browsers.
```bash theme={null}
# Or test directly
curl -sSI "https://your-distribution.tenbytecdn.com/s/files/1/.../photo.jpg?w=480&fm=auto" \
| grep -iE 'content-type|x-cache'
```
## Operational tips
* **Ship behind the checkbox.** The `enableTenbyte` toggle lets you roll back instantly.
* **Test in a draft theme.** Edit a copy, preview, then publish.
* **Watch [cache hit ratio](/docs/cdn/analytics/cache-hit-ratio).** Shopify pages reuse images aggressively; CHR should climb past 95%.
* **Cap widths.** Match Shopify's preset image sizes (320, 480, 640, 960, 1280, 1600) so you don't fragment the cache.
* **Lazy-load below the fold.** `loading="lazy"` is supported in Liquid `` tags.
## Troubleshooting
| Symptom | Fix |
| ---------------------------------- | ------------------------------------------------------------------------- |
| Images still hit `cdn.shopify.com` | `enableTenbyte` is off or `tenbyteUrl` is blank in theme settings. |
| `404` from Tenbyte | Origin not added or wrong path; the path on Tenbyte must match Shopify's. |
| Layout shifts | Add `width` and `height` to `` so the browser reserves space. |
| Broken theme | Restore from the backup you took in step 0. |
# Tenbyte CDN
Source: https://docs.tenbyte.io/docs/cdn/index
Global content delivery network with edge caching, image optimization, signed URLs, and a REST API for automation.
**Tenbyte CDN** is a global content delivery network that puts your static assets, video, and API responses on edge nodes close to your users. Lower latency, fewer origin hits, and a REST API and webhooks for automation.
## How it works
```mermaid theme={null}
flowchart LR
U[User] -->|GET asset| E[Tenbyte edge nearest PoP]
E -->|cache miss| O[Your origin]
O -->|response| E
E -->|cache hit| U
E -->|metrics + logs| A[Analytics & API]
```
Requests hit the nearest edge PoP. On a cache miss the edge fetches from your origin, caches the response per your rules, and serves the next request locally.
## Core concepts
| Concept | What it is | Where to configure |
| ---------------- | ------------------------------------------------------------- | ------------------------------------------------------------------ |
| **Distribution** | A configured CDN endpoint mapped to one or more origins. | [Create distribution](/docs/cdn/distributions/create-distribution) |
| **Origin** | The upstream your distribution pulls from (HTTP, S3, custom). | [Origins](/docs/cdn/distributions/origins) |
| **Cache rule** | Per-path TTL, query-string handling, compression. | [Cache rules](/docs/cdn/distributions/cache-rules) |
| **Access rule** | Country / IP / referrer / token gate per path. | [Access rules](/docs/cdn/distributions/access-rules/overview) |
| **Header rule** | Add / remove request and response headers. | [Headers](/docs/cdn/distributions/headers) |
| **Purge** | Invalidate cached content by path or pattern. | [Purge](/docs/cdn/purge/purge-by-pattern) |
## Why Tenbyte CDN
* **Smart routing** — anycast plus health checks pick the nearest healthy edge.
* **Global PoPs** — many points of presence per region.
* **Edge customization** — cache, headers, and access policies as code via the API.
* **Secure by default** — TLS, WAF integration, and [token-authenticated signed URLs](/docs/cdn/distributions/access-rules/token-authentication).
* **Real-time analytics** — bandwidth, requests, cache-hit ratio, response classes.
* **HTTP/2 and HTTP/3** — multiplexed, lower-handshake delivery.
* **Instant purge** — invalidate cached content via console or API.
* **Pay-as-you-go** — usage-based billing, no minimums.
## What developers get
* **REST API** — manage distributions, rules, and purges. See the [CDN API reference](/api-reference/cdn).
* **OpenAPI spec** — generate clients for your stack.
* **Webhooks** — react to purge, certificate, and traffic events.
* **Signed URLs** — protect content with time-limited tokens. [Token authentication](/docs/cdn/distributions/access-rules/token-authentication).
* **Headers control** — add `Cache-Control`, `CORS`, and security headers at the edge.
## Getting started
Point a distribution at your origin. [Create distribution →](/docs/cdn/distributions/create-distribution)
`curl -I` your distribution hostname and confirm `X-Cache: HIT` after a warmup request.
Tune TTLs, lock down content with access rules, or sign URLs.
Automate purges and rule updates from CI/CD.
Jump to the [Quick Start Guide](/docs/cdn/quickstart) for the full walk-through.
# Purge All
Source: https://docs.tenbyte.io/docs/cdn/purge/purge-all
Invalidate every cached object on a distribution. Use sparingly — prefer pattern purges.
**Purge All** wipes every cached object on a distribution. The next request for any path is a cache miss that goes all the way to your origin.
## Use this when
* You can't predict which paths changed (mass content migration, root-level config swap).
* A security incident may have served compromised content from cache.
* You're decommissioning a distribution and want a clean slate before final teardown.
For everything else — deploys, single-asset hotfixes, API response invalidation — use [Purge by Pattern](/docs/cdn/purge/purge-by-pattern).
## Cost of a Purge All
```mermaid theme={null}
flowchart LR
PURGE[Purge All] --> EDGE[All PoPs flush]
EDGE -->|first request anywhere| ORIGIN[Origin sees cold-start spike]
ORIGIN -->|cache rewarms over minutes| EDGE
```
Every active path becomes a cache miss simultaneously. Your origin will see a traffic spike — capacity-plan before pulling this trigger.
Purge All is **global, instant, and irreversible**. It will impact P95 latency and origin load until the cache rewarms. Schedule it during low traffic and warn downstream teams.
## Console flow
1. Open the distribution → **Purge** tab.
2. Pick **Purge All**.
3. Click **Purge**.
Propagates within seconds.
## Purge via API
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge/all" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN"
```
Response:
```json theme={null}
{
"purge_id": "prg_01HXYZ...",
"status": "queued",
"scope": "all"
}
```
Poll status:
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge/$PURGE_ID" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq '.status'
```
See the [CDN API reference](/api-reference/cdn) for canonical fields.
## Pre-flight checklist
* [ ] Origin can absorb a cold-start traffic spike (autoscale ready or capacity proven).
* [ ] No live deploy in progress.
* [ ] Stakeholders notified (#oncall, #web-platform).
* [ ] Confirmed pattern purge cannot solve the problem.
* [ ] Have a rollback plan if origin fails to handle the spike.
## Verify
```bash theme={null}
# Before — typical HIT ratio
curl -sSI "$CDN_HOST/" | grep -i x-cache
# x-cache: HIT
# Trigger purge, then any path
curl -sSI "$CDN_HOST/" | grep -i x-cache
# x-cache: MISS
# Watch [cache hit ratio] dashboard recover over the next few minutes.
```
## Recovery
* Watch [Cache hit ratio](/docs/cdn/analytics/cache-hit-ratio) — it nosedives immediately, recovers as paths warm.
* Watch origin error rate. If origin starts to fail, throttle traffic at your edge or scale up.
* Don't trigger another purge while recovery is in flight.
## Alternatives
| Need | Use |
| -------------------------- | -------------------------------------------------------------------- |
| Invalidate a specific path | [Purge by Pattern](/docs/cdn/purge/purge-by-pattern) — `/index.html` |
| Invalidate a folder | [Purge by Pattern](/docs/cdn/purge/purge-by-pattern) — `/static/*` |
| Roll back a deploy | Revert origin and run a targeted purge |
| Lower TTL going forward | Edit the [cache rule](/docs/cdn/distributions/cache-rules) |
# Purge by Pattern
Source: https://docs.tenbyte.io/docs/cdn/purge/purge-by-pattern
Invalidate specific paths or wildcard patterns from the CDN cache. Includes API examples and CI/CD integration.
Purge by Pattern invalidates a precise set of cached objects without dumping the whole cache. This is the right tool for deploys, content fixes, and incident response.
## When to use this
* After a deploy that changes specific paths (`/static/main.js`, `/api/v1/*`).
* After fixing a content bug that's already cached.
* When TTL is too long for the asset you just updated.
For wholesale invalidation, use [Purge All](/docs/cdn/purge/purge-all) — but pattern purges are almost always preferable.
## How patterns work
```mermaid theme={null}
flowchart LR
DEPLOY[Deploy / hotfix] --> API[Purge API or console]
API -->|match patterns| EDGE[All edge PoPs]
EDGE -->|next request| MISS[Cache MISS]
MISS --> ORIGIN[Origin fetch]
ORIGIN --> CACHE[Re-cache]
```
The first request after a purge is a `MISS`. Plan your purge timing so the resulting origin spike is acceptable.
## Pattern rules
* Must start with `/`.
* `*` is a wildcard matching one or more characters.
* Up to **10 patterns** per purge request.
| Pattern | Matches |
| ---------------- | ------------------------------------------------------ |
| `/index.html` | Single object. |
| `/images/*` | Everything under `/images/`. |
| `/static/css/*` | All CSS files. |
| `/api/v1/*` | All v1 API responses. |
| `/photos/hero.*` | All formats / sizes of `hero` (after image optimizer). |
`*` matches eagerly. `/api/*` purges every API response on the distribution. Scope tightly when you can.
## Console flow
1. Enter one pattern per line in the input box.
2. Click **Purge** to dispatch.
Purge propagates globally within a few seconds.
## Purge via API
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"paths": [
"/index.html",
"/static/main.*",
"/api/v1/products"
]
}'
```
Response:
```json theme={null}
{
"purge_id": "prg_01HXYZ...",
"status": "queued",
"paths": ["/index.html", "/static/main.*", "/api/v1/products"]
}
```
Poll the purge job:
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge/$PURGE_ID" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq '.status'
# "queued" → "in_progress" → "completed"
```
See the [CDN API reference](/api-reference/cdn) for canonical fields.
## CI/CD integration
### GitHub Actions
```yaml theme={null}
- name: Purge CDN after deploy
run: |
curl -fsS -X POST "https://api.tenbyte.io/cdn/distributions/${{ secrets.CDN_DISTRIBUTION_ID }}/purge" \
-H "Authorization: Bearer ${{ secrets.TENBYTE_API_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"paths": ["/index.html", "/static/*"]}'
```
### Shell helper
```bash theme={null}
#!/usr/bin/env bash
set -euo pipefail
: "${TENBYTE_API_TOKEN:?}"
: "${DISTRIBUTION_ID:?}"
paths_json=$(printf '%s\n' "$@" | jq -R . | jq -s '{paths: .}')
curl -fsS -X POST "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$paths_json"
```
```bash theme={null}
./purge.sh /index.html "/static/*"
```
## Verify the purge
```bash theme={null}
# Before purge — likely HIT
curl -sSI "$CDN_HOST/index.html" | grep -i x-cache
# x-cache: HIT
# Trigger purge, then check again
curl -sSI "$CDN_HOST/index.html" | grep -i x-cache
# x-cache: MISS (origin fetched fresh)
# Subsequent request
curl -sSI "$CDN_HOST/index.html" | grep -i x-cache
# x-cache: HIT
```
## Operational tips
* **Purge **before** flipping traffic.** For blue/green deploys, purge the green hostname after the new build is live, not before.
* **Use exact paths over wildcards.** `/static/main.abc123.js` invalidates one object; `/static/*` invalidates everything and risks an origin spike.
* **Avoid frequent global purges.** Each purge is a coordinated edge-wide operation. Hashed asset URLs make most purges unnecessary.
* **Monitor origin after a wide purge.** Watch [Cache hit ratio](/docs/cdn/analytics/cache-hit-ratio) — it dips immediately, then recovers as the cache rewarms.
## Limits and quotas
* Up to **10 patterns** per request.
* Purges are async; `completed` status typically lands within seconds, sometimes up to a minute under heavy load.
* Bulk purges (>1000/day) should batch and back off on `429`.
## Troubleshooting
| Symptom | Fix |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| Pattern rejected — must start with `/` | Add the leading slash. |
| `x-cache: HIT` immediately after purge | Edge briefly returned a stale node. Try one more request — global propagation isn't instant. |
| Wildcards seem to ignore deeper paths | `*` doesn't cross domains; double-check the pattern starts where you expect. |
| Origin spike after purge | Wildcard too broad. Combine with rate limits at the origin or refine the pattern. |
# Quick Start Guide
Source: https://docs.tenbyte.io/docs/cdn/quickstart
Create a Tenbyte CDN distribution, verify the edge with curl, and automate purges via the API.
Get a Tenbyte CDN distribution serving traffic in under 10 minutes. This guide covers the console flow plus the curl checks and API calls that let you automate the rest.
## Prerequisites
* A **Tenbyte account** — [Sign up](https://beta.tenbyte.io/vidinfra)
* An **origin URL** that responds to HTTPS (your website, S3 bucket, or custom server)
* An **API token** if you plan to script things — generate one in **Organization → API Keys**
* `curl` (bundled with macOS / Linux / WSL)
## Architecture at a glance
```mermaid theme={null}
flowchart LR
DEV[You] -->|console / API| TB[Tenbyte CDN]
TB -->|distribution| EDGE[Global edge PoPs]
USER[End user] -->|GET| EDGE
EDGE -->|cache miss| ORIGIN[Your origin]
ORIGIN -->|bytes| EDGE
EDGE -->|cached bytes| USER
```
## 1. Open the CDN workspace
Sign in, then pick **CDN** from the left sidebar.
The CDN workspace lists your distributions.
## 2. Create a distribution
Walk through [Create distribution](/docs/cdn/distributions/create-distribution) to point at your origin. Once active, the console shows a distribution hostname like `your-distribution.tenbytecdn.com`.
Save it to your shell so the snippets below work as-is:
```bash theme={null}
export CDN_HOST="https://your-distribution.tenbytecdn.com"
export CDN_PATH="/index.html"
```
## 3. Verify the edge with curl
First request — expect `MISS` (origin fetch):
```bash theme={null}
curl -sSI "$CDN_HOST$CDN_PATH" | grep -iE 'http/|x-cache|cache-control|server'
```
Second request — expect `HIT` (served from cache):
```bash theme={null}
curl -sSI "$CDN_HOST$CDN_PATH" | grep -iE 'http/|x-cache'
# HTTP/2 200
# x-cache: HIT
```
If you see `MISS` repeatedly, jump to [Cache rules](/docs/cdn/distributions/cache-rules) — the origin is probably sending `Cache-Control: no-store` or `private`.
## 4. Add cache, header, and access rules
| Goal | Where |
| ------------------------------------- | --------------------------------------------------------------------------------- |
| Override TTLs per path | [Cache rules](/docs/cdn/distributions/cache-rules) |
| Add CORS / security headers | [Headers](/docs/cdn/distributions/headers) |
| Geo-block, IP-allow, or referrer-lock | [Access rules](/docs/cdn/distributions/access-rules/overview) |
| Sign URLs for paid / private content | [Token authentication](/docs/cdn/distributions/access-rules/token-authentication) |
| Issue an SSL cert | [SSL](/docs/cdn/distributions/ssl) |
## 5. Automate via the API
All console operations also live in the [CDN API](/api-reference/cdn). Drop these into CI/CD or a deploy script.
```bash theme={null}
export TENBYTE_API_TOKEN="..." # from Organization → API Keys
export DISTRIBUTION_ID="..." # from the distribution detail page
```
Purge a path after a deploy:
```bash theme={null}
curl -X POST "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/purge" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"paths": ["/index.html", "/static/*"]}'
```
Inspect the distribution config:
```bash theme={null}
curl -sS "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID" \
-H "Authorization: Bearer $TENBYTE_API_TOKEN" | jq
```
Endpoint paths shown here mirror the [CDN API reference](/api-reference/cdn). Always check the reference for the exact shape — it is the source of truth.
## What "done" looks like
* [ ] `curl -I` returns `HTTP/2 200` from the distribution hostname.
* [ ] Repeat requests show `x-cache: HIT`.
* [ ] DNS for your custom domain (if any) points at the distribution CNAME.
* [ ] SSL certificate is **Active** in the console.
* [ ] You can purge a path via the API and watch the next request return `MISS`.
## Next steps
* [Cache rules](/docs/cdn/distributions/cache-rules) — fine-tune TTLs and query-string handling.
* [Token authentication](/docs/cdn/distributions/access-rules/token-authentication) — sign URLs for protected media.
* [Image optimization](/docs/cdn/distributions/image-optimizer) — resize, convert, and compress on the fly.
* [Analytics](/docs/cdn/analytics/overview) — bandwidth, cache-hit ratio, response classes.
* [FAQs](/docs/cdn/cdn-faqs) — quick answers for ops and billing questions.
# Edit Your Profile
Source: https://docs.tenbyte.io/docs/cloud/account-setup
You can update your personal details and manage key account settings from your Tenbyte Cloud profile.
This includes changing your name, updating your email, resetting your password, and reviewing information linked to your account.
## Access Your Profile
* From the right side of the dashboard, click on your **Account name**. A dropdown menu will appear.
* A dropdown menu will open. Select Profile to move to your profile dashboard.
***
## Edit your Tenbyte Profile
* From the **Profile Dashboard** you can configure following things
* **Name**: Your first and last name.
* **Email**: The email address linked to your Tenbyte Cloud account.
* **Password**: Option to reset your password.
* **Created At**: The date and time your account was created.
***
## Delegating New Access
* If someone else needs access to your cloud resources, you can grant permissions directly from this page.
* Click **+ Delegate new access** to add a new user and assign the level of access they should have.
* For a complete guide on how delegation works, visit the [Access Delegation](/docs/cloud/networking/manage-access) page under the **Networking and Security** section.
# Tenbyte Cloud Backups
Source: https://docs.tenbyte.io/docs/cloud/backup/backup
Set up and manage backups for your virtual machines in Tenbyte Cloud to ensure data protection and easy recovery.
## Select Compute Section
* From the left sidebar, click on **Compute** to view your created virtual machines (VMs).
***
## Choose Your Virtual Machine
* In the Compute section, you will see a list of all your created VMs.
* Click the VM that you want to configure backups for.
## Navigate to the Backups Tab
* After selecting your VM, you will see a detailed overview of the machine.
* Select the **Backups** tab to open the backup settings.
***
## Enable Backups
* When you enable backup service, an automatic disk-level backup will be created from the boot disk of your VM.
A backup will be created once a week and will be stored for a one-month period. You will have up to 4 backups stored at any given time.
* The estimated cost per backup will be displayed.
* To start creating backups, simply click **Enable** backups.
***
## View Backup History
* Once backups are enabled, you can see a list of all created backups in the same section.
* Each entry includes:
* **UUID** — Unique ID of the backup
* **Size** — Size of the backed-up disk
* **Created** — Date and time when the backup was made
This history allows you to choose the correct restore point easily.
***
## Disable Backups
* If you no longer wish to keep backups, you can choose to disable backups by clicking the **Disable backups** option.
***
## Restore or Create New VM from Backup
* Use the backup images to restore your VM to a previous state or create a new VM with the same configuration and modified size parameters.
# Tenbyte Cloud Snapshots
Source: https://docs.tenbyte.io/docs/cloud/backup/snapshots
Snapshots let you capture the current state of your virtual machine at a specific moment. You can use them to restore a VM, clone an environment, or create a new VM with the same configuration.
## Select Compute Section
* From the left sidebar, click on **Compute** to view your created virtual machines (VMs).
***
## Choose Your Virtual Machine
* In the Compute section, you will see a list of all your created VMs.
* Select the VM you want to create or manage snapshots for.
## Navigate to the Snapshots Tab
* After selecting the VM, the system will display its details and configuration options.
* Select **Snapshots** to open the snapshot management page.
***
## Take a Snapshot
* To create a snapshot, click the **Take snapshot** button.
* The platform will begin creating the snapshot immediately.
***
## Snapshot Details
* Once a snapshot is created, you’ll see it listed with the following information:
1. **UUID**: A unique identifier for the snapshot
2. **Size**: The total data size captured.
3. **Creation** Date: The date and time the snapshot was created.
***
## Manage Snapshots
You can use snapshots in several ways depending on your needs.
* **Restore**: Use the snapshot to return your VM to the exact state it was in when the snapshot was created.
* **Create New VM**: You can also create a new VM based on the snapshot with modified resources. Click the **+** icon next to the snapshot you want to use.
After creating a VM from a snapshot, you can reconfigure the VM by modifying its resources and settings.
* **Delete**: If a snapshot is no longer needed, click the **trash icon** to delete it permanently.
# Tenbyte Billing
Source: https://docs.tenbyte.io/docs/cloud/billing/billing
Manage your Tenbyte Cloud billing account, add funds through top ups, and monitor your current balance and usage in one place.
## Navigate to Billing Section
* From the **Tenbyte Cloud dashboard**, click on **Billing** from the left sidebar to manage your billing account.
***
## Select Your Billing Account
* In the **Billing section**, you will see your **account details**. Select your billing account name from the dashboard.
* This will open up the billing account details, where you can view or edit information related to your account.
***
## Billing Account Details
* In this section, you can view important information about your account, such as:
* **Account ID**, **Type** (Billing account), **Country**, **Ongoing balance** & more.
If your billing account has limitations, a notification will appear.
* You may also see the ongoing balance and an option to top up your account.
***
## Edit Billing Account Information
* To edit your billing account details, click on the **Edit** button. You will be able to modify the following:
* **Company name**, **VAT number**, **Invoice email**, **Contact person's details**, and address.
* Ensure that the updated details are accurate for proper billing and communication.
***
## Top Up Your Account
* If you need to add funds to your billing account, click **Top up** now.
* Enter the amount you wish to top up. The total charge, including VAT, will be displayed.
* Choose your payment method and click **Top up** to complete the process.
***
## Create a New Billing Account
* If you want to create a new billing account, go to the **Create new** option.
Fill in the necessary details.
* **Billing account name**: Choose a name for your new account.
* **Invoice details**: Add the company name, registration number, VAT number, and contact details.
* **Payment method**: Choose the preferred payment method for the new billing account and click **Create**.
# Tenbyte Cloud Support FAQs
Source: https://docs.tenbyte.io/docs/cloud/cloud-faqs
Here you will find answers to some of the most common questions about setting up and using Tenbyte Cloud services.
## 1. How do I get started with Tenbyte Cloud?
Create your **Tenbyte Cloud** account, log in to the account, and make your first v**irtual machine (VM)**. After that, you can manage your cloud resources easily on our dashboard.
***
## 2. What types of virtual machines (VMs) do you offer?
Use **Linux** or **Windows VMs** according to your choice. You can run the website, application, and as per your need.
***
## 3. How secure is Tenbyte Cloud?
We take security carefully with **DDoS protection**, and **data encryption**.
***
## 4. Can I scale my cloud services?
Yes! As per your growing requirements you can easily adjust your **VMs**, **storage**, and **network**.
***
## 5. How do I manage user access?
From the dashboard Access Management can manage access. Distribute roles and privileges to your team as per the requirement.
***
## 6. What happens if my services go down?
We guarantee **99.98% uptime**. In case anything goes wrong, we have systems in place to recover quickly and our support team is ready to assist you.
***
## 7. Do you offer support?
Yes, we provide 24/7 support via phone, email, and chat. We’re here to help whenever you need it.
***
## 8. How does billing work?
Tenbyte’s Cloud’s **pay-as-you-go** pricing has no hidden fees. We will only charge you for what you use.
# Tenbyte Cloud Init Configuration Generator
Source: https://docs.tenbyte.io/docs/cloud/cloud-init-config
Generate cloud-init configurations for automated server provisioning with Tenbyte infrastructure.
Use the generator below to create a cloud-init configuration for your server. Configure your username, password, web server, and database type to generate a ready-to-use cloud-init YAML configuration.
## How to Use
1. Enter your desired **username** and **password** for the hosting account
2. Select your preferred **web server** (Nginx, Apache2, OpenLiteSpeed, or MERN Stack)
3. Choose your **database type** (MySQL, MariaDB, or MongoDB)
4. Enable additional options like **Node.js** if needed
5. Click **Copy Config** to copy the generated YAML
6. Paste the configuration into your cloud provider's user-data field when creating a new instance
## Available Options
### Web Servers
| Server | Description |
| ----------------- | ------------------------------------------------------------------------ |
| **Nginx** | High-performance, lightweight web server with reverse proxy capabilities |
| **Apache2** | Feature-rich HTTP server with extensive module support |
| **OpenLiteSpeed** | High-performance LiteSpeed web server with LSCache support |
| **MERN Stack** | Full-stack setup with MongoDB, Express.js, React, and Node.js |
### Databases
| Database | Description |
| ----------- | ------------------------------------------------- |
| **MySQL** | Popular open-source relational database |
| **MariaDB** | MySQL-compatible database with enhanced features |
| **MongoDB** | NoSQL document database for flexible data storage |
### Additional Flags
| Flag | Description |
| ---------- | -------------------------------------------------------- |
| `--nodejs` | Install Node.js runtime on the server |
| `--yarn` | Install Yarn package manager (available with MERN stack) |
## Usage
The generated cloud-init configuration can be used when creating a new virtual machine. Simply paste the YAML configuration into the **User Data** field during instance creation, and your server will be automatically provisioned with your selected stack.
# Tenbyte Cloud Virtual Machines
Source: https://docs.tenbyte.io/docs/cloud/compute/cloud-vm
This guide explains the full process of creating a virtual machine in Tenbyte Cloud. It covers selecting an operating system or application image, configuring the machine type, setting up networking, and completing the VM setup.
## Select Virtual Machine
* To begin, open your Tenbyte Cloud dashboard and choose Virtual Machine from the list of available services.
* This takes you to the VM creation page where all configuration options are listed.
***
## Choose Operating System
* If you want to install an operating system, select **Operating System** and choose the OS.
You can choose from the following operating systems:
1. **`Ubuntu`**
2. **`Debian`**
3. **`Rocky`**
4. **`CentOS`**
5. **`OpenSUSE`**
6. **`AlmaLinux`**
7. **`Fedora`**
8. **`Windows (BYOL)`**
Each OS image is maintained and updated regularly to provide a reliable foundation for your workloads.
***
## Choose App Catalog
* If you need an application, select **App Catalog**.
Choose from available applications like:
1. **`cPanel`**
2. **`Docker`**
3. **`Mikrotik`**
4. **`Moodle`**
5. **`Node.js`**
6. **`Cyberpanel`**
7. **`Mailcoach`**
8. **`Plesk`**
9. **`Magento`**
10. **`pfSense`**
11. **`WordPress`**
For both operating systems and applications, you can choose the version that best fits your requirements during the setup process.
***
## Choose Empty Disk for ISO Booting
* If you plan to install an operating system manually using an ISO image, choose Empty disk.
***
## Select your Location
* Choose your Data center where the resource will be created.
Selecting a region close to your users or infrastructure can improve performance and lower latency.
***
## Select Server Class
* Choose between **General Purpose** or **Heavy Compute** based on your workload type.
1. **General Purpose**: Ideal for everyday applications, low to medium traffic workloads, and business systems.
2. **Heavy Compute**: Recommended for high-traffic systems, intensive compute tasks, and enterprise workloads.
***
## Configure your VM Size
* Select the **VM size** based on the resources your application requires.
* You can configure -
* **CPU Cores** – Match the number of cores to your processing demands.
* **Memory (RAM)** – Select memory based on your application size and performance needs.
* **Storage** – Choose the disk size appropriate for your files, databases, or workloads.
* This flexible configuration lets you build a VM that fits your exact use case.
***
## Public IPv4 Address
* If you require an **external IP** for your VM, **enable Public IPv4**.
Enabling Public IPv4 will incur an additional US\$2/month charge.
***
## Select VPC Network
* Choose an existing VPC network or create a new one for private and secure network setup.
* If you want to set up your own VPC network, you can follow the steps in the [Tenbyte VPC](/docs/cloud/networking/vpc) page found in the **Networking and Security** section.
***
## Fill in User Information and Billing Details
1. **Username**: Enter a username for your virtual machine. This will be used to log in.
2. **Password**: Set a password that meets the security criteria
3. **Confirm Password**: Re-type the password to ensure it has been entered correctly.
4. **SSH Public Key**: If you prefer passwordless SSH access, add your SSH key here. Select **SSH Keys**, and a pop-up will appear where you can enter a key name and paste your public key. Use the format:
**`ssh-keytype base64_encoded_key optional_comment`**.
Only single-line keys are accepted. Make sure the key is not wrapped, contains no extra spaces, and matches one of the supported key types.
5. **Initialization Script**: Optionally, you can add a custom configuration for the VM by using an initialization script. This can include cloud-init configurations to automatically set up your VM during the creation process.
6. **Resource Name**: Provide a resource name for your VM. This will be used to generate a suitable hostname for the machine if applicable.
7. **Estimated Monthly Cost**: This gives you an overview of what you’ll be charged based on the current setup.
8. **Billing Account**: Choose a billing account to associate with the VM.
If your account has limitations, a notice will appear, indicating these limits. The restriction will be removed once your total top-up reaches US\$2,000.
***
## Create the VM
* Once you’ve completed all fields and reviewed your details, click the Create button to finalize the creation of your virtual machine.
***
## View Your Created Virtual Machine
* Once your virtual machine (VM) is created, you will see it listed on your VM dashboard.
# Tenbyte Load Balancer
Source: https://docs.tenbyte.io/docs/cloud/compute/load-balancers
Configure and manage load balancers in Tenbyte Cloud for optimal traffic distribution and high availability.
## Select Load Balancer from Dashboard
* From your **Tenbyte Cloud dashboard**, select **Load Balancers** to begin setting up your load balancer across your virtual machines.
***
## Select Load Balancer Type
* Choose **Load Balancer** from the available options under Type.
***
## Location Selection
* Under Location, select the data center where your resource will be created.
***
## Public IPv4 Address
* Enable Public IPv4 if you require an external IP address for the load balancer.
Enabling Public IPv4 will add an additional US\$2/month charge for the resource.
***
## Select VPC Network
* Choose an existing VPC network for your resource or create a new one to isolate and secure your virtual machines.
***
## Target Servers
* Select the **target servers** (VMs) you want the load balancer to distribute traffic to.
***
## Configure Forwarding Rules
* Set up forwarding rules to define how the load balancer should route traffic to the VMs:
* **Protocol**: Select TCP.
* **Port**: Enter the source port.
* **Target Port**: Set the target port for the VM.
* You can add multiple rules if your application requires different ports or protocols.
***
## Review your Configuration and Create
* Provide a **Resource Name**. Review the configurations, including the Public IPv4, VPC network, target servers, and forwarding rules. Once everything looks good, click **Create** to set up the load balancer.
***
## View Your Created Load Balancer
* After creating your **Load Balancer**, you can view and manage it from the Load Balancers section in the **Network tab**.
* The Load Balancer will appear in the Network section with details like:
* **Name**: The name you assigned to the load balancer.
* **Public IPv4**: The external IP assigned to the load balancer.
* **Private IPv4**: The internal IP assigned to the load balancer.
* **Target Servers**: The VMs linked to the load balancer. You will see the assigned VMs listed along with their Private IPs.
* **Status**: The status of the load balancer.
* You can manage and configure the load balancer from here, including adjusting settings or adding new target servers.
# Tenbyte Cloud Knowledge Base
Source: https://docs.tenbyte.io/docs/cloud/index
**Tenbyte Cloud** is a high performance cloud platform built to help businesses scale and manage workloads reliably. It runs on enterprise grade hardware and supports application hosting, website deployment, and secure data storage from a single cloud environment.
## Why Tenbyte Cloud?
* **Scalable Virtual Machines**: Tenbyte offers powerful virtual machines that are scalable and can be used for ERP, ecommerce & streaming platforms.
* **Cloud Storage**: Scalable, reliable & cost effective storage for media files, backups and big data.
* **Fast Connections**: Get faster, low latency performance through direct connections to major exchanges.
* **DDoS Protection**: We provide a service guarantee that protects against DDoS attacks.
* **Virtual Private Cloud (VPC)**: You can set up your cloud **VPC** with your own IPs, subnets and security rules.
* **High Availability**: Always on services with 99.98% uptime.
* **24/7 Support**: Contact any time and get assistance with setup, migration, troubleshooting and more.
***
## Explore the Tenbyte Cloud API
Access all core endpoints, request formats & usage guides in one place.
# Tenbyte Cloud Metrics
Source: https://docs.tenbyte.io/docs/cloud/monitoring/metrics
Monitor and analyze the performance of your virtual machines in Tenbyte Cloud using key system metrics like CPU, RAM, Disk I/O, and Network bandwidth.
## Access the Metrics Tab
* From the **Tenbyte Cloud dashboard**, select the **virtual machine (VM)** you want to monitor.
* Once your VM is selected, go to the **Metrics** tab.
* In the **Metrics tab**, you will see **4 graphs** displaying key performance data for your VM:
1. **CPU Usage**
2. **RAM Usage**
3. **Disk I/O**
4. **Network Bandwidth**
### CPU Metrics
* The **CPU** (%) graph shows the **percentage of CPU usage** over time.
* It helps you **keep track of the CPU Resources** used by your virtual machine.
* If the CPU usage is higher, it can mean your VM is processing more data, running more tasks, or handling more traffic.
### RAM Metrics
* The **RAM (MB)** graph displays the **memory usage** of your VM.
* It **indicates the total RAM storage**. Then the part of RAM that is being utilized.
### Disk I/O Metrics
* The **Disk I/O (MB/s)** graph shows your **VM’s disk read** and **write operations**.
* It indicates how much data is sent to or received from the disk in seconds.
### Network Bandwidth Metrics
* The graph displays the **quantity of data** your **VM is transferring** **over the network in Mbit/s**.
* This will help you monitor incoming and outgoing traffic.
# Tenbyte Firewall
Source: https://docs.tenbyte.io/docs/cloud/networking/firewall
Create and manage firewalls in Tenbyte Cloud to control inbound and outbound traffic for your virtual machines.
Firewall rules define which connections are allowed or blocked, and can be configured and attached to VMs directly from the dashboard.
## Select Firewall from Dashboard
* Open your Cloud dashboard. From dashboard, click on **Firewall** to create your **Firewall**.
***
## Create a Firewall
* Choose **Firewall** as the **Type**.
* Choose the data center where the firewall will be applied.
### Configure Inbound Rules
* Inbound rules control traffic entering your virtual machine. Under Inbound rules, you can specify the traffic allowed to enter your virtual machine.
* **Type**: Select the type of traffic.
* **Protocol**: Choose the protocol.
* **Port Range**: Specify the port range.
* **Sources**: Enter the IP prefixes allowed to access the VM or select Any to allow all incoming traffic.
* Use inbound rules to allow only the ports required by your application and block all others.
### Configure Outbound Rules
* Outbound rules control traffic leaving your virtual machine. Under Outbound rules, specify which traffic can leave your virtual machine.
* **Type**: Select the type of traffic.
* **Protocol**: Choose the protocol.
* **Port Range**: Specify the port range.
* **Destinations**: Select All IP to allow traffic to any destination or specify a target IP range if you want to restrict the destinations.
### Configure Firewall Settings
* Enter a name for the firewall.
* Select the billing account that this firewall belongs to.
The firewall service is free, but the resources like VMs attached to it will incur additional charges.
* Click **Create** to finish creating the firewall. It will now be available to assign to your virtual machine.
***
## Assign Firewall to VM
* After creating the firewall with the inbound and outbound rules, go to your created VM dashboard.
* Navigate to the **Firewall section**.
* Click on **Attach Firewall**.
* Select the firewall you created and click on **Add**.
* Once added, the firewall rules will be applied to the VM, ensuring that only allowed traffic can access it.
# Tenbyte Access Delegations
Source: https://docs.tenbyte.io/docs/cloud/networking/manage-access
Access Delegation in Tenbyte Cloud allows controlled sharing of cloud resources with other users or systems.
You can grant limited access to a specific billing account or provide full access across all associated resources, while maintaining clear permission boundaries.
## Select Access Delegation from Dashboard
* Open your Tenbyte Cloud dashboard and click on **Access Delegation** to manage your **Access**.
* In the Access section of the Tenbyte Cloud dashboard, you can choose between two types of access:
1. **Access Delegation**
2. **API Token**
***
## Access Delegation
Allows you to delegate access to a user or system, enabling them to manage resources under your account.
### For Restricted Scope
Restricted Scope means the user will have access only to the resources tied to the selected billing account.
* Click on **New** to create a **new access delegation**.
* Under **Scope**, select **Restricted**.
* Choose the **Billing Account** you wish to share access to.
* Enter the **email address** of the user you want to delegate access to.
* Provide an **Access Name**.
* Click **Create** to send the access invitation to the specified email.
### For Global Scope
**Global Scope** means the user will have access to all resources under the billing account.
* Follow the same steps as above to create a new access delegation.
* Under **Scope**, select **Global**.
* Choose the **Billing Account** you wish to share access to.
* Enter the **email address** of the user for access delegation.
* Provide an **Access Name**.
* Click **Create** to send the access invitation.
Be cautious when selecting Global, as it grants access to all resources within the billing account.
The user will receive an invitation to accept access to the specified billing account.
***
## Access for API Token
API Token is used to generate a key for interacting with Tenbyte Cloud’s API.
* Navigate to the **Access** section again and click on **New**.
* Select **API Token** under Type.
* Provide an **Access Name** for your API token.
* Click **Create** to generate the API token.
For API Token, the scope type works similarly to Access Delegations, allowing you to specify restricted or global access.
***
## Created Access Delegations
* Once the **Access Delegation** is created, you will see the **delegated access listed** under the Access section.
* The status of the delegated access will be shown as **Pending** until the user accepts the access invitation.
* Once accepted, the user will be able to perform actions as per the scope of access.
* You can view or remove delegations anytime from the Access section.
# Tenbyte VPC
Source: https://docs.tenbyte.io/docs/cloud/networking/vpc
Create and manage Virtual Private Clouds in Tenbyte Cloud to isolate resources, define network boundaries, and control traffic flow within your cloud environment.
## Select VPC Network
* From your dashboard, click on **VPC Network** to create your own VPC network.
* When you first access the Network section, the default network is named **My Network**
## Create a New VPC Network
* To create a new VPC network, click on **Create new** in the Network section.
* Choose **VPC network** as the **Type**. This allows you to create a private network to group and isolate your cloud resources.
* Select the data center where the network will be created.
* Enter a name for your new VPC.
* Click **Create** to create the new VPC network.
The VPC network is free of charge, but you will be charged for resources connected to it.
## Assign VPC Network During VM Creation
* While creating a **new VM**, you can assign the newly created VPC network. To learn how to **create a virtual machine**, check out the [Virtual Machine](/docs/cloud/compute/cloud-vm) page under the **Compute** section of this document.
* In the VM creation screen, under VPC network, select the desired network from the dropdown:
* My Network (default)
* Newly Created
This ensures your VM is connected to the correct network during creation.
## Edit VM Network Settings
* If you want to change the VPC network after creating the VM, navigate to the **Network Section** in the VM settings.
* Click **Add sub-interface** to create additional interfaces or to modify the current one.
* Enter the **VLAN ID** for the sub-interface.
* Select the VPC network you want to associate with the VM.
* Click **Add** to associate the **VPC** network with your **VM**.
## Review VPC Network and Resources
After creating or modifying your VPC, you can view the VMs associated with the network. The **My Network** or **new vpc** will list the VMs connected to it, showing the public and private IP addresses.
# Quick Start Guide
Source: https://docs.tenbyte.io/docs/cloud/quickstart
This guide walks you through the complete process of creating your **Tenbyte Cloud account** and accessing the dashboard for the first time.
Once your account is active, you’ll be able to explore the platform, deploy cloud resources, and manage your projects.
## Prerequisites
Before starting, make sure you have:
* A **Tenbyte account** — [Sign up](https://console.tenbytecloud.com/app/).
* A valid email address that you can access immediately.
* A project or application that you want to deploy.
* A basic understanding of virtual machines, storage, or general cloud concepts.
***
## Sign up for a account
* Visit the [Tenbyte Website](https://beta.tenbyte.io/).
* On the homepage, click the "Sign Up with Email" button. This will take you to the cloud sign-in page.
* Click **Create an Account** to create your account. A registration form will appear where you can enter your details.
* **Add Your Email Address**: Enter a valid email address.
* **Create a Password**: Set a secure password that meets the following requirements:
* At least 8 characters long
* Includes one uppercase letter
* Includes one special character
* After filling out the required fields, click **Sign Up**.
* Tenbyte will send a verification link to the email address you provided.
* Once you have confirmed your email, you will be able to access your **Tenbyte Cloud dashboard**.
* If the email doesn’t appear:
* Check the spam or promotions folder
* Make sure the email address was typed correctly
***
## Use Social Sign-Up
* If you prefer a faster setup, you can choose **Sign Up with Google** instead of creating a password.
* This method links your Tenbyte Cloud account to your Google identity, making login simple and password-free.
* Use this option if you want:
* Quicker onboarding
* Fewer passwords to manage
* Automatic access control through your Google account
* Once completed, your dashboard will open just like a regular email-based account.
# Tenbyte Cloud Block Storage
Source: https://docs.tenbyte.io/docs/cloud/storage/block-storage
Block Storage in Tenbyte Cloud lets you attach high performance disks to your virtual machines. You can create new disks, expand existing ones, and manage storage based on your application’s needs.
## Select Compute Section
* Start by opening the Compute section from the left sidebar. This page lists all the virtual machines you have created.
***
## Choose Your Virtual Machine
* In the Compute section, locate the VM you want to manage.
***
## Navigate to the Disks Tab
* Once you open the selected VM, you’ll see several tabs with different configuration options.
* Click on the **Disks** tab to manage storage settings for the selected VM.
***
## View Existing Disks
* The Disks tab displays all disks currently attached to the VM.
* You may see the Boot Disk with details such as:
* **UUID**: The unique identifier for the disk.
* **Size**: The disk size.
* **Created**: The creation timestamp.
* **Est. Monthly Cost**: The cost for the disk storage.
* This view helps you understand your storage layout before making changes.
***
## Add Additional Disk
* To add a new disk, click on **Add additional disk**. You can choose the disk size based on your requirements and attach it to the VM.
* Click on the **Add** to add additional disk.
* After creation, the disk will appear in your disk list and can be formatted or mounted inside the VM.
***
## Manage Disks
* Tenbyte Cloud allows you to adjust disk size or remove additional disks based on your needs.
* Next to the disk you want to resize, click on the **Resize** button.
* Adjust the disk size according to your needs by modifying the disk size.
* After setting the desired size, click **Resize** to apply the changes.
It is highly recommended to stop the virtual machine before resizing the boot disk to prevent any issues with the operating system.
# Laravel With Tenbyte
Source: https://docs.tenbyte.io/docs/cloud/storage/laravel-with-tenbyte
How to use Laravel with Tenbyte t2-compatible storage
### How do I use Laravel with Tenbyte?
[Laravel](https://laravel.com/) is validated for use with Tenbyte. To use this product with Tenbyte, please follow the instructions below.
1. Set up your Tenbyte account and create a bucket as described [here](https://docs.tenbyte.io/docs/cloud/storage/object-storage).
2. Install Composer using the CLI.
3. Create a new Laravel project using the following command. You will receive the following output on the terminal once it is successfully created:
```bash theme={null}
composer create-project laravel/laravel
```
4. Go inside your project using the `cd` command and you will see the project files inside.
5. Now we will need to edit certain files inside this project to make this work with S3-style storage. You can either use any editor to edit the files (e.g. `vim` or `nano`) or make use of an IDE to search and edit them easily (e.g. Atom or Visual Studio Code).
6. Once you have the framework open in an IDE, create a new `.php` file in `resources -> views` and name it `fileUpload.blade.php`.
> **Note:** We recommend using the same name for the test as we have used this name when referencing in other files.
> The hierarchy would look like this
Paste the below code in `fileUpload.blade.php`:
```php theme={null}
@extends('layouts.app')
@section('content')
File Upload
@endsection
```
7. Now go to `routes -> web.php` and replace the file with the following code:
```php theme={null}
Route::get('/', function () {
return view('fileUpload');
});
Route::post('upload', function () {
request()->file('file')->store(
'my-file',
'Tenbyte'
);
})->name('upload');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
```
> **Note:** The directory here is `my-file` and your files will be uploaded inside it. We are also passing **`Tenbyte`** as a driver, which we will configure later in `filesystems.php` to specify our custom-defined driver to pass user input.
8. Go to the **root of your Laravel project** and open the `.env` file, then replace its contents with the following code.
> **NOTE:** Make sure to use your correct Access Key, Secret Access Key, Tenbyte bucket region, Tenbyte Bucket Name, and Tenbyte Region URL.
```env theme={null}
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:ZBWX+Pgx8ABy8CThdSi9ixRCyQmKQ1iWDsv1TSCMBUM=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=Bucket-Name
AWS_USE_PATH_STYLE_ENDPOINT=true
AWS_URL="t2.tenbytecloud.com"
AWS_ENDPOINT=https://t2.tenbytecloud.com/
AWS_USE_ACCELERATE_ENDPOINT=false
```
> **Note:** This example uses Tenbyte's `us-east-1` storage region. To use other Tenbyte storage regions, please use the appropriate Tenbyte service URL.
9. Now you need to create a new driver, as S3 has `amazonaws.com` hardcoded in the library. Go to `config -> filesystems.php` and replace with the following code:
```php theme={null}
return [
'default' => env('FILESYSTEM_DRIVER', 'local'),
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'Tenbyte' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'endpoint' => 'https://t2.tenbytecloud.com',
],
],
];
```
10. As the Tenbyte/S3 driver is not the default driver for uploading in Laravel, we need a Composer package to make this work. You can get this package on the Laravel website.
Now on the CLI, go inside your Laravel project and run the following commands.
For **Laravel 5 and below**:
```bash theme={null}
php artisan make:auth
```
For **Laravel 6 and above** (recommended):
```bash theme={null}
composer require laravel/ui
php artisan ui bootstrap --auth
```
Then run:
```bash theme={null}
composer require league/flysystem-aws-s3-v3
```
Output
11. Run your code using the following command and the server will start listening on port 8000:
```bash theme={null}
php artisan serve
```
Output
On the browser, navigate to `http://127.0.0.1:8000` and you will be prompted to upload files to your Tenbyte bucket. Once submitted, your files will be visible inside the bucket.
# Tenbyte Cloud T2 Object Storage
Source: https://docs.tenbyte.io/docs/cloud/storage/object-storage
Tenbyte T2 Object Storage is built for storing and managing large volumes of unstructured data. It supports creating buckets, uploading files, controlling access permissions, and sharing objects securely across applications and teams.
## Open the Storage Section
* From the left sidebar, click **Storage**.
* If you haven’t created any buckets yet, the page will appear empty.
***
## Create a New Storage Bucket
* Click **Create new**.
* Select **Storage bucket** as the resource type.
* Enter a name for your bucket.
Bucket names must use lowercase letters, numbers, or dashes. The length must be between 3–63 characters, and the name must be globally unique.
* Select a billing account.
* Click **Create**.
* Your bucket will appear in the Storage list immediately after creation.
***
## View Bucket Details
* Click the bucket name to open its details page.
Here you can see **Bucket name**, **Type (Storage bucket)**, **Creation time**, **Bucket size**, **Number of files**, **Server endpoint**, and **Billing account**.
* You will also see a section for Storage access keys:
* Access key ID
* Secret access key
* Type: Global / Restricted
These keys are used for programmatic access (S3-compatible).
***
## Upload Files to your Bucket
Inside the bucket, scroll down to the Files section. You can **Create folders**, **Upload files**, **Download files**, **Delete files**, and **Rename files**.
* To upload a file Click **Upload**.
* Choose any file from your device.
* Once the upload completes, the file will appear in the list.
You can upload directly inside the root or inside a created folder.
***
## File Access Controls
* Select a file, then open the **Access** menu from the right side of the row.
* You will see three options:
1. Share temporarily
2. Permissions
3. Copy Public URL
### Share temporarily
* Generates a temporary link that expires after a chosen duration.
* Click **Share temporarily** and select a duration.
* A temporary URL is generated.
* Copy and share the URL.
* The link expires automatically on the displayed time.
### Permissions
* This controls whether your file is **Private** or **Public**.
1. **Private (default)**
* File can only be accessed using **access keys** or **bucket permissions**.
* No public URL is available
2. **Public**
* Anyone can open the file using the public link.
* No authentication required.
* Click **Save** after choosing the desired permission.
### Copy Public URL
* If the file is already Public, the system will provide a usable URL that you can copy with one click.
If the file is Private, the public link remains disabled until you switch permissions to Public.
# Introduction to the Tenbyte T2 S3-Compatible API
Source: https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api
Overview of the Tenbyte T2 S3-Compatible API and how to get started
### Introduction to the Tenbyte T2 S3-Compatible API
The Tenbyte T2 Cloud Storage S3-Compatible API implements the most commonly used actions from the Amazon Simple Storage Service (S3) API, and it easily integrates with your existing applications, data management tools, and Amazon S3 gateways.
If you are not already a Tenbyte T2 user, you can [sign up for an account today](https://console.tenbytecloud.com/app/).
Most applications and scripts use one of the AWS SDKs or the S3 commands in the AWS CLI to access Tenbyte T2. All of the SDKs, and the CLI, allow you to override the default Amazon S3 endpoint in favor of Tenbyte T2. Sometimes, though, you might want to interact directly with Tenbyte T2 via the S3-Compatible API, perhaps in debugging an issue, or just to better understand how the service works. This documentation is the definitive reference for accessing Tenbyte T2 directly via the S3-Compatible API.
### Prerequisites
If you are familiar with Tenbyte, getting started is straightforward:
* Create a Tenbyte T2 account.
* Ensure that T2 object storage is enabled on your account.
* Create an application key. You cannot use your master application key with the S3-Compatible API.
* [Create a bucket](https://docs.tenbyte.io/docs/cloud/storage/object-storage). Note the bucket's Endpoint URL. It has the form `https://t2.tenbytecloud.com`. Make a note of the endpoint and region. At present, Tenbyte T2 provides a unified endpoint for all storage operations.
### Authentication
The S3-Compatible API supports only v4 signatures for authentication. v2 signatures are not supported at this time. To learn more about S3 authentication, refer to the [AWS Signature documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html).
**Authorization Credentials:**
```
Access Key:
Secret Key:
```
### Request and Response Formats
Communicate with the API by sending HTTP requests to resource endpoints. The HTTP method determines the action taken.
**DELETE**
Use the DELETE method to destroy a resource such as a bucket, object, or bucket setting. If it is not found, the operation will return a 4xx error and an appropriate message.
**GET**
To retrieve object data or configuration, use the GET method. Object data is returned in the format it was written; configuration is returned as XML. GET methods are read-only and do not modify any resources.
**PUT**
Use the PUT method to write object data or configuration. Configuration must be formatted as XML according to the schema defined by the Amazon S3 API.
**POST**
Use the POST method with the S3 Delete Object, S3 Complete Multipart Upload, and S3 Create Multipart Upload operations.
### HTTP Response Codes
The API uses standard HTTP response codes to show the outcome of requests. Response codes in the 2xx range indicate success, while codes in the 4xx range indicate a client-side error, such as an authorization failure or a malformed request. 4xx errors return an XML response object explaining the problem:
```xml theme={null}
NoSuchBucketThe specified bucket does not exist: NonExistentBucketNonExistentBucket
```
Codes in the 5xx range indicate a server-side problem preventing Tenbyte T2 from fulfilling your request, and include JSON diagnostics:
```json theme={null}
{
"code": "internal_error",
"message": "incident id 2f0e432cc922-9c2c28e96a16711b",
"status": 500
}
```
### Response Code Reference
| Code | Status | Description |
| ---- | --------------------- | -------------------------------------------------------------------- |
| 200 | OK | The response contains your requested information. |
| 201 | Created | Your request was accepted. The resource was created. |
| 202 | Accepted | Your request was accepted. The resource was created or updated. |
| 204 | No Content | Your request succeeded; there is no additional information returned. |
| 400 | Bad Request | Your request was malformed. |
| 401 | Unauthorized | You did not supply valid authentication credentials. |
| 403 | Forbidden | You are not allowed to perform that action. |
| 404 | Not Found | No results were found for your request. |
| 429 | Too Many Requests | Your request exceeded the API rate limit. |
| 500 | Internal Server Error | We were unable to perform the request due to server-side problems. |
### Differences from AWS S3
For the most part, the Tenbyte T2 Cloud Storage S3-Compatible API operates identically to Amazon S3. However, there are some important differences you should keep in mind when designing applications and solutions:
* **Tenbyte T2 endpoints** are located at `t2.tenbytecloud.com` rather than `amazonaws.com`. Most S3-compatible applications and tools let you customize the S3 endpoint to work with S3-compatible APIs outside of Amazon.
* **Access Control Lists (ACLs)** are set at the bucket level, and only the canned ACL values `private` and `public-read` are supported. You cannot set complex ACLs via XML. Objects inherit their bucket's ACL. Attempting to set an object's ACL to a different value from its parent results in a 403 Forbidden error.
* **File and bucket naming** — Tenbyte T2 features slightly different restrictions on file names and bucket names than Amazon S3.
* **Bucket versioning** — Buckets in Tenbyte T2 are versioned by default. Because buckets are versioned, when a file is deleted by referencing the name, only the most recent version of that file is deleted and older versions of the file continue to exist in the bucket.
* **HTTPS-only connections** — The API endpoints accept only connections over HTTPS. Non-secure connections are rejected.
* **Encryption** — Tenbyte T2 supports server-side encryption of data using either Tenbyte-managed keys (SSE-T2) or customer-managed keys (SSE-C). SSE-KMS encryption is not currently supported.
* **Not currently supported** — IAM roles, Object Tagging, and Website configuration are not currently supported.
### Bucket Operations
This set of operations allows you to manipulate Tenbyte T2 buckets.
There is no limit to the number of files in a bucket, but there is a limit of 100 buckets per account.
Aside from the S3 List Buckets operation, all bucket operations use an endpoint in the following form:
```
https://t2.tenbytecloud.com/
```
### Network Support
The Tenbyte S3-Compatible API currently supports IPv4 connections.
***
For detailed SDK examples and integration guides, see the following:
* [AWS SDK for Go with Tenbyte T2](/docs/cloud/storage/sdk-for-go)
* [AWS SDK for Java V2 with Tenbyte T2](/docs/cloud/storage/sdk-for-java)
* [AWS SDK for JavaScript V3 with Tenbyte T2](/docs/cloud/storage/sdk-for-javascript)
* [AWS SDK for Python (boto3) with Tenbyte T2](/docs/cloud/storage/sdk-for-python)
* [AWS SDK for .NET with Tenbyte T2](/docs/cloud/storage/sdk-for-dotnet)
* [AWS SDK for PHP with Tenbyte T2](/docs/cloud/storage/sdk-for-php)
* [AWS SDK for Ruby with Tenbyte T2](/docs/cloud/storage/sdk-for-ruby)
* [Laravel with Tenbyte T2](/docs/cloud/storage/laravel-with-tenbyte)
# AWS SDK for .NET with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-dotnet
How to use the AWS SDK for .NET with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for .NET with Tenbyte T2?
You can take advantage of Tenbyte T2 Cloud Storage using the [AWS SDK for .NET](https://aws.amazon.com/sdk-for-net/) alongside the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
To use the AWS SDK for .NET with Tenbyte T2, you must:
* Use version **3.7.108.0 or greater** of the [AWSSDK.Core package](https://www.nuget.org/packages/AWSSDK.Core). Older versions do not support easy configuration of a custom endpoint using the service-specific endpoint feature.
* Configure the `AWS_ENDPOINT_URL` environment variable or the `endpoint_url` setting in the shared AWS config file with your bucket's S3 endpoint. **Note:** you must include the `https://` prefix in the URL, for example: `https://t2.tenbytecloud.com`.
* Configure your Tenbyte T2 Access Key ID and Secret Access Key via one of the [methods supported by the AWS SDK for .NET](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/creds-assign.html). **Note:** the Tenbyte T2 Access Key ID is equivalent to the AWS access key id, and the Tenbyte T2 Secret Access Key is equivalent to the AWS secret access key.
This example demonstrates how to use the AWS SDK for .NET with Tenbyte T2:
```csharp theme={null}
using Amazon.S3;
using Amazon.S3.Model;
namespace Tenbyte_T2_Samples
{
public class S3_Basics
{
public static async Task Main(string[] args)
{
/*
Create an Amazon S3 client object. The constructor looks for
credentials in the following order:
1. Explicitly set in the AmazonS3Client() constructor
2. A credentials profile with the name specified by a value in AWSConfigs.AWSProfileName.
3. A credentials profile with the name specified by the AWS_PROFILE environment variable.
4. The [default] credentials profile.
5. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN environment variables - a
SessionAWSCredentials object is created from them, if they're all non-empty.
6. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables - a BasicAWSCredentials
object is created from them, if they're both non-empty.
Since AWSSDK.Core 3.7.108.0, you can set AWS_ENDPOINT_URL to https://t2.tenbytecloud.com,
rather than creating an AmazonS3Config object with a custom ServiceURL and passing it to
the AmazonS3Client constructor.
*/
IAmazonS3 client = new AmazonS3Client();
// Create a bucket and upload something into it
string bucket = "tenbyte-dotnet-sdk-sample-" + Guid.NewGuid();
string key = "sample.txt";
try
{
// The AWS SDK for .NET maps the CreateBucket operation to 'PutBucket'
await client.PutBucketAsync(new PutBucketRequest { BucketName = bucket });
await client.PutObjectAsync(new PutObjectRequest
{
BucketName = bucket,
Key = key,
ContentBody = "Hello from Tenbyte T2!"
});
Console.WriteLine($"Successfully uploaded data to {bucket}/{key}");
}
catch (AmazonS3Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
}
```
### Setting Up Environment Variables
Before running the application, set the following environment variables:
**Windows (PowerShell):**
```powershell theme={null}
$env:AWS_ENDPOINT_URL="https://t2.tenbytecloud.com"
$env:AWS_ACCESS_KEY_ID="your_T2_keyId"
$env:AWS_SECRET_ACCESS_KEY="your_T2_appKey"
```
**Linux/macOS:**
```bash theme={null}
export AWS_ENDPOINT_URL="https://t2.tenbytecloud.com"
export AWS_ACCESS_KEY_ID="your_T2_keyId"
export AWS_SECRET_ACCESS_KEY="your_T2_appKey"
```
Alternatively, you can configure credentials in `~/.aws/credentials`:
```ini theme={null}
[default]
aws_access_key_id = your_T2_keyId
aws_secret_access_key = your_T2_appKey
```
And set the endpoint in `~/.aws/config`:
```ini theme={null}
[default]
endpoint_url = https://t2.tenbytecloud.com
```
The Tenbyte S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# AWS SDK for Go with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-go
How to use the AWS SDK for Go with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for Go with Tenbyte T2?
You can take advantage of Tenbyte T2 Cloud Storage using the AWS SDK for Go alongside the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
It is easy to use the AWS Go SDK to integrate object storage into your Go environment.
The following example shows a configuration of the AWS Go SDK with the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
> **Note:** Make sure to replace `` and `` with your actual Tenbyte T2 Access Key ID and Secret Access Key from your Tenbyte console.
```go theme={null}
package main
import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
func main() {
bucket := aws.String("my-tenbyte-bucket")
key := aws.String("sample.txt")
// Configure the S3 client to point to Tenbyte T2
s3Config := &aws.Config{
Credentials: credentials.NewStaticCredentials("", "", ""),
Endpoint: aws.String("https://t2.tenbytecloud.com"),
Region: aws.String("us-east-1"),
S3ForcePathStyle: aws.Bool(true),
}
newSession := session.New(s3Config)
s3Client := s3.New(newSession)
// Create a new bucket
cparams := &s3.CreateBucketInput{
Bucket: bucket, // Required
}
_, err := s3Client.CreateBucket(cparams)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("Successfully created bucket %s\n", *bucket)
// Upload a new object "sample.txt" with the string "S3 Compatible API"
_, err = s3Client.PutObject(&s3.PutObjectInput{
Body: strings.NewReader("S3 Compatible API"),
Bucket: bucket,
Key: key,
})
if err != nil {
fmt.Printf("Failed to upload object %s/%s, %s\n", *bucket, *key, err.Error())
return
}
fmt.Printf("Successfully uploaded key %s\n", *key)
// Get Object
_, err = s3Client.GetObject(&s3.GetObjectInput{
Bucket: bucket,
Key: key,
})
if err != nil {
fmt.Println("Failed to download file", err)
return
}
fmt.Printf("Successfully downloaded key %s\n", *key)
}
```
The S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# AWS SDK for Java V2 with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-java
How to use the AWS SDK for Java V2 with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for Java V2 with Tenbyte T2?
You can take advantage of Tenbyte T2 Cloud Storage using the AWS SDK for Java V2 alongside the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
The following example shows a configuration with the Tenbyte S3-compatible endpoint:
> **Note:** Make sure to replace `ACCESS_KEY` and `SECRET_ACCESS_KEY` with your actual Tenbyte T2 Access Key ID and Secret Access Key from your Tenbyte console.
```java theme={null}
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import java.net.URI;
public class TenbyteT2Example {
public static void main(String[] args) {
final String ACCESS_KEY = "";
final String SECRET_ACCESS_KEY = "";
final String END_POINT = "https://t2.tenbytecloud.com";
Region region = Region.US_EAST_1;
AwsSessionCredentials awsCreds = AwsSessionCredentials.create(
ACCESS_KEY,
SECRET_ACCESS_KEY,
""
);
S3Client s3 = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.endpointOverride(URI.create(END_POINT))
.region(region)
.build();
// s3 client is now ready to use with Tenbyte T2
System.out.println("Successfully connected to Tenbyte T2");
}
}
```
The Tenbyte S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# AWS SDK for JavaScript V3 with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-javascript
How to use the AWS SDK for JavaScript V3 with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for JavaScript V3 with Tenbyte T2?
You can easily configure Tenbyte T2 Cloud Storage for use with the [AWS SDK for JavaScript V3](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/) using the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
The following example shows a `sample.js` that creates a bucket and uploads a file:
> **Note:** Make sure to replace the endpoint with your actual Tenbyte T2 endpoint from your Tenbyte console.
```javascript theme={null}
import { S3Client, CreateBucketCommand, PutObjectCommand } from '@aws-sdk/client-s3';
import { v4 as uuid } from 'uuid';
// Create an S3 client pointed to Tenbyte T2
const s3 = new S3Client({
endpoint: 'https://t2.tenbytecloud.com',
region: 'us-east-1',
credentials: {
accessKeyId: 'your_T2_keyId',
secretAccessKey: 'your_T2_appKey',
},
forcePathStyle: true,
});
// Create a bucket and upload something into it
var bucketName = 'tenbyte-sdk-sample-' + uuid();
var keyName = 'sample.txt';
try {
await s3.send(new CreateBucketCommand({ Bucket: bucketName }));
await s3.send(new PutObjectCommand({
Bucket: bucketName,
Key: keyName,
Body: 'Hello from Tenbyte T2!'
}));
console.log("Successfully uploaded data to " + bucketName + "/" + keyName);
} catch (err) {
console.log("Error: ", err);
}
```
The following code sample shows the content of `package.json`:
```json theme={null}
{
"dependencies": {
"@aws-sdk/client-s3": "^3.32.0",
"uuid": "^9.0.0"
},
"type": "module"
}
```
The following code sample shows how to install dependencies:
```bash theme={null}
% npm install
added 106 packages, and audited 107 packages in 3s
found 0 vulnerabilities
```
The AWS SDK for JavaScript can read credentials from the shared credentials file, environment variables, and other mechanisms. See [Setting Credentials in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html) for details.
For example, to use the shared credentials file, add your Tenbyte T2 credentials to `~/.aws/credentials` as a separate profile:
```ini theme={null}
[tenbyte]
aws_access_key_id = your_T2_keyId
aws_secret_access_key = your_T2_appKey
```
Then run the following script:
```bash theme={null}
% AWS_PROFILE=tenbyte node sample.js
Successfully uploaded data to tenbyte-sdk-sample-38cb5413-29c2-46f5-ab2d-4ac4d553f929/sample.txt
```
The Tenbyte S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# AWS SDK for PHP with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-php
How to use the AWS SDK for PHP with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for PHP with Tenbyte T2?
You can take advantage of Tenbyte T2 Cloud Storage using the AWS SDK for PHP alongside the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
> **Important:** Pre-Signed URLs that are generated with the PHP SDK are not currently compatible with Tenbyte T2.
### Prerequisites
When you create a Tenbyte T2 bucket, select the **Allow List All Bucket Names** checkbox. This option is required for the List Buckets operation. If you did not select this when you created your application key, you must create a new application key with this permission enabled.
### Configuration
First, configure your Tenbyte T2 credentials in the `~/.aws/credentials` file:
```ini theme={null}
[tenbyte]
aws_access_key_id = your_T2_keyId
aws_secret_access_key = your_T2_appKey
```
### Example: Creating a Bucket
This example shows how you create a bucket using the AWS SDK for PHP with a profile named `tenbyte` in the `~/.aws/credentials` file.
```php theme={null}
/vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
// Instantiate the S3 client using your Tenbyte T2 profile
$s3Client = new S3Client([
'endpoint' => 'https://t2.tenbytecloud.com',
'profile' => 'tenbyte',
'region' => 'us-east-1',
'version' => 'latest',
'use_path_style_endpoint' => true,
]);
// Sample to create a bucket
try {
$result = $s3Client->createBucket([
'Bucket' => 'my-tenbyte-bucket'
]);
echo "Bucket created successfully: " . $result['Location'] . "\n";
} catch (AwsException $e) {
echo "Error creating bucket: " . $e->getAwsErrorMessage() . "\n";
}
?>
```
### Installation
To use the AWS SDK for PHP, install it via Composer:
```bash theme={null}
composer require aws/aws-sdk-php
```
The Tenbyte S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# AWS SDK for Python (boto3) with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-python
How to use the AWS SDK for Python (boto3) with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for Python (boto3) with Tenbyte T2?
You can take advantage of Tenbyte T2 Cloud Storage using the AWS SDK for Python (boto3) alongside the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
You need to point the `endpoint_url` to the Tenbyte T2 S3 endpoint of the account to which you are connecting, along with supplying an Access Key ID and Secret Access Key for the account.
### Prerequisites
To use the AWS SDK for Python (boto3) with Tenbyte T2, you must:
* Use [**AWS SDK for Python (boto3) version 1.28.0 or greater**](https://aws.amazon.com/sdk-for-python/). Older versions do not support easy configuration of a custom endpoint using the service-specific endpoint feature.
* Configure the `AWS_ENDPOINT_URL` environment variable or the `endpoint_url` setting in the shared AWS config file with your Tenbyte T2 S3 endpoint. **Note:** you must include the `https://` prefix in the URL, for example `https://t2.tenbytecloud.com`.
* Configure your Tenbyte T2 Access Key ID and Secret Access Key via one of the methods supported by boto3. **Note:** the Tenbyte T2 Access Key ID is equivalent to the AWS access key id, and the Tenbyte T2 Secret Access Key is equivalent to the AWS secret access key.
### Installation
Install boto3 via pip if you haven't already:
```bash theme={null}
pip install boto3
```
### Setting Up Environment Variables
Set the following environment variables before running your application:
**Linux/macOS:**
```bash theme={null}
export AWS_ENDPOINT_URL="https://t2.tenbytecloud.com"
export AWS_ACCESS_KEY_ID="your_T2_keyId"
export AWS_SECRET_ACCESS_KEY="your_T2_appKey"
```
**Windows (PowerShell):**
```powershell theme={null}
$env:AWS_ENDPOINT_URL="https://t2.tenbytecloud.com"
$env:AWS_ACCESS_KEY_ID="your_T2_keyId"
$env:AWS_SECRET_ACCESS_KEY="your_T2_appKey"
```
Alternatively, you can configure them in `~/.aws/credentials` and `~/.aws/config`:
```ini theme={null}
# ~/.aws/credentials
[default]
aws_access_key_id = your_T2_keyId
aws_secret_access_key = your_T2_appKey
```
```ini theme={null}
# ~/.aws/config
[default]
endpoint_url = https://t2.tenbytecloud.com
```
### Example: Creating a Bucket and Uploading a File
The following example demonstrates how to create a bucket and upload data after having configured `AWS_ENDPOINT_URL`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` using either environment variables or the shared AWS config file:
```python theme={null}
import boto3
s3 = boto3.client('s3')
# Create a bucket
s3.create_bucket(Bucket='my-tenbyte-bucket')
print("Bucket created successfully: my-tenbyte-bucket")
# Upload an object
s3.put_object(
Bucket='my-tenbyte-bucket',
Key='sample.txt',
Body='Hello from Tenbyte T2!',
)
print("File uploaded successfully: sample.txt")
```
### Example: Using Inline Credentials (Without Environment Variables)
If you prefer to pass credentials directly in the code without using environment variables or config files:
```python theme={null}
import boto3
s3 = boto3.client(
's3',
endpoint_url='https://t2.tenbytecloud.com',
aws_access_key_id='your_T2_keyId',
aws_secret_access_key='your_T2_appKey',
region_name='us-east-1',
)
# Create a bucket
s3.create_bucket(Bucket='my-tenbyte-bucket')
print("Bucket created successfully: my-tenbyte-bucket")
# Upload an object
s3.put_object(
Bucket='my-tenbyte-bucket',
Key='sample.txt',
Body='Hello from Tenbyte T2!',
)
print("File uploaded successfully: sample.txt")
```
The Tenbyte S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# AWS SDK for Ruby with Tenbyte T2
Source: https://docs.tenbyte.io/docs/cloud/storage/sdk-for-ruby
How to use the AWS SDK for Ruby with Tenbyte T2 S3-compatible storage
### How do I use the AWS SDK for Ruby with Tenbyte T2?
You can take advantage of Tenbyte T2 Cloud Storage using the AWS SDK for Ruby alongside the Tenbyte [S3-Compatible API](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
You need to set the client endpoint and region to the Tenbyte S3 endpoint and region of the account to which you are connecting, along with supplying an Access Key ID and Secret Access Key for the account.
### Prerequisites
To use the AWS SDK for Ruby with Tenbyte T2, you must:
* Use **version 1.131.0 or later** of the [aws-sdk-s3 gem](https://rubygems.org/gems/aws-sdk-s3). Older versions do not support easy configuration of a custom endpoint using the service-specific endpoint feature.
* Configure the `AWS_REGION` environment variable or the `region` setting in the shared AWS config file with the region of your Tenbyte T2 endpoint. For example: `us-east-1`.
* Configure the `AWS_ENDPOINT_URL` environment variable or the `endpoint_url` setting in the shared AWS config file with your Tenbyte T2 S3 endpoint. **Note:** you must include the `https://` prefix in the URL, for example `https://t2.tenbytecloud.com`.
* Configure your Tenbyte T2 Access Key ID and Secret Access Key via one of the methods supported by the AWS SDK for Ruby. **Note:** the Tenbyte T2 Access Key ID is equivalent to the AWS access key id, and the Tenbyte T2 Secret Access Key is equivalent to the AWS secret access key.
### Installation
Install the `aws-sdk-s3` gem via Bundler or gem:
```bash theme={null}
gem install aws-sdk-s3
```
Or add it to your `Gemfile`:
```ruby theme={null}
gem 'aws-sdk-s3', '>= 1.131.0'
```
Then run:
```bash theme={null}
bundle install
```
### Setting Up Environment Variables
Set the following environment variables before running your application:
**Linux/macOS:**
```bash theme={null}
export AWS_ENDPOINT_URL="https://t2.tenbytecloud.com"
export AWS_REGION="us-east-1"
export AWS_ACCESS_KEY_ID="your_T2_keyId"
export AWS_SECRET_ACCESS_KEY="your_T2_appKey"
```
**Windows (PowerShell):**
```powershell theme={null}
$env:AWS_ENDPOINT_URL="https://t2.tenbytecloud.com"
$env:AWS_REGION="us-east-1"
$env:AWS_ACCESS_KEY_ID="your_T2_keyId"
$env:AWS_SECRET_ACCESS_KEY="your_T2_appKey"
```
Alternatively, you can configure them in `~/.aws/credentials` and `~/.aws/config`:
```ini theme={null}
# ~/.aws/credentials
[default]
aws_access_key_id = your_T2_keyId
aws_secret_access_key = your_T2_appKey
```
```ini theme={null}
# ~/.aws/config
[default]
region = us-east-1
endpoint_url = https://t2.tenbytecloud.com
```
### Example: Creating a Bucket and Uploading a File
The following example demonstrates how to create a bucket and upload data after having configured `AWS_REGION`, `AWS_ENDPOINT_URL`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` using either environment variables or the shared AWS config file:
```ruby theme={null}
require 'aws-sdk-s3'
# Use aws-sdk-s3 gem version 1.131.0 or later to configure endpoint via
# AWS_ENDPOINT_URL environment variable
s3 = Aws::S3::Client.new()
# Create a bucket
s3.create_bucket(bucket: 'my-tenbyte-bucket')
puts "Bucket created successfully: my-tenbyte-bucket"
# Upload an object
s3.put_object(
bucket: 'my-tenbyte-bucket',
key: 'sample.txt',
body: 'Hello from Tenbyte T2!'
)
puts "File uploaded successfully: sample.txt"
```
### Example: Using Inline Credentials (Without Environment Variables)
If you prefer to pass credentials directly in the code without using environment variables or config files:
```ruby theme={null}
require 'aws-sdk-s3'
s3 = Aws::S3::Client.new(
endpoint: 'https://t2.tenbytecloud.com',
region: 'us-east-1',
access_key_id: 'your_T2_keyId',
secret_access_key: 'your_T2_appKey',
force_path_style: true
)
# Create a bucket
s3.create_bucket(bucket: 'my-tenbyte-bucket')
puts "Bucket created successfully: my-tenbyte-bucket"
# Upload an object
s3.put_object(
bucket: 'my-tenbyte-bucket',
key: 'sample.txt',
body: 'Hello from Tenbyte T2!'
)
puts "File uploaded successfully: sample.txt"
```
The Tenbyte S3-Compatible API allows thousands of integrations to natively work with Tenbyte T2 Cloud Storage. If you are new to the Tenbyte S3-Compatible API, refer to the [Getting Started guide](https://docs.tenbyte.io/docs/cloud/storage/s3-compitable-api/intro-s3-compitable-api).
If you have issues using this SDK with Tenbyte T2, contact us at [support@tenbyte.io](mailto:support@tenbyte.io).
# Live Streaming Knowledge Base
Source: https://docs.tenbyte.io/docs/live-streaming/index
**Tenbyte Live Streaming** is **Tenbyte's** end to end live broadcast infrastructure that gives developers and media teams full control over stream ingest, real-time transcoding, multi-rendition delivery, and playback.
It replaces fragmented live video setups with a single, reliable pipeline built for low-latency broadcasting at any scale.
## Where Live Streaming Fits
See how different teams use Tenbyte Live Streaming in real projects.
Broadcast live channels to large audiences.
Run live classes and interactive sessions.
Monetize live events and control access.
Host live shopping and product launches.
Embed live streams into software apps.
Engage viewers with live brand content.
***
## Live Streaming Offers
### 1. Flexible Ingest
Accept live feeds via **RTMP**, **SRT**, **RTSP**, or **UDP** — whether pushed from an encoder like OBS or pulled from an existing source URL.
### 2. HLS & DASH Output
Tenbyte packages your stream into adaptive **HLS** and **MPEG-DASH** formats, ready for playback on any device, browser, or player.
### 3. Multi-Rendition Transcoding
Every stream is transcoded into multiple quality rungs simultaneously. Viewers are automatically served the best rendition for their device and connection speed.
### 4. Linear Live & Live Event Modes
Run a **24/7 linear channel** for always-on broadcasting, or schedule a **Live Event** for one-time broadcasts — all from the same interface.
### 5. Push & Pull
When creating a live stream, the first decision is how your video feed reaches Tenbyte. There are two ways: you push the feed out from your encoder, or Tenbyte pulls it from a source URL you already have.
| | Push | Pull |
| --------------------- | ------------------------------------------- | ---------------------------------------------------------- |
| **Who initiates** | Your encoder connects to Tenbyte | Tenbyte connects to your source |
| **Protocols** | RTMP, SRT | SRT, RTSP, RTMP, UDP |
| **Encoder required** | Yes — OBS, vMix, hardware encoder | No — any reachable stream URL |
| **Stream key needed** | Yes — one per protocol | No — just a source URL |
| **Best for** | Broadcasting from a local machine or studio | Re-streaming an existing feed, IP cameras, satellite links |
| **Network control** | You control when the feed starts | Tenbyte starts pulling when the stream is activated |
**Use Push** if you are broadcasting from OBS, vMix, or any hardware encoder sitting on your network. It is the most common setup and works out of the box with any standard broadcasting software.
**Use Pull** if you already have a live stream running somewhere — for example an IP camera, a broadcast encoder publishing to a local RTSP server, or an upstream feed from another provider. Tenbyte will connect to it directly so you do not need to reconfigure your source.
### 6. Custom Renditions Ladder
Add custom rungs with full control over resolution, codec, bitrate, GOP, CRF, FPS, and audio settings to match your exact delivery requirements.
### 7. Webhook Events
Receive real-time POST notifications for every stream lifecycle event — so you can verify authenticity and trigger downstream workflows automatically.
### 8. CDN-Ready Origin URLs
Every stream produces clean HLS/DASH origin URLs ready to be pointed at a CDN distribution for global, low-latency delivery to your viewers.
### 9. Powerful API Control
Create, update, start, and stop streams programmatically via the Tenbyte API — integrate live streaming directly into your platform without touching the dashboard.
> Tenbyte Live Streaming gives you a **complete live broadcast pipeline** — from encoder to viewer — so you can focus on your content, not your infrastructure.
# Configuration
Source: https://docs.tenbyte.io/docs/live-streaming/ingest-and-encoding/configuration
This page explains how to configure ingest and encoding when creating or editing a live stream.
***
## Ingest Method
The **Ingest** section defines how your video feed reaches Tenbyte. Choose one of two methods:
### Push from Your Encoder
Your encoder sends the feed directly to Tenbyte. Compatible with OBS, vMix, Wirecast, and any hardware encoder. You get a unique **Server URL** and **Stream Key** for each enabled protocol.
* Enable **RTMP**, **SRT**, or both under **Push protocols** — you get a separate stream key for each.
### Pull from a Source
Tenbyte connects to your stream URL and pulls the feed automatically. No encoder configuration needed on your end — just make sure the source URL is publicly reachable.
* Supported pull protocols: **SRT**, **RTSP**, **RTMP**, and **UDP**.
For a plain-English comparison of all protocols, see the [FAQs](/docs/live-stream/faqs).
***
## Stream Settings
| Field | Options | Description |
| -------------------- | ------------------------ | ----------------------------------------------------------------------- |
| **Stream Name** | Free text | A label to identify your stream in the dashboard. |
| **Stream Type** | Linear Live / Live Event | Linear runs 24/7 nonstop. Live Event is a one-time scheduled broadcast. |
| **Output Mode** | Video / Audio Only | Choose full video delivery or audio-only for radio-style streams. |
| **Output Protocols** | HLS / DASH | Pick at least one delivery format. Both can be enabled simultaneously. |
***
## Renditions Ladder
The **Renditions Ladder** defines the quality levels your stream is transcoded into. All rungs are encoded and delivered simultaneously — viewers are automatically served the best one for their device and connection speed.
### Templates
Click **Template** to apply a preset rendition set as a starting point:
| Template | Rungs | Description |
| ------------- | ------------------ | ------------------------------------------------------------------------ |
| **Balanced** | 3 rungs · default | 1080p, 720p, and 480p. A good all-round starting point for most streams. |
| **Bandwidth** | 2 rungs · low-cost | A leaner set optimised for lower bandwidth usage and cost. |
| **Quality** | 3 rungs · premium | Higher bitrate targets across all rungs for maximum quality output. |
You can then click any row to customize however you want.
### Adding a Custom Rung
Click **+ Add Rung** to add a custom rendition alongside the template rungs.
Each custom rung exposes the following settings:
**Video**
| Field | Description |
| ------------------ | ------------------------------------------------------------------------------------- |
| **Name** | A label for this rendition (e.g. `1080p High`). |
| **Profile** | H.264 encoding profile — `Main` is recommended for most use cases. |
| **Resolution** | Width × Height in pixels (e.g. `1280 × 720`). |
| **Codec** | Video codec — currently `H.264`. |
| **FPS** | Frames per second (e.g. `30`). |
| **GOP** | Group of pictures size. Keyframe interval is calculated automatically from GOP ÷ FPS. |
| **Target bitrate** | The target encoding bitrate in kbps. |
| **Max bitrate** | The maximum allowed bitrate in kbps. |
| **CRF** | Constant Rate Factor (0–51). Lower values = higher quality. |
**Audio**
| Field | Description |
| --------------- | --------------------------------------- |
| **Codec** | Audio codec — `AAC` recommended. |
| **Bitrate** | Audio bitrate in kbps (e.g. `128`). |
| **Sample rate** | Audio sample rate in Hz (e.g. `48000`). |
| **Channels** | `Stereo` by default. |
Click a rung row to expand and edit it, or click **Delete** to remove it.
Click a row in the renditions table to edit an existing rung at any time.
# Encoding & Renditions
Source: https://docs.tenbyte.io/docs/live-streaming/ingest-and-encoding/encoding-templates
The **Renditions Ladder** defines the quality levels your stream is transcoded into. Every rung is encoded simultaneously in real time — viewers are automatically served the best rendition for their device and connection speed, switching seamlessly between them as conditions change.
***
## Rendition Templates
Tenbyte provides three built-in templates as a starting point. Click **Template** in the Renditions Ladder section to apply one.
| Template | Rungs | Best for |
| ------------- | ------------------ | ------------------------------------------------------------------------------ |
| **Balanced** | 3 rungs · default | Most live streams. Covers 1080p, 720p, and 480p with sensible bitrate targets. |
| **Bandwidth** | 2 rungs · low-cost | Streams where delivery cost or bandwidth needs to be kept low. |
| **Quality** | 3 rungs · premium | High-production broadcasts where maximum output quality is the priority. |
The **Balanced** template is selected by default and is the right choice for most use cases.
***
## Default Balanced Renditions
| # | Rendition | Codec | Height | Target / Max Bitrate | FPS |
| - | --------- | ----------- | ------ | -------------------- | --- |
| 1 | 1080p | H.264 / AAC | 1080p | 3,000 / 3,500 kbps | 30 |
| 2 | 720p | H.264 / AAC | 720p | 1,500 / 2,000 kbps | 30 |
| 3 | 480p | H.264 / AAC | 480p | 700 / 900 kbps | 30 |
Click any row in the renditions table to expand and edit it.
***
## Adding a Custom Rung
Click **+ Add Rung** to add a custom rendition on top of the template. Custom rungs are fully configurable.
### Video Settings
| Field | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name** | A label for this rendition (e.g. `1080p High`). |
| **Profile** | H.264 encoding profile — `Main` is recommended for most use cases. |
| **Resolution** | Width × Height in pixels (e.g. `1280 × 720`). |
| **Codec** | Video codec — currently `H.264`. |
| **FPS** | Frames per second (e.g. `30`). |
| **GOP** | Group of pictures size. Keyframe interval is calculated automatically from GOP ÷ FPS — for example GOP 60 at 30 FPS produces a keyframe every 2 seconds. |
| **Target bitrate** | The target encoding bitrate in kbps. |
| **Max bitrate** | The maximum allowed bitrate in kbps. |
| **CRF** | Constant Rate Factor (0–51). Lower values produce higher quality at the cost of larger file size. |
### Audio Settings
| Field | Description |
| --------------- | ---------------------------------------------------- |
| **Codec** | Audio codec — `AAC` is recommended for HLS and DASH. |
| **Bitrate** | Audio bitrate in kbps (e.g. `128`). |
| **Sample rate** | Audio sample rate in Hz (e.g. `48000`). |
| **Channels** | `Stereo` by default. |
***
## Transmuxing
If your source is already encoded at the right bitrate and resolution, you can use **Transmuxing** instead of full re-encoding. Transmuxing passes the video and audio through without re-encoding — it only repackages the stream into the chosen output format (HLS or DASH).
This gives you the lowest latency and lowest CPU usage of any processing option.
**Use transmuxing when:**
* Your encoder is already producing the exact output quality you need.
* You want to minimise processing latency.
* You do not need multiple renditions — just a single passthrough quality level.
***
## GPU Transcoding
For high-resolution or high-bitrate streams, enable **GPU Transcoding** to offload encoding from the CPU to a dedicated GPU. This significantly increases the number of concurrent streams that can be processed and reduces encoding latency.
**Enable GPU Transcoding when:**
* You are streaming at 1080p or above with high bitrate targets.
* You are running many live channels simultaneously.
* Encoding latency is a concern for your use case.
# Ingest Protocols
Source: https://docs.tenbyte.io/docs/live-streaming/ingest-and-encoding/ingest-protocols
The ingest protocol defines how your video feed reaches Tenbyte. There are two ingest methods — **Push** and **Pull** — each supporting a different set of protocols depending on your setup.
***
## Push
With Push, your encoder initiates the connection and sends the feed directly to Tenbyte. You get a **Server URL** and **Stream Key** for each enabled protocol, which you paste into your encoder.
Compatible with OBS, vMix, Wirecast, and any hardware encoder.
You can enable one or both push protocols — each gets its own stream key.
### RTMP
Real-Time Messaging Protocol. The most widely supported ingest protocol available, compatible with virtually every streaming encoder on the market — including OBS, Wirecast, vMix, and hardware encoders from brands like Teradek and LiveU.
**Use RTMP** as your default choice. If you are using OBS or any standard broadcasting software and your network connection is stable, RTMP will work out of the box.
### SRT
Secure Reliable Transport. A modern protocol built for streaming over unpredictable or lossy networks. SRT adds encryption and automatic error recovery on top of UDP, handling packet loss and reconnections far better than RTMP.
**Use SRT** when your RTMP stream is dropping frames, stuttering, or disconnecting — for example when broadcasting from a remote location, a mobile connection, or over a long-distance link.
Both RTMP and SRT can be enabled simultaneously. Each gets its own stream key so you can switch between them without reconfiguring your stream.
***
## Pull
With Pull, Tenbyte initiates the connection — it reaches out to your source URL and pulls the feed automatically. No encoder configuration is needed on your end. Just make sure the source URL is publicly reachable before activating the stream.
**Use Pull** when you already have a live stream running somewhere — for example an IP camera, a broadcast encoder publishing to a local server, or an upstream feed from another provider.
### RTMP
Tenbyte connects to an existing RTMP source URL and pulls the feed. Use this when your source is already publishing an RTMP stream to a reachable endpoint.
### SRT
Tenbyte connects to an SRT listener and pulls the feed. Use this when your source supports SRT and you want the reliability benefits of SRT without configuring a push from your end.
### RTSP
Real Time Streaming Protocol. Commonly used by IP cameras, NVRs, and professional broadcast equipment. If your camera or device exposes an RTSP stream URL (e.g. `rtsp://192.168.1.10:554/stream`), Tenbyte can pull directly from it.
**Use RTSP** for IP cameras, security cameras, or any hardware device that publishes an RTSP feed.
### UDP
Sends the stream as an MPEG Transport Stream over UDP. Common in professional broadcast environments, satellite links, and IPTV headend systems. There is no built-in error recovery so this works best on reliable local or private networks.
**Use UDP** in controlled broadcast environments where packet loss is not a concern. Avoid it over the public internet.
For a full plain-English comparison of Push vs Pull, see the [What is Live Streaming?](/docs/live-stream) page.
# Output Protocols
Source: https://docs.tenbyte.io/docs/live-streaming/ingest-and-encoding/output-protocols
Output protocols define the delivery format Tenbyte uses to package and serve your live stream to viewers. You can enable one or both formats simultaneously to serve different players, devices, or CDNs at the same time.
***
## HLS
**HTTP Live Streaming** is Apple's adaptive bitrate protocol. It segments your stream into small files delivered over standard HTTP and is supported natively in every major browser, mobile OS, and smart TV platform — including Safari, Chrome, Firefox, iOS, Android, and most smart TVs.
HLS is the most universally compatible output format available. If you are not sure which to pick, enable HLS.
**Playback URL format**
```
https://your-cdn.tenbyte.io/{stream_id}/master.m3u8
```
***
## DASH
**MPEG-DASH** (Dynamic Adaptive Streaming over HTTP) is an open-standard alternative to HLS. Like HLS, it delivers adaptive bitrate content over HTTP — but it is codec-agnostic and integrates more cleanly with DRM systems.
DASH is recommended alongside HLS when you need broad coverage across non-Apple devices, or when your DRM setup requires it.
**Playback URL format**
```
https://your-cdn.tenbyte.io/{stream_id}/manifest.mpd
```
***
## HLS vs DASH at a Glance
| | HLS | DASH |
| ----------------------- | -------------------- | ------------------------ |
| **Standard** | Apple | Open (MPEG) |
| **Browser support** | Universal | Modern browsers |
| **Native iOS / Safari** | ✅ Yes | ❌ No |
| **DRM compatibility** | FairPlay, Widevine | Widevine, PlayReady |
| **Codec flexibility** | Limited | Codec-agnostic |
| **Best for** | Maximum device reach | DRM, non-Apple platforms |
Enabling both HLS and DASH is the recommended setup for most production streams — it ensures full coverage across all devices and browsers without any additional cost.
# Live Streaming Support FAQs
Source: https://docs.tenbyte.io/docs/live-streaming/live-faqs
Common questions about ingest protocols, stream setup, transcoding, recording, and delivery in Tenbyte Live Streaming.
***
## General
## 1. What is the difference between Linear Live and Live Event?
**Linear Live** runs continuously 24/7 — it stays active regardless of whether anyone is streaming to it. Use this for always-on channels, radio stations, or looping broadcast feeds.
**Live Event** is designed for a single scheduled broadcast with a defined start and end. Use this for webinars, sports events, concerts, or any one-time stream.
***
## 2. What output formats does Tenbyte Live Streaming support?
Tenbyte can deliver your live stream in **HLS**, **MPEG-DASH**, **RTMP**, and **HTTP-FLV** formats. You can enable more than one output at the same time to serve different players or CDNs simultaneously.
***
## 3. Can I stream audio only?
Yes. When creating a stream, set **Output Mode** to **Audio Only**. Tenbyte will strip the video track and output audio alone — useful for podcast-style streams, radio broadcasts, or any scenario where video is not needed.
***
## 4. Can I push my stream to YouTube, Facebook, or a third-party CDN?
Yes. Enable **RTMP** as an output protocol and enter the destination URL and stream key for the platform you want to push to (e.g. YouTube Live or Facebook Live). Tenbyte will re-stream the processed output to that endpoint.
***
## 5. How many renditions can I add to a stream?
There is no fixed cap. The default template includes three rungs (1080p, 720p, 480p). You can add as many custom rungs as your plan allows by clicking **+ Add Rung** during stream creation or editing.
***
## 6. Can I edit a stream's settings after it is created?
Yes. Open the stream from your Live Streams list and update the settings. Some changes — such as rendition configuration — may require the stream to be idle before they take effect.
***
## 7. What does the Idle status mean?
**Idle** means the stream has been created and is ready to receive a feed, but no encoder is currently connected or pushing to it. The stream will activate automatically once your encoder starts sending video.
***
## 8. Can developers manage live streams via API?
Yes. Tenbyte Live Streaming is fully API-driven. You can create, update, start, stop, and delete streams programmatically without touching the dashboard.
***
## Ingest Protocols
## 9. What is RTMP and when should I use it?
**RTMP** (Real-Time Messaging Protocol) is the most widely supported ingest protocol available. It is compatible with virtually every streaming encoder — including OBS, Wirecast, vMix, and hardware encoders from brands like Teradek and LiveU.
**Use RTMP** as your default choice unless you have a specific reason to switch. If you are using OBS or any standard broadcasting software, RTMP will work out of the box.
***
## 10. What is SRT and when should I use it instead of RTMP?
**SRT** (Secure Reliable Transport) is a modern protocol built for streaming over unpredictable or lossy networks like the public internet. It adds **encryption** and **automatic error recovery** on top of UDP, so it handles packet loss and reconnections far better than RTMP.
**Use SRT** when your RTMP stream is dropping frames, stuttering, or disconnecting due to network instability — for example, when streaming from a remote location, a mobile connection, or over a long-distance link.
***
## 11. What is SRT Unicast?
**SRT Unicast** is a point-to-point variant of SRT where the stream goes directly from one source to one fixed destination. It gives you all the reliability benefits of SRT but is used when you are connecting to a single specific endpoint rather than a general listener.
**Use SRT Unicast** when your setup requires a dedicated, encrypted connection between your encoder and Tenbyte's ingest server.
***
## 12. What is MPEG-TS over UDP and when is it used?
**MPEG-TS over UDP** sends your stream as an MPEG Transport Stream over the UDP protocol. It is common in professional broadcast environments, satellite links, and IPTV headend systems.
Because there is no built-in error recovery, this works best on **reliable local or private networks** where packet loss is not a concern. Avoid it over the public internet.
***
## 13. What is MPEG-TS over RTP (multicast)?
**MPEG-TS over RTP (multicast)** delivers your stream to a multicast group address over RTP. This means a single stream source can reach many receivers simultaneously without duplicating network traffic.
**Use this** in large venue setups, enterprise networks, or any environment where multiple destinations on the same network need to receive the same stream at once.
***
## 14. What is MPEG-TS over UDP (multicast)?
**MPEG-TS over UDP (multicast)** works the same way as MPEG-TS over RTP multicast but uses UDP as the transport instead of RTP. It reduces network load when multiple destinations on the same local network need to receive the same source stream simultaneously.
***
## 15. What are the MP3 over RTP and MP3 over RTMP options for?
Both are **audio-only ingest protocols**:
* **MP3 over RTP** — ingests an audio-only MP3 stream packaged inside RTP packets. Use this when your source sends RTP natively and you only need to stream audio.
* **MP3 over RTMP** — an audio-only variant of RTMP that carries an MP3 stream without a video track. Use this when your encoder publishes audio-only content via RTMP.
These are suited for radio-style broadcasts or any scenario where only audio needs to be delivered.
***
## Output Protocols
## 16. What is HLS and why is it the recommended output?
**HLS** (HTTP Live Streaming) is Apple's adaptive bitrate protocol. It segments your stream into small files delivered over standard HTTP, and it is supported natively in **every major browser, mobile OS, and smart TV platform**.
HLS is the safest, most universally compatible choice for reaching the widest audience without requiring special players.
***
## 17. What is MPEG-DASH and how does it differ from HLS?
**MPEG-DASH** is an open-standard alternative to HLS that also delivers adaptive bitrate content over HTTP. It is codec-agnostic and works well with DRM systems.
Use MPEG-DASH when you need broad compatibility with **non-Apple devices** and modern browsers, or when your DRM setup requires it. In most cases, enabling both HLS and MPEG-DASH covers your entire audience.
***
## 18. What does "MPEG-DASH output in ascending order of bitrate" mean?
By default, MPEG-DASH manifests list renditions from highest to lowest bitrate. Enabling this option **reverses the order** so the lowest bitrate appears first in the manifest.
Some players and CDNs prefer this ordering when selecting an initial rendition on slow connections — it helps them start playback faster rather than attempting a high-bitrate rendition first.
***
## 19. What is HTTP-FLV output?
**HTTP-FLV** delivers your stream as Flash Video over standard HTTP connections. It offers **very low latency** and is widely used in Asian streaming platforms and CDNs. It requires a compatible player on the viewer side but avoids the chunking overhead of HLS.
Use this if your platform or CDN specifically requires HTTP-FLV delivery.
***
## Advanced Features
## 20. What is High Availability (HA) mode?
**HA mode** keeps your channel live even if one ingest point fails. When enabled, Tenbyte accepts a **backup stream** alongside your primary feed and automatically switches to the backup if the primary drops — with no manual intervention required.
Enable HA for any production broadcast where downtime is not acceptable.
***
## 21. What is Dynamic Ad Insertion (DAI)?
**DAI** parses **SCTE-35 cue messages** embedded in MPEG-TS over UDP streams and uses them to trigger ad break insertion at the correct points in the live stream.
Enable DAI if your encoder or upstream signal includes SCTE-35 markers and you want Tenbyte to honor them for ad replacement.
***
## 22. What is GPU Transcoding?
**GPU Transcoding** offloads the video encoding workload from the CPU to a dedicated GPU. This significantly increases the number of concurrent streams the server can handle and reduces encoding latency.
Enable GPU Transcoding for **high-resolution or high-bitrate streams**, or when you are running many channels at the same time.
***
## 23. What is Transmuxing and when should I use it?
**Transmuxing** passes the video and audio through without re-encoding. The stream is repackaged into the chosen output format (e.g. HLS or MPEG-DASH) using exactly the codec settings from your encoder.
Use transmuxing when your source is **already encoded at the right bitrate and resolution** — it gives you the lowest latency and lowest CPU usage of any processing option.
***
## Recording
## 24. Can I record my live stream?
Yes. Tenbyte supports live recording in two formats:
* **HLS** — saves the stream as a set of segmented `.ts` files and a playlist. The recording is immediately ready to serve as on-demand HLS content after the broadcast ends with no additional conversion needed.
* **MP4** — saves the stream as a single MP4 file. The file is finalized and available once the stream ends, and is compatible with any video player, editor, or platform.
***
## 25. When does recording start and stop?
Recording starts automatically when your stream begins and stops when it ends. No manual action is required.
***
## Other Features
## 26. Can I add a logo or watermark to my stream?
Yes. Tenbyte supports **logo and watermark insertion**. You can upload an image, set its position on screen, and adjust its opacity. The watermark is burned into the transcoded output and will appear on all recordings and live deliveries from that channel.
***
## 27. Can I capture screenshots or thumbnails from a live stream?
Yes. The **Snapshot as JPG** feature periodically captures a still frame from the live stream and saves it as a JPEG image. This is useful for generating thumbnail previews, monitoring stream health at a glance, or displaying a current-frame image on your website without embedding the full player.
***
## 28. What is the Time Shifting / Rewind feature?
**Time Shifting** (also called DVR or catch-up) allows viewers to rewind and watch earlier parts of a live stream without leaving the live player. Tenbyte stores a rolling window of the broadcast, and viewers can scrub back within that window while others continue watching live.
The maximum rewind window duration is configured at the server level. Contact the Tenbyte team if you need to adjust the default window length.
***
## 29. What is a Webhook and how do I use it?
A **Webhook** sends a POST request to your endpoint whenever a stream lifecycle event occurs — for example, when a stream starts, stops, or encounters an error. All requests are signed with **HMAC-SHA256** so you can verify they came from Tenbyte.
To set one up, enter your endpoint URL in the **Webhook** section during stream creation. You can use webhooks to trigger downstream actions like sending notifications, updating a database, or starting a recording workflow.
***
## 30. What are Output Origin URLs and can I share them with viewers?
Output Origin URLs are the raw HLS or DASH playback endpoints generated by Tenbyte's ingest servers. They are intended **for CDN distribution setup only** — not for direct viewer playback.
Always point a CDN distribution at your stream and share the CDN's delivery URL with your viewers instead. Embedding origin URLs directly in players can cause reliability and performance issues.
# How Live Streaming Works
Source: https://docs.tenbyte.io/docs/live-streaming/live-work
Tenbyte Live Streaming structures every broadcast around three stages: **ingest, encoding, and output**. Each stage has a specific role, and together they form a single continuous pipeline from your encoder to your viewers.
### 1. Ingest — Getting the Feed In
The pipeline begins with ingest. This is where your video feed enters Tenbyte, either pushed from your encoder or pulled from a source URL. The ingest stage accepts a wide range of transport protocols — RTMP, SRT, RTSP, and UDP — and is compatible with all standard broadcasting software and hardware encoders.
Your source can be anything from a laptop running OBS to a professional hardware encoder or an IP camera on a local network. As long as the feed arrives over a supported protocol, Tenbyte takes it from there.
### 2. Encoding — Processing the Stream
Once the feed is received, Tenbyte encodes it in real time. The incoming video is decoded, processed, and re-encoded into multiple quality levels simultaneously using the renditions ladder you configured. Each rung produces an independent output at its defined resolution, bitrate, and frame rate.
This multi-rendition output is what enables adaptive bitrate playback — viewers are automatically served the highest quality their device and connection can handle, switching between renditions seamlessly without interruption.
The encoding stage also handles packaging. The encoded video is segmented and wrapped into the delivery formats you selected — HLS, DASH, or both — ready to be picked up by the output stage the moment each segment is complete.
### 3. Output — Delivering to Viewers
The final stage is output. Tenbyte writes the packaged stream segments to storage and makes them available for delivery.
**Storage** — Tenbyte is fully **S3-compatible**, meaning you can point the output at any S3-compatible object storage bucket. Segments and manifests are written continuously as the stream runs.
**Delivery** — For viewer-facing playback, connect a **Tenbyte CDN** distribution to your stream's origin URLs. The CDN caches and distributes segments globally, reducing latency and offloading origin traffic so the stream performs reliably regardless of audience size.
Output origin URLs are for CDN and storage configuration only. Always use a CDN delivery URL when embedding the stream in a player.
# Manage Streams
Source: https://docs.tenbyte.io/docs/live-streaming/manage-streams
This page covers how to view, monitor, and manage your live streams from the Tenbyte dashboard.
***
## Your Streams List
Navigate to **Live Stream** from the left sidebar to see all your streams in one place.
Each stream shows the following at a glance:
| Column | Description |
| ---------------- | -------------------------------------------------------------------------------------- |
| **Name** | The label you gave the stream when creating it. |
| **Type** | The stream type — `Linear` for 24/7 channels or `Live Event` for scheduled broadcasts. |
| **Mode** | The output mode — `Video` or `Audio Only`. |
| **Status** | The current state of the stream. |
| **Date Created** | When the stream was created. |
***
## Stream Statuses
| Status | What it means |
| ------------ | ----------------------------------------------------------------------------------- |
| **Idle** | The stream is created and ready, but no encoder is connected or pushing a feed yet. |
| **Live** | The stream is active and broadcasting to viewers. |
| **Stopping** | The stream is in the process of shutting down after the feed was disconnected. |
***
## Stream Actions
Click the **three dots (⋮)** at the end of any stream row to open the actions menu.
### Stream Detail
Opens the stream's full detail page where you can view ingest credentials, renditions, output URLs, and live preview.
### Stream Restart
Restarts the stream worker. Use this if your stream is behaving unexpectedly — for example, if the encoder is connected but the stream is not coming through properly.
### Stream Stop
Stops the stream and disconnects any active encoder feed. The stream will return to **Idle** status after stopping.
### Stream Delete
Permanently deletes the stream and all its configuration. This action cannot be undone.
Deleting a stream removes its ingest credentials and output URLs permanently. Any encoder or player pointing to those endpoints will stop working immediately.
***
## Stream Detail Page
Click on any stream name, or select **Stream Detail** from the actions menu, to open its detail page.
The detail page is split into two panels:
**Left panel**
* **Preview player** — Shows a live preview of your stream. Displays "Ready to stream" when idle and updates automatically once a feed is received.
* **Renditions** — Lists all active encode rungs with their real-time bitrate usage and peak values.
**Right panel**
* **Stream ID** — The unique identifier for this stream. Use this in API calls and CDN distribution setup.
* **Type & Protocols** — Confirms the stream type and output delivery format (HLS / DASH).
* **Ingest** — Shows the ingest mode (Push or Pull) along with the stream keys or source URL.
* **Output Origin URLs** — The raw HLS or DASH origin endpoints for CDN distribution setup.
* **Webhook** — Shows the configured webhook endpoint, or `Not configured` if none was set.
Output origin URLs are for CDN distribution setup only — never embed them directly in players. Always use a CDN delivery URL for viewer playback.
# Quick Start Guide
Source: https://docs.tenbyte.io/docs/live-streaming/quickstart
This guide walks you through creating your first live stream on Tenbyte and going live using OBS or any compatible encoder.
In just a few steps, you'll have a fully configured stream delivering to viewers in real time.
## Prerequisites
Before starting, make sure you have:
* A **Tenbyte account** — [Sign up](https://console.tenbyte.io/sign-up)
* **OBS Studio** (or any RTMP / SRT compatible encoder) installed on your machine
* An **API key** if you plan to manage streams programmatically
***
## Open Live Streaming
* After signing in, go to **Live Stream** from the left sidebar. You will see a table where your streams will be listed.
* Click **+ Create Live Stream** in the top right corner to open the stream creation form.
***
## Choose Your Ingest Method
The **Ingest** section defines how your video feed reaches Tenbyte.
* Select **Push from your encoder** if you are using OBS, vMix, or a hardware encoder. You will get a **Server URL** and **Stream Key** to paste into your encoder.
* Select **Pull from a source** if you already have a live stream URL. Tenbyte will connect to it and pull the feed automatically.
* Under **Push protocols**, enable **RTMP**, **SRT**, or both — you get a separate stream key for each.
Not sure which protocol to pick? See the [FAQs](/docs/live-stream/faqs) for a plain-English comparison of RTMP vs SRT.
***
## Configure Your Stream
Fill in the **Stream** section:
* **Stream Name** — A label to identify your stream in the dashboard (e.g. `Main Live Channel`).
* **Stream Type** — Choose **Linear Live** for a 24/7 continuous channel, or **Live Event** for a one-time scheduled broadcast.
* **Output Mode** — Choose **Video** for standard delivery, or **Audio Only** for radio-style streams.
* **Output Protocols** — Pick at least one: **HLS**, **DASH**, or both.
***
## Set Up Renditions
The **Renditions Ladder** defines the quality levels your stream is transcoded into. Click **Template** to pick a starting point:
* **Balanced** — 3 rungs (1080p, 720p, 480p) · default. Works well for most streams.
* **Bandwidth** — 2 rungs · low-cost. Good for keeping delivery costs down.
* **Quality** — 3 rungs · premium. Higher bitrate targets for maximum output quality.
You can click any row to customize more.
* To add a custom quality profile on top of the template, click **+ Add Rung** and fill in the resolution, bitrate, and audio settings.
* Optionally, enter a **Webhook URL** to receive notifications for stream events like start, stop, or error.
Once ready, click **Create Live Stream**.
***
## Connect OBS and Go Live
After the stream is created, its status of it in the stream list will show as **Idle**. Connect your encoder to start broadcasting.
* Open your stream from the stream list (you can click the three dots beside the name to click on "Stream detail" or simply click on the row of that stream) and copy the **Server URL** and **Stream Key** from the **Ingest** section.
* Open **OBS Studio** and go to **Settings → Stream**.
* Set **Service** to `Custom`.
* Paste the **Server URL** and **Stream Key** into their respective fields.
* Click **OK**, then hit **Start Streaming** in OBS.
The stream preview on your dashboard will update automatically once OBS begins pushing the feed.
If you selected **Pull** as your ingest method, no encoder setup is needed — Tenbyte connects to your source URL automatically.
***
## Stop Your Stream
When you are done broadcasting or you want to stop encoding of a stream, stop the stream from the dashboard.
* Go to the **Live Stream** list and click the **three dots (⋮)** next to your stream.
* Select **Stream Stop** from the actions menu.
The stream will disconnect the encoder feed and return to **Idle** status.
You can also use **Stream Restart** from the same menu if your stream is behaving unexpectedly — for example, if the encoder is connected but the feed is not coming through.
***
## Copy Your Stream ID
* Open your stream from the **Live Stream** list.
* In the **Stream** panel on the right, locate the **ID** field and click **Copy**.
* Use this ID in API calls, player configurations, or CDN distribution setup.
The **Output Origin URLs** shown on the stream detail page are for CDN distribution setup only — never paste them directly into a player. Always point a CDN distribution at your stream and use its delivery URL for viewer playback.
# Webhooks
Source: https://docs.tenbyte.io/docs/live-streaming/webhooks
Tenbyte Live Streaming can send real-time POST notifications to your server whenever a stream lifecycle event occurs. This lets you trigger downstream actions — like sending alerts, updating a database, or starting a recording workflow — automatically.
***
## Setting Up a Webhook
You can add a webhook endpoint when creating a stream or by editing an existing one.
* In the **Webhook** section at the bottom of the stream creation form, enter your **Endpoint URL**.
* A signing secret is generated automatically after the stream is created. Use this secret to verify that incoming requests came from Tenbyte.
The webhook endpoint URL is optional. You can leave it blank and add or update it later from the stream detail page.
***
## Webhook Events
Tenbyte sends a POST request to your endpoint for each of the following stream lifecycle events:
| Event | When it fires |
| ---------------- | ------------------------------------------------------- |
| `stream.started` | The stream feed is received and the broadcast begins. |
| `stream.stopped` | The stream feed is disconnected and the broadcast ends. |
| `stream.error` | An error occurred during ingest or processing. |
| `stream.idle` | The stream has returned to idle after stopping. |
***
## Example Payload
Each webhook request is sent as JSON with `Content-Type: application/json`.
```json theme={null}
{
"event": "stream.started",
"stream_id": "e17be730-44b9-4ca6-af35-b17fb84958d6",
"stream_name": "Main Live Channel",
"timestamp": "2026-05-06T10:32:00Z"
}
```
***
## Viewing Webhook Status
From the stream detail page, the **Webhook** panel shows the configured endpoint URL. If no webhook has been set up, it displays `Not configured`.
# Manage API Keys
Source: https://docs.tenbyte.io/docs/organization/api-keys
Create and manage API keys to securely connect applications with Tenbyte. Control key permissions, define access scope, and set validity periods without using primary login credentials.
## Open the API Keys Page
* To get started, open **API Keys** from the Organization menu in the left sidebar. You’ll be taken to a simple dashboard that lists your existing keys.
* If you haven’t created any keys yet, the page will show an empty state with a **Create API Key** option.
***
## Create a New API Key
* Click **+ Create API Key** in the top-right corner to open the creation form.
Here’s what you’ll need to fill in:
* **Name** — Give the key a short name so you know what it’s used for.
* **Expiration** — Choose how long the key should remain valid:
* 1 Month
* 6 Months
* 12 Months
* Unlimited
* **Scope Access** — Pick the services or areas this key should be able to access.
***
## Generate the Key
* After completing the fields, select **Create** to generate the key.
* Your new API key will be generated and displayed once.
***
## View or Manage Existing Keys
* Any key you’ve already created will appear in the dashboard.\
From here, you can:
* Check the key’s metadata
* Disable a key if you no longer want it active
* Delete a key entirely
* Create new keys whenever your applications need separate access
This setup helps you keep your API usage organized and gives you a clear way to control which systems can interact with your Tenbyte workspace.
# Organization Settings
Source: https://docs.tenbyte.io/docs/organization/general-settings
Manage core organization information including workspace name, logo customization, and the unique organization ID used across the Tenbyte platform.
## Organization Information
* Here you’ll find the main details tied to your organization.
* **Name**- Update the official name of your organization or team.
* **Organization ID**- A unique identifier automatically generated for your organization.
You can copy it with a single click.
* **Organization Logo**- Upload a logo to help personalize your workspace.
***
## Delete your Organization
* This section deals with actions that are permanent. If you choose to remove the organization, everything linked to it is deleted.
* Deleting your organization permanently removes:
* All videos
* All CDN distributions
* Live streams
* Analytics data
* Transcoding profiles
* All members and permissions
Only use this option if you are fully sure you no longer need anything stored or configured in this workspace.
***
## Saving Changes
* Any time you adjust your organization details, scroll to the bottom of the page and confirm the changes.
* Click **Update Organization** to apply your updates.
Keeping your organization information up to date ensures your workspace remains clear, accurate, and easy for your team to work with.
# Organization Overview
Source: https://docs.tenbyte.io/docs/organization/index
Manage teams, user permissions, API keys, and organization level settings from a single, centralized dashboard.
The menu includes a few areas you’ll use when setting things up:
1. [Organization Members](/docs/organization/members): Add team members, send invitations, and assign permissions for CDN distributions and workspace resources.
2. [API Keys](/docs/organization/api-keys): Create and manage API credentials used to authenticate with Tenbyte services.
3. [General Settings](/docs/organization/general-settings): Review and update your organization name, branding, and default preferences.
# Organize Team Members
Source: https://docs.tenbyte.io/docs/organization/members
View all workspace members, invite new users, and manage individual access permissions from one central location.
## Members
* This page lists all users in your organization along with their roles and connection details.
From this dashboard you can view -
1. **Name** — The member’s full name
2. **Email** — Email address used to sign in
3. **Connected With** — Sign-in provider like email, Google, or GitHub
4. **Role** — Owner, Admin, Member, or custom-defined role
5. **Joined At** — The date and time the member joined your workspace
To manage a member, open the three-dot menu beside their name.
The menu gives you a few options:
1. **Manage Permission** — Adjust what this person can access and control
2. **Remove Member** — Remove the user from your organization
Removing a member immediately revokes access to all dashboards, APIs, and distributions.
***
## Invite Member
* To bring new people into your workspace, select **Add Members**.
Here’s how the invitation works:
1. **Enter Email Address** - In the Invite Member section, type the email of the person you want to invite.
2. **Send Invitation** - Once the email is entered click on **Send invitation**, an invitation will be sent.
The person you invite must accept the email invitation before they appear in your Members list.
Once they join, you can assign permissions to decide what they can access.
***
## Permissions
* Permissions define what a member can view, edit, or delete inside your organization. Permissions are grouped into two areas:
1. CDN Distribution
2. Organization
You can switch between these tabs to assign access rights.
### CDN Distribution Permissions
* If your organization has CDN distributions, they will appear in this area.
Each distribution can have its own access settings.
If you want to create a new distribution, check the guide at [Create CDN Distribution](docs/cdn/distributions/create-distribution).
### Organization Permissions
* These permissions control access to global settings within your workspace.
You can assign access for:
1. **Members** — Invite users and manage their permissions
2. **Billing** — View invoices and payment information
3. **API** — Create and manage API keys
For each area, you can choose:
* **`can view`**
* **`can edit`**
* **`can edit`** (no delete)
* **`no access`**
This lets you set up access in a way that fits your team and how you want to share responsibilities.
# Vidinfra Knowledge Base
Source: https://docs.tenbyte.io/docs/vidinfra/index
**Vidinfra** is **Tenbyte’s** end to end video infrastructure platform that gives developers and media teams full control over video hosting, encoding, delivery, playback, security, and analytics.
It replaces complex video pipelines with a single, reliable system built for performance and scale.
## Where Vidinfra Fits
See how different teams use Vidinfra in real projects.
Reliable learning video delivery.
Stream to large audiences.
Monetize and control access.
Showcase products with video.
Add video into software apps.
Engage viewers with content.
***
## Vidinfra Offers
### 1. Automatic Optimization
Get the highest video compression output while maintaining visual quality.
Vidinfra’s encoding pipeline automatically optimizes bitrates, resolutions, and codecs for every device and connection speed — no manual tuning required.
### 2. HLS & DASH Support
Vidinfra outputs adaptive streaming formats (**HLS** and **MPEG-DASH**) that play seamlessly on any device, browser, or operating system using your preferred player.
### 3. Auto Format
Each video is automatically transcoded into multiple renditions and adaptive bitrates.
This lets the client device intelligently select the best stream — balancing quality and bandwidth efficiency.
### 4. Unified, Managed Pipeline
Vidinfra manages and optimizes the **entire pipeline** from ingest → transcode → storage → packaging → delivery.
Everything is accessible through one API and dashboard.
### 5. Smart Routing (Multi-CDN)
Vidinfra’s **Smart Routing engine** intelligently delivers content via multiple CDN partners worldwide.
It continuously monitors network health and routes each viewer to the fastest, lowest-latency edge — ensuring 99.99% global availability and smoother playback.
Multi-CDN improves playback by choosing the fastest CDN route in real time.
>
### 6. Global CDN Delivery
All streams are delivered via a **world-class, low-latency CDN network** optimized for video delivery.
Edge caching ensures fast start times and consistent playback across the globe.
### 7. Powerful API & SDKs
Control every part of your video lifecycle with simple, developer-friendly APIs.
Perform operations like crop, clip, overlay, watermark, or generate signed playback URLs — programmatically or via SDKs.
### 8. DRM & Access Control
Protect your content with built-in **DRM (Widevine, FairPlay, PlayReady)** and token-based access control.
Prevent unauthorized playback and downloads with secure, signed URLs.
> Vidinfra makes it easy to **ingest, transform, and deliver video at scale**, so you can focus on your product, not your pipeline.
# Traffic and Performance Metrics
Source: https://docs.tenbyte.io/docs/vidinfra/manage-library/analytics
This dashboard displays how videos are delivered across the network, highlighting usage trends, delivery performance, and caching efficiency over a selected time range.
* When you enter your preferred video library, you will see a **Statistics** option in the left sidebar. Select it to open the analytics dashboard for that library and view traffic, requests, and caching performance.
* At the top of the **Statistics** page, you will see a quick snapshot of your key analytics. This includes **Traffic Served**, **Total Requests**, and **Cache Hit Rate** for the selected time range.
Scroll down to view the detailed charts and breakdowns for each metric. These sections help you understand usage patterns, delivery quality, and caching performance in depth.
## 1. Traffic Served
Shows the total data delivered from your video library within the selected period.
### What it tells you:
* How much bandwidth your videos consumed.
* Whether usage increased or decreased compared to the previous period.
* How traffic trends shift over time.
### How to read it:
* The main number shows total MB or GB delivered.
* The percentage compares today’s traffic with the previous day.
***
## 2. Requests Served
Shows how many requests were made to fetch your videos.
### What it tells you:
* The number of video load events from viewers.
* How often content is being accessed.
### How to read it:
* The main number shows total requests.
* The percentage reflects request changes since the last time window.
***
## 3. Cache Hit Rate
Shows how often content was delivered from the cache instead of the origin.
### What it tells you:
* How efficiently your content is cached.
* Whether viewers are getting faster response times.
* How much load is reduced on the origin.
### How to read it:
* Higher percentages indicate better caching.
* A higher cache hit rate results in faster playback and lower origin usage.
# Library Configuration
Source: https://docs.tenbyte.io/docs/vidinfra/manage-library/library-settings
Manage how your video library is structured and controlled using a centralized configuration panel.
## Create your Library
* Start by creating a library that fits your workflow. Add a name, choose a category, and set it as your workspace base. For detailed steps, visit [Set Up Your Vidinfra Workspace](/docs/vidinfra/quickstart).
***
## Open Your Vidinfra Library
* When you select Vidinfra from the left sidebar, you will see all the libraries you created.
* Choose the library you want to work with. Inside the library, your uploaded videos and folders are listed in one place.
***
## Search and Filter
Vidinfra includes built-in tools to help you find videos quickly in large collections.
### Search by File Name
Use the search bar to locate videos by title. Results update instantly as you type.
### Filter by Tags
Filter your videos using the tags you assigned during upload or editing. This is useful for grouping videos by category, project, or workflow.
### Filter by Status
You can filter videos based on their current state, including **Processing**, **Transcoding**, or other workflow stages. This helps you review progress at a glance and track pending tasks.
***
## Organize Videos with Tags
Tags help you group videos by topic, project stage, event type, or team ownership. You can attach several tags to the same video to keep large collections easier to navigate.
### How to Add Tags
1. Pick the videos you want to update from your library.
2. Scroll to the Tags section in the details panel.
3. Type the tags you want to assign and save your changes.
You can create unlimited tags and assign them to any video for flexible organization.
# Library Dashboard Overview
Source: https://docs.tenbyte.io/docs/vidinfra/manage-library/overview
Get a complete overview of your video library, including upload activity, processing status, and storage usage.
## What You Can Do?
1. View All Videos
See every video uploaded or imported into your library along with its title, duration, and status.
2. Search and Filter
Quickly locate videos by name, tag, or upload date to save time when managing large collections.
3. Track Upload and Processing Status
Monitor the progress of video uploads and transcoding in real time.
4. Check Storage Usage
Keep an eye on your total and available storage to plan capacity efficiently.
5. Access Quick Actions
Use the action menu beside each video to preview, edit details, copy embed links, or delete files.
# Upload or Import Videos
Source: https://docs.tenbyte.io/docs/vidinfra/manage-videos/upload-videos
Add videos to your library and prepare them for processing and streaming.
## Vidinfra Video Submission Requirements
Before uploading videos to Vidinfra, make sure your files meet the following guidelines for smooth processing, encoding, and playback.
### File Format
* Vidinfra accepts the most common video formats:
* MP4
* MOV
### Video Codecs
* Use any of the supported codecs below:
* H.264 (AVC)
* H.265 (HEVC)
* VP9
### Resolution
* Recommended resolution: **1920×1080 (HD)** or higher
* Keep the video’s original aspect ratio (e.g., 16:9 landscape, 9:16 vertical)
### Frame Rate
* Keep the **native frame rate** of your source file
* Common values include 24, 25, 30, and 60 fps
### Audio Requirements
* Use clean, high-quality audio encoded with one of the following:
* **AAC** (recommended and most widely supported)
* **Opus** (ideal for web playback)
***
## Upload From Local
Click Upload Video to choose a file from your device. After selecting the file, Vidinfra begins the upload and prepares it for **encoding**, **thumbnail generation**, and **playback**. This option is ideal when you are adding new recordings, edited content, or raw files stored on your computer.
***
## Import From External Platforms
You can fetch videos directly from supported external platforms. Vidinfra pulls the file from the source and adds it to your library without requiring you to download it manually.
You can import videos directly from supported platforms, including:
* Vimeo
* Bunny
* Zoom
* Vdocipher
* Gumlet
* Wistia
* Amazon S3
* Other connected storage services
To learn how to upload videos in Vidinfra, see the [Upload your Video Section](/docs/vidinfra/quickstart#upload-your-video) for a full walkthrough.
# Configure Your Video
Source: https://docs.tenbyte.io/docs/vidinfra/manage-videos/video-settings
The Video Settings panel lets you control every aspect of a video after upload. You can edit basic details, add subtitles, create chapters, and review technical metadata to organize and optimize each video asset.
Vidinfra divides video settings into four tabs:
1. Overview
2. Subtitles
3. Chapters
4. Others
Below is a full explanation of each tab.
## Overview
The **Overview tab** contains the core information about your video. You can update the **name**, add a **description**, **manage tags**, and **set thumbnails**.
### Name
Enter a title that identifies your video. This name appears across your Vidinfra dashboard and in all video listings.
### Description
Add a short description to explain what the video covers. This is helpful when managing large libraries or sharing content with teams.
### Tags
Tags help you organize and filter videos. Add multiple tags to group videos by category, event, project, or workflow. For advanced tag management, check [Library Settings](/docs/vidinfra/manage-library/library-settings#organize-videos-with-tags).
### Thumbnails
Choose a thumbnail to represent the video.
You can:
1. Select a generated thumbnail
2. Upload a custom image
3. Drag and drop an image into the upload area
***
## Subtitles
The **Subtitles tab** allows you to upload caption files for your video. Subtitles help improve accessibility, viewer engagement, and searchability.
### Language Selection
Choose the subtitle language from the dropdown list.
### Upload Subtitle File
Upload a subtitle file by:
1. Dragging and dropping it into the file box
2. Clicking browse file to select it from your device
3. Vidinfra supports standard subtitle formats like VTT and SRT.
### Multiple Subtitles
* Click **Add More** to upload multiple subtitle tracks.
* Select your languages and upload the files and click on **Save subtitles**
***
## Chapters
The **Chapters tab** lets you break your video into sections. Chapters help viewers jump to key moments and improve navigation in long videos.
### Add Chapters
* Click **Add More** to create a new chapter.
* Enter the timestamp and title for each chapter.
* Add as many chapters as you need and click on **Save changes**.
If your video has no chapters yet, the panel will show: No chapters added yet.
***
## Others
The **Others tab** displays technical metadata and asset information about your video. This section helps you understand the processing status, quality outputs, and file properties.
### Meta Data
Add custom key–value pairs to store extra information about the video. Examples:
* Category
* Campaign name
* Internal tracking IDs
* Creator information
You can add multiple metadata fields using **Add More**.
### Asset Info
This section shows core details of your video asset, including:
1. **Status** – Shows whether the video is playable
2. **Duration** – Video length
3. **Format** – Playback format (e.g., `ABR`)
4. **Resolutions** – Available output qualities (240p to 1080p)
5. **Original File Size** – Size of the uploaded file
6. **Total File Size** – Size of all processed output variants
### Timeline
Displays the full processing history of the video. You can track each stage with timestamps:
* Playable
* Saving
* Packaging
* Transcoding
This helps you verify when each processing step finished and ensures the video is ready for playback.
# Customize Your Player
Source: https://docs.tenbyte.io/docs/vidinfra/player-customization/player-themes
Adjust player theme, controls, and appearance to match your brand and viewing experience.
## Open the Player Settings
From the left sidebar of your library, click on **Settings** and then select **Player** to open the player customization page.
* This section lets you control how your video player looks and behaves across devices.
* Click the three-dot menu on the right side of the player card.
* From the dropdown, select **Edit** to open the player settings.
* You can also create a new player from the top right corner based on your needs.
***
## General Info
The **General Info section** lets you define the basic details and visual style of your video player.
These settings help you identify the player and control the colors used across its interface.
### Player Name
Enter a name to identify this player preset. This helps you manage multiple players—for example, different themes for mobile, web, or specific projects.
### Primary Color
Choose the main color used in the player interface. This color is applied to key elements such as:
* The large play button
* Progress bar and seekbar
***
## Player Features
The **Player Features section** lets you control how the Vidinfra player behaves during playback. Each toggle enables or disables a specific capability that affects the viewer experience.
### Preload Video on Page Load
Loads video metadata as soon as the page opens. This reduces start time and improves playback speed.
### Subtitles
Allows viewers to turn on subtitle tracks if you uploaded any in the video settings.
### Chapters
Shows chapter markers inside the player so viewers can jump to key parts of the video.
### Picture in Picture
Lets viewers pop the video into a small floating window while browsing other tabs or apps.
### Allow Cast
Enables casting to supported devices like smart TVs. Not available for DRM or watermarked videos.
### Video Loop
Restarts the video automatically after it finishes.
### Resumable Player Position
Saves the viewer’s last watch position, allowing them to continue from where they left off.
### Big Play Button
Displays a large play button at the center of the video before playback.
### Hide Player Controls
Removes all control buttons for a clean, minimal viewing experience.
### Custom Overlays
Use the Brand Appearance section to add your own logo as a custom overlay or watermark on the video player.
#### Upload Brand Logo
You can drag and drop the image or browse files manually. The logo appears as a watermark on the player.
#### Logo Destination URL
Add a link that viewers will be taken to when they click your logo. Use this to direct users to your website, landing page, or campaign URL.
The watermark image must be smaller than 2MB. Larger files will not upload.
***
## Advanced Settings
The **Advanced Settings section** is designed for developers and teams who want deeper branding or analytics integration.
### Custom HTML Head
Lets you inject custom HTML or scripts directly into the player head area.
### Facebook Pixel
Add your Facebook Pixel ID to track video engagement and viewer actions.
### GA4 Tracking Code
Enter your Google Analytics 4 measurement ID to collect playback insights.
# Publish your Video
Source: https://docs.tenbyte.io/docs/vidinfra/publish-first-video
This guide explains how to publish a processed video for public viewing, making it easy to share and integrate across websites and applications.
## Share and Integrate Your Video
* Once you’ve uploaded or imported your video into Vidinfra, you can publish it for public viewing. In your video library, you’ll find all your videos listed along with important details like titles, durations, and other key metadata.
### Embed your Video
Embedding a video allows you to display it directly on your website or app, letting you stream content securely without needing to store the file yourself. Vidinfra’s cloud delivery makes embedding fast and reliable.
* A pop-up window will appear when you click the chain icon on your selected video. From this window, click on **Copy Embed Code** and paste it into your website to display the video.
* In the Embed section, you can choose between **Responsive** and **Fixed player** sizes to match your layout, and enable or disable **Player Controls**, **Autoplay**, **Loop**, or **Mute** to customize the viewing experience.
### URLs
The URLs tab provides direct links for streaming, integration, and sharing your video across platforms. Each link type serves a specific purpose, depending on how you plan to use the video.
* When you click the URLs tab next to Embed, you’ll see multiple links for playback, integration, and sharing.
* **Watch Page**: A direct link that opens your video in the Vidinfra player. Ideal for sharing with others or embedding on a site for quick access.
* **HLS Manifest URL**: A link for adaptive streaming that works with HLS-supported players. This ensures smooth playback across various devices by adjusting the video quality based on the viewer's internet speed.
* **MPEG-DASH URL**: A streaming link for players and platforms that support the MPEG-DASH protocol.
* **Thumbnail URL**: A static link to your video’s thumbnail image, ideal for previews or quick links.
* **Animated Thumbnail URL (WebP)**: A link to an animated thumbnail that gives viewers a preview of the video content before playback begins.
You can use HLS or DASH URLs for integrations, and the Watch Page for quick sharing.
# Quick Start Guide
Source: https://docs.tenbyte.io/docs/vidinfra/quickstart
This guide explains how to upload, process, and stream your first video with Vidinfra, Tenbyte’s all in one video platform.
In just a few steps, you'll transform a raw video file into a ready-to-stream playback link.
## Prerequisites
Before starting, make sure you have:
* A **Tenbyte account** — [Sign up](https://beta.tenbyte.io/vidinfra)
* A **video file** ready to upload (e.g. `.mp4`, `.mov`, `.mkv`)
* An **API key** with `assets:write` permission
***
## Set Up Your Vidinfra Workspace
* After signing in with your registered email and password, you will see a welcome page.
* From the left sidebar, select **Vidinfra** to open the Vidinfra workspace.
* Click on **New Library** to start building your content library for video storage and management.
* Fill in the required fields with your information, including the **library name**, **region**, and **purpose of the library**, then click **Create Library** to continue.
Choose your preferred region to ensure the best performance and streaming quality.
* Once the library is created successfully, your workspace will display the video dashboard.
From here, you can **upload** or **import** videos to start building your content library.
***
## Upload your Video
* To upload a video, click the **Upload Video** button from your library dashboard. This will allow you to select a video file from your local device.
* Alternatively, if your videos are hosted on supported platforms, you can directly import them into Vidinfra by selecting your preferred service.
To review the full video submission requirements for Vidinfra, see the [Upload Video Page](/docs/vidinfra/manage-videos/upload-videos#vidinfra-video-submission-requirements) in the Managed Videos section.
***
## Stream your Video
* Once your video is uploaded, Vidinfra automatically begins processing it. This includes:
* Optimizing the video for playback efficiency.
* Transcoding the video into multiple renditions and adaptive bitrates for different network speeds and devices.
* Converting the video into `HLS` (HTTP Live Streaming) and `DASH` (Dynamic Adaptive Streaming over HTTP) formats for smooth, adaptive playback.
> ✅ Supported formats: `.mp4`, `.mov`, `.mkv`, `.webm`, `.avi`, `.flv`
* After processing, your video is ready to be streamed. You can now:
* Embed it on your website.
* Share the playback link with your audience.
* Stream it across multiple platforms for global delivery.
***
## Copy your video ID
* Go to your Videos section where all your uploaded videos are listed.
* Click the **three dots** or the **Actions** button next to the video you want to copy the ID for.
* From the dropdown menu, select **Copy Video ID**. The video ID will be copied to your clipboard.
* Now that the video ID is copied, you can paste it wherever needed, like in URLs, APIs, or for linking purposes.
# Player SDK for Embedded Video Control
Source: https://docs.tenbyte.io/docs/vidinfra/sdk/player-sdk
The Vidinfra Player SDK is a lightweight, type safe JavaScript library for controlling embedded video players inside iframes.
It uses the **`postMessage`** API for secure, real time communication, making custom player integration simple and efficient.
## Key Features
* **Unified API**: One class manages both controlling existing iframes and embedding new players.
* **Type-safe**: Full TypeScript support with comprehensive type definitions for a reliable development - experience.
* **Framework-agnostic**: Works seamlessly with any JavaScript framework or plain JavaScript.
* **Secure**: Built-in origin validation for postMessage communication to ensure safe interactions.
* **Event-driven**: Listen to real-time player events such as play, pause, and time updates.
* **Lightweight**: The SDK is approximately 15KB when minified, making it efficient and easy to use.
## Installation
### NPM Installation
To install the Vidinfra Player SDK via npm, run the following command:
```bash theme={null}
npm install @vidinfra/player
```
### CDN Installation
Alternatively, you can load the SDK via a CDN:
```html theme={null}
```
This method allows you to use the SDK without needing to install it locally, making it easy to integrate into static or non-Node.js projects.
***
## Quick Start
The Player SDK allows you to control existing iframe players and create embedded players on the fly. Below are the basic instructions for both use cases.
### Control an Existing Iframe
If you already have an iframe on your page and want to control the video player inside it, you can easily use the **`Player`** class. With just a few lines of code, you can target an existing iframe, wait for it to be ready, and start playing the video.
```JavaScript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("iframe");
player.on("play", () => {
console.log("Video started playing");
});
await player.whenReady();
await player.play();
```
### Creating an Embedded Player
If you want to embed a video player directly into your page, Vidinfra can automatically create and inject an iframe for you. You can configure the player with your desired settings like autoplay, volume, and aspect ratio.
```JavaScript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("vidinfra-player", {
libraryId: default,
videoId: default,
playerId: default,
autoplay: false,
loop: false,
muted: false,
controls: true,
preload: true,
aspectRatio: "16:9"
});
player.setVolume(0.5);
```
To learn how to copy a video ID, check the [Quickstart Guide](/docs/vidinfra/quickstart#copy-your-video-id) in the Vidinfra section.
***
## Usage
### Controlling an Existing Iframe
If you already have an iframe in your HTML, you can control it by passing the iframe element or a CSS selector.
#### Javascript
```Javascript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("#player-iframe");
await player.whenReady();
await player.play();
```
#### CDN
```html theme={null}
```
### Creating an Embedded Player
You can dynamically create an embedded player by specifying a target element for the player:
#### Javascript
```Javascript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("vidinfra-player", {
libraryId: default,
videoId: default,
playerId: default,
autoplay: false,
loop: false,
muted: false,
controls: true,
preload: true,
aspectRatio: "16:9"
});
```
#### CDN
```html theme={null}
```
***
## API Reference
### Constructor
```Javascript theme={null}
new Player(element: HTMLIFrameElement | HTMLElement | string)
new Player(element: HTMLElement | string, options: PlayerOptions)
```
#### Parameters
* **`element`** - An iframe element, CSS selector for an iframe, or a container element for embedding
* **`options`** - Configuration options for creating an embedded player (required when creating an embed)
### PlayerOptions
The PlayerOptions defines all the customizable settings for configuring a Vidinfra player. Here, you specify key details about the video and player behavior. You can set the video’s library ID, video ID, and the player’s size, playback options, and more.
```Javascript theme={null}
interface PlayerOptions {
// Vidinfra player (required)
libraryId: string | number;
videoId: string | number;
playerId?: string | number; // Optional, defaults to 'default'
// Display options
width?: number | string;
height?: number | string;
aspectRatio?: string; // e.g., "16:9", "4:3"
// Playback options
autoplay?: boolean;
loop?: boolean;
muted?: boolean;
controls?: boolean;
preload?: boolean;
// Advanced options
loading?: "lazy" | "eager";
allow?: string;
className?: string;
baseUrl?: string;
}
```
### Playback Methods
These methods control the basic playback behavior of the video. They include actions like starting, pausing, seeking, and changing playback speed.
Start video playback.
```Javascript theme={null}
play(): Promise
```
Pause video playback.
```Javascript theme={null}
pause(): Promise
```
Toggle between play and pause states.
```Javascript theme={null}
togglePlay(): Promise
```
Seek to a specific time in seconds.
```Javascript theme={null}
seek(time: number): Promise
```
Set playback speed (e.g., 0.5, 1.0, 2.0).
```Javascript theme={null}
setPlaybackRate(rate: number): Promise
```
Get current playback rate.
```Javascript theme={null}
getPlaybackRate(): Promise
```
Get current playback position in seconds.
```Javascript theme={null}
getCurrentTime(): Promise
```
Get total video duration in seconds.
```Javascript theme={null}
getDuration(): Promise
```
Check if video is currently paused.
```Javascript theme={null}
getPaused(): Promise
```
### Volume Methods
These methods manage the audio settings for the player. You can adjust the volume, mute, or check the current audio state.
Set volume level (0-1).
```Javascript theme={null}
setVolume(volume: number): Promise
```
Get current volume level.
```Javascript theme={null}
getVolume(): Promise
```
Mute audio.
```Javascript theme={null}
mute(): Promise
```
Unmute audio.
```Javascript theme={null}
unmute(): Promise
```
Set muted state.
```Javascript theme={null}
setMuted(muted: boolean): Promise
```
Get current muted state.
```Javascript theme={null}
getMuted(): Promise
```
### Display Methods
These methods manage the visual behavior of the player, including fullscreen and control visibility.
Toggle fullscreen mode.
```Javascript theme={null}
toggleFullscreen(): Promise
```
Enter fullscreen mode.
```Javascript theme={null}
requestFullscreen(): Promise
```
Exit fullscreen mode.
```Javascript theme={null}
exitFullscreen(): Promise
```
Show player controls.
```Javascript theme={null}
showControls(): Promise
```
Hide player controls.
```Javascript theme={null}
hideControls(): Promise
```
Set controls visibility.
```Javascript theme={null}
setControlsVisible(visible: boolean): Promise
```
### Watermark Methods
These methods add a watermark to your video, which can be customized with text and styling options.
Add a watermark overlay to the video.
```Javascript theme={null}
addWatermark(config: WatermarkConfig): Promise
```
WatermarkConfig:
```Javascript theme={null}
interface WatermarkConfig {
text: string;
color?: string;
opacity?: number;
fontSize?: number;
}
```
### Utility Methods
These methods help you interact with the player’s internal state and configuration.
Check if player is ready to receive commands.
```Javascript theme={null}
isReady(): boolean
```
Returns a promise that resolves when the player is ready.
```Javascript theme={null}
whenReady(): Promise
```
Get the iframe element.
```Javascript theme={null}
getIframe(): HTMLIFrameElement
```
Get the wrapper element (only available for embedded players).
```Javascript theme={null}
getWrapper(): HTMLElement | null
```
Get the iframe source URL.
```Javascript theme={null}
getSrc(): string
```
Update player options (only available for embedded players).
```Javascript theme={null}
update(options: Partial): void
```
Clean up event listeners and remove the player.
```Javascript theme={null}
destroy(): void
```
### Event Methods
These methods allow you to listen for events like play, pause, and custom player events.
Register an event listener.
```Javascript theme={null}
on(event: string, callback: Function): this
```
Remove an event listener.
```Javascript theme={null}
off(event: string, callback?: Function): this
```
Register a one-time event listener.
```Javascript theme={null}
once(event: string, callback: Function): this
```
### Events
The player emits the following events:
| **Event** | **Description** |
| ---------------------- | ----------------------------------- |
| **`ready`** | Player is ready to receive commands |
| **`play`** | Playback has started |
| **`playing`** | Playback is playing |
| **`pause`** | Playback has paused |
| **`ended`** | Playback has ended |
| **`timeupdate`** | Playback position changed |
| **`volumechange`** | Volume or muted state changed |
| **`seeking`** | Seeking started |
| **`seeked`** | Seeking completed |
| **`waiting`** | Waiting for data |
| **`canplay`** | Enough data to play |
| **`canplaythrough`** | Can play through without buffering |
| **`loadedmetadata`** | Metadata loaded |
| **`loadeddata`** | Frame data loaded |
| **`durationchange`** | Duration changed |
| **`ratechange`** | Playback rate changed |
| **`fullscreenchange`** | Fullscreen state changed |
| **`error`** | Playback error occurred |
***
## Examples
### Basic Playback Control
```Javascript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("#player-iframe");
await player.whenReady();
document.getElementById("play-btn").addEventListener("click", () => {
player.play();
});
document.getElementById("pause-btn").addEventListener("click", () => {
player.pause();
});
player.on("timeupdate", (state) => {
const currentTime = Math.floor(state.currentTime);
const duration = Math.floor(state.duration);
console.log(`${currentTime}s / ${duration}s`);
});
```
### Volume Control
```Javascript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("#player-iframe");
await player.whenReady();
const volumeSlider = document.getElementById("volume");
volumeSlider.addEventListener("input", (e) => {
const volume = e.target.value / 100;
player.setVolume(volume);
});
const muteBtn = document.getElementById("mute");
muteBtn.addEventListener("click", async () => {
const isMuted = await player.getMuted();
player.setMuted(!isMuted);
});
```
### Creating and Controlling an Embed
```Javascript theme={null}
import { Player } from "@vidinfra/player";
const player = new Player("vidinfra-player", {
libraryId: default,
videoId: default,
playerId: default,
autoplay: false,
loop: false,
muted: false,
controls: true,
preload: true,
aspectRatio: "16:9"
});
player.on("ready", () => {
console.log("Player created and ready");
});
player.on("play", () => {
console.log("Video playing");
});
setTimeout(() => {
player.update({ loop: true });
}, 5000);
```
### TypeScript Example
```Javascript theme={null}
import { Player, PlayerOptions, WatermarkConfig } from "@vidinfra/player";
const options: PlayerOptions = {
libraryId: default,
videoId: default,
playerId: default,
autoplay: false,
loop: false,
muted: false,
controls: true,
preload: true,
aspectRatio: "16:9"
};
const player = new Player("vidinfra-player", options);
await player.whenReady();
const volume: number = await player.getVolume();
const duration: number = await player.getDuration();
const watermark: WatermarkConfig = {
text: "Confidential",
color: "#ffffff",
opacity: 0.3,
fontSize: 24
};
await player.addWatermark(watermark);
```
### Security
The Player automatically validates the origin of postMessage communications based on the iframe's source URL. For iframe-side implementations, you should also validate the origin of incoming messages:
```Javascript theme={null}
window.addEventListener("message", (event) => {
const allowedOrigin = "https://trusted-parent.com";
if (event.origin !== allowedOrigin) return;
// Handle message
});
```
***
## Browser Support
* Modern browsers with ES6+ support
* Requires **`postMessage`** API
* Fullscreen API support varies by browser
## TypeScript
Full TypeScript definitions are included with the package:
```Javascript theme={null}
import { Player, PlayerOptions, WatermarkConfig, WatermarkOptions } from "@vidinfra/player";
```
# Vidinfra Uploader SDK
Source: https://docs.tenbyte.io/docs/vidinfra/sdk/uploader-sdk
The Vidinfra Uploader SDK is a modern TypeScript based library built for reliable large video uploads.
It supports multipart uploads, progress tracking, drag and drop handling, and upload lifecycle control to simplify video ingestion workflows.
## Features
* **Video Upload**- Handles large video files through multipart upload. Uploads are split into smaller parts, improving stability on slow or unstable networks.
* **Progress Tracking**- Reports real-time progress as each part uploads. You get uploaded bytes, overall percentage, estimated speed, and expected completion time.
* **Drag & Drop**- Includes optional helpers for building a drag-and-drop upload zone. Works with standard DOM elements and requires minimal setup.
* **Pause and Resume**- Upload sessions can be paused at any time. The SDK keeps track of completed parts so the process can resume without starting over.
* **Batch Upload**- Accepts one or many files in a single call. Each upload runs independently, allowing you to manage or track them individually.
* **Secure by Design**- Uses short-lived tokens to authenticate requests. Upload endpoints never expose secret keys.
* **Customizable**- Ships with minimal UI helpers so you can apply your own styling or integrate it into an existing design system.
* **Responsive**- Supports desktop and mobile environments with no additional configuration.
* **Universal Build**- Distributed in CommonJS, ESM, and UMD formats. You can use it in modern bundlers, Node.js environments, or direct browser imports.
* **TypeScript Support**- Full TypeScript support with accurate type definitions for safer and cleaner integration.
***
## Installation
This section provides the installation commands for adding the Vidinfra Uploader SDK to a project using **`npm`**, **`yarn`**, or **`pnpm`**. It’s the initial setup step required before using the uploader.
```bash theme={null}
npm install @vidinfra/uploader
```
Or,
```bash theme={null}
yarn add @vidinfra/uploader
```
Or,
```bash theme={null}
npm install @vidinfra/uploader
```
***
## Quick Start
### ES Modules (Modern Bundlers)
This section shows how to initialize the Vidinfra Uploader SDK inside a modern JavaScript project. It sets the **upload endpoint**, **JWT token**, **target element**, and **metadata**. It also listens for a successful upload and logs when the file is complete.
```Javascript theme={null}
import VidInfraUploader from "@vidinfra/uploader";
import "@vidinfra/uploader/styles.css";
const uploader = new VidInfraUploader({
endpoint:
"https://api.tenbyte.io/v1/stream/libraries/YOUR_LIBRARY_ID/uploads",
uploadToken: "YOUR_JWT_TOKEN",
target: "#uploader",
metadata: {
libraryId: "YOUR_LIBRARY_ID",
},
});
uploader.on("upload-success", (file, response) => {
console.log("Upload complete:", file.name);
});
```
### UMD (Browser Script Tag)
This code block loads the Vidinfra Uploader in a browser using a script tag, applies the stylesheet, creates an uploader element, and initializes the uploader with the upload endpoint and token.
```Javascript theme={null}
```
***
## Configuration
This section explains the available settings for the Vidinfra Uploader. It shows the required fields and the optional options you can use to control metadata, upload behavior, and UI targets.
```Javascript theme={null}
const uploader = new VidInfraUploader({
// Required
endpoint: string, // API endpoint
uploadToken: string, // JWT token
// Optional
target: string | HTMLElement, // DOM target
metadata: {
libraryId: string,
folderId: string,
},
maxNumberOfFiles: number,
autoProceed: boolean, // Auto-start upload
dragDrop: boolean, // Enable drag & drop
note: string, // Custom dropzone text
});
```
### Supported File Formats
The Vidinfra Uploader accepts a wide range of video and audio formats. These formats are commonly used across recording tools, editing software, and streaming workflows, ensuring smooth uploads from most devices.
#### Videos
| Format | MIME Type | Details |
| -------- | ---------------- | -------------------------------------------------------------------- |
| **.mp4** | video/mp4 | Works on all devices; ideal for streaming and general uploads |
| **.mkv** | video/x-matroska | High-quality container; supports multiple audio tracks and subtitles |
| **.mov** | video/quicktime | Apple format; common in editing workflows and camera exports |
| **.avi** | video/x-msvideo | Older Windows format; used for legacy video sources |
#### Audio
| Format | MIME Type | Details |
| -------- | ---------- | ----------------------------------------------------------------------- |
| **.mp3** | audio/mpeg | Most common compressed audio format; widely supported |
| **.wav** | audio/wav | Uncompressed, high-quality audio; used in production and editing |
| **.aac** | audio/aac | Efficient compressed audio; good quality at smaller file sizes |
| **.m4a** | audio/mp4 | MPEG-4 audio container; common for music and high-quality audio exports |
### Theming
This code block shows how to customize the uploader's colors and fonts. It lets you match the Vidinfra Uploader UI with your brand styling.
```Javascript theme={null}
const uploader = new VidInfraUploader({
endpoint: "YOUR_ENDPOINT",
uploadToken: "YOUR_TOKEN",
target: "#uploader",
theme: {
primaryColor: "#9333EA", // Purple primary color
primaryLight: "#F3E8FF", // Light purple background
primaryShadow: "rgba(147, 51, 234, 0.1)", // Shadow color
textColor: "#111111", // Main text color
textSecondary: "#666666", // Secondary text color
backgroundColor: "#ffffff", // Background color
borderColor: "#e5e7eb", // Border color
successColor: "#10B981", // Success state color
errorColor: "#EF4444", // Error state color
fontFamily: "Inter, system-ui, sans-serif", // Custom font
},
});
```
### Branding
This code block controls the “Powered by Vidinfra” footer. You can keep it visible or turn it off by setting branding to true or false.
Configure the "Powered by VidInfra" footer:
```Javascript theme={null}
// Show branding (default behavior)
const uploader = new VidInfraUploader({
endpoint: "YOUR_ENDPOINT",
target: "#uploader",
branding: true, // default, can be omitted
});
// Hide branding
const uploader = new VidInfraUploader({
endpoint: "YOUR_ENDPOINT",
target: "#uploader",
branding: false,
});
```
***
## API Reference
### Methods
This section lists the main methods of the Vidinfra Uploader. It explains how to control uploads, manage files, check the uploader state, update options, and remove the uploader when you’re done.
```Javascript theme={null}
// Upload control
await uploader.upload()
uploader.pauseAll()
uploader.resumeAll()
uploader.cancelAll()
// File management
await uploader.addFile(file: File)
uploader.removeFile(fileId: string)
uploader.clear()
// State
uploader.getState()
uploader.getFiles()
// Configuration
uploader.setOptions(options)
uploader.setMeta(metadata)
uploader.destroy()
```
### Events
This section shows all events you can listen to in the Vidinfra Uploader. It covers file-added, upload progress, success, errors, completion, and pause/resume/cancel actions so you can react to each step of the upload flow.
```Javascript theme={null}
uploader.on("file-added", (file) => {});
uploader.on("upload-start", () => {});
uploader.on("upload-progress", (file, progress) => {});
// Access API response after successful upload
uploader.on("upload-success", (file, response) => {
console.log("File uploaded:", file.name);
console.log("S3 Key:", response.body.key);
console.log("S3 Location:", response.body.location);
console.log("Upload URL:", response.uploadURL);
// Full response body contains: { key, location }
});
uploader.on("upload-error", (file, error) => {});
uploader.on("complete", (result) => {
// Access all successful uploads
result.successful.forEach((file) => {
console.log("Key:", file.response.body.key);
console.log("Location:", file.response.body.location);
});
});
uploader.on("pause-all", () => {});
uploader.on("resume-all", () => {});
uploader.on("cancel-all", () => {});
```
### Response Structure
This section explains what data you get back after a successful upload. It returns the upload URL and the S3 details such as key, full file location, and video ID.
```Javascript theme={null}
{
status: 200,
uploadURL: string, // The final upload URL
body: {
key: string, // S3 object key
location: string // Full S3 URL to the uploaded file
video_id: string //
}
}
```
***
## Package Formats
This table shows all build formats included in the Vidinfra Uploader package. It explains which file to use for Node.js, modern bundlers, browsers, UMD script tags, development builds, and TypeScript types.
| Format | File | Size | Usage |
| --------------- | --------------------------- | ----- | --------------------------------- |
| **CommonJS** | `dist/index.cjs.js` | 172KB | Node.js, older bundlers |
| **ES Module** | `dist/index.esm.js` | 171KB | Modern bundlers (Vite, Webpack 5) |
| **ESM Browser** | `dist/index.browser.esm.js` | 219KB | Browser with `type="module"` |
| **UMD** | `dist/index.umd.js` | 79KB | Browser `
```
***
## Framework Examples
This section lists example integrations for popular frameworks, showing how to use the Vidinfra Uploader in React, Vue, Svelte, Next.js, Laravel, and WordPress.
This example shows how to set up the Vidinfra Uploader inside a React component. It initializes the uploader in useEffect, stores the instance, and destroys it when the component unmounts.
```Javascript theme={null}
import { useEffect, useRef } from "react";
import VidInfraUploader from "@vidinfra/uploader";
import "@vidinfra/uploader/styles.css";
function VideoUploader() {
const uploaderRef = useRef(null);
useEffect(() => {
const uploader = new VidInfraUploader({
endpoint: "YOUR_ENDPOINT",
uploadToken: "YOUR_TOKEN",
target: "#uploader",
});
uploaderRef.current = uploader;
return () => uploader.destroy();
}, []);
return ;
}
```
This example shows how to initialize the Vidinfra Uploader in a Vue 3 component. It creates the uploader in **`onMounted`** and attaches it to a div in the template.
```Javascript theme={null}
```
This example shows how to set up the Vidinfra Uploader in a Svelte component. It loads the uploader inside **`onMount`** and connects it to the uploader div.
```Javascript theme={null}
```
This example shows how to load the Vidinfra Uploader in a Next.js client component. It imports the uploader dynamically inside **`useEffect`** and attaches it to the uploader div.
```Javascript theme={null}
"use client";
import { useEffect } from "react";
export default function Uploader() {
useEffect(() => {
import("@vidinfra/uploader/styles.css");
import("@vidinfra/uploader").then((module) => {
const VidInfraUploader = module.default;
new VidInfraUploader({
endpoint: "YOUR_ENDPOINT",
uploadToken: "YOUR_TOKEN",
target: "#uploader",
});
});
}, []);
return ;
}
```
This example shows how to use the Vidinfra Uploader in a Laravel project. The Blade file loads the script, and the JavaScript file initializes the uploader using values from environment variables.
```Php theme={null}
{{-- Blade Template --}}
@vite(['resources/js/uploader.js'])
```
```Javascript theme={null}
// resources/js/uploader.js
import VidInfraUploader from "@vidinfra/uploader";
import "@vidinfra/uploader/styles.css";
const uploader = new VidInfraUploader({
endpoint: import.meta.env.VITE_UPLOAD_ENDPOINT,
uploadToken: import.meta.env.VITE_UPLOAD_TOKEN,
target: "#uploader",
});
```
This example shows how to use the Vidinfra Uploader in WordPress. It enqueues the uploader script and stylesheet, then initializes the uploader in a shortcode or template using values from WordPress settings.
```Php theme={null}
```
***
## Browser Support
The Vidinfra Uploader works on all major modern browsers. For the best performance, use the latest stable version of:
* Chrome
* Firefox
* Safari
* Edge
Older or unsupported browsers may not run advanced upload features like multipart uploads or drag-and-drop.
# Country Access Policy
Source: https://docs.tenbyte.io/docs/vidinfra/security/country-access-policy
Country Access Policy allows control over where videos can be viewed by enabling or restricting playback based on the viewer’s country.
## Open Security Settings
* From your video library dashboard, open the **Settings** dropdown in the left sidebar and select **Security**.
* This will load the security configuration dashboard, where you can manage access controls.
* In the Security dashboard, you will find two access control options:
1. Country Access Policy
2. Referrer Access Policy.
***
## Country Access Policy
The **Country Access Policy** lets you control where your videos can be viewed by allowing or blocking specific countries.
### Allow by Default
When selected, your videos are accessible to all countries except the ones you choose to block. Use this option if you want your content to be generally available with a few restricted regions.
### Deny by Default
When selected, your videos are blocked for all countries except the ones you choose to allow. This option is useful when your content is regional or limited to a specific audience.
### Select Countries
Add the countries you want to allow or block, depending on your chosen rule.
**Vidinfra** will automatically enforce access restrictions during playback based on the viewer’s location.
Adding the wrong countries may restrict viewer access. Double-check your selections.
# Dynamic Video Watermarking
Source: https://docs.tenbyte.io/docs/vidinfra/security/dynamic-watermark
Dynamic watermarking protects videos from **piracy**, **screen-recording**, and **unauthorized redistribution**. Unlike static overlays, a **dynamic watermark** moves across the video, making it much harder to crop or remove. This ensures:
* ✔ Branding stays visible
* ✔ Content is traceable
* ✔ Users are discouraged from unauthorized sharing
* ✔ You can bind each playback session to a specific user or device
***
## Quick start (copy/paste)
1. Copy the config below and set the `text` values for your brand + user/session identifier.
2. Run `encodeWatermarkConfig(config)` in your app/console to get the Base64 string.
3. Append `&watermark=` to your Vidinfra player URL (see embed example).
4. Paste the iframe snippet into your page and adjust sizing if needed.
5. Verify playback: the watermark should be visible, readable, and moving every few seconds.
***
## Prerequisites
* A Vidinfra player URL (e.g., `https://player.vidinfra.com/.../default/...`).
* A way to identify the viewer (user ID, email hash, session ID).
* Ability to run a small JS helper to encode the watermark payload.
***
## Watermark Configuration Example
Below is an example configuration with a **static brand watermark** (`"MyVideoApp"`) and a **dynamic user watermark** (`"User: 1827439"`) that moves every 3.5 seconds.
```javascript theme={null}
const watermarkConfig = [
{
text: "vidinfra player",
font: "Arial",
fontSize: 20,
fillStyle: "rgba(255,255,255,0.8)",
padding: 8,
opacity: 0.9,
},
{
text: "User: 1827439",
font: "Roboto",
fontSize: 18,
fillStyle: "rgba(255, 255, 255, 0.6)",
strokeStyle: "rgba(0, 0, 0, 0.3)",
padding: 6,
opacity: 0.85,
moveIntervalMs: 3500, // moves every 3.5 seconds
},
];
```
### Property Breakdown
| Property | Description |
| ---------------- | --------------------------------------------- |
| `text` | Content displayed (brand name, user ID, etc.) |
| `font` | Font family |
| `fontSize` | Text size (px) |
| `fillStyle` | Text color and opacity |
| `strokeStyle` | Outline for visibility |
| `padding` | Space between watermark and video edges |
| `opacity` | Transparency level |
| `moveIntervalMs` | Movement frequency for dynamic watermark |
***
## Encoding Watermark Configuration
Convert the configuration to Base64 to embed in the player URL.
```javascript theme={null}
function encodeWatermarkConfig(config) {
const jsonString = JSON.stringify(config);
// UTF-8 → Base64
return btoa(
Array.from(new TextEncoder().encode(jsonString))
.map(byte => String.fromCharCode(byte))
.join("")
);
}
```
> Tip: In Node, replace `btoa` with `Buffer.from(jsonString).toString("base64")`.
### Generated Base64 Output
Use this encoded value in your player URL:
`W3sidGV4dCI6Ik15VmlkZW9BcHAiLCJmb250IjoiQXJpYWwiLCJmb250U2l6ZSI6MjAsImZpbGxTdHlsZSI6InJnYmEoMjU1LDI1NSwyNTUsMC44KSIsInBhZGRpbmciOjgsIm9wYWNpdHkiOjAuOX0seyJ0ZXh0IjoiVXNlcjogMTgyNzQzOSIsImZvbnQiOiJSb2JvdG8iLCJmb250U2l6ZSI6MTgsImZpbGxTdHlsZSI6InJnYmEoMjU1LCAyNTUsIDI1NSwgMC42KSIsInN0cm9rZVN0eWxlIjoicmdiYSgwLCAwLCAwLCAwLjMpIiwicGFkZGluZyI6Niwib3BhY2l0eSI6MC44NSwibW92ZUludGVydmFsTXMiOjM1MDB9XQ==`
***
## Embedding the Watermark Into the Player
Add the Base64 configuration to the `watermark=` parameter of your player URL.
```html theme={null}
```
### Minimal iframe template (ready to paste)
```html theme={null}