API Documentation
Read your AI system registry — systems, models, model versions, evaluation results, reviews and approvals, metrics, model and system cards, and their risks — and the compliance program around it, AI governance and HIPAA alike, and feed it from your ML pipelines: propose systems, register model versions, record evaluation results and report metrics.
Overview
The Backsplice API gives programmatic access to your organization's AI system registry (AI systems, models, model versions, evaluation results, reviews and approvals, metrics, model and system cards, datasets, impact assessments, the human oversight roster and monitoring plans), and to the compliance program around it, AI governance and HIPAA alike: the one risk register and the risk analyses, assessments, findings, remediation, evidence metadata, vendors, incidents and breach notifications, management reviews, requests from individuals and the PHI disclosure log, devices, workforce sanctions, policies, training, the audit log and the program scores. All requests must be made over HTTPS.
| Base URL | https://backsplice.ai/api/v1/ |
| Availability | The REST API is included on Premium and Enterprise. It is not part of the Free plan, and a key from an organization that is not on a paid plan returns 403. |
| Format | JSON (Content-Type: application/json) |
| Authentication | Authorization: Bearer <api_key> |
| Rate limit | 100 requests per minute per API key. Exceeding the limit returns 429 Too Many Requests. |
Authentication
All API requests require a Bearer token. To create an API key, go to Settings → API Keys in your dashboard and click Generate new key. Store the key securely - it will only be shown once.
Include the key in every request using the Authorization header:
Authorization: Bearer bsk_••••••••••••••••••••••••••••••••••••••••••••••••
A key is bsk_ followed by 48 hexadecimal characters. Keys created before September 2026 begin ohk_ and keep working.
Scopes
Each API key is issued with one or more scopes that control which resources it can access.
| Scope | Access granted |
|---|---|
findings:read |
Read findings |
findings:write |
Create & update findings (write) |
assessments:read |
Read assessments |
assessments:write |
Create & update assessments (write) |
remediation:read |
Read tasks |
remediation:write |
Create & update tasks (write) |
evidence:read |
Read evidence metadata |
evidence:write |
Update evidence metadata (write) |
vendors:read |
Read vendors & agreements |
vendors:write |
Create & update vendors & agreements (write) |
incidents:read |
Read incidents |
incidents:write |
Create incidents (write) |
policies:read |
Read policies |
audit:read |
Read the audit log |
compliance:read |
Read the compliance score & posture |
risk_register:read |
Read the risk register |
risk_register:write |
Create risks in the risk register (write) |
ai_systems:read |
Read the systems register |
ai_systems:write |
Add systems (write) |
models:read |
Read AI models, versions and evaluation results |
models:write |
Register model versions (write) |
evaluations:write |
Record model evaluation results (write) |
cards:read |
Read published model and system cards |
approvals:read |
Read AI system reviews and signed decisions |
monitoring:read |
Read AI system monitoring metrics |
monitoring:write |
Report AI system monitoring metrics (write) |
datasets:read |
Read the dataset register and its lineage |
impact_assessments:read |
Read published AI impact and fundamental rights impact assessments |
management_reviews:read |
Read management reviews of the AI governance program |
oversight:read |
Read the human oversight roster |
monitoring_plans:read |
Read published AI system monitoring plans |
bias_audits:read |
Read the bias audits recorded for AI systems |
person_requests:read |
Read requests (never the names or contact details of the requester or the individual) |
scans:read |
Read vulnerability scans, their schedules and reports |
scans:write |
Start and cancel vulnerability scans and manage their schedules (write) |
devices:read |
Read the device register |
risk_analyses:read |
Read risk analyses and their entries |
phi_disclosures:read |
Read the disclosure log (never the individual, the recipient or the PHI) |
workforce_sanctions:read |
Read workforce sanctions (never the member or the violation) |
breach_notifications:read |
Read the breach notifications each incident gave and owes |
training:read |
Read the training roster & assignment report |
training:write |
Manage the training employee roster (write) |
webhooks:read |
List webhook endpoints |
webhooks:write |
Manage webhook endpoints (write) |
Endpoints
Returns a list of findings for your organization.
Required scope: findings:read
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: open, in_progress, resolved, accepted_risk, false_positive, all_open for every finding still open (open and in_progress on an obligation that already applies, the set the dashboard's Open Findings figure counts), or applies_later for open and in_progress findings whose obligation starts later (each row's applies_from gives the date). open alone is the literal status. |
risk_level | string | Filter by risk: critical, high, medium, low, informational |
Returns a list of assessments for your organization.
Required scope: assessments:read
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: draft, in_progress, review, completed, archived. An unrecognized value returns 400. |
limit | integer | Page size, clamped to 1–100. Default 100. |
offset | integer | Rows to skip. Default 0. |
Returns your organization's remediation tasks, or one task with ?id=. A key whose owner is not an org admin reads only the tasks assigned to them. Each task carries incident_id, the incident it is a corrective action for (null when it is not one), and external_assignee, true when the task is assigned to an invited address with no member account.
Required scope: remediation:read
Query parameters
| Parameter | Type | Description |
|---|---|---|
id | string | One task. A task outside your scope answers 404. |
status | string | Filter by status: open, in_progress, completed, deferred |
priority | string | Filter by priority: critical, high, medium, low |
from_incident | string | 1 for corrective actions only: tasks linked to an incident |
incident_id | string | One incident's corrective actions |
Read and update evidence metadata (filename, type, size, description, review/expiry dates, version). File contents are never served or writable via the API.
- GET — list evidence metadata (evidence:read).
- PATCH — update metadata by
id(evidence:write). Writable:description,review_date,expires_atonly.
Query parameters (GET)
| Parameter | Type | Description |
|---|---|---|
limit | int | Page size, 1–100 (default 100) |
offset | int | Row offset for pagination |
Read and manage vendors, including the AI each supplies (ai_involvement), whether it trains on your data (customer_data_training), whether it handles PHI for you (handles_phi: true, false, or null when not recorded; with business_associate_standing yes, possible or no, is_business_associate, and the baa_state: missing, expired, to_confirm, expiring, current or not_needed), its agreements (type baa, dpa or other, with signed and expiry dates), the agreement summary derived from them (has_agreement, agreement_signed_at, agreement_expires_at, all read-only) and review dates. Filter a list by baa. Pass ?id= to GET a single vendor.
- GET — list or fetch vendors (vendors:read).
- POST — create a vendor (vendors:write). Body:
name(required), plus optionalcontact_name,contact_email,website,services_provided,data_access,risk_level,status,handles_phi(true, false or null),ai_involvement,customer_data_training,next_review_date,notes. Returns HTTP 201. Agreements are recorded on the vendor's Agreements tab in the app; a body naming a derived agreement field is refused with 400. - PATCH — update a vendor by
id(vendors:write).
Query parameters (GET)
| Parameter | Type | Description |
|---|---|---|
id | string | Return a single vendor by id |
status | string | Filter by status: active, under_review, terminated |
risk_level | string | Filter by risk: low, medium, high, critical |
ai_involvement | string | Filter by the AI the vendor supplies: none, embedded, ai_product, model_provider |
customer_data_training | string | Filter by whether the vendor trains on your data: unknown, no, opt_out, yes |
| An unrecognized filter value is refused with HTTP 400, naming the allowed values. | ||
The Systems register. GET lists systems (filters stage, risk_tier, flag (ai or ephi), generative, q) or fetches one with ?id=, adding its intended use, oversight design and models (ai_systems:read). Every system carries uses_ai and handles_ephi as booleans. POST adds a system (ai_systems:write) with uses_ai (default true) and handles_ephi (default false), at least one true; it counts toward the limit of each flag it holds. A system that uses AI is created in proposed, unclassified; one that does not is created in use (deployed), with no review, and an AI field sent with uses_ai: false is refused. The API never decides: a request carrying risk_tier, eu_ai_act_class, is_gpai, lifecycle_stage or next_review_date is refused. A person sets those on the system's page, and the lifecycle moves only through a review.
Filters take the listed values only; any other value is refused with HTTP 400, naming the allowed values.
AI models (models:read). ?id= returns one model with its recorded versions, the systems it backs and how many evaluation results exist.
Register a new version of a model from a CI or ML pipeline (models:write). Body: model_id, version (required), optional released_on, evaluation_summary, notes. It changes no system's approval; a system that pins a version keeps its pin.
Model evaluation results, one metric per result. GET ?model_id= (optional version_id) lists them newest first, paged with limit (at most 200) and offset (models:read). POST records one (evaluations:write, not granted by default): model_id, version_id, metric, value, optional threshold, passed, dataset, notes, measured_at. Results are append-only, and passed is recorded as sent, never worked out from the threshold.
Published model and system card versions (cards:read). Pass version_id, or system_id / model_id for that subject's latest published card with its content. Drafts are never returned.
AI system reviews and the decisions approvers signed (approvals:read). Filter by system_id or status; ?id= returns one review with its approvers and decisions. Read-only: a decision is signed in the dashboard with a password and a second factor, never through a key.
Filters take the listed values only; any other value is refused with HTTP 400, naming the allowed values.
The risk register. GET lists risks (filters status, category, treatment, ai_system_id) or fetches one with its treating controls (risk_register:read). POST creates a risk (risk_register:write, org admins only) under the same rules as the form: a category is required (an AI trustworthy characteristic, a HIPAA Security Rule section, or the Privacy Rule safeguards), a NIST AI 600-1 category needs a generative system or model, and the residual pair is both or neither. Unrated residual values are null, never zero.
Filters take the listed values only; any other value is refused with HTTP 400, naming the allowed values.
The dataset register (datasets:read): each dataset's source, terms, whether a person recorded that it holds personal data, and its known limitations. Filter by status, source_type, personal_data or q; ?id= returns one dataset with the systems and models that use it, each in its role. Read-only.
Filters take the listed values only; any other value is refused with HTTP 400, naming the allowed values.
Each AI system's AI impact assessment and fundamental rights impact assessment, as the register shows them (impact_assessments:read). Filter by aiia or fria (none, draft, published, due) or q. Pass version_id (or id, the same value), or system_id and kind (aiia or fria) for that system's latest published version with its sections and how it was signed; naming a version beside a system or kind is refused. Published versions only: a draft's text is never returned, and versions are approved in the dashboard with a password and a second factor.
Management reviews of the AI governance program (management_reviews:read), drafts and finalized, filtered by status or q (every review's title, and the minutes and decisions of finalized reviews only). ?id= returns a finalized review with its minutes, decisions, actions and the program's numbers as they stood when it was finalized; a draft review is not returned. Read-only.
The human oversight roster (oversight:read): who is assigned which oversight capability on each AI system, whether they are still an active member who can act, and the date each was briefed on automation bias (automation_bias_briefed_on, null when not recorded). Lists today's current assignments unless state (current, scheduled, ended, all) says otherwise; filter by system_id or capability. Read-only.
Monitoring plans (monitoring_plans:read): every AI system in the inventory with where its plan stands (state: none, draft, published), its latest published version, when the plan was last confirmed current, whether its review is due (by the review frequency of the published version in force), whether the draft has changes that are not published, and plan_gap (a deployed system recorded as high-risk with no published plan). ?id= returns one published version, or ?system_id= that system's latest: what is monitored and why, the data sources, thresholds and escalation, responsibilities, how findings reach incidents and re-review, the review frequency, and the metrics and oversight roster as they stood when it was published. A draft's text is not returned. Read-only.
Bias audits (bias_audits:read): the bias audits recorded for your AI systems under New York City Local Law 144, newest first, filtered by system_id, method and data_source: each audit's date, the date the next is due and its state (current, due_soon, overdue), the auditor and whether independence is recorded, the method, the data used, the categories calculated, the count of people in an unknown category (null when not recorded), the published summary and what the record leaves out (gaps). ?id= adds, for an admin or an auditor, the test-data explanation and notes. Read-only.
Requests from people affected by an AI-assisted decision (person_requests:read). An admin's or auditor's key reads every request; any other member's key reads the requests they handle or review. Filter by status, request_type, legal_basis, ai_system_id, overdue=1 or q; ?id= adds the summary and the response. The requester's name and contact are never returned through the API: the requester reference identifies the request. Read-only.
Manage the delivered-training employee roster — built for HR-system sync. Employees are keyed by email (unique per organization), so re-posting a person updates them and never duplicates. Course assignment and invite emails stay in the dashboard.
- GET — list the roster,
?id=for one employee,?active=1for active only (training:read). - POST — upsert by
email(training:write). Body:full_name(required),email(required), optionaldepartmentandai_roles, a list drawn frombuilder,reviewer(approvers) andexecutive(leadership); everyone takes AI literacy and each role adds its own course. Returns HTTP 201 when created, 200 when an existing email was updated. - PATCH — update by
id:full_name,department,is_active(training:write). Deactivation excludes the employee from bulk assignment while preserving history. - DELETE — remove by
?id=(training:write). Employees with completed training cannot be deleted (HTTP 409) — completions are compliance evidence; deactivate instead.
Read-only delivered-training report (training:read): every assignment with its effective status (expired once a pass is older than the 12-month validity window), score, attempts, duration, valid-through date, reminder count, invite-failure flag, and certificate id, plus an org-level stats block. Filters: course_key, status, employee_id; paginate with limit/offset. Assigning, resending, and revoking are dashboard-only actions (they send email).
The complete merged training transcript (training:read) — both delivered employee training and legacy manually-logged completions, the same dataset as the dashboard transcript export. One call gives an auditor or HR system the organization's full training record. Filters: q (person name/email), source (delivered|logged), status; paginate with limit (max 200) / offset. Every pull is recorded in the audit log.
Manage your organization's outbound webhook endpoints.
- GET — list endpoints (webhooks:read). Append
?catalog=1for the list of subscribable event names. Signing secrets are never returned on read. - POST — create an endpoint (webhooks:write). Body:
url,events(array), optionaldescription. The signingsecretis returned once in the response. - PATCH — update
url/events/description/is_activebyid(webhooks:write). - DELETE — remove an endpoint by
id(webhooks:write).
Webhook URLs are validated against an SSRF guard. Use the X-HTTP-Method-Override header if your client can't send PATCH/DELETE.
Returns your organization's incidents: type, severity, the AI system and model involved, whether personal data was involved, the answers to whether protected health information and a system that uses AI were involved (phi_involved, ai_involved, ai_serious; null for an incident logged before the questions), people affected (null when not yet known), and whether the incident is serious and when an authority was notified. Pass ?id= for a single incident. POST creates one (incidents:write) with title, discovery_date and optional incident_type, severity, ai_system_id, ai_model_id, description, personal_data_involved, people_affected, serious_incident, phi_involved (yes, no, unknown), ai_involved (yes, no) and ai_serious (yes, no, unknown; when recorded it decides serious_incident, and ai_involved: no records it as not serious). A new incident starts open; move it on in the dashboard once it has been triaged.
Required scope: incidents:read
Query parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Return a single incident by id |
status | string | Filter: open, under_review, resolved, reported |
incident_type | string | Filter: harmful_output, inaccurate_output, biased_outcome, performance_degradation, misuse_or_attack, data_exposure, safety_harm, rights_impact, unapproved_use, outage, other, unauthorized_access, theft_loss, improper_disposal, hacking |
severity | string | Filter: low, medium, high, critical |
ai_system_id | string | Filter to incidents involving one AI system |
personal_data_involved | boolean | Filter to incidents where personal data was involved |
serious_incident | boolean | Filter to incidents recorded as serious |
Returns policies with status, version, owner, and review dates. Pass ?id= for a single policy.
Required scope: policies:read
Query parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Return a single policy by id |
status | string | Filter: draft, active, under_review, retired |
policy_type | string | Filter by type (e.g. governance, acceptable_use, transparency) |
overdue_review | boolean | Only policies past their review date |
Returns your organization's tamper-evident audit log, newest first — the same event stream that drives webhooks and SIEM export. Ideal for pulling activity into your own SIEM/GRC tooling.
Required scope: audit:read
Query parameters
| Parameter | Type | Description |
|---|---|---|
event | string | Prefix match on the event name (e.g. incident matches incident.created, incident.closed) |
event_exact | string | Match one full event name exactly |
entity_type | string | Filter by entity type (e.g. finding, policy) |
from / to | string | Bound created_at (inclusive), YYYY-MM-DD or YYYY-MM-DD HH:MM[:SS]; a date alone as to includes that whole day. Anything else, including a relative date such as yesterday, returns 400. |
Returns your organization's compliance scores, one per assessment family and never blended: the top-level score (0–100), letter grade and per-dimension breakdown are the AI governance score (Findings, Policies & Docs, Training, Incident Response), and scores lists every family you are scored in — the HIPAA score too once you have a HIPAA assessment — each with its own dimensions and the date of its last daily snapshot.
Required scope: compliance:read
Write operations
Each requires the matching *:write scope. Send a JSON body; use the X-HTTP-Method-Override header for PATCH if your client can't send it directly.
- PATCH
/api/v1/findings.php— update a finding byid. Editable:status(open,in_progress,resolved,accepted_risk,false_positive),risk_level,title,notes,description,category,recommendation,due_date. - POST
/api/v1/remediation.php— create a task. Body:title(required),description,status(notcompleted),priority,assigned_to(the email of an active member of your organization; invite anyone else from the dashboard),due_date(YYYY-MM-DD),finding_id. Returns HTTP 201 with the created task. - PATCH
/api/v1/remediation.php— update a task byid. Editable:title,description,status,priority,assigned_to,due_date. Completing a task that needs approval (or an AI approval condition) sends it to the approvers instead, answeringpending_approval: true; the other fields are still saved. - PATCH
/api/v1/assessments.php— update an assessment'sname,status, ordue_datebyid. Changing the status needs an organization admin's key, as in the dashboard:in_progress,review,completedorarchived(neverdraft). Completing does what Mark Complete does, raising the findings and recording the score. An archived assessment cannot be changed, and a completed one cannot be renamed. - POST / PATCH
/api/v1/vendors.php— create (201) or update a vendor byid(vendors:write). - PATCH
/api/v1/evidence.php— update evidence metadata (description,review_date,expires_at) byid(evidence:write). - POST / PATCH / DELETE
/api/v1/training-employees.php— upsert (by email), update, or remove training-roster employees (training:write); employees with completions can only be deactivated. POST acceptsauto_assign: trueto also assign every due built-in course and email the invites (HR-sync onboarding in one call).
Response format
List (GET) responses return HTTP 200 with a data array, the count in this page, and the limit / offset used. Findings and remediation also include a total (the full match count); assessments omit total. A successful create (POST /api/v1/remediation.php) returns HTTP 201 with the created record.
{
"data": [
{ "id": "abc123", "title": "...", "status": "open", ... }
],
"count": 1,
"total": 1,
"limit": 100,
"offset": 0
}
Paginate with ?limit= (1–100, default 100) and ?offset=.
Error responses
Errors return a non-2xx HTTP status with a JSON body carrying a single
error key:
{
"error": "Invalid or expired API key."
}
| HTTP status | Meaning |
|---|---|
400 | Malformed request — an unrecognized filter value, or invalid JSON in the body |
401 | Missing or invalid API key |
403 | Valid key, but insufficient scope, insufficient role, a disabled org module, or no accepted Data Processing Agreement |
404 | No such record, or it belongs to another organization |
405 | Method not supported on this endpoint |
409 | Conflicts with the current state of the record |
415 | Request body was not application/json |
422 | Well-formed request that fails a validation rule |
429 | Rate limit exceeded. See the Retry-After and X-RateLimit-* headers |
500 | Internal server error |
Rate limit headers
Every response carries the current window state, so a client can back off before it is throttled rather than after:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests permitted in the current window |
X-RateLimit-Remaining | Requests left in it |
X-RateLimit-Reset | Unix timestamp when the window resets |
Retry-After | Seconds to wait. Sent with a 429. |
Example
Fetch all open critical findings using curl:
curl -s \
-H "Authorization: Bearer bsk_••••••••••••••••••••••••••••••••••••••••••••••••" \
-H "Accept: application/json" \
"https://backsplice.ai/api/v1/findings.php?status=open&risk_level=critical"
Example response:
{
"data": [
{
"id": "fnd_01j9kx4",
"title": "No documented human oversight for an automated decision system",
"risk_level": "critical",
"status": "open",
"created_at": "2026-01-15T09:32:00Z"
}
],
"count": 1
}