Skip to main content
For AI agents: a documentation index is available at https://docs.coverbase.com/llms.txt. This page is also available in markdown by appending .md to the URL.
These endpoints let you build and tune the control sets your vendors are assessed against. A control set (cbctst_...) holds sections (cbctsn_...) and controls (cbctrl_...). Settings on the set apply to every control in it: AI evaluation guidance, strictness, evidence sources, applicability and Zero Touch eligibility. Controls are versioned. A material edit to a control creates a new version with a new id and the same perma_id, so past assessments keep the text they were evaluated on. Control sets and sections are edited in place. Every change to a set or control is recorded in its activity, as the same edit in the dashboard is. All endpoints are org-scoped to the API key. See API conventions for shared behavior. None of these honor Idempotency-Key. Archiving or unarchiving a set or section also needs control_set:archive:org, and archiving a control needs control:archive:org. Archiving and unarchiving stay with signed-in users: in every organization, a request made with an API key that archives or unarchives returns 403 api_key_not_allowed.

Control set object

string
Control set ID (cbctst_...).
string
Name.
string
policy, questionnaire or internal.
string | null
Description.
boolean
Whether the set is archived.
boolean
Whether the set applies to every vendor.
string[]
Tags whose vendors the set applies to.
string[]
Inherent risk levels whose vendors the set applies to.
boolean
Whether Zero Touch assessments can use the set.
integer
How strictly the AI judges evidence, from 1 (lenient) to 5 (skeptical). New sets use 3.
string | null
Guidance the AI applies when it evaluates every control in the set.
string | null
Guidance for remediation wording.
boolean
Whether evaluations search the web.
string | null
Guidance for web search.
object[]
The evidence sources the AI draws on.
boolean
Whether the AI uses only the listed evidence sources.
object[]
Documents vendors provide, each { "document_type": "<slug>", "is_required": true }.
string | null
Risk domain the set rolls up to.
number | null
The set’s share of the vendor rating. null leaves it out of the weighting.
string | null
The scale every live control uses. null when the controls use different scales or none.
string[]
Users who watch the set.
string | null
The library template the set was copied from.
integer | null
The template revision the copy carries.
string | null
The questionnaire derived from the set.
integer
Number of live controls.
integer
Unix timestamp (seconds).

Evidence source object

string
document, factsheet, web_search or contracts.
string[]
For document: the document types to search. Empty means every type.
string | null
How the AI uses the source.
boolean
When true, the AI cites this source or flags its absence.
string
For a required document source: any (one type is enough) or all.
string
For web_search: the lowest publisher credibility accepted.
string[]
For web_search: page types to exclude.
A contracts source shares contract terms with every evaluation, so adding one needs contract:read:org.

List control sets

GET
GET /v1/control-sets

Query parameters

integer
default:"50"
Page size, from 1 to 200.
integer
default:"0"
Number of sets to skip.
boolean
default:"false"
Include archived sets.
Returns an items array of control set objects, newest first, with total, limit and offset.

Create a control set

POST
POST /v1/control-sets
Returns 201 Created with the control set object. To copy a framework template with its sections and controls, send its slug from the library as use_library.

Request body

string
required
Name.
string
default:"policy"
policy, questionnaire or internal. A library copy takes the template’s type.
string
Description.
boolean
default:"false"
Apply the set to every vendor.
string[]
Tags whose vendors the set applies to.
boolean
Make the set available to Zero Touch assessments.
integer
From 1 (lenient) to 5 (skeptical).
string
Set-level AI guidance.
string
Remediation guidance. A library copy ignores it.
boolean
default:"false"
Let evaluations search the web.
string
Web search guidance, at most 2000 characters.
object[]
boolean
default:"true"
Use only the listed evidence sources.
object[]
Required documents. A library copy ignores it.
string
Risk domain. A library copy otherwise takes the template’s domain.
string
Scale for every control of the set.
string[]
Users who watch the set.
string
Library template slug to copy.

Example request

cURL

Retrieve a control set

GET
GET /v1/control-sets/{control_set_id}
Returns the control set object, archived or live, or 404 control_set_not_found.

Update a control set

PATCH
PATCH /v1/control-sets/{control_set_id}
Only the fields you send change. To clear risk_domain_id or vendor_rating_weight, send null. An archived set returns 409 control_set_archived. Returns the updated control set object.

Request body

Every create field except control_set_type and use_library, plus:
string[]
Inherent risk levels the set applies to. Replaces the list.
number
Share of the vendor rating, greater than 0 and at most 1000.
boolean
Archive the set with its sections and controls. Needs control_set:archive:org. An API key gets 403 api_key_not_allowed.
Lists you send (applied_to_tag_ids, evidence_sources, document_requirement, watcher_ids) replace the stored list. A scale_id applies to every live control.

Update many control sets

PATCH
PATCH /v1/control-sets/bulk
Applies up to 200 updates in one call. If any update fails, none is applied, and the error names the failing item in detail.id. Each control set may appear once per call.
object[]
required
From 1 to 200 items. Each item takes control_set_id and the fields of Update a control set, with the same rules.
Returns an items array of the updated control set objects, in request order.

Get control set stats

GET
GET /v1/control-sets/{control_set_id}/stats
Returns vendor_count (vendors the live set applies to) and vendor_percentage (their share of the org’s vendors).

List sections

GET
GET /v1/control-sets/{control_set_id}/sections
integer
default:"100"
Page size, from 1 to 500.
integer
default:"0"
Number of sections to skip.
boolean
default:"false"
Include archived sections.
Returns an items array of section objects in display order, with total, limit and offset.

Section object

string
Section ID (cbctsn_...).
string
Parent control set.
string
Name.
string | null
Description.
string
Section reference, for example CC6.
string
Fractional order key.
boolean
Whether the section is archived.
boolean | null
Overrides the set’s web search setting. null inherits it.
string | null
Web search guidance.
string | null
Risk domain.
string[]
Users who watch the section.
integer
Unix timestamp (seconds).

Create a section

POST
POST /v1/control-sets/{control_set_id}/sections
Returns 201 Created with the section object. An archived set returns 409 control_set_archived. Every watcher must be a member of your organization, or the request returns 422 invalid_watcher.
string
required
Name.
string
required
Section reference.
string
Description.
string
Fractional order key. Without it, the section goes last.
boolean
Override the set’s web search setting.
string
Web search guidance, at most 2000 characters.
string
Risk domain.
string[]
Users who watch the section.

Update a section

PATCH
PATCH /v1/control-sections/{control_section_id}
Takes the create fields and is_archived. Only the fields you send change. To clear risk_domain_id, send null. Archiving a section archives its controls and needs control_set:archive:org. An API key that archives or unarchives a section gets 403 api_key_not_allowed. An archived section accepts only is_archived: false. Returns the updated section object.

Control object

string
Control version ID (cbctrl_...).
string
ID shared by every version of the control.
integer
Version number, starting at 1.
string
Control set.
string | null
Section.
string | null
Reference, for example SOC2-CC6.1. Unique within the set.
string
What the vendor must do.
string | null
The question vendors answer.
string | null
Extra guidance shown with the question.
string
How the question is answered, for example free_text, select_one or select_multiple.
string | null
Guidance the AI follows when it evaluates the control.
integer | null
Scoring weight.
boolean
Whether an answer is required.
boolean
Whether respondents can add a comment.
boolean
Whether a comment is required.
string[]
Supporting document type slugs.
boolean | null
Overrides the set’s web search setting.
string | null
Web search guidance.
object[]
Evidence sources for this control. Empty means the set’s sources apply.
string | null
document_required or attestation_only.
string | null
A risk scale level. When set, a failing control floors the score at this level.
string | null
What the floor applies to, for example risk_domain.
string | null
Scale the control is scored on.
boolean
Whether this version is archived. An earlier version is archived once a newer one exists.
object[]
Live answer choices, each with id, perma_id, name, description, value and sort_order.
integer
Unix timestamp (seconds).

List controls

GET
GET /v1/control-sets/{control_set_id}/controls
integer
default:"100"
Page size, from 1 to 500.
integer
default:"0"
Number of controls to skip.
boolean
default:"false"
Include archived controls.
Returns the latest version of each control as an items array of control objects, in set order, with total, limit and offset.

Create a control

POST
POST /v1/control-sets/{control_set_id}/controls
Returns 201 Created with version 1 of the control object. An archived set returns 409 control_set_archived. To set evidence_requirement or the significant-deficiency floor, send a PATCH afterwards.
string
required
What the vendor must do.
string
A live section of the same set.
string
Reference. A duplicate within the set returns 409 duplicate_external_idx.
string
The question vendors answer.
string
Extra guidance shown with the question.
string
default:"free_text"
How the question is answered.
object[]
Answer choices, each { "name": "Yes", "description": null, "value": 1, "sort_order": null }.
string
AI evaluation guidance.
integer
default:"1"
Scoring weight.
boolean
default:"true"
Whether an answer is required.
boolean
Let respondents add a comment.
boolean
Require a comment. Turns on allow_comments.
string[]
Supporting document type slugs.
boolean
Override the set’s web search setting.
string
Web search guidance, at most 2000 characters.
object[]
string
Scale. Without it, the org’s default scale applies.

Retrieve a control

GET
GET /v1/controls/{control_id}
Returns the control object for that version, archived or live, or 404 control_not_found.

Update a control

PATCH
PATCH /v1/controls/{control_id}
Takes every create field, all optional, plus the fields below. Only the fields you send change. Returns the resulting control object. A material change creates a new version, and the response carries its new id. These fields are material: expectation, question, question_additional_instructions, response_type, eval_instructions, weight, is_required, control_section_id, significant_deficiency_level_id, significant_deficiency_scope and options. Other fields change the version in place.
string
document_required or attestation_only. Send null to clear it.
string
A risk scale level. Send null to clear the floor.
string
What the floor applies to. Send null to clear it.
string
Move to this section of the same set. Send unassigned to remove it from its section.
object[]
Answer choices to add or edit. A new choice has no id. To edit an existing choice, send its id and perma_id with the fields to change, or "is_archived": true to remove it.
boolean
Archive or unarchive the control. Needs control:archive:org. An API key gets 403 api_key_not_allowed.
If you edit an earlier version, the request returns 409 control_superseded with the latest version’s ID in the message.

Example request

cURL

Update many controls

PATCH
PATCH /v1/controls/bulk
Applies up to 200 control updates in one call. If any update fails, none is applied, and the error names the failing item in detail.id. Each control may appear once per call.
object[]
required
From 1 to 200 items. Each item takes control_id and the fields of Update a control, with the same rules.
Returns an items array in request order. Each item has previous_id (the ID you sent) and control (the resulting control object). A material change gives control a new id.

Get control history

GET
GET /v1/controls/{control_id}/history
integer
default:"20"
Versions per page, from 1 to 100.
integer
default:"0"
Page number, counted in pages of limit versions.
Returns an items array of control objects, newest version first, starting from the version you name.

Move, archive or unarchive controls

POST
POST /v1/controls/bulk-action
Moves many controls into one section, or archives or unarchives them. If any control fails, nothing changes. The section must belong to the same control set as every control, or the request returns 422 invalid_bulk_action. Unarchiving an earlier version of a control returns 409 control_superseded, because a newer version is live. Each moved control takes a new version. Returns { "action": "add_to_section", "control_count": 2 }.
string
required
add_to_section, archive or unarchive. Archiving and unarchiving needs control:archive:org, and an API key gets 403 api_key_not_allowed.
string[]
required
From 1 to 500 control IDs.
string
Destination section. Required for add_to_section.

Review a framework reference

PATCH
PATCH /v1/controls/{control_id}/framework-references/{index}
Accepts or rejects a suggested framework reference on a control. Only an accepted reference counts toward framework coverage.
string
required
accept, reject (removes the reference) or no_clause (records that the framework has no matching clause).
Returns framework_references, the control’s references after the change, or 404 framework_reference_not_found.

Start a crosswalk

POST
POST /v1/control-sets/{control_set_id}/crosswalk
Returns 202 Accepted. Suggests, in the background, a reference in each target framework for every control of the set. A suggestion counts toward coverage only once you accept it.
string[]
required
From 1 to 50 framework control sets to map onto. Each must be a live control set of your organization other than this one, or the request returns 422 invalid_crosswalk_targets and nothing is queued.
Returns queued and target_control_set_ids, the distinct targets that were queued. An archived subject set returns 409 control_set_archived.

Read a crosswalk

GET
GET /v1/control-sets/{control_set_id}/crosswalk
Returns frameworks and rows. Each framework has framework, control_set_id, accepted_clauses, total_clauses and suggested. Each row has control_id, external_idx, expectation, section and refs. Each reference has index (the value a review takes), framework, reference, rationale and review_state (suggested or accepted).

List library templates

GET
GET /v1/control-set-library
Returns an items array of templates you can copy with use_library. Each has slug, name, num_controls, control_set_type, audience (vendor or internal), description and is_web_search_enabled.

List library updates

GET
GET /v1/control-set-library/updates
Returns an items array of the org’s library copies whose template has a newer revision. Each has control_set_id, control_set_name, template_slug, template_name, from_revision, to_revision, vendor_count and changes. Each change has external_idx, kind (added, changed or removed), expectation, previous_expectation and is_conflict (the copy was edited by hand).

Apply a library update

POST
POST /v1/control-sets/{control_set_id}/apply-library-update
Brings a library copy to its template’s latest revision. Changed controls take a new version. Controls edited by hand stay as they are. Returns applied and conflicts (lists of external_idx) and to_revision, or 409 no_library_update.

Draft a reassessment of affected vendors

POST
POST /v1/control-sets/{control_set_id}/reassess-affected
Returns 201 Created with reassessment_id and vendor_count. Drafts one reassessment of the vendors assessed with the set.
string[]
Vendors to include. Without it, every vendor assessed with the set is included.

Export a control set

POST
POST /v1/control-sets/{control_set_id}/exports
Returns 202 Accepted with the export’s id and status. Coverbase builds an Excel workbook of the set, named export_filename, in the background. Poll GET /v1/control-set-exports/{export_id}: once status is complete, the response carries a download_url that expires after expires_in seconds. The poll response is never cached.

Find matching control sets

GET
GET /v1/vendors/{vendor_id}/control-set-matches
Lists the control sets that apply to a vendor, one row per set, with the reason: applied to every vendor, the vendor’s inherent risk, or one of its tags. The route also checks that you can read the vendor. GET /v1/assessments/{assessment_id}/control-set-matches lists the control sets the assessment’s custom questionnaires match that are not on the assessment yet. Each row has the questionnaire_name, a score, and how many questions overlap. The route also checks that you can read the assessment.

Error responses