---
title: "Certificate revocation list"
method: GET
path: "/api/v1/productions/revoked-certificates"
tags: ["Productions"]
---

# Certificate revocation list

`GET /api/v1/productions/revoked-certificates`

## Request

- Base URL: `https://easy2257.com`
- URL: `https://easy2257.com/api/v1/productions/revoked-certificates`
- Auth: HTTP bearer

Certificates revoked since a timestamp, scoped to productions linked to your partner account. Run it on a daily cron. Every entry is a takedown signal: a reason starting `removal_request:` means take the content down. Annual renewals are not revocations and no longer enter this list (entries recorded before that split carry `type: supersession` and their content stays up). Advance your watermark from the top-level `retrievedAt`, and page with `nextCursor`.

## Query parameters

- `since` string, date-time: ISO 8601. Defaults to 30 days ago. Use the `retrievedAt` from your last successful sync.
- `limit` string: 1 to 10000. Default 1000.
- `cursor` string: `nextCursor` from the previous page, passed back verbatim.

## Response `200`

Revocation list.

- CrlResponse
  - `retrievedAt` string, date-time, required: Server time at which this response was built. This is the watermark: pass it as `since` on your next sync. There is no top-level `revokedAt`, and the per-item `revokedAt` values belong to individual certificates, so advancing a watermark off one of those will make your sync stall or skip.
  - `revocations` object[], required
    - `productionId` string, required
    - `revokedAt` string, date-time, required: When this certificate was revoked.
    - `reason` string, required: Free-form string, not a fixed enum. `removal_request:<id>` means an admin actioned a removal request, so pull the content. Match that one on the `removal_request:` prefix, since the id varies. `unspecified` means no reason was recorded. `annual_renewal` appears only on entries recorded before renewals were split out of this feed; the content stays up for those.
    - `type` 'revocation' | 'supersession', required: What the entry is. `revocation` means the certified record was pulled: take the content down. `supersession` means an annual renewal replaced the certificate and the content stays up; it appears only on entries recorded before renewals stopped being written to this feed. New renewals never enter the list — they arrive as `production.certificate_renewed` webhooks and in `GET /api/v1/productions/{productionId}/certificates`.
  - `nextCursor` string, nullable, required: Opaque page cursor derived from the certificate record's `jwtId`. Pass it back verbatim as `cursor`. It is not a `productionId`, and ordering is stable on (revokedAt, jwtId) so pages never skip or repeat. null on the last page.

## Other responses

- `400`: `since` is not a valid date. `code` is `invalid_parameter`.
- `401`: No `Authorization: Bearer` header, or a key that is unknown, revoked, or expired. The body carries only `error`, never a `code`.
- `403`: Rejected before the handler: a test-mode key (`TEST_MODE_UNAVAILABLE`) or a partner account that is not ACTIVE. Never used for cross-partner access, which returns 404.
- `429`: Rate limit exceeded: 300 requests per 60 seconds per API key, shared across all `/api/v1` endpoints (requests without a `Bearer` key fall back to 60 per 60 seconds per client IP, and a per-address flood ceiling of 1200 per 60 seconds also applies). Honor `Retry-After`.
- `500`: Server error. Retry with exponential backoff.

---

[API](https://skmtc.dev/easy2257/apis/easy2257-partner-api.md) · [All operations](https://skmtc.dev/easy2257/apis/easy2257-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/easy2257/apis/easy2257-partner-api/revisions/f880026c1f04?raw)
