Submit Result
Register the result of a task-type activity.
POST /api/integration/activity-results/tasks
Submits the result of a task-type activity. The result is associated with the corresponding activity and updates its status in Reten.
The operation is an idempotent UPSERT: if the activity does not yet have a result, it is created; if it already has one, its details are overwritten with the latest submission (last-write-wins). You can re-send the result without getting a conflict.
Authentication: Required — permission activity-result:submit
Required headers
| Header | Value |
|---|---|
x-api-key | YOUR_API_KEY |
Content-Type | application/json |
x-project-id is optional: this is a project-optional endpoint.
- With a tenant key or a user token, sending the header narrows the request to that project, so
activity_idmust belong to it. Without the header, the result takes the project of its activity. A header that is sent is validated — see Project errors. - A result without
activity_idhas no activity to take a project from: with a project key it takes the key's project; with a tenant key or a user token it needs the header, and without it the API responds400. - A project key always works in its own project: an
activity_idof another project responds404.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
activity_id | string (UUID) | No | Activity ID in Reten. If omitted, the result is registered as a standalone execution (STANDALONE), which needs a project (see Required headers) |
provider_activity_id | string | No | Activity ID in your system. For correlation/tracking only — does not identify or resolve the activity in Reten |
commerce_external_id | string | Conditional | Commerce external ID. Required only for standalone executions (without activity_id); with a linked activity it is derived from it |
occurred_at | string (ISO 8601) | Yes | Date and time when the activity was handled |
task_result | object | Yes | Task result detail (see table below) |
The activity is resolved only by activity_id. If sent, the result is linked to that activity; if omitted, it is registered as a standalone execution (STANDALONE). provider_activity_id is for correlation/tracking with your system only and does not resolve the activity.
commerce_external_id is optional when the activity is linked to an activity (activity_id): the commerce is derived from the activity. It is only required for standalone executions (STANDALONE) — when activity_id is not sent — and in that case, if the commerce does not exist, it is created as a placeholder.
task_result fields
| Field | Type | Required | Description |
|---|---|---|---|
result | string | Yes | Result type code (obtained from List Configurations) |
comment | string | No | Operator comment about the activity |
operator_external_id | string | No | External ID of the operator who handled the activity |
future_scheduled_at | string (ISO 8601) | Conditional | Reschedule date. Required if the result type has requiresFutureScheduledAt: true |
payload | object | No | Additional result data |
Example
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": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"commerce_external_id": "COM-001",
"occurred_at": "2026-04-11T10:30:00.000Z",
"task_result": {
"result": "SALE_COMPLETED",
"comment": "Customer accepted renewal offer",
"operator_external_id": "OP-042"
}
}'const response = await fetch(
`${BASE_URL}/api/integration/activity-results/tasks`,
{
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
activity_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
commerce_external_id: "COM-001",
occurred_at: "2026-04-11T10:30:00.000Z",
task_result: {
result: "SALE_COMPLETED",
comment: "Customer accepted renewal offer",
operator_external_id: "OP-042",
},
}),
}
);
const data = await response.json();import requests
response = requests.post(
f"{BASE_URL}/api/integration/activity-results/tasks",
headers={
"x-api-key": "YOUR_API_KEY",
},
json={
"activity_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"commerce_external_id": "COM-001",
"occurred_at": "2026-04-11T10:30:00.000Z",
"task_result": {
"result": "SALE_COMPLETED",
"comment": "Customer accepted renewal offer",
"operator_external_id": "OP-042",
},
},
)
data = response.json()Response 201 Created
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"source": "RETEN_ACTIVITY",
"origin": "EXTERNAL",
"activityId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"providerActivityId": null,
"commerceExternalId": "COM-001",
"resultStatus": "COMPLETED",
"occurredAt": "2026-04-11T10:30:00.000Z",
"createdAt": "2026-04-11T10:30:05.000Z",
"updatedAt": "2026-04-11T10:30:05.000Z",
"result": {
"code": "SALE_COMPLETED",
"label": "Venta completada"
},
"comment": "Customer accepted renewal offer",
"operatorExternalId": "OP-042",
"futureScheduledAt": null
}Validation rules
commerce_external_idis only required for standalone executions (withoutactivity_id); in that case, if the commerce does not exist it is created as a placeholder. With a linked activity the commerce is derived from it and this field is optional.operator_external_idis optional; if sent and the operator does not exist, it is created as a placeholder.- The
resultcode must be an active result type (see List Configurations); otherwise the request returns422—El tipo de resultado seleccionado no está activo. - If the result type has
requiresFutureScheduledAt: true, thefuture_scheduled_atfield is mandatory (otherwise422—Este tipo de resultado requiere una fecha comprometida.) and must fall today or later in the tenant's timezone (otherwise422—La fecha programada no puede ser en el pasado.) - If the activity already has a result, the submission overwrites it (idempotent UPSERT); no conflict is returned
- The linked activity must be in a state that accepts a result (
READY,DISPATCHED,RETRYINGorCOMPLETED— inCOMPLETED, the submission overwrites the existing result); otherwise the request returns422—La actividad no está en un estado válido para registrar resultado. - It is not allowed to register a result for an activity whose execution date has already crossed the end-of-day cutoff; in that case the request returns
422—La actividad corresponde a un día ya cerrado y no admite registrar resultado.Standalone executions (STANDALONE, withoutactivity_id) are exempt from this rule
Errors
| Status | Description |
|---|---|
400 | Validation error in the body — missing or invalid fields |
400 | A result without activity_id has no project: a tenant key or a user token that does not send x-project-id — Falta el header obligatorio x-project-id: un resultado sin activity_id necesita proyecto. |
401 | Invalid, revoked or expired API key, or its owner is inactive (see Errors) |
403 | The key does not have the activity-result:submit permission |
404 | The activity_id does not exist in the tenant or, when the request has a project (a project key or x-project-id), in that project — Actividad no encontrada. |
422 | The activity does not accept a result in its current state, its day was closed by the end-of-day cutoff, the result type is not active, or future_scheduled_at is missing or in the past (see Validation rules) |