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

# Verificar um certificado

> A rota anônima que responde se um certificado é verdadeiro.

**Anônima.** É a rota de quem recebeu um certificado e quer conferir: um empregador, uma escola,
um conselho profissional. O código impresso é a credencial — ele tem aleatoriedade suficiente
para não ser adivinhado e não aparece em nenhuma listagem pública.

Aceita o código como está impresso (em grupos de quatro) ou corrido, em maiúsculas ou
minúsculas.

Certificado **revogado** responde 200 com `revoked: true`, e não 404: quem confere precisa da
diferença entre "não existe" e "foi cancelado". Titular removido do club responde 200 com
`holder_removed: true` e sem o nome.

```bash theme={null}
curl https://api.weve.cx/v1/certificates/4K7P-2QX9-8MHT
```


## OpenAPI

````yaml GET /v1/certificates/{code}
openapi: 3.0.3
info:
  title: weve API
  description: >
    Contrato entre a API Go e o dashboard. **Este arquivo é a fonte de
    verdade**:

    os tipos e a interface de servidor em Go, e o client TypeScript, são todos

    gerados daqui (`make openapi`). Handler que divergir da interface não
    compila.


    A superfície interna (`/internal/*`) fica de fora de propósito: é acesso de

    máquina, protegido por segredo dedicado, e não é contrato de cliente.
  version: 0.2.0
servers:
  - url: https://api.weve.cx
    description: produção
  - url: http://localhost:8080
    description: desenvolvimento
security: []
tags:
  - name: health
  - name: session
  - name: account
  - name: clubs
  - name: members
  - name: webhooks
  - name: outgoing-webhooks
  - name: sales-platforms
  - name: catalog
  - name: content
  - name: classroom
  - name: community
  - name: mentorships
  - name: agents
  - name: lives
  - name: students
  - name: auth
  - name: campaigns
  - name: workflows
  - name: email
  - name: exports
  - name: certificates
paths:
  /v1/certificates/{code}:
    parameters:
      - $ref: '#/components/parameters/CertificateCode'
    get:
      tags:
        - certificates
      summary: Verifica um certificado por código
      description: |
        **Anônima.** É a rota que responde a quem recebeu um certificado e quer
        saber se ele é verdadeiro — um empregador, uma escola, um conselho
        profissional. O código impresso no certificado É a credencial: ele tem
        aleatoriedade suficiente para não ser adivinhado, e não aparece em
        nenhuma listagem pública.

        O código é aceito como está impresso (em grupos de quatro) ou corrido,
        em maiúsculas ou minúsculas.

        Certificado REVOGADO responde 200 com `revoked: true` e a data — não
        404: um código que some é indistinguível de um erro nosso, e quem está
        conferindo precisa da diferença entre "não existe" e "foi cancelado".

        Aluno removido do club responde 200 com `holder_removed: true` e sem o
        nome: a remoção não pode ser anulada por esta página.

        Tem teto próprio por IP — é a única leitura anônima que fala de uma
        pessoa nomeada.
      operationId: verifyCertificate
      responses:
        '200':
          description: O certificado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertificateVerification'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    CertificateCode:
      name: code
      in: path
      required: true
      description: |
        O código do certificado, como está impresso (em grupos de quatro) ou
        corrido, em maiúsculas ou minúsculas.
      schema:
        type: string
        minLength: 8
        maxLength: 40
  schemas:
    CertificateVerification:
      type: object
      required:
        - code
        - code_formatted
        - course_title
        - club_name
        - lesson_count
        - issued_at
        - completed_at
        - revoked
        - holder_removed
      description: |
        O que a página pública mostra a quem confere um código. Não traz id de
        aluno, de curso nem e-mail: quem verifica precisa saber se o documento é
        verdadeiro, e nada além disso.
      properties:
        code:
          type: string
        code_formatted:
          type: string
        student_name:
          type: string
          nullable: true
          description: Nulo quando o titular foi removido do club.
        course_title:
          type: string
        club_name:
          type: string
        club_slug:
          type: string
          nullable: true
          description: O subdomínio do club, para a página se vestir com a marca dele.
        hours:
          type: integer
          nullable: true
        lesson_count:
          type: integer
        issued_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        revoked:
          type: boolean
          description: |
            Certificado revogado responde 200 com este campo verdadeiro, e não
            404: quem confere precisa da diferença entre "não existe" e "foi
            cancelado".
        revoked_at:
          type: string
          format: date-time
          nullable: true
        holder_removed:
          type: boolean
          description: |
            O titular pediu para ser removido do club. O certificado continua
            existindo como fato, e o nome não é mais mostrado — esta página não
            pode anular uma remoção.
    ErrorEnvelope:
      type: object
      description: >-
        Envelope único de erro da API. O `code` é o contrato com o cliente — a
        `message` é diagnóstico, e pode mudar.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
          properties:
            code:
              type: string
            message:
              type: string
  responses:
    NotFound:
      description: Recurso não encontrado
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    TooManyRequests:
      description: Teto por IP atingido
      headers:
        Retry-After:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: >-
        Falha inesperada. O corpo nunca traz o erro real — ele fica no log e no
        rastreamento.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'

````

## Related topics

- [Ver um certificado](/api-reference/certificates/get.md)
- [Revogar um certificado](/api-reference/certificates/revoke.md)
- [Reemitir um certificado](/api-reference/certificates/reissue.md)
- [Baixar o PDF de um certificado](/api-reference/certificates/download.md)
- [Listar certificados](/api-reference/certificates/list.md)
