Reten Docs

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

HeaderValue
x-api-keyYOUR_API_KEY
Content-Typeapplication/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_id must 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_id has 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 responds 400.
  • A project key always works in its own project: an activity_id of another project responds 404.

Request body

FieldTypeRequiredDescription
activity_idstring (UUID)NoActivity ID in Reten. If omitted, the result is registered as a standalone execution (STANDALONE), which needs a project (see Required headers)
provider_activity_idstringNoActivity ID in your system. For correlation/tracking only — does not identify or resolve the activity in Reten
commerce_external_idstringConditionalCommerce external ID. Required only for standalone executions (without activity_id); with a linked activity it is derived from it
occurred_atstring (ISO 8601)YesDate and time when the activity was handled
task_resultobjectYesTask 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

FieldTypeRequiredDescription
resultstringYesResult type code (obtained from List Configurations)
commentstringNoOperator comment about the activity
operator_external_idstringNoExternal ID of the operator who handled the activity
future_scheduled_atstring (ISO 8601)ConditionalReschedule date. Required if the result type has requiresFutureScheduledAt: true
payloadobjectNoAdditional 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_id is only required for standalone executions (without activity_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_id is optional; if sent and the operator does not exist, it is created as a placeholder.
  • The result code must be an active result type (see List Configurations); otherwise the request returns 422 — El tipo de resultado seleccionado no está activo.
  • If the result type has requiresFutureScheduledAt: true, the future_scheduled_at field is mandatory (otherwise 422 — Este tipo de resultado requiere una fecha comprometida.) and must fall today or later in the tenant's timezone (otherwise 422 — 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, RETRYING or COMPLETED — in COMPLETED, the submission overwrites the existing result); otherwise the request returns 422 — 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, without activity_id) are exempt from this rule

Errors

StatusDescription
400Validation error in the body — missing or invalid fields
400A 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.
401Invalid, revoked or expired API key, or its owner is inactive (see Errors)
403The key does not have the activity-result:submit permission
404The 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.
422The 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)