Skip to main content

cert-ctrl HTTP API Reference

This document lists the public REST endpoints that end users typically need for certificate issuance and distribution. It intentionally focuses on certificates, issuance status, and download/deployment flows.

Conventions

  • Base URL: https://api.cjj365.cc
  • API key auth: Authorization: Bearer ak_... (recommended for automation)
  • API key permissions: endpoints enforce scope checks like certificates:*[read] or certificates:<certificate_id>[read]
  • Response wrapper:
    • success: 200/201/204 with optional { "data": ... }
    • error: status >= 400 with { "error": { "code": int, "what": string } }
  • Pagination: most list endpoints accept offset and limit (default limit 100)
  • User scope: use /apiv1/me/... with an API key (no user id in path)

Health

  • GET /health

Devices (API key)

These endpoints help automation discover devices and manage assignments without needing a user_id in the URL.

Paths

  • GET /apiv1/me/devices
  • GET /apiv1/me/devices/:device_id
  • GET /apiv1/me/devices/by-public-id/:device_public_id
  • GET /apiv1/me/devices/:device_id/certificates
  • GET /apiv1/me/devices/:device_id/certificates/:certificate_id
  • GET /apiv1/me/devices/:device_id/certificates/:certificate_id/bundle

Assign certificate to device (API key)

  • POST /apiv1/me/certificate-assign

Certificates (API key)

Paths

  • GET /apiv1/me/certificates
  • POST /apiv1/me/certificates
  • GET /apiv1/me/acme-accounts/:acme_account_id/certificates
  • GET /apiv1/me/certificates/:certificate_id
  • GET /apiv1/me/certificates/:certificate_id/devices
  • POST /apiv1/me/certificates/:certificate_id/issues
  • GET /apiv1/me/certificates/:certificate_id/issues
  • GET /apiv1/me/certificates/:certificate_id/issue-result
  • GET /apiv1/me/certificates/:certificate_id/export

Notes

  • POST /.../issues initiates issuance or renewal for the certificate.
    • Response: 200 JSON with a correlation id so clients can poll deterministically:
      • data.issue_history_id (integer)
      • data.status: PENDING | PROCESSING | SUCCESS | FAILED | CANCELLED
    • For ACME-backed providers this is asynchronous:
      • First call typically returns PENDING (queued)
      • Worker will update the same history row to PROCESSING and then final status.
    • Single in-flight behavior: if the latest history row is already PENDING/PROCESSING, the server returns that existing issue_history_id instead of enqueueing a second job.
    • For SELF_CA the server may complete inline and return SUCCESS (and may also include the issued cert record in data.cert).
    • Request body is currently ignored; send {}.
  • GET /.../issues lists issuance history rows (ordered newest-first on the MySQL backend).
  • GET /.../issues/history is accepted as a legacy alias for listing history rows (prefer GET /.../issues).
  • POST /.../issues/history exists as an internal worker callback and is not intended for end users.
  • GET /.../issue-result currently returns the certificate record on production.

Polling guidance

  • Call POST /apiv1/me/certificates/:certificate_id/issues and read data.issue_history_id.
  • Poll GET /apiv1/me/certificates/:certificate_id/issues?offset=0&limit=10 until the row with id == issue_history_id reaches a terminal status (SUCCESS/FAILED/CANCELLED).

Create certificate example

curl -X POST https://api.cjj365.cc/apiv1/me/certificates \
-H "Authorization: Bearer ak_yourtoken" \
-H "Content-Type: application/json" \
-d '{
"domain_name": "example.com",
"sans": ["example.com", "www.example.com"],
"acct_id": 7,
"action": "create",
"key_algorithm": "ECDSA",
"policy": "HYBRID"
}'

Downloads and Distribution

Export certificate bundle (API key)

  • GET /apiv1/me/certificates/:certificate_id/export
    • Production currently responds with JSON (certificate record).
    • HEAD is not supported (use GET).
    • For a device-ready zip bundle, use: GET /apiv1/me/devices/:device_id/certificates/:certificate_id/bundle

Assign certificate to device (API key)

  • POST /apiv1/me/certificate-assign

ACME accounts (API key)

  • GET /apiv1/me/acme-accounts
  • POST /apiv1/me/acme-accounts
  • GET /apiv1/me/acme-accounts/:acme_account_id
  • PUT /apiv1/me/acme-accounts/:acme_account_id
  • DELETE /apiv1/me/acme-accounts/:acme_account_id

Note: API key scope name is acme_accounts (underscore).

Scope

This document does not describe admin/billing/internal worker endpoints. Those exist, but are not relevant for most certificate issuance and distribution users.