Audit Logs API
The Audit Logs API provides access to the complete audit trail of all actions in Cohera. Every create, update, delete, and access event is recorded for compliance with 21 CFR Part 11 and EU GMP Annex 11 requirements.
Audit Log Entry Model
Section titled “Audit Log Entry Model”{ "id": "log_abc123def456", "timestamp": "2024-01-20T14:30:45.123Z", "action": "update", "entity_type": "supplier", "entity_id": "ent_supplier_789", "entity_name": "Acme Chemicals GmbH", "user": { "id": "user_xyz123", "email": "j.smith@company.com", "name": "John Smith", "role": "quality_manager" }, "client": { "ip_address": "192.168.1.100", "user_agent": "Mozilla/5.0...", "api_key_id": "key_abc123" }, "changes": { "attributes.qualification_status": { "from": "pending", "to": "qualified" }, "attributes.qualification_date": { "from": null, "to": "2024-01-20" } }, "metadata": { "reason": "Completed qualification audit", "workflow_state": "qualified", "request_id": "req_xyz789" }, "signature": { "required": true, "signed": true, "signature_id": "sig_abc123", "meaning": "I approve this qualification status change" }}Action Types
Section titled “Action Types”| Action | Description |
|---|---|
create | Entity created |
read | Entity accessed (configurable) |
update | Entity modified |
delete | Entity deleted |
restore | Entity restored from deletion |
transition | Workflow state transition |
approve | Approval submitted |
reject | Approval rejected |
sign | Electronic signature applied |
login | User login |
logout | User logout |
export | Data exported |
Query Audit Logs
Section titled “Query Audit Logs”GET /v1/audit-logsQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
entity_type | string | Filter by entity type |
entity_id | string | Filter by specific entity |
action | string | Filter by action type |
user_id | string | Filter by user |
from | datetime | Start of time range |
to | datetime | End of time range |
has_signature | boolean | Only signed actions |
page | integer | Page number |
per_page | integer | Items per page (max 100) |
Example Request
Section titled “Example Request”curl -X GET "https://api.cohera.io/v1/audit-logs?entity_type=supplier&action=update&from=2024-01-01T00:00:00Z&to=2024-01-31T23:59:59Z" \ -H "Authorization: Bearer YOUR_API_KEY"from datetime import datetime, timedelta
response = requests.get( "https://api.cohera.io/v1/audit-logs", params={ "entity_type": "supplier", "action": "update", "from": (datetime.now() - timedelta(days=30)).isoformat() + "Z", "to": datetime.now().isoformat() + "Z", "per_page": 50 }, headers={"Authorization": "Bearer YOUR_API_KEY"})
logs = response.json()["data"]for log in logs: print(f"{log['timestamp']}: {log['user']['name']} - {log['action']} {log['entity_name']}")const from = new Date();from.setDate(from.getDate() - 30);
const params = new URLSearchParams({ entity_type: "supplier", action: "update", from: from.toISOString(), to: new Date().toISOString(), per_page: "50",});
const response = await fetch( `https://api.cohera.io/v1/audit-logs?${params}`, { headers: { Authorization: `Bearer ${process.env.COHERA_API_KEY}`, }, });
const { data: logs } = await response.json();logs.forEach((log) => { console.log( `${log.timestamp}: ${log.user.name} - ${log.action} ${log.entity_name}` );});Response
Section titled “Response”{ "data": [ { "id": "log_abc123", "timestamp": "2024-01-20T14:30:45.123Z", "action": "update", "entity_type": "supplier", "entity_id": "ent_supplier_789", "entity_name": "Acme Chemicals GmbH", "user": { "id": "user_xyz123", "name": "John Smith" }, "changes": { "attributes.qualification_status": { "from": "pending", "to": "qualified" } } } ], "meta": { "total": 156, "page": 1, "per_page": 50 }}Get Entity Audit Trail
Section titled “Get Entity Audit Trail”Get the complete audit history for a specific entity.
GET /v1/audit-logs/entity/{entity_id}curl -X GET "https://api.cohera.io/v1/audit-logs/entity/ent_supplier_789" \ -H "Authorization: Bearer YOUR_API_KEY"response = requests.get( f"https://api.cohera.io/v1/audit-logs/entity/{entity_id}", headers={"Authorization": "Bearer YOUR_API_KEY"})
trail = response.json()["data"]print(f"Audit trail for {trail['entity_name']}:")print(f"Created: {trail['created_at']} by {trail['created_by']}")print(f"Total changes: {len(trail['history'])}")
for entry in trail["history"]: print(f" {entry['timestamp']}: {entry['action']} by {entry['user']['name']}")const response = await fetch( `https://api.cohera.io/v1/audit-logs/entity/${entityId}`, { headers: { Authorization: `Bearer ${process.env.COHERA_API_KEY}`, }, });
const { data: trail } = await response.json();console.log(`Audit trail for ${trail.entity_name}:`);console.log(`Created: ${trail.created_at} by ${trail.created_by}`);console.log(`Total changes: ${trail.history.length}`);
trail.history.forEach((entry) => { console.log( ` ${entry.timestamp}: ${entry.action} by ${entry.user.name}` );});Response
Section titled “Response”{ "data": { "entity_id": "ent_supplier_789", "entity_type": "supplier", "entity_name": "Acme Chemicals GmbH", "created_at": "2024-01-10T09:00:00Z", "created_by": "user_intake_001", "current_version": 5, "history": [ { "version": 5, "timestamp": "2024-01-20T14:30:45Z", "action": "update", "user": {"id": "user_xyz123", "name": "John Smith"}, "changes": { "attributes.qualification_status": {"from": "pending", "to": "qualified"} }, "signature": {"signed": true, "signature_id": "sig_abc123"} }, { "version": 4, "timestamp": "2024-01-18T11:00:00Z", "action": "update", "user": {"id": "user_abc456", "name": "Jane Doe"}, "changes": { "attributes.risk_level": {"from": "high", "to": "medium"} } } ] }}User Activity Log
Section titled “User Activity Log”Get all actions performed by a specific user.
GET /v1/audit-logs/user/{user_id}Query Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
from | datetime | Start of time range |
to | datetime | End of time range |
action | string | Filter by action type |
Retention Policies
Section titled “Retention Policies”Get Retention Policy
Section titled “Get Retention Policy”GET /v1/audit-logs/retentionResponse
Section titled “Response”{ "data": { "policy_id": "ret_default", "name": "Default Retention Policy", "retention_period_years": 15, "applies_to": ["all"], "archive_after_years": 2, "archive_storage": "s3_glacier", "deletion_policy": "manual_with_approval", "exceptions": [ { "entity_types": ["certificate", "quality_event"], "retention_period_years": 25, "reason": "Regulatory requirement for batch records" } ] }}Export Audit Data
Section titled “Export Audit Data”Export audit logs for regulatory submissions or external archival.
POST /v1/audit-logs/exportRequest Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
format | string | Yes | Export format: csv, json, pdf |
from | datetime | Yes | Start of time range |
to | datetime | Yes | End of time range |
entity_types | array | No | Filter by entity types |
actions | array | No | Filter by action types |
include_signatures | boolean | No | Include signature details |
include_raw_data | boolean | No | Include before/after data snapshots |
curl -X POST "https://api.cohera.io/v1/audit-logs/export" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "format": "pdf", "from": "2024-01-01T00:00:00Z", "to": "2024-01-31T23:59:59Z", "entity_types": ["supplier", "certificate"], "include_signatures": true }'export_request = { "format": "pdf", "from": "2024-01-01T00:00:00Z", "to": "2024-01-31T23:59:59Z", "entity_types": ["supplier", "certificate"], "include_signatures": True}
response = requests.post( "https://api.cohera.io/v1/audit-logs/export", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, json=export_request)
export_job = response.json()["data"]print(f"Export job created: {export_job['job_id']}")print(f"Status: {export_job['status']}")const exportRequest = { format: "pdf", from: "2024-01-01T00:00:00Z", to: "2024-01-31T23:59:59Z", entity_types: ["supplier", "certificate"], include_signatures: true,};
const response = await fetch("https://api.cohera.io/v1/audit-logs/export", { method: "POST", headers: { Authorization: `Bearer ${process.env.COHERA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify(exportRequest),});
const { data: exportJob } = await response.json();console.log(`Export job created: ${exportJob.job_id}`);console.log(`Status: ${exportJob.status}`);Response
Section titled “Response”{ "data": { "job_id": "export_abc123", "status": "processing", "format": "pdf", "parameters": { "from": "2024-01-01T00:00:00Z", "to": "2024-01-31T23:59:59Z", "entity_types": ["supplier", "certificate"] }, "estimated_records": 1250, "created_at": "2024-02-01T10:00:00Z", "download_url": null }}Check Export Status
Section titled “Check Export Status”GET /v1/audit-logs/export/{job_id}{ "data": { "job_id": "export_abc123", "status": "completed", "format": "pdf", "records_exported": 1247, "file_size_bytes": 5242880, "created_at": "2024-02-01T10:00:00Z", "completed_at": "2024-02-01T10:05:30Z", "download_url": "https://api.cohera.io/v1/audit-logs/export/export_abc123/download", "expires_at": "2024-02-08T10:05:30Z" }}Download Export
Section titled “Download Export”GET /v1/audit-logs/export/{job_id}/downloadReturns the export file with appropriate content headers.
Compliance Reports
Section titled “Compliance Reports”Generate 21 CFR Part 11 Compliance Report
Section titled “Generate 21 CFR Part 11 Compliance Report”POST /v1/audit-logs/reports/21cfr11{ "from": "2024-01-01T00:00:00Z", "to": "2024-01-31T23:59:59Z", "include_sections": [ "electronic_signatures", "audit_trail_completeness", "access_controls", "system_validations" ]}Response
Section titled “Response”{ "data": { "report_id": "rpt_compliance_abc123", "report_type": "21cfr11", "period": { "from": "2024-01-01T00:00:00Z", "to": "2024-01-31T23:59:59Z" }, "summary": { "overall_compliance": "compliant", "findings": 0, "observations": 2 }, "sections": { "electronic_signatures": { "status": "compliant", "total_signatures": 145, "valid_signatures": 145, "details": "All electronic signatures contain required elements" }, "audit_trail_completeness": { "status": "compliant", "total_records": 12500, "complete_records": 12500, "details": "All records contain timestamp, user, and change details" }, "access_controls": { "status": "compliant", "observations": [ "2 users have not completed annual security training" ] } }, "generated_at": "2024-02-01T10:30:00Z", "download_url": "https://api.cohera.io/v1/audit-logs/reports/rpt_compliance_abc123/download" }}Real-time Audit Stream
Section titled “Real-time Audit Stream”For real-time monitoring, subscribe to the audit log stream via webhooks.
Configure Webhook
Section titled “Configure Webhook”POST /v1/webhooks{ "url": "https://your-server.com/webhooks/audit", "events": ["audit.create", "audit.signature"], "filters": { "entity_types": ["certificate", "quality_event"], "actions": ["create", "update", "delete", "sign"] }}Webhook Payload
Section titled “Webhook Payload”{ "event": "audit.create", "timestamp": "2024-01-20T14:30:45.123Z", "data": { "id": "log_abc123", "action": "update", "entity_type": "certificate", "entity_id": "cert_xyz789", "user": { "id": "user_abc123", "name": "John Smith" }, "changes": { "status": {"from": "pending", "to": "valid"} } }}