Tamper-proof audit logging for your organization. Every record is SHA-256 hashed and chained into an immutable, verifiable ledger.
https://api.audita.app
Audita is a tamper-proof audit logging service. Each record is SHA-256 hashed and chained to the previous one, forming an immutable ledger.
1
Create your organization and obtain your API key from the Audita dashboard.
2
Store the API key securely (environment variable, secrets manager). It cannot be retrieved again.
3
Send audit events from your backend using the endpoints documented below.
4
Use the dashboard to search, visualize, and export your audit history.
The API supports two authentication schemes. Most endpoints accept both interchangeably.
API Key (server-to-server)
Intended for organizations integrating server-to-server. Pass the key in the request header:
X-API-Key: your-api-key
The API key is returned only once when creating an organization. Store it securely — it cannot be retrieved again.
Bearer Token (JWT)
Intended for human actors via the web app. Obtain tokens via POST /api/auth/login:
Authorization: Bearer <accessToken>
Access token expires in 24 hours. Refresh token expires in 7 days. Use POST /api/auth/refresh to obtain a new access token.
Which auth method does each endpoint accept?
| Endpoint group | Bearer (JWT) | API Key |
|---|---|---|
| /api/auth/** | — | — (public) |
| /api/users/** | ✓ | — |
| /api/organizations/** | ✓ | — |
| /api/audits/** | ✓ | ✓ |
| /api/notifications/** | ✓ | ✓ |
| /api/anomaly-rules/** | ✓ | ✓ |
| /api/webhooks/** | ✓ | ✓ |
| /api/scheduled-exports/** | ✓ | ✓ |
| /api/retention-policies/** | ✓ | ✓ |
| /api/pii-rules/** | ✓ | ✓ |
| /api/dashboards/** | ✓ | ✓ |
| /api/app-errors/** | ✓ | ✓ |
| /api/subscriptions/** | ✓ | — |
Store your API key as an environment variable. Never hardcode it in source code or commit it to version control.
Rate limiting is applied per client (by API key prefix, JWT prefix, or IP address). When exceeded the server returns HTTP 429.
| Endpoint Group | Path | Limit | Window |
|---|---|---|---|
| Registration | POST /api/auth/register | 3 req | 1 min |
| Resend verification | POST /api/auth/resend-verification | 3 req | 1 min |
| Auth (general) | /api/auth/** | 10 req | 1 min |
| Invitations | /api/organizations/{id}/invitations | 5 req | 1 min |
| Exports | /api/audits/export/** | 5 req | 1 min |
| Audits | /api/audits/** | 1 000 req | 1 min |
| Users | /api/users/** | 20 req | 1 min |
| Organizations | /api/organizations/** | 10 req | 1 min |
| Contact | /api/contact | 2 req | 1 min |
| Health | /ping | 10 req | 1 min |
| Default | everything else | 50 req | 1 min |
HTTP 429 Too Many Requests
{
"error": "Too Many Requests",
"message": "Rate limit exceeded for AUDITS. Limit is 1000 per 60 seconds."
}Implement exponential backoff on 429 — do not retry immediately.
All error responses share the same structure:
{
"error": "Bad Request",
"message": "action must be one of: CREATE, UPDATE, DELETE, ACCESS, OTHER"
}Validation error (HTTP 400):
{
"error": "Validation Error",
"details": {
"fieldName": "must not be blank",
"email": "must be a valid email"
}
}| Status | Meaning |
|---|---|
| 400 | Validation failure — check the message or details field |
| 401 | Missing or invalid API key / expired token |
| 403 | Authenticated but insufficient permissions |
| 404 | Resource not found, or belongs to a different organization |
| 409 | Conflict — resource already exists (e.g. duplicate retention policy) |
| 429 | Rate limit exceeded |
| 500 | Server error — retry with exponential backoff |
Read this section before implementing your audit pipeline.
Use bulk for multiple events
Prefer POST /api/audits/bulk (up to 500 events) over N individual calls. This reduces latency, lowers request count, and guarantees atomic insertion.
Always set an idempotency key
Set idempotencyKey to a stable UUID generated before the request. On retry, the server returns the original record without creating a duplicate.
Use eventTimestamp for the real event time
createdAt is set at insertion time. Use eventTimestamp to record when the event actually occurred, especially if you buffer events before sending.
Implement client-side batching for high-volume systems
For >10 events/second: buffer in memory, flush every 100–500ms or when buffer reaches 100 events. On shutdown (SIGTERM/SIGINT), flush the remaining buffer.
Retry with exponential backoff
On network errors or 5xx: 1s → 2s → 4s → fail after 4 attempts. On 429: wait for Retry-After. On 400: do not retry.
Use correlationId for distributed tracing
Pass a shared correlationId (e.g. a request ID or trace ID) across all audit events from the same user action to reconstruct the full story.
/ping
Verifies that the API is reachable. No authentication required.
pong
curl https://api.audita.app/ping
All /api/auth/** endpoints are public — no authentication required.
/api/auth/register
Creates a new user account. Sends a 6-digit email verification code valid for 15 minutes.
| Field | Type | Required | Notes |
|---|---|---|---|
| username | string | yes | |
| string | yes | Must be a valid email | |
| password | string | yes | |
| organizationId | UUID | no | Associates to an org on creation |
| role | string | yes | ADMIN or USER |
{ "message": "User created. Check your email for the verification code." }/api/auth/verify
Activates an account with the emailed 6-digit code.
| Field | Type | Required |
|---|---|---|
| string | yes | |
| code | string | yes |
{ "message": "Account verified successfully." }/api/auth/resend-verification
Resends the verification code to the given email. Rate limited to 3 req/min.
| Field | Type | Required |
|---|---|---|
| string | yes |
{ "message": "Verification code resent." }/api/auth/login
Authenticates and returns access + refresh tokens. You can pass either username or email.
| Field | Type | Required | Notes |
|---|---|---|---|
| username | string | no | Either username or email is required |
| password | string | yes |
{
"accessToken": "eyJhbGci...",
"refreshToken": "eyJhbGci...",
"username": "john",
"organizationId": "550e8400-...",
"role": "USER"
}/api/auth/refresh
Exchanges a refresh token for a new access token.
| Field | Type | Required |
|---|---|---|
| refreshToken | string | yes |
{ "accessToken": "eyJhbGci..." }Manage users. Most endpoints require Bearer auth.
/api/users/me
Returns the authenticated user's full profile including organization and current plan. Requires Bearer auth.
{
"id": "uuid",
"username": "john",
"email": "john@example.com",
"createdAt": "2025-01-01T00:00:00Z",
"organization": {
"id": "uuid",
"name": "Acme Corp",
"plan": {
"name": "GROWTH",
"priceMonthly": 399.00,
"maxAuditsPerDay": 10000,
"maxInternalUsers": 10,
"hotStorageDays": 90
}
}
}/api/users/{id}
Returns a user by ID. Public — no auth required.
/api/users/email/{email}
Returns a user by email. Public — no auth required.
/api/users/organization/{organizationId}
Returns all users belonging to an organization. Requires Bearer auth.
/api/users/assign-organization
Assigns a user (by email) to an organization. Requires Bearer auth with ADMIN role.
| Field | Type | Required |
|---|---|---|
| string | yes |
/api/users/{id}/role/admin
Promotes a user to ADMIN role. Requires Bearer auth.
/api/users/{userId}/remove-from-organization
Removes a user from their current organization. Requires Bearer auth with ADMIN role.
/api/organizations/by-apikey
Resolves the organization associated with your API key. Useful for verifying connectivity and retrieving your organizationId. No authentication header required — pass the key as a query parameter.
| Parameter | Type | Required | Description |
|---|---|---|---|
| apiKey | string | yes | Your API key |
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Acme Corp",
"status": "ACTIVE",
"createdAt": "2026-01-15T09:00:00Z",
"apiKey": "ak_••••••••",
"allowedIps": []
}curl "https://api.audita.app/api/organizations/by-apikey?apiKey=your-api-key"
/api/organizations
Creates a new organization. The API key is returned only in this response — store it securely, it cannot be retrieved again. Requires Bearer auth.
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | yes | Organization name |
{
"id": "uuid",
"name": "Acme Corp",
"status": "ACTIVE",
"createdAt": "2025-01-01T00:00:00Z",
"apiKey": "ak_live_xxxxxxxxxxxxxxxx",
"allowedIps": []
}/api/organizations/{id}
Returns an organization by ID. Requires Bearer auth.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Organization ID |
/api/organizations/{id}/invitations
Sends an invitation email to a new user. Requires Bearer auth. Rate limited to 5 req/min.
| Field | Type | Required | Description |
|---|---|---|---|
| string | yes | Email address to invite |
(empty body)
/api/organizations/{id}/allowed-ips
Returns the current IP allowlist for API key authentication. Requires Bearer auth.
{ "allowedIps": ["192.168.1.0/24", "10.0.0.1"] }/api/organizations/{id}/allowed-ips
Replaces the IP allowlist. An empty list removes all IP restrictions. Accepts IPv4, IPv6, CIDR ranges, hostnames. Max 100 entries. Requires Bearer auth.
| Field | Type | Required | Description |
|---|---|---|---|
| allowedIps | string[] | yes | List of IPs, CIDR ranges, or hostnames |
/api/audits
Creates a single audit record. The record is appended to your organization's hash chain.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| organizationId | UUID | yes | — | Your organization ID |
| resourceType | string | yes | max 200 | Type of resource (e.g. USER, ORDER) |
| resourceId | string | yes | max 200 | Unique identifier of the resource |
| action | string | yes | enum | CREATE, UPDATE, DELETE, ACCESS, OTHER |
| actorData | string | no | max 2,000 | Who performed the action |
| payload | string | no | max 100,000 | Resource state after the action (JSON recommended) |
| beforeState | string | no | max 100,000 | Resource state before the action |
| correlationId | string | no | max 200 | Shared trace ID across services |
| metadata | string | no | max 100,000 | Additional context. IP and user-agent are auto-merged |
| eventTimestamp | ISO-8601 | no | — | When the event actually occurred |
| idempotencyKey | string | no | max 200 | Unique key to prevent duplicates on retry. Strongly recommended |
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "USER",
"resourceId": "usr_01J2K3L4M5",
"action": "UPDATE",
"actorData": "user:adm_99Z",
"payload": "{\"email\": \"new@acme.com\"}",
"correlationId": "req_abc123",
"createdAt": "2026-03-22T13:58:01Z",
"idempotencyKey": "550e8400-e29b-41d4-a716-446655440000"
}curl -X POST https://api.audita.app/api/audits \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "USER",
"resourceId": "usr_01J2K3L4M5",
"action": "UPDATE",
"actorData": "user:adm_99Z",
"payload": "{\"email\": \"new@acme.com\"}",
"beforeState": "{\"email\": \"old@acme.com\"}",
"correlationId": "req_abc123",
"eventTimestamp": "2026-03-22T13:58:00Z",
"idempotencyKey": "550e8400-e29b-41d4-a716-446655440000"
}'/api/audits/bulk
Creates up to 500 audit records in a single atomic transaction. All records must belong to the same organization.
| Constraint | Value |
|---|---|
| Minimum items | 1 |
| Maximum items | 500 |
Each item follows the same schema as POST /api/audits. Returns an array of created audit objects in the same order.
curl -X POST https://api.audita.app/api/audits/bulk \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "ORDER",
"resourceId": "ord_111",
"action": "CREATE",
"payload": "{\"total\": 99.99}",
"idempotencyKey": "bulk-ord-111-create"
},
{
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "ORDER",
"resourceId": "ord_112",
"action": "UPDATE",
"payload": "{\"status\": \"SHIPPED\"}",
"idempotencyKey": "bulk-ord-112-update"
}
]'/api/audits/{id}
Returns a single audit record by ID. Returns 404 if the audit belongs to a different organization.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Audit record ID |
curl https://api.audita.app/api/audits/7c9e6679-7425-40de-944b-e07fc1f90ae7 \ -H "X-API-Key: $AUDITA_API_KEY"
/api/audits
Searches and paginates audit records. Results are sorted by createdAt descending (newest first).
| Parameter | Type | Required | Description |
|---|---|---|---|
| organizationId | UUID | no | Resolved from API key if omitted |
| resourceType | string[] | no | Filter by resource type(s). Repeatable |
| resourceId | string | no | Filter by exact resource ID |
| action | string[] | no | Filter by action(s). Repeatable |
| actorData | string[] | no | Filter by actor(s). Repeatable |
| correlationId | string | no | Filter by correlation ID |
| fromDate | ISO-8601 | no | Start of date range (inclusive) |
| toDate | ISO-8601 | no | End of date range (inclusive) |
| payloadKey | string[] | no | JSON key path within payload (positional) |
| payloadValue | string[] | no | Value to match for each payloadKey |
| includeArchived | boolean | no | Include archived records. Default: false |
| page | integer | no | Page number (0-indexed). Default: 0 |
| size | integer | no | Page size. Default: 20 |
{
"content": [ /* array of audit objects */ ],
"totalElements": 1542,
"totalPages": 78,
"page": 0,
"size": 20
}curl "https://api.audita.app/api/audits?resourceType=USER&action=DELETE&fromDate=2026-03-15T00:00:00Z&page=0&size=20" \ -H "X-API-Key: $AUDITA_API_KEY"
/api/audits/count
Counts audits matching specific (action, resourceType) tuples since a given date. Arrays are positional — index i of each array forms one query tuple.
| Parameter | Type | Required | Description |
|---|---|---|---|
| dateFrom | ISO-8601 | yes | Start of counting window |
| action | string[] | yes | Action(s) to count. Must have same length as resource |
| resource | string[] | yes | Resource type(s) to count |
| actor | string[] | no | Actor filter(s). Positional |
| title | string[] | no | Display labels for each tuple |
[
{ "title": "User deletions", "action": "DELETE", "resource": "USER", "count": 12 },
{ "title": "Order creations", "action": "CREATE", "resource": "ORDER", "count": 304 }
]curl "https://api.audita.app/api/audits/count?dateFrom=2026-03-01T00:00:00Z&action=DELETE&action=CREATE&resource=USER&resource=ORDER&title=User+deletions&title=Order+creations" \ -H "X-API-Key: $AUDITA_API_KEY"
/api/audits/metrics
Returns aggregated metrics: total count, breakdown by action, breakdown by resource type, and daily counts. Defaults to the last 30 days.
| Parameter | Type | Required | Description |
|---|---|---|---|
| from | YYYY-MM-DD | no | Start date. Default: 30 days ago |
| to | YYYY-MM-DD | no | End date. Default: today |
| resource | string | no | Filter to a specific resource type |
{
"total": 4821,
"byAction": { "CREATE": 1200, "UPDATE": 2100, "DELETE": 300, "ACCESS": 1221, "OTHER": 0 },
"byResourceType": { "USER": 900, "ORDER": 3921 },
"byDay": [
{ "date": "2026-03-01", "count": 142 },
{ "date": "2026-03-02", "count": 98 }
]
}curl "https://api.audita.app/api/audits/metrics?from=2026-03-01&to=2026-03-22" \ -H "X-API-Key: $AUDITA_API_KEY"
/api/audits/verify/{organizationId}
Walks the entire audit chain and re-computes every SHA-256 hash. Returns valid: true if intact, or details of the first broken link.
This operation is proportional to total audit count. Do not call it on every request — use it for scheduled integrity checks.
| Parameter | Type | Description |
|---|---|---|
| organizationId | UUID | Your organization ID |
{ "valid": true, "totalChecked": 4821 }curl https://api.audita.app/api/audits/verify/3fa85f64-5717-4562-b3fc-2c963f66afa6 \ -H "X-API-Key: $AUDITA_API_KEY"
/api/audits/{id}/integrity
Verifies the integrity of a single audit — re-computes its SHA-256 hash and validates its link to the previous record.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Audit record ID |
{ "valid": true, "auditId": "7c9e6679-...", "hashMatch": true, "chainLinkValid": true }curl https://api.audita.app/api/audits/7c9e6679-7425-40de-944b-e07fc1f90ae7/integrity \ -H "X-API-Key: $AUDITA_API_KEY"
/api/audits/{id}/diff
Returns a structured diff between beforeState and payload for a single audit.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Audit record ID |
{
"auditId": "uuid",
"action": "UPDATE",
"resourceType": "user",
"resourceId": "user-123",
"createdAt": "2025-06-01T12:00:01Z",
"hasDiff": true,
"diff": [
{ "field": "email", "changeType": "MODIFIED", "before": "old@example.com", "after": "new@example.com" },
{ "field": "phone", "changeType": "ADDED", "before": null, "after": "+1-555-0100" },
{ "field": "nickname", "changeType": "REMOVED", "before": "Johnny", "after": null }
]
}/api/audits/correlation/{correlationId}
Returns all audits sharing the same correlationId, plus a summary of the distributed trace.
| Parameter | Type | Description |
|---|---|---|
| correlationId | string | Correlation ID to look up |
{
"correlationId": "req-abc-123",
"events": [ /* AuditResponseDTO[] */ ],
"summary": {
"totalEvents": 4,
"resourceTypes": ["user", "order"],
"actions": ["CREATE", "UPDATE"],
"actors": ["admin@acme.com"],
"firstEvent": "2025-06-01T12:00:00Z",
"lastEvent": "2025-06-01T12:00:05Z"
}
}/api/audits/import
Imports audits from a CSV or Excel (.xlsx) file. Processing is asynchronous.
| Field | Type | Required | Description |
|---|---|---|---|
| file | multipart/form-data | yes | .csv or .xlsx file |
{
"status": "ACCEPTED",
"message": "Import started. Records will be processed in the background."
}Export endpoints stream the result as a ZIP file containing the export. Auth: Bearer or API Key.
/api/audits/export/{organizationId}
Exports filtered audits as an Excel (.xlsx) file inside a ZIP. Also creates an ACCESS audit record.
| Parameter | Type | Notes |
|---|---|---|
| from | Instant | Start of time range (optional) |
| to | Instant | End of time range (optional) |
| resourceType | string[] | Multi-value filter (optional) |
| action | string[] | Multi-value filter (optional) |
| actorData | string[] | Multi-value filter (optional) |
Optional JSON body to extract custom columns from payload:
{
"customColumns": {
"User ID": "payload.userId",
"Department": "payload.department"
}
}Content-Type: application/zip Content-Disposition: attachment; filename=audits.zip Body: ZIP containing audits.xlsx
/api/audits/export/{organizationId}/json
Same as above but exports a JSON file inside the ZIP.
Content-Type: application/zip Content-Disposition: attachment; filename=audits.zip Body: ZIP containing audits.json
/api/audits/compliance-report/{organizationId}
Generates a PDF compliance report for the given time range.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| from | YYYY-MM-DD | yes | Start date |
| to | YYYY-MM-DD | yes | End date |
| verify | boolean | no | If true, runs integrity check and includes result in report |
Content-Type: application/pdf
Timeline endpoints provide a temporal view of audit activity — by actor (grouped into sessions) or by resource (full event history). Auth: Bearer or API Key.
/api/audits/timeline/actor
Returns all audit events for a given actor, grouped into inactivity-based sessions.
| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
| actor | string | yes | — | actorData value to look up |
| organizationId | UUID | no | — | Resolved from auth context if omitted |
| from | Instant | no | — | Start of time range |
| to | Instant | no | — | End of time range |
| maxEvents | integer | no | 500 | Max 2 000 |
| sessionGapMinutes | integer | no | 30 | Inactivity gap that splits sessions |
{
"actor": "admin@acme.com",
"organizationId": "uuid",
"totalEvents": 87,
"truncated": false,
"sessions": [
{
"sessionIndex": 0,
"startedAt": "2025-06-01T09:00:00Z",
"endedAt": "2025-06-01T09:45:00Z",
"durationMinutes": 45,
"eventCount": 23,
"events": [ /* AuditResponseDTO[] */ ]
}
]
}truncated: true means maxEvents was hit and results were cut off.
/api/audits/timeline/resource/{resourceType}/{resourceId}
Returns the full event history of a specific resource, paginated.
| Parameter | Type | Default | Notes |
|---|---|---|---|
| resourceType (path) | string | — | e.g. user, order |
| resourceId (path) | string | — | e.g. user-123 |
| organizationId | UUID | — | |
| from | Instant | — | |
| to | Instant | — | |
| page | integer | 0 | |
| size | integer | 50 |
{
"resourceType": "user",
"resourceId": "user-123",
"organizationId": "uuid",
"totalEvents": 120,
"firstSeenAt": "2024-01-01T00:00:00Z",
"lastSeenAt": "2025-06-01T12:00:00Z",
"page": 0,
"totalPages": 3,
"events": [ /* AuditResponseDTO[] */ ]
}Audita signs every webhook delivery using HMAC-SHA256. Verify the signature before processing the payload:
X-Webhook-Signature: sha256=<hmac-sha256-hex>
Compute HMAC-SHA256(secret, raw-request-body) and compare to the header. Reject non-matching requests.
| Event | Triggered when |
|---|---|
| audit.created | A single audit is created |
| audit.bulk_created | Multiple audits are created in a single bulk call |
| anomaly.triggered | An anomaly rule exceeds its configured threshold |
| webhook.test | A manual test ping is sent |
Event payload bodies delivered to your endpoint:
audit.created{
"event": "audit.created",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"audit": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "USER",
"resourceId": "usr_01J2K3L4M5",
"action": "UPDATE",
"actorData": "user:adm_99Z",
"createdAt": "2026-03-22T14:00:00Z"
}
}{
"event": "audit.bulk_created",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"count": 2,
"audits": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "ORDER",
"resourceId": "ord_111",
"action": "CREATE",
"actorData": "service:checkout",
"createdAt": "2026-03-22T14:00:00Z"
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f01234567891",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceType": "ORDER",
"resourceId": "ord_112",
"action": "UPDATE",
"actorData": "service:checkout",
"createdAt": "2026-03-22T14:00:01Z"
}
]
}{
"event": "anomaly.triggered",
"ruleId": "c3d4e5f6-a7b8-9012-cdef-012345678912",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"action": "DELETE",
"resourceType": "USER",
"count": 42,
"threshold": 10,
"windowSeconds": 60,
"windowStart": "2026-03-22T13:59:00Z",
"triggeredAt": "2026-03-22T14:00:00Z"
}/api/webhooks
Registers a webhook endpoint. The signing secret is returned only in this response — store it securely.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | yes | HTTPS endpoint to receive event payloads |
| events | string[] | yes | Events to subscribe to |
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://yourapp.com/webhooks/audita",
"events": ["audit.created", "audit.bulk_created", "anomaly.triggered"],
"secret": "whsec_abc123xyz...",
"active": true,
"createdAt": "2026-03-22T14:00:00Z"
}curl -X POST https://api.audita.app/api/webhooks \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/audita",
"events": ["audit.created", "audit.bulk_created", "anomaly.triggered"]
}'/api/webhooks
Lists all registered webhooks for your organization.
curl https://api.audita.app/api/webhooks \ -H "X-API-Key: $AUDITA_API_KEY"
/api/webhooks/{id}
Permanently deletes a webhook.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Webhook ID |
curl -X DELETE https://api.audita.app/api/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \ -H "X-API-Key: $AUDITA_API_KEY"
/api/webhooks/{id}/test
Sends a synthetic ping event to verify that the endpoint is reachable and that signature verification works.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Webhook ID |
curl -X POST https://api.audita.app/api/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/test \ -H "X-API-Key: $AUDITA_API_KEY"
Defines how many days audit records are kept before automatic expiry. Each organization can have at most one policy. If no policy is set, records are retained indefinitely.
/api/retention-policies
Creates a retention policy. Returns 409 if one already exists — use PUT to update.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| retentionDays | integer | yes | >= 1 | Days to retain audit records |
{
"id": "d4e5f6a7-b8c9-0123-defa-456789012345",
"organizationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"retentionDays": 365,
"createdAt": "2026-03-22T14:00:00Z",
"updatedAt": "2026-03-22T14:00:00Z"
}curl -X POST https://api.audita.app/api/retention-policies \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "retentionDays": 365 }'/api/retention-policies
Returns the current retention policy for your organization.
curl https://api.audita.app/api/retention-policies \ -H "X-API-Key: $AUDITA_API_KEY"
/api/retention-policies/{id}
Updates the retention period.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Retention policy ID |
curl -X PUT https://api.audita.app/api/retention-policies/d4e5f6a7-b8c9-0123-defa-456789012345 \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "retentionDays": 730 }'PII rules define which JSON fields in payload or actorData should be hashed (SHA-256) before storage or after a configurable retention period. Auth: Bearer or API Key.
/api/pii-rules
Returns all PII redaction rules for the organization.
[
{
"id": "uuid",
"organizationId": "uuid",
"fieldName": "payload",
"jsonPaths": ["email", "user.nationalId"],
"searchRetentionDays": 90,
"createdAt": "2025-01-01T00:00:00Z"
}
]/api/pii-rules
Creates a new PII redaction rule.
| Field | Type | Required | Notes |
|---|---|---|---|
| fieldName | string | yes | "payload" or "actorData" |
| jsonPaths | string[] | no | Dot-notation paths e.g. "user.email". Empty = hash the entire field |
| searchRetentionDays | integer | no | Days the value stays searchable before hashing. Min 0, max 3 650 |
{
"id": "uuid",
"organizationId": "uuid",
"fieldName": "payload",
"jsonPaths": ["email", "user.nationalId"],
"searchRetentionDays": 90,
"createdAt": "2025-01-01T00:00:00Z"
}/api/pii-rules/{id}
Deletes a PII redaction rule.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | PII rule ID |
(no body)
Monitors your audit stream in real time. When (action, resourceType) count exceeds threshold within windowSeconds, an alert is sent to the configured notification channel.
Before creating a rule, you must have at least one notification channel configured.
/api/anomaly-rules
Creates an anomaly detection rule.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| action | string | yes | enum | Action to monitor: CREATE, UPDATE, DELETE, ACCESS, OTHER |
| resourceType | string | yes | max 50 | Resource type to monitor |
| threshold | integer | yes | >= 1 | Number of events that triggers the alert |
| windowSeconds | long | yes | >= 1 | Rolling evaluation window in seconds |
| cooldownSeconds | long | no | — | Minimum gap between alerts. Defaults to windowSeconds |
| notificationChannelId | UUID | yes | — | Channel to alert on |
{
"id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"action": "DELETE",
"resourceType": "USER",
"threshold": 50,
"windowSeconds": 300,
"cooldownSeconds": 300,
"notificationChannelId": "c1b2a3d4-e5f6-7890-abcd-ef1234567890",
"createdAt": "2026-03-22T14:00:00Z"
}curl -X POST https://api.audita.app/api/anomaly-rules \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "DELETE",
"resourceType": "USER",
"threshold": 50,
"windowSeconds": 300,
"cooldownSeconds": 600,
"notificationChannelId": "c1b2a3d4-e5f6-7890-abcd-ef1234567890"
}'/api/anomaly-rules
Lists all anomaly rules for your organization.
curl https://api.audita.app/api/anomaly-rules \ -H "X-API-Key: $AUDITA_API_KEY"
/api/anomaly-rules/{id}
Deletes an anomaly rule. Alerts stop immediately.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Anomaly rule ID |
curl -X DELETE https://api.audita.app/api/anomaly-rules/f1e2d3c4-b5a6-7890-fedc-ba9876543210 \ -H "X-API-Key: $AUDITA_API_KEY"
Defines where Audita sends alerts. Supported types: SLACK (Incoming Webhook) and EMAIL.
/api/notifications/channels
Connects a notification channel.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| type | string | yes | SLACK or EMAIL | Channel type |
| config | string | yes | max 2,048 | Slack: Incoming Webhook URL. Email: recipient address |
| name | string | no | max 255 | Human-readable label (e.g. "#alerts") |
{
"id": "c1b2a3d4-e5f6-7890-abcd-ef1234567890",
"type": "SLACK",
"config": "https://hooks.slack.com/services/...",
"name": "#security-alerts",
"active": true,
"createdAt": "2026-03-22T14:00:00Z"
}curl -X POST https://api.audita.app/api/notifications/channels \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "SLACK",
"config": "https://hooks.slack.com/services/T00/B00/xxxx",
"name": "#security-alerts"
}'/api/notifications/channels
Lists all notification channels for your organization.
curl https://api.audita.app/api/notifications/channels \ -H "X-API-Key: $AUDITA_API_KEY"
/api/notifications/channels/{id}
Disconnects a notification channel. Anomaly rules linked to this channel will stop sending alerts.
| Parameter | Type | Description |
|---|---|---|
| id | UUID | Channel ID |
curl -X DELETE https://api.audita.app/api/notifications/channels/c1b2a3d4-e5f6-7890-abcd-ef1234567890 \ -H "X-API-Key: $AUDITA_API_KEY"
/api/notifications/send
Sends a notification immediately to a specific channel. If channelId is omitted, broadcasts to all active channels.
| Field | Type | Required | Description |
|---|---|---|---|
| channelId | UUID | no | Target channel. Omit to broadcast to all active channels |
| subject | string | yes | Notification subject |
| message | string | yes | Notification body |
| organizationId | UUID | no | Resolved from auth if omitted |
(no body — sending is asynchronous)
Report HTTP error occurrences from your application to populate the Audita observability dashboard. Call this from your error handler or middleware.
Accepted codes: 400 401 403 404 405 408 409 422 429 500 502 503 504
/api/app-errors
Reports one or more occurrences of an error code.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| errorCode | string | yes | predefined code | HTTP status code of the error |
| occurrences | integer | yes | >= 1 | How many times this error occurred |
curl -X POST https://api.audita.app/api/app-errors \
-H "X-API-Key: $AUDITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "errorCode": "500", "occurrences": 3 }'Scheduled exports deliver a filtered export file to an email address at a specific future time. Auth: Bearer or API Key.
/api/scheduled-exports
Returns all scheduled exports for the organization.
[
{
"id": "uuid",
"organizationId": "uuid",
"recipientEmail": "reports@acme.com",
"scheduledAt": "2025-07-01T06:00:00Z",
"status": "PENDING",
"format": "XLSX",
"createdAt": "2025-06-01T00:00:00Z",
"executedAt": null,
"errorMessage": null
}
]/api/scheduled-exports
Schedules a future export. The scheduledAt time must be in the future.
| Field | Type | Required | Notes |
|---|---|---|---|
| recipientEmail | string | yes | Must be a valid email |
| scheduledAt | Instant | yes | Must be in the future |
| format | string | no | CSV or JSON (default CSV) |
| filters | object | no | fromDate, toDate, resourceTypes, actions, actorDataList, correlationId |
| customColumns | map | no | Column header → JSON path within payload |
{
"id": "uuid",
"recipientEmail": "reports@acme.com",
"scheduledAt": "2025-07-01T06:00:00Z",
"status": "PENDING",
"format": "CSV",
"createdAt": "2025-06-01T00:00:00Z"
}/api/scheduled-exports/{id}
Deletes a scheduled export. Returns HTTP 409 if the export is currently RUNNING.
(no body)
Dashboards store named visualization configurations (layout + widget settings as a JSON string). Auth: Bearer or API Key.
/api/dashboards
Returns all dashboards for the organization.
[
{
"id": "uuid",
"organizationId": "uuid",
"name": "Security Overview",
"configuration": "{\"widgets\":[...]}",
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-06-01T00:00:00Z"
}
]/api/dashboards/{id}
Returns a single dashboard by ID.
/api/dashboards
Creates (or upserts if id is provided) a dashboard.
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | no | Optional — if provided, upserts the dashboard |
| name | string | yes | Dashboard name |
| configuration | string | yes | JSON string of widget layout configuration |
{
"id": "uuid",
"name": "Security Overview",
"configuration": "{\"widgets\":[{\"type\":\"bar\",\"metric\":\"byAction\"}]}",
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-01T00:00:00Z"
}/api/dashboards/{id}
Updates the dateFrom field of a dashboard (persists the user's selected time range).
| Field | Type | Required | Description |
|---|---|---|---|
| dateFrom | string | yes | Date string e.g. 2025-06-01 |
/api/dashboards/{id}
Deletes a dashboard.
(no body)
Manage plan subscriptions and payment integrations. Stripe and MercadoPago are supported. Auth: Bearer (subscriptions); public (payment webhooks).
Plans
| Plan | Monthly price |
|---|---|
| STARTUP | $199 |
| GROWTH | $399 |
| ENTERPRISE | $899 |
/api/subscriptions/stripe/checkout-session
Creates a Stripe embedded checkout session.
| Field | Type | Required | Description |
|---|---|---|---|
| userId | UUID | yes | User to subscribe |
| planName | string | yes | STARTUP, GROWTH, or ENTERPRISE |
{
"clientSecret": "cs_test_xxx",
"publishableKey": "pk_test_xxx"
}/api/subscriptions/stripe/session-status
Returns the status of a Stripe checkout session.
| Parameter | Type | Required |
|---|---|---|
| sessionId | string | yes |
{ "status": "complete", "subscriptionId": "sub_xxx" }/api/subscriptions/stripe/portal
Creates a Stripe customer portal session for managing billing and plan changes.
| Parameter | Type | Required |
|---|---|---|
| userId | UUID | yes |
{ "url": "https://billing.stripe.com/session/..." }/api/subscriptions/user/{userId}
Returns the active subscription for a user.
{
"id": "uuid",
"planName": "GROWTH",
"userId": "uuid",
"createdAt": "2025-01-01T00:00:00Z",
"expirationDate": "2025-01-31T00:00:00Z",
"status": "ACTIVE",
"autoRenew": true
}/api/subscriptions/{id}
Cancels a subscription.
(no body)
/api/payments/webhook/stripe
Receives Stripe webhook events. The server validates the Stripe-Signature header. Public — no auth required.
This endpoint is public. The server validates the Stripe-Signature header using HMAC-SHA256. Returns HTTP 400 if validation fails.
/api/payments/webhook/mercadopago
Receives MercadoPago webhook events. Validates via x-signature and x-request-id headers. Public — no auth required.
/api/contact
Sends a contact form message. Public — no authentication required. Rate limited to 2 req/min.
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | yes | Sender's name |
| string | yes | Sender's email | |
| message | string | yes | Message body |
{ "message": "Tu mensaje ha sido enviado correctamente." }