# Certificados del borde

> Lista los certificados TLS de una zona y el estado del certificado de cada sitio con proxy.

OpenWAF emite y renueva automáticamente (ACME) los certificados del borde de cada nombre con proxy. Esta ruta los lista, nunca con sus claves privadas, junto con el estado de cada sitio.

| Operación | Ruta |
|---|---|
| [Listar certificados](https://developers.openwaf.dev/es/api/certificates/#list-certs) | `GET /v1/orgs/{org}/zones/{zone}/certs` |

## Listar certificados

```http
GET /v1/orgs/{org}/zones/{zone}/certs
```

Lista los certificados TLS de la zona, nunca con sus claves privadas, con el estado de su emisión ACME, y el estado del certificado de cada sitio con proxy en `sites` (válido, emisión pendiente o fallida, días que le quedan).

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |

#### Respuesta

- `200`: Devuelve un objeto con los campos de abajo.

| Campo | Tipo | Descripción |
|---|---|---|
| `items` | array de objeto |  |
| `items[].id` | string (uuid) | Id. |
| `items[].zone_id` | string (uuid) | Id de la zona. |
| `items[].hostname` | string |  |
| `items[].cert_pem` | string |  |
| `items[].fingerprint_sha256` | string | Huella SHA-256 del certificado. |
| `items[].not_after` | string (date-time) | Fin de la validez. |
| `items[].source` | string | manual = subido por OpenWAF; acme = emitido automáticamente con ACME. Uno de `manual`, `acme`. |
| `items[].uploaded_by` | string |  |
| `items[].created_at` | string (date-time) | Fecha de creación. |
| `items[].issuance` | [ACMEIssuance](https://developers.openwaf.dev/es/api/schemas/#acme-issuance) |  |
| `sites` | array de [HostCertStatus](https://developers.openwaf.dev/es/api/schemas/#host-cert-status) |  |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/certs" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.listCerts({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.list_certs(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "items": [
    {
      "id": "a5614527-0ce6-43be-ad1d-d012b7394867",
      "zone_id": "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
      "hostname": "www.example.com",
      "cert_pem": "example",
      "fingerprint_sha256": "example",
      "not_after": "2026-10-27T09:30:00Z",
      "source": "manual",
      "created_at": "2026-10-27T09:30:00Z",
      "issuance": {
        "name": "example.com",
        "names": [],
        "state": "pending",
        "challenge": "example",
        "last_error": "",
        "failures": 0,
        "next_attempt_at": "2026-10-27T09:30:00Z",
        "last_attempt_at": "2026-10-27T09:30:00Z",
        "last_success_at": "2026-10-27T09:30:00Z",
        "updated_at": "2026-10-27T09:30:00Z"
      }
    }
  ],
  "sites": [
    {
      "org_id": "1e7c9a3b-5d2f-4b8a-9c6e-0f2a4b6c8d1e",
      "zone_id": "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
      "zone": "example.com",
      "dns_mode": "delegated",
      "hostname": "www.example.com",
      "state": "valid",
      "source": "",
      "cert_id": "2e0a4ad6-9d2a-4999-a9cb-f10436c964f5",
      "cert_name": "example",
      "not_after": "2026-10-27T09:30:00Z",
      "days_left": 0,
      "challenge": "example",
      "last_error": "",
      "failures": 0,
      "next_attempt_at": "2026-10-27T09:30:00Z",
      "last_attempt_at": "2026-10-27T09:30:00Z",
      "warning": ""
    }
  ]
}
```
