Compliance API
On this page
The compliance API gives your organization's own security, legal and compliance team the records Strata keeps: who your members are, how your organization is set up, and every conversation with its messages and files. Pull them into your archive, eDiscovery platform or SIEM, and erase a conversation or a file when a request or an incident calls for it.
Activity (who did what, when) comes from the audit trail at GET /v1/audit. The compliance API is the content half beside it.
#Two scopes: reading and deleting
| Scope | What it allows | Who can grant it |
|---|---|---|
compliance:read | Every GET below: the directory, the settings, conversations, messages and files | An admin with View member chats |
compliance:delete | The two DELETE calls: a conversation, or one file of it | An admin with Manage compliance |
No role holds View member chats at first; an admin who holds Manage member-chat oversight switch grants it in a role of its own (Granting View member chats). They are separate on purpose: a key that reads your conversations can never erase one. Give each its own key, and give a deletion key only to the system or person that handles erasure requests. An admin cannot grant a scope for something they could not do themselves; trying returns 403 with the code COMPLIANCE_SCOPE_REQUIRES_PERMISSION. See API keys.
#Conversations need member chat oversight
Reading conversations and their files follows the same rule as an admin reading them in Strata: your organization's Member chat oversight switch must be on (Organization then Data and privacy). When it is off, those calls return 403 with the type oversight_off. The directory and the settings do not depend on it.
#Everything is scoped to the key's organization
Every call reads the organization the API key belongs to and nothing else. An id from another organization is 404, the same answer as an id that does not exist.
#Endpoints
| Call | Returns |
|---|---|
GET /v1/compliance/users | Every member: id, email, name, role, whether active, when they joined and were last active, and whether their chats and outputs are kept; then your organization's API identities (the service accounts API keys act as, and its API bot), so the owner of every conversation can be looked up. Each row's kind is member, api_service_account or api_bot |
GET /v1/compliance/groups | Every group with its member ids |
GET /v1/compliance/roles | Every role with its permissions, the models and extensions it allows, and how many members hold it |
GET /v1/compliance/settings | Retention periods, oversight and audit level, sign-in and security settings, what the AI may do (Analysis, sub-agents, web, email and file sharing, Jira and Confluence writes), and the active legal holds. Never a secret |
GET /v1/compliance/conversations | Conversations, the most recently changed first |
GET /v1/compliance/conversations/{conversation_id} | One conversation with every message |
GET /v1/compliance/conversations/{conversation_id}/files | The files and saved artifacts of one conversation |
GET /v1/compliance/conversations/{conversation_id}/files/{file_id}/content | A file's bytes |
DELETE /v1/compliance/conversations/{conversation_id} | Erases a conversation |
DELETE /v1/compliance/conversations/{conversation_id}/files/{file_id} | Erases one file of a conversation |
#Listing conversations
GET /v1/compliance/conversations takes:
limit- Rows per page, up to 500 (default 100)
cursor- The
next_cursorfrom the previous page. A cursor this API did not issue returns400 invalid_cursor user_id- One member's conversations only
since,until- Changed at or after
since, and beforeuntil(ISO 8601) include_deletedtruealso lists conversations a member deleted
A member who deletes a chat only hides it: Strata keeps it until your organization's retention period removes it, so include_deleted=true shows what is still kept. Page with cursor until has_more is false. For a nightly pull, record the newest updated_at you stored and pass it as since next time.
GET /v1/compliance/users pages the same way, with limit and cursor.
#Reading a conversation
GET /v1/compliance/conversations/{conversation_id} returns the conversation and every message, including older ones Strata has moved to archive and cold storage. Each message carries its parent_message_id, so edited prompts and retried answers keep their branches. When older messages could not be read, the response says incomplete: true rather than passing part of a conversation off as all of it.
#Deleting
DELETE /v1/compliance/conversations/{conversation_id} erases the conversation, its messages (archived and cold copies included), its files and its shares. DELETE /v1/compliance/conversations/{conversation_id}/files/{file_id} erases one file.
- A legal hold stops it. When the member is under a legal hold, the delete is refused with
409and the typelegal_hold, naming the hold, and the refusal is recorded. Release the hold first. - Files created by Analysis live in a separate store that this call cannot reach yet; that store's lifecycle rule removes them within 180 days.
- A delete cannot be undone.
#What the API records
Your audit trail shows every use of the compliance API, with the API key named the way the API keys page names it:
- reading a conversation, its file list or a file:
member_chat.viewed,member_chat.files_viewed,member_chat.file_downloaded, the same rows an admin's reading writes; - a list or directory pull:
compliance.conversations_listedandcompliance.directory_read, once per walk; - deletes:
compliance.conversation_deletedandcompliance.file_deleted; a refusal under a hold:legal_hold.blocked.
#Errors
Errors are application/problem+json (Errors). The ones particular to this API:
| Status and type | Meaning |
|---|---|
403 insufficient_scope | The key does not hold the scope the call needs |
403 oversight_off | Member chat oversight is off, so conversations cannot be read |
404 not_found | Not in the key's organization, or gone |
409 legal_hold | A delete refused because the member is under a legal hold |
400 invalid_cursor | A cursor this API did not issue |