Initiate a Cobrowse Session Programmatically via the Genesys Cloud Conversations API
What You Will Build
- A working Python script that initiates a cobrowse session for a specific user and application using the Genesys Cloud Conversations API.
- The code uses the
POST /api/v2/conversations/cobrowseendpoint to create a new cobrowse session and returns the session ID and join URL. - This tutorial covers Python 3.9+ using the official
genesys-cloudSDK and rawrequestslibrary for granular control.
Prerequisites
- OAuth Client Type: A Private Key OAuth Client is recommended for server-to-server integration.
- Required Scopes:
cobrowse:session:writeis mandatory to initiate a session.cobrowse:session:readis required if you intend to manage or terminate the session later. - SDK Version:
genesys-cloudPython SDK version 2.0.0 or higher. - Runtime: Python 3.9+.
- Dependencies:
pip install genesys-cloud httpx python-dotenv - Environment: You must have the Genesys Cloud
organization_id,region(e.g.,mypurecloud.comorusw2.pure.cloud), and theuser_idof the agent who will host the cobrowse session.
Authentication Setup
The Genesys Cloud API requires OAuth 2.0 authentication. For programmatic access, the Private Key flow is the standard. You must generate a Private Key from the Genesys Cloud Admin Console (Organization > Integrations > OAuth Clients).
The following code demonstrates how to initialize the client and handle token retrieval. The genesys-cloud SDK handles token caching and refresh automatically when configured correctly.
import os
from genesyscloud.auth_client import AuthClient
from genesyscloud.rest import ApiException
from dotenv import load_dotenv
load_dotenv()
def get_auth_client() -> AuthClient:
"""
Initializes and returns a configured AuthClient.
Uses Private Key flow.
"""
# Load credentials from environment variables
org_id = os.getenv("GENESYS_ORG_ID")
region = os.getenv("GENESYS_REGION") # e.g., mypurecloud.com
client_id = os.getenv("GENESYS_CLIENT_ID")
private_key_path = os.getenv("GENESYS_PRIVATE_KEY_PATH")
if not all([org_id, region, client_id, private_key_path]):
raise ValueError("Missing required environment variables for authentication.")
# Initialize the AuthClient
auth_client = AuthClient(
org_id=org_id,
region=region,
client_id=client_id,
private_key_path=private_key_path
)
# Attempt to get an access token to verify configuration
try:
token = auth_client.get_access_token()
if not token:
raise Exception("Failed to retrieve access token. Check private key permissions.")
return auth_client
except ApiException as e:
print(f"Authentication error: {e.status} {e.reason}")
raise
# Initialize global auth client
auth_client = get_auth_client()
Implementation
Step 1: Construct the Cobrowse Session Request Body
The POST /api/v2/conversations/cobrowse endpoint requires a JSON body defining the session parameters. The critical fields are hostUserId (the agent), application (the target app), and sessionName.
You must know the applicationId for the target application. For standard web cobrowsing, this is often web. For specific custom applications, you must query the Applications API first or use the known ID. For this tutorial, we assume a standard Web Cobrowse session.
import json
from typing import Dict, Any
def build_cobrowse_request(host_user_id: str, session_name: str = "Programmatic Cobrowse") -> Dict[str, Any]:
"""
Constructs the JSON payload for initiating a cobrowse session.
Args:
host_user_id: The UUID of the Genesys Cloud user who will host the session.
session_name: A descriptive name for the session.
Returns:
A dictionary representing the JSON body.
"""
request_body = {
"hostUserId": host_user_id,
"application": {
"id": "web", # Standard web cobrowse application ID
"type": "web"
},
"sessionName": session_name,
"timeoutSeconds": 1800, # 30 minutes timeout
"metadata": {
"source": "api-tutorial",
"context": "developer-demo"
}
}
return request_body
Step 2: Execute the API Call with Error Handling
We will use httpx for the HTTP request to demonstrate full control over headers, timeouts, and error handling. While the SDK provides a wrapper, raw HTTP is often preferred for complex integrations where you need to inspect raw headers or handle specific 4xx/5xx responses differently.
The endpoint is https://{region}.mypurecloud.com/api/v2/conversations/cobrowse.
import httpx
import os
from httpx import HTTPStatusError
def initiate_cobrowse_session(auth_client: AuthClient, host_user_id: str, session_name: str = "Programmatic Cobrowse") -> Dict:
"""
Initiates a cobrowse session via the Conversations API.
Args:
auth_client: The initialized Genesys AuthClient.
host_user_id: The UUID of the hosting user.
session_name: The name of the session.
Returns:
The JSON response containing session ID and join URL.
"""
# Get the current access token
token = auth_client.get_access_token()
if not token:
raise RuntimeError("No valid access token available.")
# Define headers
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
"X-Genesys-Application-Name": "Cobrowse-API-Client" # Optional: for logging
}
# Define URL
region = os.getenv("GENESYS_REGION", "mypurecloud.com")
url = f"https://{region}.mypurecloud.com/api/v2/conversations/cobrowse"
# Build request body
body = build_cobrowse_request(host_user_id, session_name)
# Send request
try:
with httpx.Client(timeout=10.0) as client:
response = client.post(url, headers=headers, json=body)
# Raise an exception for bad status codes (4xx, 5xx)
response.raise_for_status()
return response.json()
except HTTPStatusError as e:
response = e.response
print(f"HTTP Error {response.status_code}: {response.text}")
if response.status_code == 401:
raise Exception("Authentication failed. Token may be expired or invalid.")
elif response.status_code == 403:
raise Exception("Forbidden. Ensure the OAuth client has 'cobrowse:session:write' scope.")
elif response.status_code == 400:
raise Exception(f"Bad Request. Check the request body format. Details: {response.text}")
elif response.status_code == 429:
raise Exception("Rate Limited. Wait and retry.")
else:
raise Exception(f"Unexpected HTTP error: {response.status_code}")
except httpx.RequestError as e:
print(f"Network error: {e}")
raise
Step 3: Process the Response and Extract Join URL
The response from the API contains the id of the session and, crucially, the joinUrl. This URL is what the participant (customer) uses to join the cobrowse session. The host (agent) is automatically associated with the session based on the hostUserId.
def process_response(session_data: Dict) -> None:
"""
Parses the API response and extracts useful information.
Args:
session_data: The JSON response from the API.
"""
session_id = session_data.get("id")
join_url = session_data.get("joinUrl")
status = session_data.get("status")
host_user_id = session_data.get("hostUserId")
print("-" * 20)
print(f"Cobrowse Session Created:")
print(f"Session ID: {session_id}")
print(f"Status: {status}")
print(f"Host User ID: {host_user_id}")
print(f"Join URL: {join_url}")
print("-" * 20)
# In a production app, you would send this join_url to the customer via SMS, Email, or a widget
# send_to_customer(join_url)
Complete Working Example
The following script combines all steps into a single executable module. It loads environment variables, authenticates, initiates the session, and prints the result.
#!/usr/bin/env python3
"""
Genesys Cloud Cobrowse Session Initiator
This script demonstrates how to programmatically create a cobrowse session
using the Genesys Cloud Conversations API.
Prerequisites:
1. Install dependencies: pip install genesys-cloud httpx python-dotenv
2. Create a .env file with the following variables:
GENESYS_ORG_ID=your_org_id
GENESYS_REGION=mypurecloud.com
GENESYS_CLIENT_ID=your_client_id
GENESYS_PRIVATE_KEY_PATH=/path/to/your/private.key
GENESYS_HOST_USER_ID=uuid_of_agent_to_host
"""
import os
import sys
from typing import Dict, Any
import httpx
from httpx import HTTPStatusError
from genesyscloud.auth_client import AuthClient
from genesyscloud.rest import ApiException
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
def get_auth_client() -> AuthClient:
"""Initializes and returns a configured AuthClient."""
org_id = os.getenv("GENESYS_ORG_ID")
region = os.getenv("GENESYS_REGION")
client_id = os.getenv("GENESYS_CLIENT_ID")
private_key_path = os.getenv("GENESYS_PRIVATE_KEY_PATH")
if not all([org_id, region, client_id, private_key_path]):
raise ValueError("Missing required environment variables for authentication.")
auth_client = AuthClient(
org_id=org_id,
region=region,
client_id=client_id,
private_key_path=private_key_path
)
try:
token = auth_client.get_access_token()
if not token:
raise Exception("Failed to retrieve access token.")
return auth_client
except ApiException as e:
print(f"Authentication error: {e.status} {e.reason}")
raise
def build_cobrowse_request(host_user_id: str, session_name: str) -> Dict[str, Any]:
"""Constructs the JSON payload for the cobrowse session."""
return {
"hostUserId": host_user_id,
"application": {
"id": "web",
"type": "web"
},
"sessionName": session_name,
"timeoutSeconds": 1800,
"metadata": {
"source": "api-tutorial"
}
}
def initiate_cobrowse_session(auth_client: AuthClient, host_user_id: str) -> Dict:
"""Initiates a cobrowse session via the Conversations API."""
token = auth_client.get_access_token()
if not token:
raise RuntimeError("No valid access token available.")
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json"
}
region = os.getenv("GENESYS_REGION", "mypurecloud.com")
url = f"https://{region}.mypurecloud.com/api/v2/conversations/cobrowse"
body = build_cobrowse_request(host_user_id, "API-Initiated-Session")
try:
with httpx.Client(timeout=10.0) as client:
response = client.post(url, headers=headers, json=body)
response.raise_for_status()
return response.json()
except HTTPStatusError as e:
print(f"API Error {e.response.status_code}: {e.response.text}")
raise
except httpx.RequestError as e:
print(f"Network error: {e}")
raise
def main():
"""Main execution block."""
try:
host_user_id = os.getenv("GENESYS_HOST_USER_ID")
if not host_user_id:
raise ValueError("GENESYS_HOST_USER_ID environment variable is not set.")
print("Initializing Genesys Cloud Auth Client...")
auth_client = get_auth_client()
print("Authentication successful.")
print("Initiating Cobrowse Session...")
session_data = initiate_cobrowse_session(auth_client, host_user_id)
session_id = session_data.get("id")
join_url = session_data.get("joinUrl")
print("-" * 30)
print("Session Created Successfully")
print(f"Session ID: {session_id}")
print(f"Join URL: {join_url}")
print("-" * 30)
except Exception as e:
print(f"Fatal Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Common Errors & Debugging
Error: 403 Forbidden
- Cause: The OAuth client lacks the
cobrowse:session:writescope. - Fix: Navigate to the Genesys Cloud Admin Console, go to Organization > Integrations > OAuth Clients, select your client, and add the
cobrowse:session:writescope. Restart your application to pick up the new token.
Error: 400 Bad Request - “Invalid Host User”
- Cause: The
hostUserIdprovided in the request body does not exist, is not an active user, or does not have a valid cobrowse license/assignment. - Fix: Verify the UUID is correct. Ensure the user is active in Genesys Cloud. Check that the user is assigned to a team or queue that allows cobrowsing.
Error: 400 Bad Request - “Application Not Found”
- Cause: The
application.idprovided (e.g.,web) does not exist in your organization, or you are using a custom application ID that is not configured. - Fix: For standard web cobrowsing, ensure you use
"id": "web". If using a custom app, verify the ID via the Applications API (GET /api/v2/cobrowse/applications).
Error: 429 Too Many Requests
- Cause: You have exceeded the rate limit for the Conversations API.
- Fix: Implement exponential backoff. The Genesys Cloud API returns
Retry-Afterheaders in 429 responses. Parse this header and wait before retrying.
Error: 500 Internal Server Error
- Cause: A transient issue on the Genesys Cloud platform.
- Fix: Retry the request after a short delay. If the error persists, check the Genesys Cloud Service Status page or contact Support.