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

# Resolver un paso

> Aprueba, clasifica o etiqueta un documento desde tu integración, a nombre de un miembro de tu compañía.

Envía una de las opciones que devolvió [Paso actual de un documento](/api-reference/workflow-steps/current) y Payana avanza el flujo.

<Info>
  No envíes ramas del flujo ni estados internos: envía un `value` de `decision.options`. Payana lo traduce a lo que el paso necesita — la rama, la etiqueta, el valor del campo.
</Info>

## A nombre de quién

<Warning>
  `acting_user_email` es obligatorio, y debe ser uno de los `assignees` del paso.

  Tu `api-key` identifica a tu compañía, no a una persona. Como una aprobación queda registrada a nombre de alguien, debes indicar de quién: no existe un "usuario del sistema" al que atribuirla.
</Warning>

El registro de actividad del documento deja constancia de que la decisión entró por integración, además de a nombre de quién — así queda distinguible de esa persona actuando desde Payana.

<Steps>
  <Step title="Consulta el paso">
    `GET /workflow-steps/current?entity_reference=…` te da la referencia del paso, sus opciones y sus `assignees`.
  </Step>

  <Step title="Elige una opción y quién decide">
    Un `value` de `options` (o varios, si `multiple` es `true`), y el email de un `assignee`.
  </Step>

  <Step title="Envía la decisión">
    `POST /workflow-steps/{reference}/complete`.

    <Check>
      Un `200` con `status: completed` significa que el paso se resolvió y el flujo avanzó.
    </Check>
  </Step>
</Steps>

## Cuando faltan otros

<Note>
  Si el paso exige que decidan **todos** sus responsables, la respuesta vuelve con `status: pending`. No es un error: tu decisión quedó registrada y el paso espera a los demás. Consulta `GET /workflow-steps/current` para ver quiénes faltan en `assignees` (`acted: false`).
</Note>

## Errores frecuentes

<AccordionGroup>
  <Accordion title="403 · not_assigned">
    El miembro que indicaste no está habilitado para ese paso. Consulta `assignees` antes de decidir; la lista cambia si reconfiguran el flujo.
  </Accordion>

  <Accordion title="409 · step_not_pending">
    Alguien más ya lo resolvió, desde Payana o desde otra llamada. Vuelve a consultar el paso actual del documento.
  </Accordion>

  <Accordion title="422 · invalid_decision">
    El valor no está entre los que el paso ofrece. En etiquetado sin restricción (`options_complete: false`) también se rechaza una etiqueta que no exista en tu compañía.
  </Accordion>

  <Accordion title="422 · unsupported_step">
    El paso no se decide desde esta API — está en manos de un agente, o su acción se resuelve por otra vía. `GET /workflow-steps/current` lo anticipa con `actionable: false`.
  </Accordion>
</AccordionGroup>

<CardGroup cols={2}>
  <Card title="Paso actual de un documento" icon="magnifying-glass" href="/api-reference/workflow-steps/current">
    De dónde salen las opciones que envías aquí.
  </Card>

  <Card title="Aprobar documento" icon="check" href="/api-reference/documents/approve">
    Aprobación directa, sin pasar por el flujo.
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /workflow-steps/{reference}/complete
openapi: 3.1.0
info:
  title: Payana Accounts Payable API
  description: >-
    API pública para gestionar cuentas por pagar (payments) y beneficiarios
    (beneficiaries) en Payana, incluyendo notificaciones por webhooks cuando se
    procesan pagos.
  version: 1.0.0
servers:
  - url: https://api.prod.payana.cloud/public/api/v1
    description: Production
  - url: https://api.develop.payana.cloud/public/api/v1
    description: Develop
security:
  - apiKeyAuth: []
tags:
  - name: Payments
    description: Crear y listar pagos
  - name: Beneficiaries
    description: Crear, listar y consultar beneficiarios
  - name: Webhooks
    description: Eventos de webhooks enviados por Payana
  - name: Banks
    description: Listar y consultar bancos
  - name: Transactions In
    description: Transacciones entrantes (polling, mismo formato que webhooks)
  - name: Documents
    description: Listar, consultar y operar documentos (cuentas por pagar)
  - name: DIAN Events
    description: >-
      Encolar eventos DIAN (030 Acuse de recibo, 031 Reclamo, 032 Recibo del
      bien, 033 Aceptación expresa, 034 Aceptación tácita) para documentos
      identificados por CUFE. El procesamiento es asíncrono.
  - name: Fiscal Sync
    description: >-
      Disparar y consultar sincronización de documentos fiscales desde el SAT
      (México) o la DIAN (Colombia).
  - name: Workflow Steps
    description: >-
      Resolver el paso en que está parado un documento dentro de su flujo:
      aprobación, clasificación o etiquetado.
paths:
  /workflow-steps/{reference}/complete:
    post:
      tags:
        - Workflow Steps
      summary: Resolver un paso
      description: >-
        Resuelve el paso con la decisión del cuerpo. Envía uno de los
        `decision.options[].value` que devolvió `GET /workflow-steps/current`;
        Payana deriva la rama del flujo y el efecto correspondiente.


        - **`acting_user_email` es obligatorio.** La `api-key` identifica a tu
        compañía, no a una persona: la decisión se registra a nombre del miembro
        que indiques, y ese miembro debe estar en `assignees`.

        - Si el paso exige que decidan todos sus responsables, la respuesta
        puede volver con `status: pending`: tu decisión quedó registrada y
        faltan las demás.

        - El registro de actividad del documento deja constancia de que la
        decisión entró por integración, además de a nombre de quién.
      parameters:
        - name: reference
          in: path
          required: true
          description: >-
            Referencia del paso, tal como la devuelve `GET
            /workflow-steps/current`.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompleteWorkflowStepRequest'
            examples:
              aprobar:
                summary: Aprobar
                value:
                  decision: approve
                  acting_user_email: ana@acme.co
              rechazar:
                summary: Rechazar con motivo
                value:
                  decision: reject
                  comment: Falta el soporte de la factura
                  acting_user_email: ana@acme.co
              clasificar:
                summary: Clasificar
                value:
                  decision: '451'
                  acting_user_email: ana@acme.co
              etiquetar:
                summary: Etiquetar (varias)
                value:
                  decision:
                    - '88'
                    - '91'
                  acting_user_email: ana@acme.co
      responses:
        '200':
          description: Paso resuelto, o decisión registrada a la espera de las demás
          content:
            application/json:
              schema:
                type: object
                properties:
                  step:
                    $ref: '#/components/schemas/WorkflowStepCompletionView'
              example:
                step:
                  reference: 550e8400-e29b-41d4-a716-446655440042
                  action: document.approval
                  status: completed
                  completed_at: '2026-08-05T14:03:11.000Z'
                  decision:
                    kind: approval
                    values:
                      - approve
                    labels:
                      - Aprobar
                  acted_by:
                    email: ana@acme.co
                    name: Ana Gómez
        '400':
          description: >-
            Cuerpo o referencia inválidos (`invalid_input`), o
            `acting_user_email` que no es miembro de tu compañía
            (`acting_user_not_found_in_company`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowStepError'
        '401':
          description: Header `api-key` ausente o inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowStepError'
        '403':
          description: >-
            El miembro indicado no está asignado al paso (`not_assigned`), o tu
            compañía no tiene habilitada esta API (`feature_not_enabled`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowStepError'
        '404':
          description: El paso no existe en tu compañía (`step_not_found`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowStepError'
        '409':
          description: El paso ya no está pendiente (`step_not_pending`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowStepError'
        '422':
          description: >-
            El paso no admite decisión por esta API (`unsupported_step`), o el
            valor no está entre los ofrecidos (`invalid_decision`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowStepError'
components:
  schemas:
    CompleteWorkflowStepRequest:
      type: object
      required:
        - decision
        - acting_user_email
      properties:
        decision:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
          description: >-
            Uno de los `decision.options[].value` del paso; una lista cuando
            `decision.multiple` es `true`. No es una rama del motor: la rama la
            deriva Payana del contrato de la acción.
          example: approve
        comment:
          type: string
          maxLength: 2000
          description: Motivo libre que queda registrado con la completación.
        acting_user_email:
          type: string
          format: email
          description: >-
            El miembro de tu compañía a nombre de quien se registra la decisión.
            **Obligatorio**: la `api-key` identifica a la compañía, no a una
            persona. Debe estar en `assignees`.
    WorkflowStepCompletionView:
      type: object
      required:
        - reference
        - action
        - status
        - completed_at
        - decision
        - acted_by
      properties:
        reference:
          type: string
          format: uuid
        action:
          type: string
          nullable: true
        status:
          type: string
          description: >-
            Queda `pending` cuando el paso exige que decidan todos sus
            responsables y aún faltan: tu decisión quedó registrada.
          example: completed
        completed_at:
          type: string
          format: date-time
          nullable: true
        decision:
          type: object
          properties:
            kind:
              type: string
              enum:
                - approval
                - classification
                - tagging
            values:
              type: array
              items:
                type: string
            labels:
              type: array
              items:
                type: string
        acted_by:
          type: object
          properties:
            email:
              type: string
              nullable: true
            name:
              type: string
              nullable: true
    WorkflowStepError:
      type: object
      required:
        - status
        - code
        - message
      description: >-
        Error de los endpoints de workflow steps. `code` es un token estable en
        snake_case; `message` es texto para humanos y puede cambiar.
      properties:
        status:
          type: integer
          example: 422
        code:
          type: string
          example: invalid_decision
        message:
          type: string
          example: 'Decision value not offered by this step: maybe'
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: api-key
      description: API key provista por Payana.

````