Audits and violations
Read the results of compliance audits and record review decisions. Every decision follows the same rules as the Typetone app and shows up in the audit's activity trail.
Endpoints
List audits
api.app.typetone.ai/public/v1/audits Returns the workspace's compliance audits, newest first, with a violation count for each.
Authorization
X-API-KeyheaderrequiredYour workspace API key.
Query parameters
limitintegerdefault20Maximum number of results.
Response · 200
auditsarray of AuditrequiredThe audits, newest first.
returnedintegerrequiredNumber of items in this response.
limitintegerrequiredMaximum number of results.
Errors
-
401Missing or invalid API key. -
403The workspace is not on a plan with API access. -
404The resource does not exist in this workspace. -
422A parameter or the request body is invalid.detailsays which.
curl "https://api.app.typetone.ai/public/v1/audits?limit=20" \
-H "X-API-Key: $TYPETONE_API_KEY" import os
import requests
response = requests.get(
"https://api.app.typetone.ai/public/v1/audits?limit=20",
headers={"X-API-Key": os.environ["TYPETONE_API_KEY"]},
)
response.raise_for_status()
print(response.json()) const response = await fetch("https://api.app.typetone.ai/public/v1/audits?limit=20", {
headers: {
"X-API-Key": process.env.TYPETONE_API_KEY,
},
});
const data = await response.json(); {
"audits": [
{
"id": "cmuf2k8x10001ab12cd34ef56",
"name": "Homepage audit",
"status": "COMPLETED",
"created_at": "2026-09-24T09:30:00Z",
"completed_at": "2026-09-24T09:42:00Z",
"total_assets": 42,
"completed_assets": 3,
"failed_assets": 3,
"total_violations": 42
}
],
"returned": 3,
"limit": 3
} List violations
api.app.typetone.ai/public/v1/audits/{audit_id}/violations Pages through the violations of one audit. By default it returns open violations nobody has decided on yet (review_state=undecided), so a reviewer can work through the queue. review_progress counts every state for the whole audit.
Authorization
X-API-KeyheaderrequiredYour workspace API key.
Path parameters
audit_idstringrequiredID of the audit, from List audits.
Query parameters
review_statestringundecided,elevated_risk,urgent_violation,dismissedorfixed. As a filter,allreturns every state.One of
undecidedelevated_riskurgent_violationdismissedfixedallseveritystring | nullSeverity of the rule:
CRITICAL,HIGH,MEDIUM,LOWorUNSPECIFIED.One of
UNSPECIFIEDLOWMEDIUMHIGHCRITICALsearchstring | nullOnly violations whose text, reason or rule name contains this term.
pageintegerdefault1Page number, starting at 1.
page_sizeintegerdefault20Results per page.
Response · 200
audit_idstringrequiredID of the audit, from List audits.
violationsarray of ViolationrequiredThe violations on this page.
totalintegerrequiredTotal number of matching violations.
pageintegerrequiredPage number, starting at 1.
page_sizeintegerrequiredResults per page.
has_morebooleanrequiredWhether there is another page.
review_progressReviewProgressrequiredHow many violations of the whole audit are in each review state.
Errors
-
401Missing or invalid API key. -
403The workspace is not on a plan with API access. -
404The resource does not exist in this workspace. -
422A parameter or the request body is invalid.detailsays which.
curl "https://api.app.typetone.ai/public/v1/audits/cmrl4bksl5wtt78geytff18uw/violations?review_state=string&page_size=20" \
-H "X-API-Key: $TYPETONE_API_KEY" import os
import requests
response = requests.get(
"https://api.app.typetone.ai/public/v1/audits/cmrl4bksl5wtt78geytff18uw/violations?review_state=string&page_size=20",
headers={"X-API-Key": os.environ["TYPETONE_API_KEY"]},
)
response.raise_for_status()
print(response.json()) const response = await fetch("https://api.app.typetone.ai/public/v1/audits/cmrl4bksl5wtt78geytff18uw/violations?review_state=string&page_size=20", {
headers: {
"X-API-Key": process.env.TYPETONE_API_KEY,
},
});
const data = await response.json(); {
"audit_id": "cmrl4bksl5wtt78geytff18uw",
"violations": [
{
"id": "cmuf2k8x10001ab12cd34ef56",
"audit_id": "cmrl4bksl5wtt78geytff18uw",
"review_state": "undecided",
"severity": "HIGH",
"rule_id": "cmoa6kg13yytl58gel3vakaxy",
"rule_name": "No guaranteed returns",
"asset_id": "cmrl4apwj5wtdllge0x59w6v2",
"asset_name": "Savings account landing page",
"asset_url": "https://www.example.com/savings",
"violating_text": "Guaranteed 8% return, every year.",
"reason": "The copy promises a guaranteed return, which is misleading for an investment product.",
"recommended_solution": "Remove the guarantee and state that returns can vary.",
"suggested_text": "Target return of 8% a year. Returns are not guaranteed.",
"dismissal_reason": null,
"group_id": "cmrl4g2b75wv1jfge9hx0p2kd",
"assigned_to_user_ids": [
"cmuf2k8x10001ab12cd34ef56"
]
}
],
"total": 42,
"page": 1,
"page_size": 20,
"has_more": false,
"review_progress": {
"undecided": 3,
"elevated_risk": 3,
"urgent_violation": 3,
"dismissed": 3,
"fixed": 3
}
} Get a violation
api.app.typetone.ai/public/v1/violations/{violation_id} Everything a reviewer needs to decide: the flagged text, why it was flagged, the rule, the recommended fix, suggested replacement text and the comment thread.
Authorization
X-API-KeyheaderrequiredYour workspace API key.
Path parameters
violation_idstringrequiredID of the violation, from List violations.
Response · 200
idstringrequiredUnique ID.
audit_idstring | nullrequiredID of the audit, from List audits.
review_statestringrequiredundecided,elevated_risk,urgent_violation,dismissedorfixed. As a filter,allreturns every state.One of
undecidedelevated_riskurgent_violationdismissedfixedseveritystring | nullrequiredSeverity of the rule:
CRITICAL,HIGH,MEDIUM,LOWorUNSPECIFIED.rule_idstring | nullrequiredThe rule the violation breaks.
rule_namestring | nullrequiredName of the rule.
asset_idstring | nullrequiredThe asset (web page, document or post) the violation was found on.
asset_namestring | nullrequiredName of the asset.
asset_urlstring | nullrequiredURL or identifier of the asset.
violating_textstring | nullrequiredThe text on the asset that triggered the violation.
reasonstringrequiredWhy the audit flagged this text.
recommended_solutionstring | nullrequiredHow to fix the violation.
suggested_textstring | nullrequiredReplacement text that would fix the violation, when the audit could suggest one.
dismissal_reasonstring | nullrequiredWhy the violation was dismissed, when it was.
group_idstring | nullrequiredViolations with the same group_id are the same finding on several assets; review them together with apply_to_group.
assigned_to_user_idsarray of stringrequiredUsers the violation is assigned to in the app.
rule_descriptionstring | nullrequiredWhat the rule checks.
rule_explanationstring | nullrequiredBackground on the rule, such as the regulation behind it.
commentsarray of ViolationCommentrequiredThe comment thread, oldest first.
Errors
-
401Missing or invalid API key. -
403The workspace is not on a plan with API access. -
404The resource does not exist in this workspace. -
422A parameter or the request body is invalid.detailsays which.
curl "https://api.app.typetone.ai/public/v1/violations/cmrl4efwd5wu8jfgepgjbxam6" \
-H "X-API-Key: $TYPETONE_API_KEY" import os
import requests
response = requests.get(
"https://api.app.typetone.ai/public/v1/violations/cmrl4efwd5wu8jfgepgjbxam6",
headers={"X-API-Key": os.environ["TYPETONE_API_KEY"]},
)
response.raise_for_status()
print(response.json()) const response = await fetch("https://api.app.typetone.ai/public/v1/violations/cmrl4efwd5wu8jfgepgjbxam6", {
headers: {
"X-API-Key": process.env.TYPETONE_API_KEY,
},
});
const data = await response.json(); {
"id": "cmuf2k8x10001ab12cd34ef56",
"audit_id": "cmrl4bksl5wtt78geytff18uw",
"review_state": "undecided",
"severity": "HIGH",
"rule_id": "cmoa6kg13yytl58gel3vakaxy",
"rule_name": "No guaranteed returns",
"asset_id": "cmrl4apwj5wtdllge0x59w6v2",
"asset_name": "Savings account landing page",
"asset_url": "https://www.example.com/savings",
"violating_text": "Guaranteed 8% return, every year.",
"reason": "The copy promises a guaranteed return, which is misleading for an investment product.",
"recommended_solution": "Remove the guarantee and state that returns can vary.",
"suggested_text": "Target return of 8% a year. Returns are not guaranteed.",
"dismissal_reason": null,
"group_id": "cmrl4g2b75wv1jfge9hx0p2kd",
"assigned_to_user_ids": [
"cmuf2k8x10001ab12cd34ef56"
],
"rule_description": "string",
"rule_explanation": "string",
"comments": [
{
"id": "cmuf2k8x10001ab12cd34ef56",
"author_email": "reviewer@example.com",
"content": "Checked with legal: fix before Friday.",
"created_at": "2026-09-24T09:30:00Z"
}
]
} Review a violation
api.app.typetone.ai/public/v1/violations/{violation_id}/review Records a review decision. dismiss needs a reason; the other actions don't take one (add a comment instead). Set apply_to_group to apply the decision to every violation with the same group_id: the same finding on several assets.
Authorization
X-API-KeyheaderrequiredYour workspace API key.
Path parameters
violation_idstringrequiredID of the violation, from List violations.
Request body
actionstringrequiredThe decision:
dismiss,elevated_risk,urgent_violation,mark_fixedorreopen.One of
dismisselevated_riskurgent_violationmark_fixedreopenreasonstring | nullRequired for, and only accepted with, action 'dismiss'.
apply_to_groupbooleandefaultfalseApply the same decision to every violation with the same group_id.
Response · 200
violation_idstringrequiredID of the violation, from List violations.
actionstringrequiredThe decision:
dismiss,elevated_risk,urgent_violation,mark_fixedorreopen.One of
dismisselevated_riskurgent_violationmark_fixedreopenreview_statestringrequiredundecided,elevated_risk,urgent_violation,dismissedorfixed. As a filter,allreturns every state.One of
undecidedelevated_riskurgent_violationdismissedfixedviolations_updatedintegerrequiredHow many violations the decision was applied to (more than one with
apply_to_group).
Errors
-
401Missing or invalid API key. -
403The workspace is not on a plan with API access. -
404The resource does not exist in this workspace. -
422A parameter or the request body is invalid.detailsays which.
curl -X POST "https://api.app.typetone.ai/public/v1/violations/cmrl4efwd5wu8jfgepgjbxam6/review" \
-H "X-API-Key: $TYPETONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "urgent_violation",
"apply_to_group": false
}' import os
import requests
response = requests.post(
"https://api.app.typetone.ai/public/v1/violations/cmrl4efwd5wu8jfgepgjbxam6/review",
headers={"X-API-Key": os.environ["TYPETONE_API_KEY"]},
json={
"action": "urgent_violation",
"apply_to_group": False
},
)
response.raise_for_status()
print(response.json()) const response = await fetch("https://api.app.typetone.ai/public/v1/violations/cmrl4efwd5wu8jfgepgjbxam6/review", {
method: "POST",
headers: {
"X-API-Key": process.env.TYPETONE_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"action": "urgent_violation",
"apply_to_group": false
}),
});
const data = await response.json(); {
"violation_id": "cmrl4efwd5wu8jfgepgjbxam6",
"action": "dismiss",
"review_state": "undecided",
"violations_updated": 3
} Something unclear or missing? Tell us and we'll improve this page.
Comment on a violation
api.app.typetone.ai/public/v1/violations/{violation_id}/commentsAdds a comment to the violation's thread. Mentions in the comment don't assign the violation or notify anyone.
Authorization
X-API-KeyheaderrequiredYour workspace API key.
Path parameters
violation_idstringrequiredID of the violation, from List violations.
Request body
commentstringrequiredThe comment text, up to 5,000 characters.
Response · 201
idstringrequiredUnique ID.
author_emailstring | nullrequiredEmail of the person who wrote the comment, when they belong to your workspace.
contentstringrequiredcreated_atdatetimerequiredWhen it was created.
Errors
401Missing or invalid API key.403The workspace is not on a plan with API access.404The resource does not exist in this workspace.422A parameter or the request body is invalid.detailsays which.