Increase Genesys Cloud Data Action Timeouts from 3 Seconds
What You Will Build
- One sentence: This tutorial shows how to programmatically increase the timeout for Genesys Cloud Data Actions from the default 3 seconds to a higher value, such as 10 or 30 seconds.
- One sentence: This uses the Genesys Cloud Platform API v2, specifically the
/api/v2/integrations/actionsendpoint. - One sentence: The programming language covered is Python using the
requestslibrary.
Prerequisites
- OAuth client type: Service Account with
integration:writescope. - SDK version: Genesys Cloud Platform API v2 (latest).
- Language/runtime requirements: Python 3.8+.
- External dependencies:
requests,python-dotenv.
Authentication Setup
Genesys Cloud uses OAuth 2.0 for authentication. For server-to-server integrations, use the Client Credentials Grant flow. The token expires after 59 minutes, so you must implement token caching or refresh logic.
import requests
import os
from datetime import datetime, timedelta
class GenesysAuth:
def __init__(self, client_id: str, client_secret: str, env_name: str = "us-east-1"):
self.client_id = client_id
self.client_secret = client_secret
self.env_name = env_name
self.token_url = f"https://{env_name}.mypurecloud.com/oauth/token"
self.access_token = None
self.token_expiry = None
def get_token(self) -> str:
"""
Retrieves an OAuth access token.
Returns the token string.
Raises requests.exceptions.HTTPError on failure.
"""
# Check if token is still valid (subtract 5 minutes for buffer)
if self.access_token and self.token_expiry and datetime.now() < self.token_expiry - timedelta(minutes=5):
return self.access_token
data = {
"grant_type": "client_credentials",
"client_id": self.client_id,
"client_secret": self.client_secret
}
try:
response = requests.post(self.token_url, data=data)
response.raise_for_status()
token_data = response.json()
self.access_token = token_data["access_token"]
# Genesys tokens expire in 59 minutes (3540 seconds)
self.token_expiry = datetime.now() + timedelta(seconds=3535)
return self.access_token
except requests.exceptions.HTTPError as e:
print(f"Authentication failed: {e.response.status_code} - {e.response.text}")
raise
Implementation
Step 1: Retrieve the Current Data Action Configuration
Before modifying the timeout, you must retrieve the existing Data Action configuration. The timeout is not a global setting but is defined within the specific Action definition. You need the id of the Data Action you wish to modify.
class GenesysDataActionManager:
def __init__(self, auth: GenesysAuth):
self.auth = auth
self.base_url = f"https://{auth.env_name}.mypurecloud.com/api/v2"
def get_headers(self) -> dict:
token = self.auth.get_token()
return {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
def get_data_action(self, action_id: str) -> dict:
"""
Retrieves a specific Data Action by ID.
Required Scope: integration:read
"""
url = f"{self.base_url}/integrations/actions/{action_id}"
headers = self.get_headers()
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
print(f"Failed to retrieve action {action_id}: {e.response.status_code} - {e.response.text}")
raise
Step 2: Update the Timeout Configuration
The timeout field in the Data Action body specifies the maximum time in seconds that the action can take to complete. The default is often 3 seconds. You can increase this to 10, 15, 30, or up to 60 seconds depending on your use case.
Critical Note: The timeout field is an integer representing seconds. It must be between 1 and 60.
def update_data_action_timeout(self, action_id: str, new_timeout: int) -> dict:
"""
Updates the timeout for a specific Data Action.
Required Scope: integration:write
"""
if not 1 <= new_timeout <= 60:
raise ValueError("Timeout must be between 1 and 60 seconds.")
# First, get the current action to preserve other fields
current_action = self.get_data_action(action_id)
# Update the timeout field
current_action["timeout"] = new_timeout
url = f"{self.base_url}/integrations/actions/{action_id}"
headers = self.get_headers()
try:
response = requests.put(url, headers=headers, json=current_action)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
print(f"Failed to update action {action_id}: {e.response.status_code} - {e.response.text}")
raise
Step 3: Verify the Update
After updating, verify that the timeout has been applied by retrieving the action again.
def verify_timeout_update(self, action_id: str, expected_timeout: int) -> bool:
"""
Verifies that the timeout has been updated correctly.
"""
updated_action = self.get_data_action(action_id)
return updated_action.get("timeout") == expected_timeout
Complete Working Example
This script retrieves a Data Action, increases its timeout from 3 seconds to 10 seconds, and verifies the update.
import os
import sys
from dotenv import load_dotenv
from GenesysAuth import GenesysAuth
from GenesysDataActionManager import GenesysDataActionManager
def main():
# Load environment variables
load_dotenv()
client_id = os.getenv("GENESYS_CLIENT_ID")
client_secret = os.getenv("GENESYS_CLIENT_SECRET")
env_name = os.getenv("GENESYS_ENV_NAME", "us-east-1")
action_id = os.getenv("GENESYS_ACTION_ID")
if not all([client_id, client_secret, action_id]):
print("Missing required environment variables: GENESYS_CLIENT_ID, GENESYS_CLIENT_SECRET, GENESYS_ACTION_ID")
sys.exit(1)
# Initialize authentication
auth = GenesysAuth(client_id, client_secret, env_name)
# Initialize Data Action Manager
manager = GenesysDataActionManager(auth)
# Define new timeout
new_timeout = 10 # seconds
try:
print(f"Updating Data Action {action_id} timeout to {new_timeout} seconds...")
updated_action = manager.update_data_action_timeout(action_id, new_timeout)
print(f"Update successful. New timeout: {updated_action['timeout']} seconds")
# Verify the update
is_verified = manager.verify_timeout_update(action_id, new_timeout)
if is_verified:
print("Verification successful.")
else:
print("Verification failed. Timeout may not have been updated correctly.")
except Exception as e:
print(f"An error occurred: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
Common Errors & Debugging
Error: 401 Unauthorized
- What causes it: The OAuth token is invalid, expired, or missing.
- How to fix it: Ensure your
client_idandclient_secretare correct. Check that the token retrieval logic is working. - Code showing the fix: The
GenesysAuthclass handles token expiration. If you still see 401, check that the Service Account has theintegration:writescope.
Error: 403 Forbidden
- What causes it: The Service Account does not have the required
integration:writescope. - How to fix it: Go to the Genesys Cloud Admin Console, navigate to Admin > Security > Service Accounts, and ensure the
integration:writescope is checked for your Service Account. - Code showing the fix: No code change is needed. This is a permission issue in the Genesys Cloud platform.
Error: 400 Bad Request
- What causes it: The
timeoutvalue is outside the allowed range (1-60 seconds) or the JSON payload is malformed. - How to fix it: Ensure the
timeoutis an integer between 1 and 60. Check the JSON structure of the request body. - Code showing the fix: The
update_data_action_timeoutmethod includes a validation check:if not 1 <= new_timeout <= 60: raise ValueError(...).
Error: 429 Too Many Requests
- What causes it: You have exceeded the Genesys Cloud API rate limits.
- How to fix it: Implement exponential backoff and retry logic.
- Code showing the fix:
import time
def make_request_with_retry(func, *args, max_retries=3, base_delay=1):
for attempt in range(max_retries):
try:
return func(*args)
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
delay = base_delay * (2 ** attempt)
print(f"Rate limited. Retrying in {delay} seconds...")
time.sleep(delay)
else:
raise
raise Exception("Max retries exceeded")