Get the owner viewer
curl --request GET \
--url https://api.phone-harness.com/sessions/{sid}/owner-viewer \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.phone-harness.com/sessions/{sid}/owner-viewer"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.phone-harness.com/sessions/{sid}/owner-viewer', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"url": "https://viewer.example.com/opaque-owner-capability",
"expires_at": 1800000900
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}Viewer
Get the owner viewer
Mint an opaque, expiring interactive viewer URL for a ready, owned session. Treat it as a secret and never log it. Current embedding is restricted to the configured Phone Harness dashboard origin; arbitrary third-party embedding is not a supported integration. Reconnection does not extend the phone deadline. Watch grants cannot call this endpoint.
GET
https://api.phone-harness.com
/
sessions
/
{sid}
/
owner-viewer
Get the owner viewer
curl --request GET \
--url https://api.phone-harness.com/sessions/{sid}/owner-viewer \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.phone-harness.com/sessions/{sid}/owner-viewer"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.phone-harness.com/sessions/{sid}/owner-viewer', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"url": "https://viewer.example.com/opaque-owner-capability",
"expires_at": 1800000900
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}{
"error": "<string>",
"code": "<string>",
"state": "<string>",
"unsupported": true,
"outcome": "unknown",
"id": "<string>",
"request_key": "<string>",
"cleanup_complete": true,
"balance_cents": 123,
"session": "<string>",
"session_limit": 123,
"active_session_count": 123,
"available_session_slots": 123
}Authorizations
Phone Harness account API key (pck_…). The dashboard may use a Clerk session JWT with the same header. Never put an account key in a URL.
Path Parameters
Session ID returned by POST /sessions.