Overview
Use the Private Links API to manage Private Links from your own backend: create a link to a private service in your AWS or Azure network, list the links in a project, check the health of a link, and delete a link.
This API is available through the following clients:
The Go SDK is the only server SDK that supports this API. To learn how to use it, see Monitor and manage Private Links.
Implementation details
To implement your own client, use the details in the following sections.
Endpoints
The Private Links API is built with Twirp . Arguments are passed as JSON to an endpoint using the POST method.
The Private Links API is accessible via /twirp/livekit.CloudAgent/<MethodName> on the agents.livekit.cloud host, not your project URL. For example:
https://agents.livekit.cloud/twirp/livekit.CloudAgent/ListPrivateLinks
Authorization header
All endpoints require a signed access token with the agent admin grant. The token identifies your project, so each request only reads or changes the Private Links in that project. Set the token using the HTTP header:
Authorization: Bearer <token>
The Go SDK sets this header automatically.
To call the API directly, generate the token in a trusted backend or monitoring job. Never send your API secret as the bearer token or expose it in client-side code.
The lk token create command can't add the agent admin grant, but any JSON Web Token (JWT) library can generate the token. Sign the token with your API secret using the HS256 algorithm, and include the following claims:
| Claim | Value |
|---|---|
iss | Your API key. |
exp | Expiration time, as a Unix timestamp in seconds. |
agent | {"admin": true} |
For example, the following generates a token that expires after five minutes with the Go SDK:
package mainimport ("fmt""os""time""github.com/livekit/protocol/auth")func main() {token, err := auth.NewAccessToken(os.Getenv("LIVEKIT_API_KEY"), os.Getenv("LIVEKIT_API_SECRET")).SetAgentGrant(&auth.AgentGrant{Admin: true}).SetValidFor(5 * time.Minute).ToJWT()if err != nil {fmt.Println(err)return}fmt.Println(token)}
The curl examples on this page read the token from the TOKEN environment variable. Save the token you generate to that variable:
export TOKEN="<token>"
Version header
The Private Links API also requires an X-LIVEKIT-CLI-VERSION header. The server reads its value as a semantic version and checks it against a minimum version. Requests without the header, or with an older version, fail with a malformed error. The LiveKit CLI and the Go cloudagents client set this header automatically: the CLI sends its own version, and the Go client sends the Go SDK version.
X-LIVEKIT-CLI-VERSION: <LIVEKIT_CLI_VERSION>
When you call the API directly, send your installed LiveKit CLI version instead of writing a fixed value, so the value doesn't fall below the minimum:
export LIVEKIT_CLI_VERSION="$(lk --version | awk '{print $3}')"
Post body
Twirp expects an HTTP POST request. The body must be a JSON object with the application/json media type, containing parameters specific to that request.
For example, the following lists the Private Links in a project. The ListPrivateLinks method takes no parameters, so the body is an empty object:
curl -X POST https://agents.livekit.cloud/twirp/livekit.CloudAgent/ListPrivateLinks \-H "Authorization: Bearer $TOKEN" \-H "X-LIVEKIT-CLI-VERSION: $LIVEKIT_CLI_VERSION" \-H 'Content-Type: application/json' \-d '{}'
The response lists each link in the project:
{"items": [{"private_link_id": "CAPL_a1b2c3d4e5f6","name": "customer-redis","region": "us-east","port": 6379,"endpoint": "com.amazonaws.vpce.us-east-1.vpce-svc-0a1b2c3d4e5f67890","connection_endpoint": "customer-redis-p-a1b2c3d4-x1y2z.link","cloud_region": "us-east-1"}]}
When passing in parameters, the server accepts either snake_case or camelCase for keys. Responses use snake_case keys.
API methods
The Private Links API allows you to create, delete, and list Private Links, and to check the status of a link.
The livekit_cloud_agent.proto file contains all RPC definitions.
CreatePrivateLink
Create a private link to a private service in your AWS or Azure network. Requires the agent admin permission.
After you create a link, approve its connection request in your cloud account. To learn more, see the setup guide for AWS or Azure.
Each project supports a limited number of Private Links in each LiveKit region. To learn more, see Limitations. If the project has reached its limit, the request fails with a resource_exhausted error. If a link with the same name already exists in the project, the request fails with an already_exists error.
Returns CreatePrivateLinkResponse.
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | yes | Name of the link, unique within the project. Must be 1 to 63 characters of lowercase letters, numbers, and hyphens, starting with a letter and ending with a letter or number. |
| region | string | yes | LiveKit agent region for the link, such as us-east. Your agent must run in the same region. |
| port | uint32 | yes | TCP port of your service, from 1 to 65535. |
| endpoint | string | yes | Identifier for the service to connect to: an AWS endpoint service name, an Azure Private Link Service alias, or an Azure Resource ID. |
| cloud_region | string | Cloud provider region of your service, such as us-east-1 or eastus. Required when endpoint is an Azure Resource ID. For other endpoints, LiveKit reads the region from endpoint, and this value must match it if set. |
DestroyPrivateLink
Delete a private link. Requires the agent admin permission.
After you delete a link, agents can no longer connect through it. If no link with the given ID exists in the project, the request fails with a not_found error. If the link was already deleted, the request succeeds without making any changes.
Returns an empty object.
| Parameter | Type | Required | Description |
|---|---|---|---|
| private_link_id | string | yes | ID of the link to delete. |
ListPrivateLinks
List the Private Links in a project. Requires the agent admin permission.
The response doesn't include deleted links or the status of each link. To get the status of a link, use GetPrivateLinkStatus.
Returns ListPrivateLinksResponse.
| Parameter | Type | Required | Description |
|---|---|---|---|
| None | This method takes no parameters. Send an empty JSON object as the request body. |
GetPrivateLinkStatus
Get the current status of a private link. Requires the agent admin permission.
If the link doesn't exist in the project, the request fails with a not_found error.
Returns GetPrivateLinkStatusResponse.
| Parameter | Type | Required | Description |
|---|---|---|---|
| private_link_id | string | yes | ID of the link to check. |
For example, the following request gets the status of a link:
curl -X POST https://agents.livekit.cloud/twirp/livekit.CloudAgent/GetPrivateLinkStatus \-H "Authorization: Bearer $TOKEN" \-H "X-LIVEKIT-CLI-VERSION: $LIVEKIT_CLI_VERSION" \-H 'Content-Type: application/json' \-d '{ "private_link_id": "CAPL_a1b2c3d4e5f6" }'
The response contains the status, the time it was last updated, and the reason for it:
{"value": {"status": "PRIVATE_LINK_STATUS_HEALTHY","updated_at": "2026-09-23T23:41:23.841487Z","reason": ""}}
Types
The Private Links API includes the following types.
PrivateLink
Represents a single private link.
| Field | Type | Description |
|---|---|---|
| private_link_id | string | Unique identifier for the link. |
| name | string | Name of the link. |
| region | string | LiveKit agent region for the link. |
| port | uint32 | TCP port of your service. |
| endpoint | string | Identifier for the service the link connects to, in lowercase. |
| connection_endpoint | string | Hostname your agent uses to connect to the service through the link, ending in .link. It resolves only from within a deployed agent. |
| cloud_region | string | Cloud provider region of your service. |
PrivateLinkStatus
The current status of a private link.
| Field | Type | Description |
|---|---|---|
| status | Status | Current status of the link. |
| updated_at | Timestamp | Time the status was last updated. In JSON, a timestamp string such as 2026-09-23T23:41:23.841487Z. |
| reason | string | Details about the status. Empty when the status is PRIVATE_LINK_STATUS_HEALTHY. When the status is PRIVATE_LINK_STATUS_UNHEALTHY, contains the error from the failed connectivity check or the connection state, when available. |
Status
The status of a private link. To learn what each status means and how a link moves between them, see Status values.
| Value | Description |
|---|---|
| PRIVATE_LINK_STATUS_UNKNOWN | LiveKit can't determine the status. |
| PRIVATE_LINK_STATUS_PROVISIONING | LiveKit is creating or reconciling the resources for the link. |
| PRIVATE_LINK_STATUS_PENDING_APPROVAL | The connection is waiting for you to approve it in your cloud account. |
| PRIVATE_LINK_STATUS_APPROVED | You approved the connection, but a connectivity result isn't available yet. |
| PRIVATE_LINK_STATUS_HEALTHY | The latest connectivity check succeeded. |
| PRIVATE_LINK_STATUS_UNHEALTHY | The connectivity check failed, or the connection is unavailable. |
CreatePrivateLinkResponse
Returned by CreatePrivateLink.
| Field | Type | Description |
|---|---|---|
| private_link | PrivateLink | The new link. |
ListPrivateLinksResponse
Returned by ListPrivateLinks.
| Field | Type | Description |
|---|---|---|
| items | List<PrivateLink> | Private Links in the project. |
GetPrivateLinkStatusResponse
Returned by GetPrivateLinkStatus.
| Field | Type | Description |
|---|---|---|
| value | PrivateLinkStatus | Current status of the link. |