DivisionCero

Platform API

Read and write your team's cybersecurity records (risks, incidents, controls, policies, assets, third parties, projects and audit findings) from your own systems.

The DivisionCero public API exposes a team's records as REST over JSON. Each endpoint in this section includes its full schema, code samples and a playground to try it with your own key.

Base URL
https://app.divisioncero.com/api/v1

Authentication

Every call requires a team API key. Create it in the team settings (Settings → API) and send it in the Authorization header:

curl https://app.divisioncero.com/api/v1/risks \
  -H "Authorization: Bearer dcero_..."

The key determines the team and what it can read or write: no endpoint takes the team as a parameter. Session cookies are not accepted, so the API can be called from any origin (open CORS).

Permissions

You choose the key's permissions when you create it. Each endpoint states the permission it requires in its description; if the key doesn't have it, the response is 403.

ModuleReadWrite
Risksrisks.readrisks.write
Incidentsincidents.readincidents.write
Controlscontrols.read—
Policiespolicies.read—
Assetsassets.read—
Third partiesthird_parties.read—
Projectsprojects.read—
Audit findingsaudits.read—

Pagination and filters

List endpoints accept the same query parameters:

ParameterDescription
limitPage size, from 1 to 100 (default 50).
offsetRecords to skip (default 0).
searchSearches the code and the title or name.
updated_sinceOnly records updated since this date (ISO 8601); useful for incremental syncs.

The response wraps the records in data and indicates whether there are more pages:

{
  "data": [],
  "has_more": true,
  "next_offset": 50
}

To go through the whole list, repeat the call with offset=next_offset until has_more is false.

Creating and updating records

Risks and incidents support POST (create, responds 201) and PATCH (update). In a PATCH only the fields you send change; sending null clears an optional field.

The catalog identifiers these records require (category, treatment approach, detection source, status…) are specific to each team. Look them up first with GET /risks/catalogs and GET /incidents/catalogs.

Every write is recorded in the team's audit log under the name of the key that made it.

Rate limit

Each key can make 300 requests every 60 seconds. All responses include the headers:

  • RateLimit-Limit: requests allowed in the window.
  • RateLimit-Remaining: remaining requests.
  • RateLimit-Reset: seconds until the window resets.

When the limit is exceeded the response is 429 with the Retry-After header.

Errors

Errors respond with a JSON body containing code, status and message:

{
  "code": "UNAUTHORIZED",
  "status": 401,
  "message": "Missing, invalid or expired API key"
}
StatusCodeCause
400BAD_REQUESTInvalid parameters or body.
401UNAUTHORIZEDMissing, invalid or expired key.
403FORBIDDENThe key doesn't have the required permission.
404NOT_FOUNDThe route or record doesn't exist.
409CONFLICTThe record already exists (for example, a duplicate code).
429TOO_MANY_REQUESTSThe rate limit was exceeded.
500INTERNAL_SERVER_ERRORUnexpected error.

How is this guide?

On this page