> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inagent.inconcertcx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reagendar un contacto

> Programa un nuevo intento mediante el identificador interno o externo del contacto.

Reagenda un contacto ya cargado en el lote. En el body debes enviar **exactamente uno** de estos campos:

* `contactId`: identificador interno que genera Inagent al importar el contacto.
* `identifier`: identificador externo definido en el sistema de origen.

El campo `scheduledAt` fija cuándo se realizará el próximo intento. Debe contener una fecha futura en UTC, con formato ISO 8601, y estar situada dentro de los próximos 30 días.

<Info>
  Usa `resetAttempts: true` si el contacto ya agotó sus intentos o ya fue contactado. Sin este campo, la fecha se guarda, pero el contacto no vuelve a ponerse en marcación en esos casos. La respuesta `200` confirma que la solicitud fue aceptada; el motor de marcación puede tardar en reflejar la nueva fecha.
</Info>

## Ejemplos de body

<CodeGroup>
  ```json contactId theme={null}
  {
    "contactId": "7d2f8a1b-3c4e-4f50-9a6b-2c3d4e5f6a7b",
    "scheduledAt": "2026-09-23T08:41:43.522Z",
    "resetAttempts": true,
    "reason": "El cliente pidió que lo llamen más tarde"
  }
  ```

  ```json identifier theme={null}
  {
    "identifier": "CLI-001",
    "scheduledAt": "2026-09-23T08:41:43.522Z",
    "resetAttempts": true,
    "reason": "El cliente pidió que lo llamen más tarde"
  }
  ```
</CodeGroup>

<Warning>
  No envíes `contactId` e `identifier` en la misma petición.
</Warning>


## OpenAPI

````yaml api-reference/dialer/openapi.yaml PUT /batches/{batchId}/contacts/schedule/
openapi: 3.1.0
info:
  title: AutoContact API
  version: final
  summary: Gestión de lotes de marcación automática y carga de contactos.
  description: >
    API de AutoContact: gestión de lotes de marcación automática y de los
    contactos que los integran.


    Todos los recursos se publican bajo `/autocontact/api/v1/`.


    ## Autenticación


    Las peticiones se autentican con el header `apikey`. La misma credencial
    permite operar los lotes

    de la cuenta a los que tenga acceso. El servicio deriva la cuenta de esa
    credencial y verifica que

    el recurso solicitado le pertenezca.


    Un lote que no pertenece a la cuenta responde `404`, igual que un lote
    inexistente.


    ## Operaciones asíncronas


    Algunas operaciones responden `202` en lugar de `200`: la petición se acepta
    y el trabajo continúa

    en segundo plano. Es el caso de la carga de contactos, el arranque y la
    eliminación de un lote.


    Esas respuestas incluyen un `operationId` que se consulta en

    `GET /batches/operations/{operationId}` para conocer el resultado.


    `POST /batches` no genera una operación: devuelve directamente el `batchId`,
    el estado `created` y

    el origen del lote, sin `operationId`.


    Tiempo de retención de las operaciones:


    | Tipo de operación | Disponible durante |

    |---|---|

    | Carga de contactos | 6 horas |

    | Ciclo de vida del lote (arranque, archivado, eliminación) | 1 hora, y 10
    minutos desde que finaliza |


    ## Reintentos seguros con `Idempotency-Key`


    Las operaciones de escritura aceptan el header opcional `Idempotency-Key`.
    Resuelve el caso en que

    se produce un error de red después de que la petición llegó al servicio: sin
    este header no es

    posible determinar si el trabajo se procesó, y reintentar podría duplicar
    llamadas telefónicas.


    Con el header, un reintento que use la misma clave y el mismo cuerpo
    devuelve la respuesta original

    sin procesar nada de nuevo. Las claves se conservan 24 horas.


    Recomendación de uso: generar un identificador único (por ejemplo un UUID)
    antes del primer intento

    y reutilizarlo solo en los reintentos de esa misma operación.


    Requisitos de la clave: entre 1 y 255 caracteres, solo ASCII imprimible. Una
    clave que no cumpla

    estos requisitos se rechaza con `400 INVALID_IDEMPOTENCY_KEY` en lugar de
    ignorarse, para evitar

    procesar la petición sin la protección que el cliente espera tener.


    ### Headers de respuesta


    | Header | Cuándo aparece | Significado |

    |---|---|---|

    | `Idempotency-Replayed: true` | En un reintento | La respuesta corresponde
    a la petición original; no se procesó de nuevo |

    | `Retry-After` | Junto a `409 IDEMPOTENCY_KEY_IN_FLIGHT` | Segundos a
    esperar antes de reintentar |

    | `Idempotency-Status: bypassed` | Excepcionalmente | La petición se procesó
    **sin** protección de idempotencia |


    El header `Idempotency-Status: bypassed` indica que el servicio de
    idempotencia no estaba

    disponible y la petición se procesó igualmente, para no interrumpir la
    operación. La respuesta es

    válida, pero esa petición concreta no quedó protegida: si no se recibe
    respuesta, se recomienda

    verificar el estado antes de reintentar.


    Las respuestas con error `5xx` no se almacenan, de modo que un reintento con
    la misma clave vuelve a

    procesar la petición.
servers:
  - url: https://api.backend.inconcertcc.com/autocontact/api/v1
    description: API de Inagent
security:
  - ApiKeyAuth: []
tags:
  - name: Lotes
    description: |
      Creación, consulta y control de lotes de marcación.
  - name: Contactos
    description: |
      Carga de contactos en un lote, reagendamiento y anulación.
  - name: Direcciones bloqueadas
    description: |
      Direcciones excluidas de la marcación en toda la cuenta.
  - name: Operaciones
    description: |
      Seguimiento de las operaciones asíncronas que devuelven `202`.
paths:
  /batches/{batchId}/contacts/schedule/:
    parameters:
      - $ref: '#/components/parameters/BatchId'
    put:
      tags:
        - Contactos
      summary: Reagenda un contacto ya cargado
      description: >
        Establece cuándo se volverá a intentar contactar con un contacto que ya
        está en el lote. Un caso

        habitual es que la persona atienda la llamada y solicite que se le
        contacte más tarde.


        El contacto se puede identificar mediante su `contactId` interno o
        mediante el `identifier`

        asignado en el sistema de origen. Debe enviarse exactamente uno de los
        dos campos.


        Acepta el header `Idempotency-Key`.


        ## Diferencia con el campo `scheduledAt` de la carga


        El campo `scheduledAt` de la carga de contactos programa el primer
        intento de un contacto nuevo.

        Esta operación reprograma un contacto ya cargado, en cualquier momento.


        ## Procesamiento


        La respuesta `200` confirma que la solicitud se ha aceptado. La
        reprogramación la aplica el motor

        de marcación, de modo que una consulta inmediatamente posterior puede no
        reflejar todavía la

        nueva fecha.


        ## Restricciones de la fecha


        `scheduledAt` debe tener formato ISO 8601, expresarse en UTC, ser una
        fecha futura y estar dentro

        de los próximos 30 días. Cada caso devuelve `400` con un mensaje que
        identifica el motivo.


        Si el contacto ya agotó sus intentos o ya fue contactado, envíe
        `resetAttempts: true`. Sin este

        campo la fecha se guarda, pero el contacto no vuelve a ponerse en
        marcación en esos casos.
      operationId: scheduleContact
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - scheduledAt
              properties:
                contactId:
                  type: string
                  format: uuid
                  description: >-
                    Identificador interno asignado por el servicio al importar
                    el contacto.
                  example: 7d2f8a1b-3c4e-4f50-9a6b-2c3d4e5f6a7b
                identifier:
                  type: string
                  description: Identificador del contacto en el sistema de origen.
                  example: CLI-001
                scheduledAt:
                  type: string
                  format: date-time
                  description: >
                    Fecha y hora del próximo intento. Debe ser futura y estar
                    dentro de los próximos 30

                    días.
                  example: '2026-09-23T08:41:43.522Z'
                resetAttempts:
                  type: boolean
                  description: >
                    Indica si se reinicia el contador de intentos al reagendar.
                    Es necesario para volver

                    a marcar un contacto que agotó sus intentos o que ya fue
                    contactado.
                  example: true
                reason:
                  type: string
                  description: >
                    Motivo de la reprogramación. Queda registrado a título
                    informativo y no afecta al

                    comportamiento de la marcación.
                  example: El cliente pidió que lo llamen más tarde
              oneOf:
                - required:
                    - contactId
                  not:
                    required:
                      - identifier
                - required:
                    - identifier
                  not:
                    required:
                      - contactId
            examples:
              porContactId:
                summary: Reagendar mediante el identificador interno
                value:
                  contactId: 7d2f8a1b-3c4e-4f50-9a6b-2c3d4e5f6a7b
                  scheduledAt: '2026-09-23T08:41:43.522Z'
                  resetAttempts: true
                  reason: El cliente pidió que lo llamen más tarde
              porIdentifier:
                summary: Reagendar mediante el identificador externo
                value:
                  identifier: CLI-001
                  scheduledAt: '2026-09-23T08:41:43.522Z'
                  resetAttempts: true
                  reason: El cliente pidió que lo llamen más tarde
      responses:
        '200':
          description: Reprogramación aceptada.
          headers:
            Idempotency-Replayed:
              $ref: '#/components/headers/IdempotencyReplayed'
            Idempotency-Status:
              $ref: '#/components/headers/IdempotencyStatus'
          content:
            application/json:
              schema:
                type: object
                required:
                  - contactId
                  - batchId
                  - scheduledAt
                  - scheduled
                properties:
                  contactId:
                    type: string
                    format: uuid
                  batchId:
                    type: string
                    format: uuid
                  scheduledAt:
                    type: string
                    format: date-time
                  scheduled:
                    type: boolean
                  reason:
                    type: string
              example:
                contactId: 7d2f8a1b-3c4e-4f50-9a6b-2c3d4e5f6a7b
                batchId: 3f8a1b2c-5d6e-4f70-8a9b-1c2d3e4f5a6b
                scheduledAt: '2026-09-23T08:41:43.522Z'
                scheduled: true
                reason: El cliente pidió que lo llamen más tarde
        '400':
          description: >
            Falta `scheduledAt`, la fecha no es válida, no es futura, supera los
            30 días, o la

            `Idempotency-Key` tiene un formato incorrecto.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/SimpleError'
                  - $ref: '#/components/schemas/IdempotencyKeyError'
              examples:
                faltante:
                  value:
                    message: >-
                      Missing or invalid required field: scheduledAt (ISO 8601
                      datetime string expected)
                formato:
                  value:
                    message: >-
                      Invalid date format: scheduledAt must be a valid ISO 8601
                      datetime
                pasado:
                  value:
                    message: 'Invalid date: scheduledAt must be a future date'
                fueraDeRango:
                  value:
                    message: 'Invalid date: scheduledAt must be within 30 days from now'
                claveInvalida:
                  summary: '`Idempotency-Key` mal formada'
                  value:
                    code: INVALID_IDEMPOTENCY_KEY
                    message: 'Invalid Idempotency-Key header: it must not be empty'
                    details:
                      - field: Idempotency-Key
                        code: EMPTY
                        reason: must not be empty
                    meta:
                      rejection: EMPTY
        '401':
          description: Credencial ausente o inválida.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimpleError'
              example:
                message: Unauthorized
        '404':
          description: El lote no existe o no pertenece a la cuenta.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimpleError'
              example:
                message: Batch not found
        '409':
          description: >
            Conflicto de idempotencia: hay una petición idéntica en proceso, o
            la clave se ha utilizado

            con un cuerpo distinto.
          headers:
            Retry-After:
              description: >
                Segundos a esperar antes de reintentar. Solo con
                `IDEMPOTENCY_KEY_IN_FLIGHT`.
              schema:
                type: integer
              example: 2
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdempotencyConflictError'
              examples:
                enVuelo:
                  value:
                    code: IDEMPOTENCY_KEY_IN_FLIGHT
                    message: >-
                      A request with this Idempotency-Key is still being
                      processed. Retry shortly.
                    meta:
                      retryAfterSeconds: 2
                claveReusada:
                  value:
                    code: IDEMPOTENCY_KEY_REUSED
                    message: >-
                      This Idempotency-Key was already used with a different
                      request body.
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    BatchId:
      name: batchId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Id del lote.
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 255
        pattern: ^[\x20-\x7E]+$
      description: >
        Clave para hacer el reintento seguro. Opcional.


        Un UUID por operación lógica, reusado en los reintentos de ese mismo
        envío. Ver "Reintentos

        seguros" en la descripción de la API.
      example: 3f8a1b2c-5d6e-4f70-8a9b-1c2d3e4f5a6b
  headers:
    IdempotencyReplayed:
      description: >
        Presente con valor `true` cuando la respuesta es una repetición de un
        request ya procesado con

        la misma clave. No se ejecutó nada nuevo.
      schema:
        type: string
        enum:
          - 'true'
    IdempotencyStatus:
      description: >
        Aparece con valor `bypassed` cuando se envió una clave válida pero la
        petición se procesó sin

        protección de idempotencia, porque el servicio que la gestiona no estaba
        disponible.


        La respuesta es válida, pero esa petición concreta no cuenta con la
        garantía de reintento seguro:

        si no se recibe respuesta, verifique el estado antes de reintentar.
      schema:
        type: string
        enum:
          - bypassed
  schemas:
    SimpleError:
      type: object
      required:
        - message
      description: >
        Error con mensaje descriptivo.


        Algunos traen `code` estable (los más nuevos); otros solo `message`.


        Los mensajes pueden aparecer en español o en inglés según el caso, y
        algunos errores todavía no

        incluyen `code`. Cuando esté presente, utilice `code` para tratar el
        error de forma programática.
      properties:
        code:
          type: string
          description: >
            Presente en los errores ya normalizados (`MISSING_PARAMETER`,
            `OPERATION_NOT_FOUND`,

            `VALIDATION_FAILED`, `INVALID_IDEMPOTENCY_KEY`, y los de
            idempotencia).
        message:
          type: string
    IdempotencyKeyError:
      type: object
      required:
        - code
        - message
      description: >
        La clave de idempotencia recibida no cumple los requisitos de formato.


        Se rechaza en lugar de ignorarse, para no procesar la petición sin la
        protección que el cliente

        espera tener.
      properties:
        code:
          type: string
          enum:
            - INVALID_IDEMPOTENCY_KEY
        message:
          type: string
        details:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                enum:
                  - Idempotency-Key
              code:
                type: string
                enum:
                  - EMPTY
                  - TOO_LONG
                  - INVALID_CHARACTERS
              reason:
                type: string
              meta:
                type: object
                additionalProperties: true
        meta:
          type: object
          description: >
            `rejection` es el dato estable para ramificar; el texto de `reason`
            es informativo.
          properties:
            rejection:
              type: string
              enum:
                - EMPTY
                - TOO_LONG
                - INVALID_CHARACTERS
          additionalProperties: true
    IdempotencyConflictError:
      type: object
      required:
        - code
        - message
      description: >
        Conflicto de idempotencia. Los dos casos se resuelven distinto:


        * `IDEMPOTENCY_KEY_IN_FLIGHT`: hay una petición idéntica en proceso.
        Espere el tiempo indicado en
          `Retry-After` y reintente con la misma clave.
        * `IDEMPOTENCY_KEY_REUSED`: la clave ya se utilizó con un cuerpo
        distinto. Utilice una clave nueva
          para la nueva petición.
      properties:
        code:
          type: string
          enum:
            - IDEMPOTENCY_KEY_IN_FLIGHT
            - IDEMPOTENCY_KEY_REUSED
        message:
          type: string
        meta:
          type: object
          additionalProperties: true
          properties:
            retryAfterSeconds:
              type: integer
  responses:
    InternalError:
      description: Error interno.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/SimpleError'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: apikey
      description: API key obtenida desde la interfaz de Inagent, dentro del marcador.

````