Quickstart: Pull Integration
Set up your first pull integration with Reten in 4 steps.
This guide walks you step by step from obtaining your API key to submitting your first activity result. By the end you will have a working integration with the Reten API.
Reten Environments
| Environment | Admin Panel | API Base URL |
|---|---|---|
| Development | app-development.reten.ai | https://api-development.reten.ai |
| Staging | app-staging.reten.ai | https://api-staging.reten.ai |
| Production | app.reten.ai | https://api.reten.ai |
Use the admin panel URL to manage API keys and dispatch configurations. Replace BASE_URL in code examples with the API base URL for your environment.
Step 1: Obtain an API key
Ask a tenant administrator to create an API key with the following permissions:
VIEW_ACTIVITIES— to query activities and configurationsSUBMIT_ACTIVITY_RESULT— to submit activity results
Once created, you will receive:
- API Key:
rtn_sk_...(shown only once)
Store the API key securely. It cannot be retrieved after creation. If you lose it, you will need to revoke it and create a new one.
Step 2: Verify your key
Make a test request to confirm your key works correctly:
curl -X GET BASE_URL/api/integration/task-result-type-configs \
-H "x-api-key: YOUR_API_KEY"const BASE_URL = "https://api.reten.ai";
const API_KEY = "YOUR_API_KEY";
const response = await fetch(
`${BASE_URL}/api/integration/task-result-type-configs`,
{
headers: {
"x-api-key": API_KEY,
},
}
);
if (!response.ok) {
console.error(`Error ${response.status}: ${await response.text()}`);
process.exit(1);
}
const configs = await response.json();
console.log("Available result types:", configs);import requests
BASE_URL = "https://api.reten.ai"
API_KEY = "YOUR_API_KEY"
response = requests.get(
f"{BASE_URL}/api/integration/task-result-type-configs",
headers={
"x-api-key": API_KEY,
},
)
if response.status_code != 200:
print(f"Error {response.status_code}: {response.text}")
exit(1)
configs = response.json()
print("Available result types:", configs)If you receive a 200 OK with a list of configurations, your key is working. If you receive 401, verify that the x-api-key header is correct. If you receive 403, the key does not have the required permissions — ask the tenant administrator to add them.
Step 3: List your activities
Query the pending task-type activities:
curl -X GET "BASE_URL/api/integration/activities/tasks?status=PENDING&per_page=5" \
-H "x-api-key: YOUR_API_KEY"const params = new URLSearchParams({
status: "PENDING",
per_page: "5",
});
const response = await fetch(
`${BASE_URL}/api/integration/activities/tasks?${params}`,
{
headers: {
"x-api-key": API_KEY,
},
}
);
const { data, meta } = await response.json();
console.log(`${meta.total} activities found`);
for (const activity of data) {
console.log(`- ${activity.id}: ${activity.commerceName} (${activity.status})`);
}response = requests.get(
f"{BASE_URL}/api/integration/activities/tasks",
headers={
"x-api-key": API_KEY,
},
params={
"status": "PENDING",
"per_page": 5,
},
)
result = response.json()
print(f"{result['meta']['total']} activities found")
for activity in result["data"]:
print(f"- {activity['id']}: {activity['commerceName']} ({activity['status']})")The response includes paginated activities with their details: assigned commerce, operator, scheduled date, and current status. See the full reference for all available fields.
Step 4: Submit a result
After handling an activity, submit the result to Reten. Use the id from the activity in the previous step and a valid result code from step 2:
curl -X POST BASE_URL/api/integration/activity-results/tasks \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"activity_id": "ACTIVITY_ID",
"commerce_external_id": "COMMERCE_EXTERNAL_ID",
"occurred_at": "2026-04-11T10:30:00.000Z",
"status": "EFFECTIVE",
"task_result": {
"result": "SALE_COMPLETED",
"comment": "Customer accepted renewal offer",
"operator_external_id": "OPERATOR_EXTERNAL_ID"
}
}'const activityId = "ACTIVITY_ID"; // From step 3
const commerceExternalId = "COMMERCE_EXTERNAL_ID"; // From step 3
const response = await fetch(
`${BASE_URL}/api/integration/activity-results/tasks`,
{
method: "POST",
headers: {
"x-api-key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
activity_id: activityId,
commerce_external_id: commerceExternalId,
occurred_at: new Date().toISOString(),
status: "EFFECTIVE",
task_result: {
result: "SALE_COMPLETED",
comment: "Customer accepted renewal offer",
operator_external_id: "OPERATOR_EXTERNAL_ID",
},
}),
}
);
if (response.status === 201) {
const result = await response.json();
console.log("Result registered:", result.id);
}from datetime import datetime, timezone
activity_id = "ACTIVITY_ID" # From step 3
commerce_external_id = "COMMERCE_EXTERNAL_ID" # From step 3
response = requests.post(
f"{BASE_URL}/api/integration/activity-results/tasks",
headers={
"x-api-key": API_KEY,
},
json={
"activity_id": activity_id,
"commerce_external_id": commerce_external_id,
"occurred_at": datetime.now(timezone.utc).isoformat(),
"status": "EFFECTIVE",
"task_result": {
"result": "SALE_COMPLETED",
"comment": "Customer accepted renewal offer",
"operator_external_id": "OPERATOR_EXTERNAL_ID",
},
},
)
if response.status_code == 201:
result = response.json()
print(f"Result registered: {result['id']}")A 201 Created response confirms that the result was registered successfully.
Next steps
- Check the endpoint reference for all available parameters and fields
- Review error handling to implement retries and diagnostics
- If you need to receive activities in real time, see Receiving Activities (Dispatch)