The API and API keys

Create a read-only or audit key, then read domains, findings and comparisons, start audits and follow them: the API reference, with curl examples.

Updated

From the Solo plan, an API lets your scripts, your CI and your AI assistants read the results of your domains and start audits. It answers in JSON, and the latest audit can also be read as SARIF, the format code-scanning tools understand. The GitHub Action and the MCP server are built on it.

Create a key

  1. Open Settings and find the API keys card.
  2. Give the key a name that says where it is used, such as “GitHub Actions”.
  3. Tick Can start audits only if this key must start audits (a CI job that runs one at each deployment). Leave it unticked for a key that only reads.
  4. Press Create key and copy the key at once: it starts with pc_ and is shown only once. Store it as a secret in your CI or password manager.

Only owners and admins can create and revoke keys. The card lists each key with its first characters, what it may do, when it was created and when it was last used. Revoke stops a key at once. When a member is removed from the workspace, the keys they created are revoked with them.

Call the API

The API lives at https://app.perimetry.cloud. Send the key in the Authorization header of every request, never in the address:

Authorization: Bearer pc_…

Every answer carries Perimetry-Api-Version: 1 and the state of your hourly limit (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset). Version 1 only ever gains fields: nothing is renamed or removed, so a script written today keeps working.

Wherever a request takes :id, you can give the domain’s id or its name (example.com).

The domain, findings and compare requests take lang=fr or lang=de for the titles, explanations and fixes of the findings in French or German; English by default.

Request What it does
GET /api/v1/me The workspace, the plan, what the key may do, and what is left of the hourly limit.
GET /api/v1/domains The domains of the workspace: id, name, status, client, score, grade, open findings by severity, dates of the last and next audits, link to the report. ?name=example.com keeps one.
GET /api/v1/domains/:id One domain: its score, its last audit with the score change since the previous one, new and fixed findings, and the three findings to fix first.
GET /api/v1/domains/:id/findings The open findings of the latest audit, worst first, each with its fix, the DNS records ready to copy and the NIS2, Cyber Essentials and ISO 27001 requirements. Options: min_severity, include_accepted=1, limit, lang.
GET /api/v1/domains/:id/compare What changed since the previous audit: score from and to, findings added, fixed or changed in severity, hosts, ports, certificates, look-alikes.
GET /api/v1/domains/:id/audits The history of audits: date, score, grade, counts (limit, 100 at most).
GET /api/v1/domains/:id/latest The latest audit in full, with its findings and the accepted ones; ?format=sarif for SARIF.
POST /api/v1/domains/:id/audit Starts an audit of a proved domain (key that can start audits). Answers 202 with a run to follow.
GET /api/v1/runs/:id Where that audit stands: queued, running (with its progress), done (new score, previous score, change) or failed.

Every field of every answer, the error codes and the OpenAPI 3.1 specification to download (for Postman, code generators and automation tools) are in the API reference.

Examples

List your domains:

curl -H "Authorization: Bearer $PERIMETRY_API_KEY" https://app.perimetry.cloud/api/v1/domains

The serious findings of one domain, with their fixes, in French:

curl -H "Authorization: Bearer $PERIMETRY_API_KEY" \
  "https://app.perimetry.cloud/api/v1/domains/example.com/findings?min_severity=high&lang=fr"

What changed since the previous audit:

curl -H "Authorization: Bearer $PERIMETRY_API_KEY" https://app.perimetry.cloud/api/v1/domains/example.com/compare

Start an audit, then follow it until it is done:

curl -X POST -H "Authorization: Bearer $PERIMETRY_API_KEY" https://app.perimetry.cloud/api/v1/domains/example.com/audit
# → {"apiVersion":1,"queued":true,"run":{"id":"6f1c…","status":"queued",…}}
curl -H "Authorization: Bearer $PERIMETRY_API_KEY" https://app.perimetry.cloud/api/v1/runs/6f1c…

The latest audit as SARIF, for a code-scanning tool:

curl -H "Authorization: Bearer $PERIMETRY_API_KEY" -o perimetry.sarif \
  "https://app.perimetry.cloud/api/v1/domains/example.com/latest?format=sarif"

Limits

  • Calls per hour, for the whole workspace: 300 on Solo, 1,200 on Agency, 3,600 on Agency Plus. Beyond that the API answers 429 with a Retry-After header until the next hour starts.
  • Audits on demand: the same rule as the Audit now button (one an hour per domain on Solo, as often as needed on the Agency plans), and, through the API, one every 15 minutes per domain. While an audit of the domain is already waiting or running, a new request follows that one instead of starting another.

Errors

Errors answer in JSON with a message and a stable code: {"error": "…", "code": "…"}.

  • 400 invalid_parameter: a parameter has a value the API does not accept, for example min_severity=urgent; the message names the values allowed.
  • 401 unauthorized: the key is missing, malformed, revoked or unknown.
  • 403 plan_excludes_api: the workspace’s plan does not include the API. insufficient_scope: the key cannot start audits.
  • 404 not_found: the domain is not in this workspace; no_audit: it has no audit yet.
  • 409 not_verified: an audit was asked for a domain that is not proved.
  • 429 rate_limited: the hourly limit is reached; audit_too_soon: an audit on demand of this domain ran too recently; too_many_failures: sixty requests with a wrong key came from your network in fifteen minutes. In each case, Retry-After gives the seconds to wait.

The journal

Each call is recorded for 90 days: its time, its key, the route (never the parameters) and the answer. Owners and admins see the latest under Recent API calls in the API keys card. Each audit started through the API also appears in the Activity of the workspace, with the key that started it.

Ideas

  • Fail a deployment when the score drops: see Perimetry Cloud in your CI.
  • Ask Claude or another assistant about your domains: see The MCP server.
  • Feed the scores of all your domains into your own dashboard.