> ## 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.

# Credentials Vault for Courts

> Register, query, update and delete lawyer credentials for courts securely on the Judit API. Access lawsuits under secrecy and sources that require login.

export const VaultAnimation = () => <iframe sandbox="allow-scripts" scrolling="no" style={{
  width: '100%',
  height: '540px',
  border: 'none',
  borderRadius: '12px',
  display: 'block',
  margin: '20px 0'
}} srcDoc={`<!doctype html><html><head><meta charset="utf-8"><style>*{margin:0;padding:0;box-sizing:border-box}html,body{width:100%;height:100%;overflow:hidden;background:#090c0d}canvas{display:block;width:100%;height:100%}</style></head><body><canvas id="c"></canvas><script>(function(){
var A='#4FD1C5',J='#1FC16B',T='#E0A82E',P='#C084FC',M='#7A8599';
var BG='#090c0d',TXT='#e5e7eb',NF='#111827',PT2='#0a1020';
var TOTAL=30.0;
var XP={cli:0.09,judit:0.38,cofre:0.65,court:0.90};
var NW=86,NH=42;
var FLOWS=[
  {id:'reg',title:'① Credential Registration',sub:'Configure once per court',col:A,ts:1,te:14,act:['cli','cofre','court'],steps:[
    {fr:'cli',to:'court',label:'validates credential',note:'creates user/password in the portal',col:T,ts:1.5,te:2.3,yp:0.35},
    {fr:'cli',to:'cofre',label:'POST /credentials',note:'{system_name, customer_key, password}',col:P,ts:3.2,te:4.0,yp:0.52},
    {fr:'cofre',to:'cli',label:'CREDENTIAL_CREATED',note:'encrypted credential',col:P,ts:4.5,te:5.3,yp:0.68}]},
  {id:'use',title:'② Using in a Query',sub:'Reference customer_key in the request',col:J,ts:16,te:29,act:['cli','judit','cofre','court'],steps:[
    {fr:'cli',to:'judit',label:'POST /requests',note:'{customer_key}',col:A,ts:16.5,te:17.3,yp:0.28},
    {fr:'judit',to:'cofre',label:'fetches credential',note:'',col:P,ts:17.8,te:18.6,yp:0.40},
    {fr:'cofre',to:'judit',label:'credential found',note:'',col:P,ts:19.1,te:19.9,yp:0.52},
    {fr:'judit',to:'court',label:'authenticated access',note:'secret lawsuit',col:T,ts:20.4,te:21.2,yp:0.64},
    {fr:'court',to:'judit',label:'restricted data',note:'',col:J,ts:21.7,te:22.5,yp:0.76},
    {fr:'judit',to:'cli',label:'response_data',note:'',col:J,ts:23.0,te:23.8,yp:0.88}]}
];
var NODES=[{id:'cli',label:'Your App',col:A},{id:'judit',label:'Judit API',col:J},{id:'cofre',label:'Vault',col:P},{id:'court',label:'Court',col:T}];
var cv=document.getElementById('c');
function setup(){var dpr=Math.min(window.devicePixelRatio||1,2),r=cv.getBoundingClientRect(),W=r.width||window.innerWidth,H=r.height||window.innerHeight;cv.width=Math.max(1,W*dpr);cv.height=Math.max(1,H*dpr);var ctx=cv.getContext('2d');ctx.setTransform(dpr,0,0,dpr,0,0);return{ctx:ctx,w:W,h:H};}
function ease(t){return t<0.5?2*t*t:1-Math.pow(-2*t+2,2)/2;}
function rr(ctx,x,y,w,h,r){ctx.beginPath();ctx.moveTo(x+r,y);ctx.arcTo(x+w,y,x+w,y+h,r);ctx.arcTo(x+w,y+h,x,y+h,r);ctx.arcTo(x,y+h,x,y,r);ctx.arcTo(x,y,x+w,y,r);ctx.closePath();}
function gx(n,w){return n==='cli'?w*XP.cli:n==='judit'?w*XP.judit:n==='cofre'?w*XP.cofre:w*XP.court;}
function eg(fr,to,w){var fx=gx(fr,w),tx=gx(to,w),d=tx>fx?1:-1;return{x1:fx+d*NW/2,x2:tx-d*NW/2,d:d};}
function dPkt(ctx,x,y,lbl,col){var pw=Math.max(36,lbl.length*6+14),ph=20;ctx.save();ctx.shadowColor=col;ctx.shadowBlur=18;rr(ctx,x-pw/2,y-ph/2,pw,ph,5);ctx.fillStyle=col;ctx.fill();ctx.shadowBlur=0;ctx.fillStyle=PT2;ctx.font='bold 9px monospace';ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillText(lbl,x,y+0.5);ctx.restore();}
function draw(ctx,w,h,t){
  var ct=t%TOTAL;
  ctx.fillStyle=BG;ctx.fillRect(0,0,w,h);
  var fl=null;for(var i=0;i<FLOWS.length;i++){if(ct>=FLOWS[i].ts&&ct<FLOWS[i].te){fl=FLOWS[i];break;}}
  var nodeY=h*0.21;
  for(var i=0;i<NODES.length;i++){var n=NODES[i],lx=gx(n.id,w),ia=!fl||(fl.act.indexOf(n.id)>=0);ctx.save();ctx.strokeStyle=n.col;ctx.globalAlpha=ia?0.35:0.07;ctx.lineWidth=1;ctx.setLineDash([4,7]);ctx.beginPath();ctx.moveTo(lx,nodeY+NH/2);ctx.lineTo(lx,h*0.95);ctx.stroke();ctx.restore();}
  if(fl){ctx.save();ctx.fillStyle=fl.col;ctx.font='bold 13px Inter,system-ui,sans-serif';ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillText(fl.title,w/2,h*0.055);ctx.fillStyle=M;ctx.font='10.5px Inter,system-ui,sans-serif';ctx.fillText(fl.sub,w/2,h*0.118);ctx.restore();}
  if(fl){for(var si=0;si<fl.steps.length;si++){var s=fl.steps[si],sy=h*s.yp,e=eg(s.fr,s.to,w),x1=e.x1,x2=e.x2,d=e.d,clx=(x1+x2)/2;var state=ct<s.ts?'pre':ct>s.te?'done':'live',alpha=state==='pre'?0.10:state==='done'?0.55:1.0;ctx.save();ctx.globalAlpha=alpha;ctx.strokeStyle=s.col;ctx.lineWidth=1.5;ctx.setLineDash([]);ctx.beginPath();ctx.moveTo(x1,sy);ctx.lineTo(x2,sy);ctx.stroke();ctx.fillStyle=s.col;ctx.beginPath();ctx.moveTo(x2,sy);ctx.lineTo(x2-d*7,sy-4);ctx.lineTo(x2-d*7,sy+4);ctx.closePath();ctx.fill();ctx.fillStyle=TXT;ctx.font='bold 10px monospace';ctx.textAlign='center';ctx.textBaseline='bottom';ctx.fillText(s.label,clx,sy-4);if(s.note){ctx.fillStyle=M;ctx.font='9px monospace';ctx.fillText(s.note,clx,sy-16);}ctx.restore();if(state==='live'){var p=ease((ct-s.ts)/(s.te-s.ts));dPkt(ctx,x1+(x2-x1)*p,sy+14,s.label,s.col);}}}
  for(var i=0;i<NODES.length;i++){var nd=NODES[i],px=gx(nd.id,w),ia=!fl||(fl.act.indexOf(nd.id)>=0);ctx.save();ctx.globalAlpha=ia?1:0.18;if(ia){ctx.shadowColor=nd.col;ctx.shadowBlur=14;}rr(ctx,px-NW/2,nodeY-NH/2,NW,NH,8);ctx.fillStyle=NF;ctx.fill();ctx.shadowBlur=0;ctx.strokeStyle=ia?nd.col:'rgba(255,255,255,0.10)';ctx.lineWidth=ia?1.8:1;ctx.stroke();ctx.fillStyle=ia?nd.col:M;ctx.font='bold 11px Inter,system-ui,sans-serif';ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillText(nd.label,px,nodeY);ctx.restore();}
  for(var f=0;f<FLOWS.length;f++){var ia=fl&&fl.id===FLOWS[f].id;ctx.save();ctx.beginPath();ctx.arc(w/2+(f-0.5)*24,h*0.965,ia?5:3,0,Math.PI*2);ctx.fillStyle=ia?FLOWS[f].col:'rgba(255,255,255,0.18)';ctx.fill();ctx.restore();}
}
var dim,t0;
function loop(){var t=(performance.now()-t0)/1000;draw(dim.ctx,dim.w,dim.h,t);requestAnimationFrame(loop);}
window.addEventListener('load',function(){dim=setup();t0=performance.now();loop();});
window.addEventListener('resize',function(){dim=setup();});
cv.addEventListener('click',function(e){var r=cv.getBoundingClientRect(),cx=e.clientX-r.left,cy=e.clientY-r.top;for(var f=0;f<FLOWS.length;f++){var dx=cx-(dim.w/2+(f-(FLOWS.length-1)/2)*24),dy=cy-dim.h*0.962;if(dx*dx+dy*dy<=144){t0=performance.now()-FLOWS[f].ts*1000;break;}}});
cv.addEventListener('mousemove',function(e){var r=cv.getBoundingClientRect(),cx=e.clientX-r.left,cy=e.clientY-r.top,over=false;for(var f=0;f<FLOWS.length;f++){var dx=cx-(dim.w/2+(f-(FLOWS.length-1)/2)*24),dy=cy-dim.h*0.962;if(dx*dx+dy*dy<=144){over=true;break;}}cv.style.cursor=over?'pointer':'default';});
})()</script></body></html>`} />;

The **Credentials Vault** stores, encrypted, the credentials (CPF/OAB + password) that lawyers use to authenticate in Brazilian courts. With this, Judit can access lawsuits under **judicial secrecy** on behalf of the lawyer, without your application ever storing or transmitting the password.

> 🤖 Base endpoint: `https://crawler.prod.judit.io/credentials`. Register once per system/court and reference it later in queries via `credential.customer_key`.

## When to use

<CardGroup cols={2}>
  <Card title="Access to secret lawsuits" icon="lock">
    Required to query civil and labor lawsuits under judicial secrecy.
  </Card>

  <Card title="Multi-tenant for firms" icon="users">
    Use `customer_key` to separate credentials per lawyer/client of the firm.
  </Card>

  <Card title="LGPD/GDPR compliance" icon="shield-halved">
    Passwords are stored encrypted in a dedicated vault — your application never transits the password.
  </Card>

  <Card title="Wildcard credential" icon="asterisk">
    Register `"system_name": "*"` as fallback for courts without a specific credential.
  </Card>

  <Card title="A1 digital certificate" icon="certificate" href="#registering-a-credential-with-a-digital-certificate-a1">
    Courts that only accept certificate login use the `POST /credentials/certificate` route.
  </Card>
</CardGroup>

<VaultAnimation />

## Endpoint to register your keys in the credentials vault

To start using the credentials vault, you must make a POST request to the `crawler.prod.judit.io/credentials` route and register the lawyers' credentials for the courts made available.

### Request Payload

The POST request must include a payload with the following properties:

* `system_name`: The acronym of the [court and system](/en/resource/glossary#credentials-vault-list) for which the new credential will be registered.
  * `Note:` A wildcard credential can be registered using `"system_name": "*"`. If a credential is registered under the wildcard, all courts without their own specific credential will use the wildcard credential.

* `customer_key`: Custom identifier to associate the credential with a client or lawyer. It can be any name or label defined by whoever is registering the credential, making it easier to organize and manage credentials.

* `username`: CPF (Cadastro de Pessoas Físicas — Brazilian individual taxpayer ID) or OAB number (Ordem dos Advogados do Brasil — Brazilian Bar Association), as required by the court's system where the login will be performed.

* `password`: Password registered at the respective court.

Properties required only for courts that enforce two-factor authentication:

* `custom_data`: Optional object intended to store additional information specific to the system or use-case context. It may include custom fields such as a secret required for authentication or other specific settings.

* `secret`: Two-factor authentication token for the system being registered.

`Note:` Registered credentials are encrypted, ensuring data security, and cannot be retrieved afterwards. To modify information already registered, simply create a new record using the same `customer_key` and the same `system_name`. The new registration will automatically replace the existing credential.

Example payload for registering credentials without two-factor authentication:

```json theme={null}

{
  "credentials": [
    {
      "system_name": "PJE TJBA - 1º grau",
      "customer_key": "00000001",
      "username": "999.999.999-99",
      "password": "Senha123"
    },
    {
      "system_name": "ESAJ - TJAC - 1º grau",
      "customer_key": "00000002",
      "username": "999.999.999-99",
      "password": "Senha123"
    }
  ]
}
```

Example payload for registering credentials with two-factor authentication:

```json theme={null}

{
  "credentials": [
    {
      "system_name": "PJE TJBA - 1º grau",
      "customer_key": "00000001",
      "username": "999.999.999-99",
      "password": "Senha123",
      "custom_data": {
				"secret": "<TOKEN>"
			}
    }
  ]
}
```

Example response to the request:

```json theme={null}

[
    {
        "system_name": "ESAJ - TJAC - 1º grau",
        "message": "CREDENTIAL_CREATED"
    },
    {
        "system_name": "PJE TJBA - 1º grau",
        "message": "CREDENTIAL_CREATED"
    }
]
```

## Registering a credential with a digital certificate (A1)

Some courts do not accept CPF/OAB + password login and require a **digital certificate**. For those cases, the Credentials Vault has a dedicated route for certificate upload: `POST /credentials/certificate`.

<Warning>
  The certificate **cannot** be sent through the `POST /credentials` route. If you try to place certificate fields inside `custom_data`, the API responds with the `CERTIFICATE_FIELDS_NOT_ALLOWED` error. Always use `/credentials/certificate`.
</Warning>

### What you need before you start

| Item | Detail |
| :- | :- |
| **A1 certificate** | A `.pfx` or `.p12` file (PKCS#12 standard). **A3** certificates (USB token or smart card) are **not accepted**, because they depend on connected hardware. |
| **File password** | The password of the `.pfx` file itself, defined when the certificate was issued or exported. **It is not the court portal password.** |
| **Size** | The file must be at most **64 KB**. |
| **Validity** | The certificate must be within its validity period. Expired certificates are rejected on upload. |
| **Your `api-key`** | The same key you already use on the other Judit routes. |

<Info>
  If you have an A3 certificate and need to use it in automated queries, you must issue an A1 certificate for the same holder. Contact your Certification Authority (Serasa, Certisign, Soluti, etc.).
</Info>

### Step 1 — Convert the `.pfx` file to Base64

An HTTP request body in JSON only carries text, and a `.pfx` is a binary file. So, before sending it, the file must be converted to **Base64** — which is simply the same file rewritten as text.

<Note>
  Base64 is **not encryption and not a hash**. It is only a way to represent the file using text characters. Nothing is lost and nothing is scrambled in the conversion.
</Note>

Pick the command for your operating system:

<CodeGroup>
  ```bash macOS theme={null}
  # Produces the Base64 on a single line and copies it to the clipboard
  base64 -i ./certificate.pfx | tr -d '\n' | pbcopy
  ```

  ```bash Linux theme={null}
  # The -w 0 flag prevents line breaks
  base64 -w 0 ./certificate.pfx > certificate.base64.txt
  ```

  ```powershell Windows (PowerShell) theme={null}
  # Produces the Base64 on a single line and saves it to a .txt file
  [Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\path\certificate.pfx")) | Set-Content certificate.base64.txt
  ```

  ```javascript Node.js theme={null}
  const fs = require("fs");

  const fileBase64 = fs.readFileSync("./certificate.pfx").toString("base64");
  console.log(fileBase64);
  ```

  ```python Python theme={null}
  import base64

  with open("certificate.pfx", "rb") as f:
      file_base64 = base64.b64encode(f.read()).decode()

  print(file_base64)
  ```
</CodeGroup>

<Warning>
  **The Base64 string must be a single line, with no line breaks.** If you run `base64 file.pfx` without `tr -d '\n'` (macOS) or without `-w 0` (Linux), the output is split across several lines and the API will respond with `PFX_MALFORMED`.
</Warning>

**How to tell it worked:** the generated text is huge (thousands of characters — that is normal) and usually starts with `MII`. If what you copied is something short like `C:\certificates\mine.pfx` or `./certificate.pfx`, you copied the file **path**, not its content.

### Step 2 — Send the certificate to the vault

```bash 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": "<pfx-content-in-base64>",
  "password": "123456"
}'
```

<Warning>
  Authentication uses the **`api-key`** header, exactly like the other Judit routes. **Do not use `Authorization: Bearer`** — this route does not use a Bearer token.
</Warning>

#### Request body fields

| Field | Type | Required | Description |
| :- | :- | :- | :- |
| `file_base64` | string | **Yes** | Content of the `.pfx` / `.p12` file converted to Base64, on a single line (the result of Step 1). |
| `password` | string | **Yes** | Password of the `.pfx` file. Again: the certificate password, not the court password. |
| `system_name` | string | Recommended | System and court where the certificate will be used, exactly as it appears in the [vault systems list](/en/api-reference/endpoint/vault/vault) — for example `ESAJ - TJSP - 1º grau`. Use `"*"` to register the certificate as a **wildcard credential**, valid for any court without a specific credential. |
| `customer_key` | string | Recommended | Identifier you define for this credential (per lawyer, client or firm). This is the same key you will send in the query. If omitted, the default value `"*"` is used. |
| `custom_data` | object | No | Only needed when the court also requires two-factor authentication. See [Step 5](#step-5-optional--certificate--2fa-code). |

<Info>
  The `customer_key` is just a reference label chosen by you. It has no relation to the court and it is not a password.
</Info>

#### Step by step in Postman

<Steps>
  <Step title="Method and URL">
    Select **POST** and enter the URL `https://crawler.prod.judit.io/credentials/certificate`.
  </Step>

  <Step title="Headers">
    On the **Headers** tab, add two rows:

    | Key | Value |
    | :- | :- |
    | `api-key` | your Judit key |
    | `Content-Type` | `application/json` |
  </Step>

  <Step title="Body">
    On the **Body** tab, select **raw** and, in the selector on the right, choose **JSON**. Paste the JSON with the four fields and replace `file_base64` with the text generated in Step 1.

    <Warning>
      Do not use **form-data** or Postman's **File** type to attach the `.pfx`. This route only accepts JSON, with the file already converted to Base64.
    </Warning>
  </Step>

  <Step title="Send">
    Click **Send**. The expected response is a `200` with the `CERTIFICATE_CREATED` message.
  </Step>
</Steps>

### Step 3 — Check the response

```json theme={null}
{
  "message": "CERTIFICATE_CREATED",
  "customer_key": "teste",
  "subject_cn": "HOLDER NAME:12345678909",
  "not_after": "2027-01-01T00:00:00.000Z",
  "uploaded_at": "2026-07-31T17:00:00.000Z"
}
```

| Field | Description |
| :- | :- |
| `message` | `CERTIFICATE_CREATED` on the first upload; `CERTIFICATE_UPDATED` when you replace an already registered certificate of the same holder. |
| `customer_key` | Key of the credential that was just created or updated. |
| `subject_cn` | Certificate holder (name and CPF/CNPJ), read from the file itself. Use it to confirm you sent the right certificate. |
| `not_after` | Certificate expiration date, in ISO 8601. Note it down so you can renew before it expires. |
| `uploaded_at` | Upload date and time, in ISO 8601. |

The certificate is validated at upload time (password, validity and size) and stored encrypted. The response **never** returns the file or the password — once registered, the certificate cannot be read back.

### Step 4 — Use the certificate in a query

Usage is the same as any other vault credential: just send the same `customer_key` in `search.search_params.credential`.

```bash theme={null}
curl --location 'https://requests.prod.judit.io/requests/' \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--data '{
  "search": {
    "search_type": "lawsuit_cnj",
    "search_key": "0000000-00.0000.0.00.0000",
    "search_params": {
      "credential": {
        "customer_key": "teste"
      }
    }
  }
}'
```

<Note>
  If you registered the certificate with the default `customer_key` `"*"`, you do not need to send `credential` in the query — it will be used automatically as the wildcard credential.
</Note>

### Step 5 (optional) — Certificate + 2FA code

Some courts require **two things at once**: the digital certificate **and** the 2FA secret — sent in the `secret` field, and called secret key, manual key or authenticator setup key on the court portal.

It is all done in a **single request**: just add the `custom_data` object, with the `secret` key inside it, to the same certificate payload.

```bash 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": "<pfx-content-in-base64>",
  "password": "123456",
  "custom_data": {
    "secret": "JBSWY3DPEHPK3PXP"
  }
}'
```

| Field | Type | Required | Description |
| :- | :- | :- | :- |
| `custom_data` | object | No | Object with extra credential data. Only send it when the court requires 2FA. |
| `custom_data.secret` | string | No | The credential's 2FA secret — the **fixed setup key** of the authenticator app. |

<Warning>
  The `secret` is the authenticator's **fixed setup key** (something like `JBSWY3DPEHPK3PXP`) — **never** the temporary 6-digit code, which changes every few seconds. Registering the 6-digit code makes the credential stop working within minutes.
</Warning>

<Note>
  Not sure where to find that key? It appears during the 2FA setup on the court portal, behind options such as "I can't scan the QR Code", "Enter key manually", "Show secret key" or "Setup key".
</Note>

<Info>
  If the credential already had a `secret` registered before, uploading the certificate **does not erase** it. You can send `custom_data` again to update it, or omit the field to keep what is already stored.
</Info>

### Replacing, renewing or removing the certificate

* **Renew or replace:** repeat the same upload with the same `customer_key` and `system_name`. The credential is updated, the previous certificate is discarded and the response comes back with `CERTIFICATE_UPDATED`.
* **Different holder:** if the new certificate belongs to another CPF/CNPJ, the API returns `CERTIFICATE_HOLDER_MISMATCH` (409). Remove the credential before registering the new holder's certificate.
* **List:** use `GET https://crawler.prod.judit.io/credentials?customer_key=teste` with the `api-key` header. A credential registered with `system_name: "*"` appears in the list with `name: "*"`.
* **Remove:** use `DELETE https://crawler.prod.judit.io/credentials` sending `system_name` and `customer_key`. The stored certificate is deleted along with the credential. If it does not exist, the response is `404` (`CREDENTIAL_NOT_FOUND`).

### Errors and how to fix them

| Code | HTTP | What happened | How to fix |
| :- | :- | :- | :- |
| `PFX_MALFORMED` | 400 | The Base64 is invalid or the `.pfx` file is corrupted. | Redo Step 1 making sure it is a single line, with no breaks and no spaces. Confirm you sent the file content, not its path. |
| `PFX_PASSWORD_INVALID` | 400 | The password provided does not open the file. | Use the `.pfx` file password, not the court portal password. Try opening the certificate locally with that password. |
| `PFX_NO_PRIVATE_KEY` | 400 | The file has no private key. | Export the certificate again, selecting the option to export the private key. |
| `PFX_NO_CERTIFICATE` | 400 | The file has no certificate. | Check that the exported file is really a complete `.pfx` / `.p12`. |
| `PFX_EXPIRED` | 400 | The certificate has expired. | Issue or renew the certificate with your Certification Authority. |
| `PFX_NOT_YET_VALID` | 400 | The certificate is not valid yet. | Wait for the start of the validity period. |
| `PFX_TOO_LARGE` | 400 | The file is larger than 64 KB. | Export only the holder's certificate, without unnecessary chains or extra certificates. |
| `CERTIFICATE_HOLDER_MISMATCH` | 409 | A certificate is already registered in this credential and it belongs to another holder. | Remove the credential and register it again with the new holder. |
| `CREDENTIAL_TYPE_CONFLICT` | 409 | A username/password credential already exists for this combination of `customer_key` and system. | Use a different `customer_key` for the certificate, or remove the username/password credential first. |
| `CERTIFICATE_FIELDS_NOT_ALLOWED` | 400 | You tried to send certificate fields to the `POST /credentials` route. | Send the certificate through `POST /credentials/certificate`. |

### Most common mistakes in practice

<AccordionGroup>
  <Accordion title="I sent the file path instead of its content">
    `"file_base64": "C:\\certificates\\mine.pfx"` is wrong. The field expects the **Base64 text** generated in Step 1, with thousands of characters — not the file location on your computer.
  </Accordion>

  <Accordion title="The Base64 came out split across several lines">
    This happens when the command runs without `tr -d '\n'` (macOS) or without `-w 0` (Linux). Redo the conversion using exactly the commands from Step 1.
  </Accordion>

  <Accordion title="I used the court password in the password field">
    The `password` field is the `.pfx` file password, created when the certificate was issued or exported. The court portal password does not open the file and results in `PFX_PASSWORD_INVALID`.
  </Accordion>

  <Accordion title="I used Authorization: Bearer and got an authentication error">
    This route authenticates through the `api-key` header. Remove the `Authorization` header and send `api-key: your-key`.
  </Accordion>

  <Accordion title="I tried to attach the .pfx as a file in Postman">
    The route only accepts `Content-Type: application/json` with the file already converted to Base64. Do not use **form-data**, **binary** or Postman's file picker.
  </Accordion>

  <Accordion title="My certificate is A3 (token or smart card)">
    A3 certificates require the physical device connected at login time and therefore cannot be registered in the vault. You need an A1 certificate (`.pfx` / `.p12` file) for the same holder.
  </Accordion>

  <Accordion title="I registered the certificate but the query still does not return the secret lawsuit">
    The certificate only authenticates the holder. Access to the lawsuit depends on that holder's permissions inside the court. If the lawyer is not enabled in the lawsuit, the response will remain limited to public data.
  </Accordion>
</AccordionGroup>

## Endpoint to verify registered credentials

To check whether a credential is registered, send a GET request to the `crawler.prod.judit.io/credentials` endpoint, including the `customer_key` parameter that corresponds to the credential you want to look up.

The response will return every credential available in the vault associated with the queried `customer_key`. The `credential_status` field indicates the status of each credential:

* active: Credential registered and active.
* not exists: Credential not found in the system.

Below is an example GET request to check whether a credential exists:

```bash theme={null}

curl --location 'https://crawler.prod.judit.io/credentials?customer_key=teste_01' \
--header 'api-key: <API-KEY>'

```

Below is an example response for the GET request above:

```json theme={null}

{
    "systems": [
        {
            "name": "*",
            "customer_key": "",
            "credential_status": "not exists"
        },
        {
            "name": "ESAJ - TJAM - 1º grau",
            "customer_key": "teste_01",
            "credential_status": "active"
        },
        {
            "name": "PROJUDI TJGO - 1º grau",
            "customer_key": "teste_01",
            "credential_status": "active"
        }
    ]
}

```

## Endpoint to delete a key from the Credentials Vault

To delete a system from the credentials vault, you must make a DELETE request to the `crawler.prod.judit.io/credentials` route.

### Request Payload

The DELETE request must include a payload with the following properties:

* `system_name`: The acronym of the [court and system](/en/resource/glossary#credentials-vault-list) whose credential will be removed.
* `customer_key`: Custom identifier added when the credential was registered.

Example payload to delete a credential:

```json theme={null}

{
	"system_name": "PROJUDI TJGO - 1º grau",
    "customer_key":"teste_01"
}

```

* If the request succeeds, the response will be an empty object.

Keeping credentials up to date at the courts is entirely the user's responsibility. It is therefore up to the user to register the credential at the corresponding court and to monitor its validity and status to ensure that it is not suspended or invalidated.


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