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

# Cadastro de Certificado Digital

> Cadastre um certificado digital A1 (.pfx / .p12) como credencial no Cofre. Esta é a única rota que aceita upload de certificado.

<Warning>
  O certificado **não** pode ser enviado pela rota `POST /credentials`. Campos de certificado dentro de `custom_data` são recusados com o erro `CERTIFICATE_FIELDS_NOT_ALLOWED`.
</Warning>

<ParamField body="file_base64" type="string" required>
  Conteúdo do arquivo `.pfx` / `.p12` (PKCS#12) convertido para Base64, em **uma única linha**, sem quebras. Arquivo com no máximo 64 KB.
</ParamField>

<ParamField body="password" type="string" required>
  Senha do arquivo `.pfx`. Não é a senha do portal do tribunal.
</ParamField>

<ParamField body="system_name" type="string">
  Sistema e tribunal em que o certificado será usado, por exemplo `ESAJ - TJSP - 1º grau`. Use `*` para cadastrar como credencial coringa.
</ParamField>

<ParamField body="customer_key" type="string">
  Identificador da credencial definido por você. Se omitido, é usado o valor padrão `*`.
</ParamField>

<ParamField body="custom_data" type="object">
  Dados extras da credencial. Envie apenas quando o tribunal também exigir autenticação em dois fatores.

  <Expandable title="properties">
    <ParamField body="secret" type="string">
      Segredo 2FA (`secret`) — a chave **fixa** de configuração do aplicativo autenticador, nunca o código temporário de 6 dígitos.
    </ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --location 'https://crawler.prod.judit.io/credentials/certificate' \
  --header 'api-key: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "customer_key": "teste",
    "system_name": "ESAJ - TJSP - 1º grau",
    "file_base64": "<conteudo-do-pfx-em-base64>",
    "password": "123456"
  }'
  ```

  ```bash cURL com 2FA theme={null}
  curl --location 'https://crawler.prod.judit.io/credentials/certificate' \
  --header 'api-key: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "customer_key": "teste",
    "system_name": "ESAJ - TJSP - 1º grau",
    "file_base64": "<conteudo-do-pfx-em-base64>",
    "password": "123456",
    "custom_data": {
      "secret": "JBSWY3DPEHPK3PXP"
    }
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
  	"message": "CERTIFICATE_CREATED",
  	"customer_key": "teste",
  	"subject_cn": "NOME DO TITULAR:12345678909",
  	"not_after": "2027-01-01T00:00:00.000Z",
  	"uploaded_at": "2026-07-31T17:00:00.000Z"
  }
  ```
</ResponseExample>

**Se já existir um certificado do mesmo titular nessa credencial, a mensagem será `CERTIFICATE_UPDATED` e o certificado anterior é descartado.**

<Accordion title="Erros possíveis">
  | Código                        | HTTP | Quando acontece                                                                              |
  | :---------------------------- | :--- | :------------------------------------------------------------------------------------------- |
  | `PFX_MALFORMED`               | 400  | Base64 inválido ou arquivo PFX corrompido                                                    |
  | `PFX_PASSWORD_INVALID`        | 400  | Senha do arquivo incorreta                                                                   |
  | `PFX_NO_PRIVATE_KEY`          | 400  | Arquivo sem chave privada                                                                    |
  | `PFX_NO_CERTIFICATE`          | 400  | Arquivo sem certificado                                                                      |
  | `PFX_EXPIRED`                 | 400  | Certificado vencido                                                                          |
  | `PFX_NOT_YET_VALID`           | 400  | Certificado ainda não vigente                                                                |
  | `PFX_TOO_LARGE`               | 400  | Arquivo maior que 64 KB                                                                      |
  | `CERTIFICATE_HOLDER_MISMATCH` | 409  | Novo certificado pertence a outro titular (CPF/CN)                                           |
  | `CREDENTIAL_TYPE_CONFLICT`    | 409  | Já existe credencial de usuário/senha para a mesma combinação de credencial e `customer_key` |
</Accordion>

Guia completo, com conversão do arquivo para Base64 e passo a passo no Postman: [Cofre de Credenciais — certificado digital](/essentials/cofre-de-credenciais#cadastro-de-credencial-com-certificado-digital-a1).


## OpenAPI

````yaml openapi/vault.json POST /credentials/certificate
openapi: 3.0.3
info:
  title: JUDIT - Credentials Vault API
  description: >-
    OpenAPI description for the credentials vault routes, used to register and
    inspect per-tribunal system credentials. Mirrored locally so this page's
    playground exposes exactly one base URL (no other Judit service host).
    Transcribed from the fields already documented on the vault/vault and
    vault/vaultcreate pages.
  version: 1.0.0
servers:
  - url: https://crawler.prod.judit.io
    description: Production server
security:
  - ApiKeyAuth: []
tags:
  - name: Credentials
    description: Register and inspect tribunal system credentials stored in the vault
paths:
  /credentials/certificate:
    post:
      tags:
        - Credentials
      summary: Register or update a digital certificate credential
      description: >-
        Uploads an A1 digital certificate (PKCS#12 `.pfx` / `.p12`, max 64 KB)
        as a credential in the vault. This is the only route that accepts
        certificate upload — sending certificate fields to `POST /credentials`
        returns `CERTIFICATE_FIELDS_NOT_ALLOWED`. When the court also requires
        two-factor authentication, send the 2FA setup key in
        `custom_data.secret` in this same payload.
      operationId: postCredentialsCertificate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - file_base64
                - password
              properties:
                file_base64:
                  type: string
                  description: PFX/P12 file content encoded as a single-line Base64 string
                password:
                  type: string
                  description: Password of the PKCS#12 file (not the court portal password)
                system_name:
                  type: string
                  description: e.g. "ESAJ - TJSP - 1º grau" or `*` (wildcard)
                customer_key:
                  type: string
                  description: >-
                    Client-defined identifier for the credential. Defaults to
                    `*`
                custom_data:
                  type: object
                  description: >-
                    Extra credential data. Only required when the court also
                    enforces two-factor authentication.
                  properties:
                    secret:
                      type: string
                      description: >-
                        2FA secret — the fixed authenticator setup key, never
                        the temporary 6-digit code
            example:
              customer_key: teste
              system_name: ESAJ - TJSP - 1º grau
              file_base64: MIIK...
              password: '123456'
              custom_data:
                secret: JBSWY3DPEHPK3PXP
      responses:
        '200':
          description: Certificate created or updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    enum:
                      - CERTIFICATE_CREATED
                      - CERTIFICATE_UPDATED
                  customer_key:
                    type: string
                  subject_cn:
                    type: string
                    description: Certificate holder (CN)
                  not_after:
                    type: string
                    format: date-time
                    description: Certificate expiration date
                  uploaded_at:
                    type: string
                    format: date-time
              example:
                message: CERTIFICATE_CREATED
                customer_key: teste
                subject_cn: NOME DO TITULAR:12345678909
                not_after: '2027-01-01T00:00:00.000Z'
                uploaded_at: '2026-07-31T17:00:00.000Z'
        '400':
          description: >-
            Invalid certificate file. Possible codes: `PFX_MALFORMED`,
            `PFX_PASSWORD_INVALID`, `PFX_NO_PRIVATE_KEY`, `PFX_NO_CERTIFICATE`,
            `PFX_EXPIRED`, `PFX_NOT_YET_VALID`, `PFX_TOO_LARGE`
        '409':
          description: >-
            Conflict. Possible codes: `CERTIFICATE_HOLDER_MISMATCH`,
            `CREDENTIAL_TYPE_CONFLICT`
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api-key
      description: API key for authentication

````