Audita
On this page
Getting StartedAuthenticationRate LimitingError HandlingBest PracticesHealth CheckAuth EndpointsUser EndpointsOrganizationsAuditsExportsTimelineWebhooksRetention PoliciesPII Redaction RulesAnomaly RulesNotification ChannelsScheduled ExportsDashboardsApp ErrorsSubscriptionsContact

API Reference

Tamper-proof audit logging for your organization. Every record is SHA-256 hashed and chained into an immutable, verifiable ledger.

https://api.audita.app

Getting Started

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.


Authentication

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 groupBearer (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

Rate limiting is applied per client (by API key prefix, JWT prefix, or IP address). When exceeded the server returns HTTP 429.

Endpoint GroupPathLimitWindow
RegistrationPOST /api/auth/register3 req1 min
Resend verificationPOST /api/auth/resend-verification3 req1 min
Auth (general)/api/auth/**10 req1 min
Invitations/api/organizations/{id}/invitations5 req1 min
Exports/api/audits/export/**5 req1 min
Audits/api/audits/**1 000 req1 min
Users/api/users/**20 req1 min
Organizations/api/organizations/**10 req1 min
Contact/api/contact2 req1 min
Health/ping10 req1 min
Defaulteverything else50 req1 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.


Error Handling

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"
  }
}
StatusMeaning
400Validation failure — check the message or details field
401Missing or invalid API key / expired token
403Authenticated but insufficient permissions
404Resource not found, or belongs to a different organization
409Conflict — resource already exists (e.g. duplicate retention policy)
429Rate limit exceeded
500Server error — retry with exponential backoff

Best Practices — Audit Ingestion

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.


Health Check
GET

/ping

Verifies that the API is reachable. No authentication required.

Response200 OK
pong
curl https://api.audita.app/ping

Auth Endpoints

All /api/auth/** endpoints are public — no authentication required.

POST

/api/auth/register

Creates a new user account. Sends a 6-digit email verification code valid for 15 minutes.

FieldTypeRequiredNotes
usernamestringyes
emailstringyesMust be a valid email
passwordstringyes
organizationIdUUIDnoAssociates to an org on creation
rolestringyesADMIN or USER
Response200 OK
{ "message": "User created. Check your email for the verification code." }

POST

/api/auth/verify

Activates an account with the emailed 6-digit code.

FieldTypeRequired
emailstringyes
codestringyes
Response200 OK
{ "message": "Account verified successfully." }

POST

/api/auth/resend-verification

Resends the verification code to the given email. Rate limited to 3 req/min.

FieldTypeRequired
emailstringyes
Response200 OK
{ "message": "Verification code resent." }

POST

/api/auth/login

Authenticates and returns access + refresh tokens. You can pass either username or email.

FieldTypeRequiredNotes
usernamestringnoEither username or email is required
passwordstringyes
Response200 OK
{
  "accessToken": "eyJhbGci...",
  "refreshToken": "eyJhbGci...",
  "username": "john",
  "organizationId": "550e8400-...",
  "role": "USER"
}

POST

/api/auth/refresh

Exchanges a refresh token for a new access token.

FieldTypeRequired
refreshTokenstringyes
Response200 OK
{ "accessToken": "eyJhbGci..." }

User Endpoints

Manage users. Most endpoints require Bearer auth.

GET

/api/users/me

Returns the authenticated user's full profile including organization and current plan. Requires Bearer auth.

Response200 OK
{
  "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
    }
  }
}

GET

/api/users/{id}

Returns a user by ID. Public — no auth required.


GET

/api/users/email/{email}

Returns a user by email. Public — no auth required.


GET

/api/users/organization/{organizationId}

Returns all users belonging to an organization. Requires Bearer auth.


POST

/api/users/assign-organization

Assigns a user (by email) to an organization. Requires Bearer auth with ADMIN role.

FieldTypeRequired
emailstringyes

PATCH

/api/users/{id}/role/admin

Promotes a user to ADMIN role. Requires Bearer auth.


POST

/api/users/{userId}/remove-from-organization

Removes a user from their current organization. Requires Bearer auth with ADMIN role.


Organizations
GET

/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.

ParameterTypeRequiredDescription
apiKeystringyesYour API key
Response200 OK
{
  "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"

POST

/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.

FieldTypeRequiredDescription
namestringyesOrganization name
Response201 Created
{
  "id": "uuid",
  "name": "Acme Corp",
  "status": "ACTIVE",
  "createdAt": "2025-01-01T00:00:00Z",
  "apiKey": "ak_live_xxxxxxxxxxxxxxxx",
  "allowedIps": []
}

GET

/api/organizations/{id}

Returns an organization by ID. Requires Bearer auth.

ParameterTypeDescription
idUUIDOrganization ID

POST

/api/organizations/{id}/invitations

Sends an invitation email to a new user. Requires Bearer auth. Rate limited to 5 req/min.

FieldTypeRequiredDescription
emailstringyesEmail address to invite
Response200 OK
(empty body)

GET

/api/organizations/{id}/allowed-ips

Returns the current IP allowlist for API key authentication. Requires Bearer auth.

Response200 OK
{ "allowedIps": ["192.168.1.0/24", "10.0.0.1"] }

PUT

/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.

FieldTypeRequiredDescription
allowedIpsstring[]yesList of IPs, CIDR ranges, or hostnames

Audits
POST

/api/audits

Creates a single audit record. The record is appended to your organization's hash chain.

FieldTypeRequiredConstraintsDescription
organizationIdUUIDyesYour organization ID
resourceTypestringyesmax 200Type of resource (e.g. USER, ORDER)
resourceIdstringyesmax 200Unique identifier of the resource
actionstringyesenumCREATE, UPDATE, DELETE, ACCESS, OTHER
actorDatastringnomax 2,000Who performed the action
payloadstringnomax 100,000Resource state after the action (JSON recommended)
beforeStatestringnomax 100,000Resource state before the action
correlationIdstringnomax 200Shared trace ID across services
metadatastringnomax 100,000Additional context. IP and user-agent are auto-merged
eventTimestampISO-8601noWhen the event actually occurred
idempotencyKeystringnomax 200Unique key to prevent duplicates on retry. Strongly recommended
Response201 Created
{
  "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"
  }'

POST

/api/audits/bulk

Creates up to 500 audit records in a single atomic transaction. All records must belong to the same organization.

ConstraintValue
Minimum items1
Maximum items500

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"
    }
  ]'

GET

/api/audits/{id}

Returns a single audit record by ID. Returns 404 if the audit belongs to a different organization.

ParameterTypeDescription
idUUIDAudit record ID
curl https://api.audita.app/api/audits/7c9e6679-7425-40de-944b-e07fc1f90ae7 \
  -H "X-API-Key: $AUDITA_API_KEY"

GET

/api/audits

Searches and paginates audit records. Results are sorted by createdAt descending (newest first).

ParameterTypeRequiredDescription
organizationIdUUIDnoResolved from API key if omitted
resourceTypestring[]noFilter by resource type(s). Repeatable
resourceIdstringnoFilter by exact resource ID
actionstring[]noFilter by action(s). Repeatable
actorDatastring[]noFilter by actor(s). Repeatable
correlationIdstringnoFilter by correlation ID
fromDateISO-8601noStart of date range (inclusive)
toDateISO-8601noEnd of date range (inclusive)
payloadKeystring[]noJSON key path within payload (positional)
payloadValuestring[]noValue to match for each payloadKey
includeArchivedbooleannoInclude archived records. Default: false
pageintegernoPage number (0-indexed). Default: 0
sizeintegernoPage size. Default: 20
Response200 OK
{
  "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"

GET

/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.

ParameterTypeRequiredDescription
dateFromISO-8601yesStart of counting window
actionstring[]yesAction(s) to count. Must have same length as resource
resourcestring[]yesResource type(s) to count
actorstring[]noActor filter(s). Positional
titlestring[]noDisplay labels for each tuple
Response200 OK
[
  { "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"

GET

/api/audits/metrics

Returns aggregated metrics: total count, breakdown by action, breakdown by resource type, and daily counts. Defaults to the last 30 days.

ParameterTypeRequiredDescription
fromYYYY-MM-DDnoStart date. Default: 30 days ago
toYYYY-MM-DDnoEnd date. Default: today
resourcestringnoFilter to a specific resource type
Response200 OK
{
  "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"

GET

/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.

ParameterTypeDescription
organizationIdUUIDYour organization ID
Response200 OK
{ "valid": true, "totalChecked": 4821 }
curl https://api.audita.app/api/audits/verify/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
  -H "X-API-Key: $AUDITA_API_KEY"

GET

/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.

ParameterTypeDescription
idUUIDAudit record ID
Response200 OK
{ "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"

GET

/api/audits/{id}/diff

Returns a structured diff between beforeState and payload for a single audit.

ParameterTypeDescription
idUUIDAudit record ID
Response200 OK
{
  "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 }
  ]
}

GET

/api/audits/correlation/{correlationId}

Returns all audits sharing the same correlationId, plus a summary of the distributed trace.

ParameterTypeDescription
correlationIdstringCorrelation ID to look up
Response200 OK
{
  "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"
  }
}

POST

/api/audits/import

Imports audits from a CSV or Excel (.xlsx) file. Processing is asynchronous.

FieldTypeRequiredDescription
filemultipart/form-datayes.csv or .xlsx file
Response202 Accepted
{
  "status": "ACCEPTED",
  "message": "Import started. Records will be processed in the background."
}

Exports

Export endpoints stream the result as a ZIP file containing the export. Auth: Bearer or API Key.

POST

/api/audits/export/{organizationId}

Exports filtered audits as an Excel (.xlsx) file inside a ZIP. Also creates an ACCESS audit record.

ParameterTypeNotes
fromInstantStart of time range (optional)
toInstantEnd of time range (optional)
resourceTypestring[]Multi-value filter (optional)
actionstring[]Multi-value filter (optional)
actorDatastring[]Multi-value filter (optional)

Optional JSON body to extract custom columns from payload:

{
  "customColumns": {
    "User ID": "payload.userId",
    "Department": "payload.department"
  }
}
Response200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename=audits.zip

Body: ZIP containing audits.xlsx

POST

/api/audits/export/{organizationId}/json

Same as above but exports a JSON file inside the ZIP.

Response200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename=audits.zip

Body: ZIP containing audits.json

GET

/api/audits/compliance-report/{organizationId}

Generates a PDF compliance report for the given time range.

ParameterTypeRequiredNotes
fromYYYY-MM-DDyesStart date
toYYYY-MM-DDyesEnd date
verifybooleannoIf true, runs integrity check and includes result in report
Response200 OK
Content-Type: application/pdf

Timeline

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.

GET

/api/audits/timeline/actor

Returns all audit events for a given actor, grouped into inactivity-based sessions.

ParameterTypeRequiredDefaultNotes
actorstringyesactorData value to look up
organizationIdUUIDnoResolved from auth context if omitted
fromInstantnoStart of time range
toInstantnoEnd of time range
maxEventsintegerno500Max 2 000
sessionGapMinutesintegerno30Inactivity gap that splits sessions
Response200 OK
{
  "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.


GET

/api/audits/timeline/resource/{resourceType}/{resourceId}

Returns the full event history of a specific resource, paginated.

ParameterTypeDefaultNotes
resourceType (path)stringe.g. user, order
resourceId (path)stringe.g. user-123
organizationIdUUID
fromInstant
toInstant
pageinteger0
sizeinteger50
Response200 OK
{
  "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[] */ ]
}

Webhooks

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.

EventTriggered when
audit.createdA single audit is created
audit.bulk_createdMultiple audits are created in a single bulk call
anomaly.triggeredAn anomaly rule exceeds its configured threshold
webhook.testA 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"
  }
}
audit.bulk_created
{
  "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"
    }
  ]
}
anomaly.triggered
{
  "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"
}
POST

/api/webhooks

Registers a webhook endpoint. The signing secret is returned only in this response — store it securely.

FieldTypeRequiredDescription
urlstringyesHTTPS endpoint to receive event payloads
eventsstring[]yesEvents to subscribe to
Response201 Created
{
  "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"]
  }'

GET

/api/webhooks

Lists all registered webhooks for your organization.

curl https://api.audita.app/api/webhooks \
  -H "X-API-Key: $AUDITA_API_KEY"

DELETE

/api/webhooks/{id}

Permanently deletes a webhook.

ParameterTypeDescription
idUUIDWebhook ID
curl -X DELETE https://api.audita.app/api/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "X-API-Key: $AUDITA_API_KEY"

POST

/api/webhooks/{id}/test

Sends a synthetic ping event to verify that the endpoint is reachable and that signature verification works.

ParameterTypeDescription
idUUIDWebhook ID
curl -X POST https://api.audita.app/api/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/test \
  -H "X-API-Key: $AUDITA_API_KEY"

Retention Policies

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.

POST

/api/retention-policies

Creates a retention policy. Returns 409 if one already exists — use PUT to update.

FieldTypeRequiredConstraintsDescription
retentionDaysintegeryes>= 1Days to retain audit records
Response201 Created
{
  "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 }'

GET

/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"

PUT

/api/retention-policies/{id}

Updates the retention period.

ParameterTypeDescription
idUUIDRetention 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 Redaction Rules

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.

GET

/api/pii-rules

Returns all PII redaction rules for the organization.

Response200 OK
[
  {
    "id": "uuid",
    "organizationId": "uuid",
    "fieldName": "payload",
    "jsonPaths": ["email", "user.nationalId"],
    "searchRetentionDays": 90,
    "createdAt": "2025-01-01T00:00:00Z"
  }
]

POST

/api/pii-rules

Creates a new PII redaction rule.

FieldTypeRequiredNotes
fieldNamestringyes"payload" or "actorData"
jsonPathsstring[]noDot-notation paths e.g. "user.email". Empty = hash the entire field
searchRetentionDaysintegernoDays the value stays searchable before hashing. Min 0, max 3 650
Response201 Created
{
  "id": "uuid",
  "organizationId": "uuid",
  "fieldName": "payload",
  "jsonPaths": ["email", "user.nationalId"],
  "searchRetentionDays": 90,
  "createdAt": "2025-01-01T00:00:00Z"
}

DELETE

/api/pii-rules/{id}

Deletes a PII redaction rule.

ParameterTypeDescription
idUUIDPII rule ID
Response204 No Content
(no body)

Anomaly Rules

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.

POST

/api/anomaly-rules

Creates an anomaly detection rule.

FieldTypeRequiredConstraintsDescription
actionstringyesenumAction to monitor: CREATE, UPDATE, DELETE, ACCESS, OTHER
resourceTypestringyesmax 50Resource type to monitor
thresholdintegeryes>= 1Number of events that triggers the alert
windowSecondslongyes>= 1Rolling evaluation window in seconds
cooldownSecondslongnoMinimum gap between alerts. Defaults to windowSeconds
notificationChannelIdUUIDyesChannel to alert on
Response201 Created
{
  "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"
  }'

GET

/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"

DELETE

/api/anomaly-rules/{id}

Deletes an anomaly rule. Alerts stop immediately.

ParameterTypeDescription
idUUIDAnomaly rule ID
curl -X DELETE https://api.audita.app/api/anomaly-rules/f1e2d3c4-b5a6-7890-fedc-ba9876543210 \
  -H "X-API-Key: $AUDITA_API_KEY"

Notification Channels

Defines where Audita sends alerts. Supported types: SLACK (Incoming Webhook) and EMAIL.

POST

/api/notifications/channels

Connects a notification channel.

FieldTypeRequiredConstraintsDescription
typestringyesSLACK or EMAILChannel type
configstringyesmax 2,048Slack: Incoming Webhook URL. Email: recipient address
namestringnomax 255Human-readable label (e.g. "#alerts")
Response201 Created
{
  "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"
  }'

GET

/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"

DELETE

/api/notifications/channels/{id}

Disconnects a notification channel. Anomaly rules linked to this channel will stop sending alerts.

ParameterTypeDescription
idUUIDChannel ID
curl -X DELETE https://api.audita.app/api/notifications/channels/c1b2a3d4-e5f6-7890-abcd-ef1234567890 \
  -H "X-API-Key: $AUDITA_API_KEY"

POST

/api/notifications/send

Sends a notification immediately to a specific channel. If channelId is omitted, broadcasts to all active channels.

FieldTypeRequiredDescription
channelIdUUIDnoTarget channel. Omit to broadcast to all active channels
subjectstringyesNotification subject
messagestringyesNotification body
organizationIdUUIDnoResolved from auth if omitted
Response202 Accepted
(no body — sending is asynchronous)

App Errors

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

POST

/api/app-errors

Reports one or more occurrences of an error code.

FieldTypeRequiredConstraintsDescription
errorCodestringyespredefined codeHTTP status code of the error
occurrencesintegeryes>= 1How 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

Scheduled exports deliver a filtered export file to an email address at a specific future time. Auth: Bearer or API Key.

GET

/api/scheduled-exports

Returns all scheduled exports for the organization.

Response200 OK
[
  {
    "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
  }
]

POST

/api/scheduled-exports

Schedules a future export. The scheduledAt time must be in the future.

FieldTypeRequiredNotes
recipientEmailstringyesMust be a valid email
scheduledAtInstantyesMust be in the future
formatstringnoCSV or JSON (default CSV)
filtersobjectnofromDate, toDate, resourceTypes, actions, actorDataList, correlationId
customColumnsmapnoColumn header → JSON path within payload
Response201 Created
{
  "id": "uuid",
  "recipientEmail": "reports@acme.com",
  "scheduledAt": "2025-07-01T06:00:00Z",
  "status": "PENDING",
  "format": "CSV",
  "createdAt": "2025-06-01T00:00:00Z"
}

DELETE

/api/scheduled-exports/{id}

Deletes a scheduled export. Returns HTTP 409 if the export is currently RUNNING.

Response204 No Content
(no body)

Dashboards

Dashboards store named visualization configurations (layout + widget settings as a JSON string). Auth: Bearer or API Key.

GET

/api/dashboards

Returns all dashboards for the organization.

Response200 OK
[
  {
    "id": "uuid",
    "organizationId": "uuid",
    "name": "Security Overview",
    "configuration": "{\"widgets\":[...]}",
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-06-01T00:00:00Z"
  }
]

GET

/api/dashboards/{id}

Returns a single dashboard by ID.


POST

/api/dashboards

Creates (or upserts if id is provided) a dashboard.

FieldTypeRequiredDescription
idUUIDnoOptional — if provided, upserts the dashboard
namestringyesDashboard name
configurationstringyesJSON string of widget layout configuration
Response201 Created
{
  "id": "uuid",
  "name": "Security Overview",
  "configuration": "{\"widgets\":[{\"type\":\"bar\",\"metric\":\"byAction\"}]}",
  "createdAt": "2025-01-01T00:00:00Z",
  "updatedAt": "2025-01-01T00:00:00Z"
}

PUT

/api/dashboards/{id}

Updates the dateFrom field of a dashboard (persists the user's selected time range).

FieldTypeRequiredDescription
dateFromstringyesDate string e.g. 2025-06-01

DELETE

/api/dashboards/{id}

Deletes a dashboard.

Response204 No Content
(no body)

Subscriptions & Payments

Manage plan subscriptions and payment integrations. Stripe and MercadoPago are supported. Auth: Bearer (subscriptions); public (payment webhooks).

Plans

PlanMonthly price
STARTUP$199
GROWTH$399
ENTERPRISE$899
POST

/api/subscriptions/stripe/checkout-session

Creates a Stripe embedded checkout session.

FieldTypeRequiredDescription
userIdUUIDyesUser to subscribe
planNamestringyesSTARTUP, GROWTH, or ENTERPRISE
Response201 Created
{
  "clientSecret": "cs_test_xxx",
  "publishableKey": "pk_test_xxx"
}

GET

/api/subscriptions/stripe/session-status

Returns the status of a Stripe checkout session.

ParameterTypeRequired
sessionIdstringyes
Response200 OK
{ "status": "complete", "subscriptionId": "sub_xxx" }

POST

/api/subscriptions/stripe/portal

Creates a Stripe customer portal session for managing billing and plan changes.

ParameterTypeRequired
userIdUUIDyes
Response200 OK
{ "url": "https://billing.stripe.com/session/..." }

GET

/api/subscriptions/user/{userId}

Returns the active subscription for a user.

Response200 OK
{
  "id": "uuid",
  "planName": "GROWTH",
  "userId": "uuid",
  "createdAt": "2025-01-01T00:00:00Z",
  "expirationDate": "2025-01-31T00:00:00Z",
  "status": "ACTIVE",
  "autoRenew": true
}

DELETE

/api/subscriptions/{id}

Cancels a subscription.

Response204 No Content
(no body)

POST

/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.


POST

/api/payments/webhook/mercadopago

Receives MercadoPago webhook events. Validates via x-signature and x-request-id headers. Public — no auth required.


Contact
POST

/api/contact

Sends a contact form message. Public — no authentication required. Rate limited to 2 req/min.

FieldTypeRequiredDescription
namestringyesSender's name
emailstringyesSender's email
messagestringyesMessage body
Response200 OK
{ "message": "Tu mensaje ha sido enviado correctamente." }
Last updated: March 2026