Skip to content

Public API

The public API lets scripts and other tools read your organisation’s fix list, advisories, exposures, repositories and evidence log, and act on them: acknowledge, record decisions and request upgrade merge requests.

Base URL https://app.mopokehq.com/api/public/v1
OpenAPI 3.1 document https://app.mopokehq.com/api/public/v1/openapi.json (no key needed)
Authentication Authorization: Bearer mpk_api_...
Format JSON in and out

Load the OpenAPI document into your API client or code generator for every field and answer. This page covers the essentials.

Create keys in Settings, Integrations, API keys. Any member can create keys for themselves; owners and admins also see everyone’s keys and can revoke them.

  • A key belongs to one person in one organisation and acts as them. It can never do more than they can, and it stops working when they leave the organisation.
  • Scopes: read (every GET) or read and write (also the POST endpoints). A read key calling a write endpoint gets 403 insufficient_scope.
  • Expiry: 30 days, 90 days (the default) or a year.
  • The key is shown once. MopokeHQ stores only a hash and the last four characters, and shows when each key was last used.
  • Creating and revoking a key are recorded in the evidence log.

The same keys work for the MCP server.

The public API accepts only API keys, not browser sessions, so it needs no Origin header and cannot be called from a signed-in browser tab.

Terminal window
curl -H "Authorization: Bearer $MOPOKE_API_KEY" \
"https://app.mopokehq.com/api/public/v1/now?tier=now"

Paths are relative to the base URL.

Method and path Scope What it does
GET /me read The key, its owner, their role and the organisation
GET /now?tier=&limit= read The fix list: actions grouped by upgrade, in the order to work them. tier is now, week or later.
GET /responses?status=&priority=&limit=&cursor= read Advisories that matched (the API calls them responses), newest first. status is open, confirm (waiting to confirm), resolved or dismissed; priority is p1, p2 or p3.
GET /responses/{id} read One response with its exposures. {id} can also be the advisory id or a CVE id.
GET /exposures?status=&response_id=&component_id=&package=&limit=&cursor= read Exposures, newest first. status is open or fixed.
GET /components?limit=&cursor= read Repositories (the API calls them components) by name, with their last upload and open exposures
GET /evidence?after=&kind=&limit= read The evidence log in chain order, with each record’s hash and previous hash
GET /search?q=&limit= read Actions, advisories and repositories matching q
POST /acknowledge write Take responses on, which stops the P1 escalation
POST /decisions write Record “not affected” or “accepted risk”
POST /fixes write Ask for upgrade merge requests for every repository in a Now action

Acknowledge (up to 500 ids):

{ "response_ids": ["5d0c1f9e-..."] }

Not affected, with a VEX justification:

{
"response_ids": ["5d0c1f9e-..."],
"decision": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"reason": "We only call the parser on trusted input at build time."
}

justification is one of component_not_present, vulnerable_code_not_in_execute_path, vulnerable_code_cannot_be_controlled_by_adversary, inline_mitigations_already_exist or false_positive.

Accepted risk, with a review date at most a year away:

{
"response_ids": ["5d0c1f9e-..."],
"decision": "accepted",
"reason": "Internal tool behind the VPN; replacing it next quarter.",
"review_on": "2027-01-31"
}

Upgrade merge requests, with an action’s key from /now:

{ "action_key": "npm:axios:1" }

Upgrade merge requests are opened by the scheduled mopoke act job in your pipeline, on GitLab today.

Writes run through the same code as the web app, as the key’s owner, so the rules are the same: deciding a P1 needs an owner or admin, and every change is recorded in the evidence log under the owner’s name.

Lists page with next_cursor: pass it back as cursor with the same filters. It is empty on the last page. limit is up to 200 on most lists and up to 500 on /now.

The evidence log pages differently, in chain order: pass the next_after value back as after. limit is up to 1000.

Errors are JSON with a code and a message a person can act on:

{ "error": "insufficient_scope", "message": "..." }
Status Codes
401 api_key_required, invalid_api_key (unknown or revoked), api_key_expired. Sent with a WWW-Authenticate: Bearer header.
403 insufficient_scope, not_a_member (the key’s owner left the organisation), or a role refusal from a write
429 rate_limited, with Retry-After in seconds

Each key may make 120 requests a minute, with bursts of 60. The limit is there to stop a runaway script; spread large exports over time.

To react to changes as they happen (a new P1, a fix confirmed live, a package held), subscribe to webhooks rather than polling the API.