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

# Testar webhook

> Entrega **imediatamente** um evento `ping` para a `webhook_url` cadastrada, com a mesma autenticação
e a mesma assinatura (`X-Wincred-Signature`) das notificações reais, e devolve o resultado da tentativa.

- Não tem corpo de requisição (se você enviar um, ele é ignorado).
- A entrega é síncrona, **sem retentativa**, e não entra na fila nem no histórico de notificações.
  O `ping` não é um evento que se assine.
- Uma falha na entrega **não é erro desta rota**: a resposta é 200 com `delivered: false` e o motivo em `error`.
- Parceiro sem `webhook_url` cadastrada: 422 `WEBHOOK_NOT_CONFIGURED`.

É o **segundo passo** do teste de integração.




## OpenAPI

````yaml /api-do-parceiro/openapi.yaml post /webhooks/test
openapi: 3.1.0
info:
  title: API do Parceiro Wincred
  version: 1.0.0
  summary: Indique clientes, acompanhe a contratação e receba notificações por webhook.
  description: >
    API REST para parceiros comerciais indicarem clientes para o crédito
    consignado CLT

    da Wincred e acompanharem a contratação. A integração é de servidor para
    servidor e tem

    baixo acoplamento: o seu sistema indica o cliente e, a partir daí, atua como
    um ouvinte

    do que acontece na Wincred, por webhooks e por consulta, enquanto o cliente
    conduz a

    simulação e a contratação no link seguro da Wincred.


    O servidor publicado aqui é o **ambiente de dev**, o ambiente de testes do
    parceiro. O host

    de produção é enviado por e-mail na ativação. Antes da primeira indicação,
    siga o passo a passo

    de teste: `GET /ping`, `POST /webhooks/test` e uma indicação com dados
    sintéticos. O onboarding é

    assistido de ponta a ponta pelo time de integrações da Wincred.


    ## Convenções


    - **Base:** `<host>/partners/v1`. Só HTTPS. Corpo sempre JSON em UTF-8.

    - **Autenticação:** `Authorization: Bearer <chave do parceiro>`, com a chave
    entregue pela Wincred.

    - **Identificador de requisição:** envie `X-Request-Id` (até 64 caracteres,
    `[A-Za-z0-9_-]`);
      se faltar ou for inválido, geramos um. Ele volta no header `X-Request-Id` de toda resposta e no
      campo `request_id` de todo erro. Informe-o ao suporte: ele nos permite localizar a requisição rapidamente.
    - **Dinheiro:** string decimal com ponto, por exemplo `"5000.00"`. Nunca
    número JSON, para preservar a precisão.

    - **Datas e horas:** RFC 3339 com o fuso de São Paulo, por exemplo
    `2026-10-05T10:12:00-03:00`.
      Data de nascimento: `AAAA-MM-DD`.
    - **Enums:** minúsculas com sublinhado (`awaiting_client`).

    - **Evolução:** campo novo em resposta ou webhook não é quebra de contrato:
    ignore o que não conhece.
      Uma quebra de contrato dá origem a `/partners/v2`.
    - **Campo desconhecido na requisição é recusado** (400). Os nomes dos campos
    diferenciam maiúsculas de minúsculas.


    ## Ordem em que a API avalia a requisição


    Saber a ordem das verificações ajuda a interpretar o erro recebido.


    1. API desligada: 503 `SERVICE_UNAVAILABLE`, antes mesmo da autenticação.

    2. Corpo com `Content-Length` acima de 16 KB: 413 `PAYLOAD_TOO_LARGE`, antes
    da autenticação.

    3. Chave de API: 401 `UNAUTHENTICATED`.

    4. Limite de requisições por minuto: 429 `RATE_LIMITED`. Uma requisição
    inválida também consome o limite.

    5. Formato do corpo: 400 `INVALID_REQUEST` ou 422 `VALIDATION_FAILED`, sem
    criar processo.

    6. Regras que dependem do cadastro do parceiro (hub, faixa de valor, limite
    diário): 403, 422 ou 429.


    ## Limites


    | Limite | Valor |

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

    | Corpo da requisição | 16 KB (16384 bytes) |

    | Tempo máximo de processamento | 10 s; depois disso, 503
    `SERVICE_UNAVAILABLE` |

    | Requisições por minuto | Por parceiro, contado separadamente para `POST
    /referrals`, `GET /referrals/{process_external_id}`, `GET /ping` e `POST
    /webhooks/test`. Ao exceder: 429 com `Retry-After` |

    | Encerramentos sem contrato por CPF | Padrão 3 por CPF por dia,
    configurável por parceiro. Ao exceder: 429 `CPF_DAILY_LIMIT_REACHED` |


    ## Respostas fora do envelope


    Por segurança, a API aceita chamadas apenas dos IPs que o parceiro informou
    à Wincred (allowlist de entrada).

    Uma chamada de um IP fora da lista é bloqueada na camada de gateway/WAF,
    antes de chegar à API, e por isso

    recebe 403 **sem** o envelope de erro. Fale com o time de integrações para
    liberar o IP.
  contact:
    name: Integrações Wincred
servers:
  - url: https://orchestrator-partner.dev.wincred.digital/partners/v1
    description: >-
      Dev, o ambiente de testes do parceiro. O host de produção é enviado por
      e-mail na ativação.
security:
  - bearerAuth: []
tags:
  - name: Webhooks
    description: >-
      Notificações que a Wincred envia para a webhook_url do parceiro a cada
      etapa da indicação.
  - name: Indicações
    description: Criar a indicação de um cliente e consultar o andamento do processo.
  - name: Teste de integração
    description: Rotas para validar a chave e o webhook antes da primeira indicação real.
paths:
  /webhooks/test:
    post:
      tags:
        - Teste de integração
      summary: Testar webhook
      description: >
        Entrega **imediatamente** um evento `ping` para a `webhook_url`
        cadastrada, com a mesma autenticação

        e a mesma assinatura (`X-Wincred-Signature`) das notificações reais, e
        devolve o resultado da tentativa.


        - Não tem corpo de requisição (se você enviar um, ele é ignorado).

        - A entrega é síncrona, **sem retentativa**, e não entra na fila nem no
        histórico de notificações.
          O `ping` não é um evento que se assine.
        - Uma falha na entrega **não é erro desta rota**: a resposta é 200 com
        `delivered: false` e o motivo em `error`.

        - Parceiro sem `webhook_url` cadastrada: 422 `WEBHOOK_NOT_CONFIGURED`.


        É o **segundo passo** do teste de integração.
      operationId: sendTestWebhook
      parameters:
        - $ref: '#/components/parameters/XRequestId'
      responses:
        '200':
          description: Resultado da tentativa de entrega.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookTestResult'
              examples:
                entregue:
                  value:
                    event_id: 7d0f3a6e-2b1c-4d5e-8f90-1a2b3c4d5e6f
                    delivered: true
                    http_status: 200
                    error: null
                    duration_ms: 120
                timeout:
                  value:
                    event_id: 0b9f3c2e-6d1a-4e8b-9c7d-2a4f6e8b0c1d
                    delivered: false
                    http_status: null
                    error: timeout
                    duration_ms: 5000
                erro-de-tls:
                  value:
                    event_id: 1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f
                    delivered: false
                    http_status: null
                    error: tls_error
                    duration_ms: 30
                resposta-fora-de-2xx:
                  summary: Seu endpoint respondeu 404
                  value:
                    event_id: 2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f6a
                    delivered: false
                    http_status: 404
                    error: http_status
                    duration_ms: 80
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '422':
          description: >-
            O parceiro ainda não tem `webhook_url` cadastrada. Fale com o time
            de integrações.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                sem-webhook:
                  value:
                    error:
                      code: WEBHOOK_NOT_CONFIGURED
                      message: Webhook não configurado.
                      request_id: req-rest
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    XRequestId:
      name: X-Request-Id
      in: header
      required: false
      description: >
        Identificador da requisição, até 64 caracteres `[A-Za-z0-9_-]`. Se
        faltar ou for inválido, a Wincred gera um.

        Volta no header `X-Request-Id` da resposta e no `request_id` de todo
        erro.
      schema:
        type: string
        pattern: ^[A-Za-z0-9_-]{1,64}$
      example: meu-teste-001
  headers:
    XRequestId:
      description: >-
        O `X-Request-Id` que você enviou (se válido) ou o que a Wincred gerou.
        Informe-o ao suporte.
      schema:
        type: string
        pattern: ^[A-Za-z0-9_-]{1,64}$
    RetryAfter:
      description: Segundos de espera antes de tentar novamente.
      schema:
        type: integer
        minimum: 1
  schemas:
    WebhookTestResult:
      type: object
      required:
        - event_id
        - delivered
        - http_status
        - error
        - duration_ms
      properties:
        event_id:
          type: string
          description: >-
            Identificador do `ping` enviado (o mesmo que o seu endpoint recebeu
            em `X-Wincred-Event-Id`).
        delivered:
          type: boolean
          description: '`true` quando o seu endpoint respondeu 2xx.'
        http_status:
          type:
            - integer
            - 'null'
          description: >-
            Status HTTP da sua resposta. `null` quando não houve resposta
            (timeout, conexão ou TLS).
        error:
          type:
            - string
            - 'null'
          enum:
            - timeout
            - connection_error
            - tls_error
            - http_status
            - null
          description: >
            `null` quando entregou. `timeout`: o seu endpoint não respondeu
            dentro do prazo; `connection_error`: não foi possível conectar

            (inclui nome de host que não resolve); `tls_error`: falha de
            certificado ou handshake;

            `http_status`: respondeu fora de 2xx (veja `http_status`).
        duration_ms:
          type: integer
          format: int64
          description: Duração da tentativa, em milissegundos.
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    Error:
      type: object
      required:
        - code
        - message
        - request_id
      description: >-
        Envelope de erro. Programe contra `code`; a `message` é um texto fixo
        por código e pode mudar de redação.
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          description: Texto fixo em português para cada `code`.
        request_id:
          type: string
          description: O mesmo valor do header `X-Request-Id`. Informe-o ao suporte.
        details:
          type: array
          description: >
            Presente só quando o erro aponta campos: 422 `VALIDATION_FAILED`
            gerado na borda e 400 `INVALID_REQUEST`

            quando o campo é localizável (tipo errado, campo desconhecido, campo
            duplicado).
          items:
            $ref: '#/components/schemas/ErrorDetail'
        retry_after:
          type: string
          format: date-time
          description: >-
            Só em `CPF_DAILY_LIMIT_REACHED`: a próxima meia-noite de São Paulo,
            RFC 3339. O `Retry-After` (segundos) vem no header.
    ErrorCode:
      type: string
      description: >
        | HTTP | `code` | Quando | O que fazer |

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

        | 400 | `INVALID_REQUEST` | JSON malformado, tipo errado, campo
        desconhecido, `Content-Type` errado, id que não é UUID | Corrija; não
        repita igual |

        | 401 | `UNAUTHENTICATED` | Chave ausente, malformada, inválida ou
        revogada | Confira a chave |

        | 403 | `HUB_INACTIVE` | Hub desligado | Não repita |

        | 404 | `REFERRAL_NOT_FOUND` | Processo inexistente ou de outro parceiro
        | Confira o id |

        | 413 | `PAYLOAD_TOO_LARGE` | Corpo acima de 16 KB | Corrija |

        | 422 | `VALIDATION_FAILED` | Formato de dado do cliente, valor ou
        prazo, ou campo obrigatório ausente | Corrija pelos `details` |

        | 422 | `LOAN_REQUEST_INVALID` | Valor ou prazo fora da faixa do hub |
        Ajuste pela faixa de `GET /ping` |

        | 422 | `HUB_NOT_FOUND` | `hub_code` inexistente ou de outro parceiro |
        Corrija |

        | 422 | `WEBHOOK_NOT_CONFIGURED` | `POST /webhooks/test` sem
        `webhook_url` cadastrada | Fale com a Wincred |

        | 429 | `RATE_LIMITED` | Limite por minuto do parceiro | Espere o
        `Retry-After` |

        | 429 | `CPF_DAILY_LIMIT_REACHED` | Limite diário de indicações sem
        sucesso do CPF | Não repita antes de `retry_after` |

        | 500 | `INTERNAL_ERROR` | Erro nosso | Repita com espera |

        | 503 | `SERVICE_UNAVAILABLE` | API desligada, serviço fora do ar ou
        tempo máximo de 10 s | Repita com espera |
      enum:
        - INVALID_REQUEST
        - UNAUTHENTICATED
        - HUB_INACTIVE
        - REFERRAL_NOT_FOUND
        - PAYLOAD_TOO_LARGE
        - VALIDATION_FAILED
        - LOAN_REQUEST_INVALID
        - HUB_NOT_FOUND
        - WEBHOOK_NOT_CONFIGURED
        - RATE_LIMITED
        - CPF_DAILY_LIMIT_REACHED
        - INTERNAL_ERROR
        - SERVICE_UNAVAILABLE
    ErrorDetail:
      type: object
      required:
        - field
        - reason
      properties:
        field:
          type: string
          description: >-
            Caminho do campo com pontos, por exemplo
            `customer.address.zip_code`.
          example: customer.cpf
        reason:
          type: string
          description: >
            | `reason` | Significado |

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

            | `REQUIRED` | Campo obrigatório ausente ou vazio |

            | `INVALID_FORMAT` | Formato ou tipo inválido |

            | `INVALID_CHECK_DIGIT` | CPF com dígito verificador inválido ou
            dígitos repetidos |

            | `OUT_OF_RANGE` | Fora do tamanho ou da faixa permitida |

            | `NOT_ALLOWED` | Valor bem formado, mas não aceito (por exemplo,
            código de país diferente de 55) |

            | `UNKNOWN_FIELD` | Campo que a API não conhece |
          enum:
            - REQUIRED
            - INVALID_FORMAT
            - INVALID_CHECK_DIGIT
            - OUT_OF_RANGE
            - NOT_ALLOWED
            - UNKNOWN_FIELD
  responses:
    Unauthenticated:
      description: Chave de API ausente, malformada, inválida ou revogada. Confira a chave.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            sem-chave:
              value:
                error:
                  code: UNAUTHENTICATED
                  message: Chave de API ausente, inválida ou revogada.
                  request_id: 0b9f3c2e-6d1a-4e8b-9c7d-2a4f6e8b0c1d
    RateLimited:
      description: >-
        Excedeu o limite por minuto. Aguarde o `Retry-After` (segundos). O corpo
        não traz `retry_after`.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            limite-por-minuto:
              value:
                error:
                  code: RATE_LIMITED
                  message: Limite de requisições excedido.
                  request_id: req-rate
    InternalError:
      description: >-
        Erro interno da Wincred. Repita com espera; `POST /referrals` é seguro
        de repetir. Se persistir, informe o `request_id` ao time de integrações.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            erro-interno:
              value:
                error:
                  code: INTERNAL_ERROR
                  message: Erro interno.
                  request_id: req-rest
    ServiceUnavailable:
      description: >
        API desligada, serviço da Wincred fora do ar ou tempo máximo de 10 s
        excedido.

        Repita com espera.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            indisponivel:
              value:
                error:
                  code: SERVICE_UNAVAILABLE
                  message: Serviço indisponível.
                  request_id: 0b9f3c2e-6d1a-4e8b-9c7d-2a4f6e8b0c1d
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Chave de API do parceiro, entregue pelo time de integrações da Wincred.
        Header:

        `Authorization: Bearer <chave do parceiro>` (o esquema `Bearer` não
        diferencia maiúsculas).

        Por segurança, chave ausente, malformada, inválida ou revogada recebem a
        mesma resposta: 401 `UNAUTHENTICATED`.

        Guarde a chave apenas no servidor e solicite a rotação ao time de
        integrações quando precisar trocá-la.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.