Increase Genesys Cloud Data Action Timeouts via API
What You Will Build
- This tutorial demonstrates how to programmatically increase the execution timeout for Genesys Cloud Data Actions, resolving cases where actions fail due to the default 3-second limit.
- The code uses the Genesys Cloud Platform Client V2 SDK to update Integration Data Action configurations.
- The examples are provided in Python and JavaScript, covering authentication, retrieval of existing configurations, and application of new timeout values.
Prerequisites
- OAuth Client Type: Service Account or Password Grant client.
- Required Scopes:
integration:integration:readintegration:integration:writeintegration:dataaction:read(if accessing specific data action metadata)
- SDK Version:
- Python:
genesys-cloud-py>= 1.0.0 - JavaScript:
genesys-cloud-javascript-client>= 1.0.0
- Python:
- Language/Runtime:
- Python 3.8+
- Node.js 16+
- External Dependencies:
- Python:
pip install genesys-cloud-py - JavaScript:
npm install @genesys/cloud
- Python:
Authentication Setup
Genesys Cloud APIs require OAuth 2.0 authentication. For server-to-server integrations, such as updating configuration settings, the Service Account flow or Password Grant flow is appropriate. The following examples establish a configured API client instance.
Python Authentication
import os
from purecloudplatformclientv2 import PlatformApiClient, Configuration
from purecloudplatformclientv2.rest import ApiException
def get_platform_client() -> PlatformApiClient:
"""
Initialize and return a configured Genesys Cloud Platform API Client.
"""
# Retrieve credentials from environment variables
client_id = os.getenv("GENESYS_CLIENT_ID")
client_secret = os.getenv("GENESYS_CLIENT_SECRET")
environment = os.getenv("GENESYS_ENVIRONMENT", "mypurecloud.com")
if not client_id or not client_secret:
raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET environment variables must be set.")
# Configure the client
config = Configuration(
client_id=client_id,
client_secret=client_secret,
host=f"https://{environment}",
)
# Create the API client instance
client = PlatformApiClient(config)
# Authenticate the client
try:
client.authenticate()
except ApiException as e:
print(f"Authentication failed: {e}")
raise
return client
JavaScript Authentication
import { PlatformClient } from '@genesys/cloud';
async function getPlatformClient() {
const clientId = process.env.GENESYS_CLIENT_ID;
const clientSecret = process.env.GENESYS_CLIENT_SECRET;
const environment = process.env.GENESYS_ENVIRONMENT || 'mypurecloud.com';
if (!clientId || !clientSecret) {
throw new Error('GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET environment variables must be set.');
}
const config = {
clientId,
clientSecret,
host: `https://${environment}`,
};
const client = new PlatformClient(config);
try {
await client.authenticate();
} catch (error) {
console.error('Authentication failed:', error);
throw error;
}
return client;
}
Implementation
Step 1: Retrieve the Integration and Data Action Configuration
Before modifying the timeout, you must identify the specific Integration ID and the Data Action ID associated with the failing call. Data Action timeouts are often defined at the Integration level or within the specific Data Action definition depending on the integration type.
For most custom integrations or standard third-party integrations, the timeout setting resides in the Integration object’s dataActions array or a linked configuration object.
Python: Fetching Integration Details
from purecloudplatformclientv2 import IntegrationsApi
def get_integration_by_name(client: PlatformApiClient, integration_name: str) -> dict:
"""
Retrieve an integration object by its name.
"""
integrations_api = IntegrationsApi(client)
try:
# Fetch all integrations (pagination handled internally for small sets,
# but for production, implement pagination loop)
response = integrations_api.get_integrations(page_size=100)
for integration in response.entities:
if integration.name == integration_name:
return integration
raise ValueError(f"Integration '{integration_name}' not found.")
except ApiException as e:
print(f"Error fetching integrations: {e}")
raise
JavaScript: Fetching Integration Details
import { IntegrationsApi } from '@genesys/cloud';
async function getIntegrationByName(client, integrationName) {
const integrationsApi = new IntegrationsApi(client);
try {
const response = await integrationsApi.getIntegrations({ pageSize: 100 });
const integration = response.entities.find(i => i.name === integrationName);
if (!integration) {
throw new Error(`Integration '${integrationName}' not found.`);
}
return integration;
} catch (error) {
console.error('Error fetching integrations:', error);
throw error;
}
}
Step 2: Identify the Timeout Parameter
The default timeout for Data Actions is often 3,000 milliseconds (3 seconds). This value is typically located in the timeout field within the dataActions list of the Integration object, or in a specific configuration JSON blob depending on the integration provider.
For Genesys Cloud native Data Actions (like Salesforce, Zendesk, etc.), the timeout might be controlled by the dataActionTimeout property in the Integration object or within the specific DataAction definition if exposed via the API.
Critical Note: Not all integrations expose the timeout field in the API payload. If the timeout field is absent, it may be hardcoded or managed via a different endpoint (e.g., Flow settings if the Data Action is called from a Flow). However, for standard Integrations, the field is usually present.
If the timeout is set at the Flow level (when calling a Data Action from a Flow), you must update the Flow object. If it is set at the Integration level, you update the Integration object. This tutorial focuses on the Integration level, which is the common source of the “3-second default” issue for external API calls.
Inspecting the Payload
When you retrieve the integration, inspect the dataActions array. You will see entries similar to this:
{
"id": "data-action-id-123",
"name": "GetCustomerData",
"timeout": 3000,
"url": "https://api.example.com/customer",
"method": "GET"
}
If timeout is missing or set to 3000, this is the value you need to change.
Step 3: Update the Timeout Value
To increase the limit, you must perform a PUT request to the Integration endpoint with the updated payload. The maximum timeout allowed by Genesys Cloud for Data Actions is typically 30,000 milliseconds (30 seconds). Setting it to 5,000 milliseconds (5 seconds) or higher will resolve the 5-second call failure.
Python: Updating the Integration
from purecloudplatformclientv2 import IntegrationsApi, Integration
def update_data_action_timeout(client: PlatformApiClient, integration: Integration, new_timeout_ms: int) -> Integration:
"""
Update the timeout for all data actions in an integration, or a specific one.
"""
integrations_api = IntegrationsApi(client)
# Clone the integration to avoid mutating the original object reference
updated_integration = Integration(
id=integration.id,
name=integration.name,
enabled=integration.enabled,
version=integration.version, # Critical for optimistic locking
data_actions=integration.data_actions
)
if updated_integration.data_actions:
for action in updated_integration.data_actions:
# Check if the action has a timeout field that can be modified
# Note: The SDK model may not have a direct 'timeout' attribute on DataAction
# if it is nested in a custom JSON config.
# For standard Genesys Data Actions, it is often a direct property.
# Assuming the DataAction object has a 'timeout' attribute
if hasattr(action, 'timeout'):
action.timeout = new_timeout_ms
# If timeout is inside a 'configuration' dict (common for custom integrations)
elif action.configuration and 'timeout' in action.configuration:
action.configuration['timeout'] = new_timeout_ms
try:
# Update the integration
response = integrations_api.put_integration(
integration_id=integration.id,
body=updated_integration
)
print(f"Integration '{integration.name}' updated successfully.")
return response
except ApiException as e:
if e.status == 409:
print("Conflict: The integration version has changed. Please fetch the latest version and retry.")
else:
print(f"Error updating integration: {e}")
raise
JavaScript: Updating the Integration
import { IntegrationsApi } from '@genesys/cloud';
async function updateDataActionTimeout(client, integration, newTimeoutMs) {
const integrationsApi = new IntegrationsApi(client);
// Create a deep copy to avoid mutation issues
const updatedIntegration = JSON.parse(JSON.stringify(integration));
if (updatedIntegration.dataActions) {
updatedIntegration.dataActions.forEach(action => {
// Standard Genesys Data Action structure
if (action.timeout !== undefined) {
action.timeout = newTimeoutMs;
}
// Custom integration configuration structure
else if (action.configuration && action.configuration.timeout !== undefined) {
action.configuration.timeout = newTimeoutMs;
}
});
}
try {
const response = await integrationsApi.putIntegration({
integrationId: updatedIntegration.id,
body: updatedIntegration
});
console.log(`Integration '${updatedIntegration.name}' updated successfully.`);
return response;
} catch (error) {
if (error.status === 409) {
console.error('Conflict: The integration version has changed. Please fetch the latest version and retry.');
} else {
console.error('Error updating integration:', error);
}
throw error;
}
}
Complete Working Example
The following Python script combines authentication, retrieval, and update logic into a single executable module. It searches for an integration by name and updates the timeout for all its data actions to 10,000 milliseconds (10 seconds).
import os
import sys
from purecloudplatformclientv2 import PlatformApiClient, Configuration, IntegrationsApi, Integration
from purecloudplatformclientv2.rest import ApiException
def main():
# 1. Setup Authentication
try:
client = get_platform_client()
except Exception as e:
print(f"Failed to authenticate: {e}")
sys.exit(1)
# 2. Configuration
INTEGRATION_NAME = os.getenv("TARGET_INTEGRATION_NAME", "MyCustomAPI")
NEW_TIMEOUT_MS = int(os.getenv("NEW_TIMEOUT_MS", "10000")) # 10 seconds
MAX_TIMEOUT_MS = 30000 # Genesys Cloud hard limit
if NEW_TIMEOUT_MS > MAX_TIMEOUT_MS:
print(f"Warning: Timeout {NEW_TIMEOUT_MS}ms exceeds maximum limit of {MAX_TIMEOUT_MS}ms. Capping at {MAX_TIMEOUT_MS}ms.")
NEW_TIMEOUT_MS = MAX_TIMEOUT_MS
# 3. Retrieve Integration
integrations_api = IntegrationsApi(client)
target_integration = None
try:
response = integrations_api.get_integrations(page_size=100)
for integration in response.entities:
if integration.name == INTEGRATION_NAME:
target_integration = integration
break
if not target_integration:
print(f"Integration '{INTEGRATION_NAME}' not found.")
sys.exit(1)
print(f"Found Integration: {target_integration.id} ({target_integration.name})")
except ApiException as e:
print(f"Error fetching integrations: {e}")
sys.exit(1)
# 4. Update Timeout
try:
# Clone the integration object
updated_integration = Integration(
id=target_integration.id,
name=target_integration.name,
enabled=target_integration.enabled,
version=target_integration.version,
data_actions=target_integration.data_actions
)
actions_updated = 0
if updated_integration.data_actions:
for action in updated_integration.data_actions:
# Attempt to update standard timeout field
if hasattr(action, 'timeout') and action.timeout is not None:
old_timeout = action.timeout
action.timeout = NEW_TIMEOUT_MS
print(f"Updated Data Action '{action.name}' timeout from {old_timeout}ms to {NEW_TIMEOUT_MS}ms")
actions_updated += 1
# Attempt to update custom configuration timeout
elif action.configuration and isinstance(action.configuration, dict):
if 'timeout' in action.configuration:
old_timeout = action.configuration['timeout']
action.configuration['timeout'] = NEW_TIMEOUT_MS
print(f"Updated Data Action '{action.name}' config timeout from {old_timeout}ms to {NEW_TIMEOUT_MS}ms")
actions_updated += 1
if actions_updated == 0:
print("No data actions with modifiable timeout fields found.")
return
# 5. Commit Changes
integrations_api.put_integration(
integration_id=target_integration.id,
body=updated_integration
)
print(f"Successfully updated {actions_updated} data action(s) in Integration '{INTEGRATION_NAME}'.")
except ApiException as e:
if e.status == 409:
print("Conflict Error: The integration was modified by another user since you fetched it. Please run the script again.")
else:
print(f"Error updating integration: {e}")
sys.exit(1)
def get_platform_client() -> PlatformApiClient:
client_id = os.getenv("GENESYS_CLIENT_ID")
client_secret = os.getenv("GENESYS_CLIENT_SECRET")
environment = os.getenv("GENESYS_ENVIRONMENT", "mypurecloud.com")
if not client_id or not client_secret:
raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET environment variables must be set.")
config = Configuration(
client_id=client_id,
client_secret=client_secret,
host=f"https://{environment}",
)
client = PlatformApiClient(config)
client.authenticate()
return client
if __name__ == "__main__":
main()
Common Errors & Debugging
Error: 409 Conflict
- What causes it: Genesys Cloud uses optimistic locking via the
versionfield. If another user or process modifies the integration between yourGETandPUTrequests, the server rejects the update. - How to fix it: Implement a retry loop that re-fetches the integration, re-applies the timeout changes, and attempts the update again.
- Code Fix:
def update_with_retry(client, integration_id, update_func, max_retries=3):
for attempt in range(max_retries):
try:
# Fetch latest version
latest = integrations_api.get_integration(integration_id=integration_id)
# Apply changes to latest object
updated = update_func(latest)
# Attempt update
integrations_api.put_integration(integration_id=integration_id, body=updated)
return
except ApiException as e:
if e.status == 409 and attempt < max_retries - 1:
print(f"Version conflict. Retrying ({attempt + 1}/{max_retries})...")
continue
raise
Error: 400 Bad Request
- What causes it: The timeout value exceeds the platform limit (30,000 ms) or is set to an invalid type (e.g., string instead of integer).
- How to fix it: Validate the
NEW_TIMEOUT_MSvariable before sending the request. Ensure it is an integer and less than or equal to 30,000.
Error: 401 Unauthorized
- What causes it: The OAuth token is expired or the client lacks the
integration:integration:writescope. - How to fix it: Verify the OAuth scopes assigned to the Service Account in the Genesys Cloud Admin Console. Ensure the token is refreshed if using a long-running process.
Error: Timeout Field Not Found
- What causes it: The specific Data Action type does not support configurable timeouts via the API, or the timeout is managed at the Flow level.
- How to fix it:
- Check if the Data Action is called from a Flow. If so, update the
timeoutproperty in the Flow’scontactFormor specificActionnode within the Flow JSON. - If using a custom Integration, ensure the
configurationJSON blob includes thetimeoutkey. Some third-party integrations require you to define the timeout in theconfigurationobject rather than a top-level field.
- Check if the Data Action is called from a Flow. If so, update the