Increase Genesys Cloud Data Action Timeout Beyond Default Limits
What You Will Build
- One sentence: This tutorial demonstrates how to configure and enforce longer timeout values for Genesys Cloud Data Actions using the Genesys Cloud Platform Client SDK in Python.
- One sentence: This uses the Genesys Cloud API v2 endpoints for External Applications and Integration Objects.
- One sentence: The programming language covered is Python 3.9+.
Prerequisites
- OAuth client type: Confidential Client (Service Account) or Public Client (User Context) with appropriate permissions.
- Required scopes:
integration:externalapplication:write,integration:externalapplication:read,integration:integrationobject:write,integration:integrationobject:read. - SDK version:
genesys-cloud-py-sdkversion 126.0.0 or later. - Language/runtime requirements: Python 3.9+ installed on your local machine or CI/CD runner.
- External dependencies:
pip install genesys-cloud-py-sdk.
Authentication Setup
Genesys Cloud uses OAuth 2.0 for authentication. For server-side integrations involving Data Actions (which often run in the background via PureCloud Assistant or API triggers), a Service Account is the standard approach. This avoids the need for interactive user logins and ensures consistent token availability.
The following code initializes the SDK client using environment variables for security. It implements automatic token refresh, which is critical for long-running scripts that might exceed the default 1-hour token lifespan.
import os
from genesyscloud import PureCloudPlatformClientV2, Configuration
def init_genesys_client():
"""
Initialize the Genesys Cloud SDK client with OAuth authentication.
Returns:
PureCloudPlatformClientV2: The configured client instance.
"""
# Retrieve credentials from environment variables
client_id = os.getenv("GENESYS_CLIENT_ID")
client_secret = os.getenv("GENESYS_CLIENT_SECRET")
api_host = os.getenv("GENESYS_API_HOST", "api.mypurecloud.com")
if not client_id or not client_secret:
raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET must be set in environment variables.")
# Configure the SDK
config = Configuration()
config.host = api_host
# Create the client with credentials
# The SDK handles token acquisition and automatic refresh
client = PureCloudPlatformClientV2(client_id, client_secret, config=config)
return client
Note on Token Refresh: The PureCloudPlatformClientV2 constructor automatically manages the OAuth token lifecycle. When a 401 Unauthorized response is received due to token expiration, the SDK intercepts the error, refreshes the token using the stored refresh token (or client credentials flow), and retries the request transparently. You do not need to implement manual retry logic for authentication failures.
Implementation
Step 1: Understand the Timeout Constraint
Genesys Cloud Data Actions have a default timeout limit of 3 seconds for synchronous execution. This limit is enforced by the platform to prevent blocking of the main thread during conversation processing. If your external API call takes 5 seconds, the Data Action will fail with a timeout error, and the conversation will not receive the expected data.
To resolve this, you must adjust the timeout configuration at the External Application level. The External Application acts as a proxy and security boundary for all Data Actions associated with it. By increasing the timeout here, you allow the Data Action to wait longer for a response from the target endpoint.
The maximum allowed timeout for a Data Action is 30 seconds. If your operation requires more than 30 seconds, you must redesign the architecture to use asynchronous patterns (e.g., Webhooks or Queue-based processing) instead of synchronous Data Actions.
Step 2: Retrieve the External Application Configuration
Before modifying the timeout, you must retrieve the current configuration of the External Application. This ensures you do not overwrite other critical settings such as allowed origins, headers, or authentication details.
from genesyscloud.rest import ApiException
def get_external_application(client: PureCloudPlatformClientV2, external_app_id: str):
"""
Retrieve the current configuration of an External Application.
Args:
client: The initialized Genesys Cloud client.
external_app_id: The UUID of the External Application.
Returns:
ExternalApplicationEntity: The current configuration object.
"""
try:
# Use the ExternalApplicationsApi to fetch the application
external_apps_api = client.external_applications_api
response = external_apps_api.get_integration_externalapplication(external_app_id)
if response is None:
raise ValueError(f"External Application with ID {external_app_id} not found.")
return response.body
except ApiException as e:
if e.status == 404:
raise ValueError(f"External Application with ID {external_app_id} not found. Check the ID.")
elif e.status == 401:
raise ValueError("Authentication failed. Check your OAuth token.")
elif e.status == 403:
raise ValueError("Permission denied. Ensure the client has 'integration:externalapplication:read' scope.")
else:
raise e
Error Handling:
- 404 Not Found: The
external_app_idis incorrect or the application has been deleted. - 401 Unauthorized: The OAuth token is invalid or expired. The SDK should handle refresh, but if the credentials are wrong, this error persists.
- 403 Forbidden: The OAuth client lacks the
integration:externalapplication:readscope.
Step 3: Update the Timeout Configuration
The timeout property in the External Application configuration is specified in milliseconds. To increase the timeout from 3 seconds (3000 ms) to 5 seconds (5000 ms), you must update this value.
def update_external_application_timeout(client: PureCloudPlatformClientV2, external_app_id: str, new_timeout_ms: int):
"""
Update the timeout configuration for an External Application.
Args:
client: The initialized Genesys Cloud client.
external_app_id: The UUID of the External Application.
new_timeout_ms: The new timeout value in milliseconds.
Raises:
ValueError: If the timeout is out of acceptable range.
ApiException: If the API call fails.
"""
# Validate timeout range
# Genesys Cloud supports timeouts between 1000 ms and 30000 ms
if new_timeout_ms < 1000 or new_timeout_ms > 30000:
raise ValueError("Timeout must be between 1000 ms and 30000 ms.")
# Retrieve current configuration
current_config = get_external_application(client, external_app_id)
# Update the timeout
current_config.timeout = new_timeout_ms
# Prepare the request body
# The SDK requires a Body object for PUT requests
body = ExternalApplicationEntity(
name=current_config.name,
description=current_config.description,
allowed_origins=current_config.allowed_origins,
allowed_headers=current_config.allowed_headers,
timeout=new_timeout_ms,
# Preserve other existing settings
api_version=current_config.api_version,
# ... copy other relevant fields if necessary
)
try:
# Use the ExternalApplicationsApi to update the application
external_apps_api = client.external_applications_api
response = external_apps_api.put_integration_externalapplication(
external_app_id,
body=body
)
if response is None:
raise ValueError("Failed to update External Application. No response received.")
return response.body
except ApiException as e:
if e.status == 400:
raise ValueError(f"Bad Request: {e.body}. Check the configuration values.")
elif e.status == 401:
raise ValueError("Authentication failed. Check your OAuth token.")
elif e.status == 403:
raise ValueError("Permission denied. Ensure the client has 'integration:externalapplication:write' scope.")
else:
raise e
Critical Parameter: The timeout field is an integer representing milliseconds. Setting it to 5000 allows the Data Action to wait up to 5 seconds for a response.
Step 4: Verify the Data Action Configuration
After updating the External Application, you must ensure that the specific Data Action associated with this application is configured to use the updated timeout. In Genesys Cloud, the Data Action itself does not have an independent timeout setting; it inherits the timeout from its parent External Application. However, you must verify that the Data Action is correctly linked.
def get_data_action(client: PureCloudPlatformClientV2, data_action_id: str):
"""
Retrieve the configuration of a specific Data Action.
Args:
client: The initialized Genesys Cloud client.
data_action_id: The UUID of the Data Action.
Returns:
DataActionEntity: The Data Action configuration object.
"""
try:
data_actions_api = client.data_actions_api
response = data_actions_api.get_integration_dataaction(data_action_id)
if response is None:
raise ValueError(f"Data Action with ID {data_action_id} not found.")
return response.body
except ApiException as e:
if e.status == 404:
raise ValueError(f"Data Action with ID {data_action_id} not found.")
elif e.status == 401:
raise ValueError("Authentication failed.")
elif e.status == 403:
raise ValueError("Permission denied. Ensure the client has 'integration:dataaction:read' scope.")
else:
raise e
Complete Working Example
The following script combines all steps into a single executable module. It retrieves the External Application, updates the timeout to 5 seconds, and verifies the Data Action configuration.
import os
import sys
from genesyscloud import PureCloudPlatformClientV2, Configuration, ExternalApplicationEntity, DataActionEntity
from genesyscloud.rest import ApiException
def init_genesys_client():
client_id = os.getenv("GENESYS_CLIENT_ID")
client_secret = os.getenv("GENESYS_CLIENT_SECRET")
api_host = os.getenv("GENESYS_API_HOST", "api.mypurecloud.com")
if not client_id or not client_secret:
raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET must be set.")
config = Configuration()
config.host = api_host
return PureCloudPlatformClientV2(client_id, client_secret, config=config)
def update_timeout(client: PureCloudPlatformClientV2, external_app_id: str, data_action_id: str):
external_apps_api = client.external_applications_api
data_actions_api = client.data_actions_api
# Step 1: Get External Application
try:
ext_app_response = external_apps_api.get_integration_externalapplication(external_app_id)
if not ext_app_response.body:
print("Error: External Application not found.")
return
ext_app = ext_app_response.body
except ApiException as e:
print(f"Error fetching External Application: {e}")
return
# Step 2: Update Timeout
new_timeout_ms = 5000 # 5 seconds
if ext_app.timeout != new_timeout_ms:
print(f"Updating timeout from {ext_app.timeout} ms to {new_timeout_ms} ms.")
ext_app.timeout = new_timeout_ms
try:
update_response = external_apps_api.put_integration_externalapplication(
external_app_id,
body=ext_app
)
if update_response.body:
print("Timeout updated successfully.")
else:
print("Error: Failed to update timeout.")
except ApiException as e:
print(f"Error updating timeout: {e}")
return
else:
print("Timeout is already set to 5000 ms.")
# Step 3: Verify Data Action
try:
da_response = data_actions_api.get_integration_dataaction(data_action_id)
if not da_response.body:
print("Error: Data Action not found.")
return
da = da_response.body
print(f"Data Action '{da.name}' is linked to External Application '{ext_app.name}'.")
print(f"Effective timeout for this Data Action is now {ext_app.timeout} ms.")
except ApiException as e:
print(f"Error verifying Data Action: {e}")
if __name__ == "__main__":
# Configuration
EXTERNAL_APP_ID = os.getenv("GENESYS_EXTERNAL_APP_ID")
DATA_ACTION_ID = os.getenv("GENESYS_DATA_ACTION_ID")
if not EXTERNAL_APP_ID or not DATA_ACTION_ID:
print("Error: GENESYS_EXTERNAL_APP_ID and GENESYS_DATA_ACTION_ID must be set.")
sys.exit(1)
try:
client = init_genesys_client()
update_timeout(client, EXTERNAL_APP_ID, DATA_ACTION_ID)
except Exception as e:
print(f"Fatal error: {e}")
sys.exit(1)
Common Errors & Debugging
Error: 400 Bad Request
- What causes it: The
timeoutvalue is outside the allowed range (1000-30000 ms) or the request body is malformed. - How to fix it: Ensure the
timeoutvalue is an integer between 1000 and 30000. Check that all required fields in theExternalApplicationEntityare present. - Code showing the fix:
# Ensure timeout is within bounds if new_timeout_ms < 1000: new_timeout_ms = 1000 if new_timeout_ms > 30000: new_timeout_ms = 30000
Error: 403 Forbidden
- What causes it: The OAuth client lacks the
integration:externalapplication:writescope. - How to fix it: Go to the Genesys Cloud Admin Portal > Platform > OAuth > Applications > [Your Application] > Scopes. Add the
integration:externalapplication:writescope. - Code showing the fix: No code fix is required. This is a configuration issue in the Genesys Cloud admin console.
Error: 429 Too Many Requests
- What causes it: You have exceeded the API rate limit.
- How to fix it: Implement exponential backoff retry logic. The SDK does not automatically retry 429 errors.
- Code showing the fix:
import time def api_call_with_retry(api_method, *args, max_retries=3, **kwargs): for attempt in range(max_retries): try: return api_method(*args, **kwargs) except ApiException as e: if e.status == 429: wait_time = 2 ** attempt # Exponential backoff print(f"Rate limited. Waiting {wait_time} seconds before retry.") time.sleep(wait_time) else: raise e raise Exception("Max retries exceeded.")