Pular para o conteúdo principal

Audit Logs

Notifica maintains comprehensive audit logs for all sensitive operations performed on your account. Audit logs help you maintain compliance, debug issues, and monitor security events.

Overview​

Every API key operation, team member change, subscription modification, domain configuration, and webhook change is automatically logged with:

  • Who performed the action (user, API key, or system)
  • What action was performed
  • When it happened (with microsecond precision)
  • Which resource was affected
  • Where the request came from (IP address, user agent)
  • Additional context (metadata specific to the action)

Audit logs are immutable — once created, they cannot be modified or deleted. They are retained indefinitely for compliance purposes.

Tracked Events​

API Keys​

EventDescriptionMetadata
api_key.createdA new API key was generatedenvironment, key_type, scopes
api_key.revokedAn API key was revokedkey_prefix, revoked_reason
api_key.rotatedAn API key was rotated with a grace periodold_key_prefix, new_key_prefix, grace_period_hours

Team Members​

EventDescriptionMetadata
team_member.invitedA new team member was invited to the workspaceemail, role
team_member.removedA team member was removed from the workspaceemail, role
team_member.role_changedA team member's role or permissions were changedold_role, new_role

Subscriptions​

EventDescriptionMetadata
subscription.createdA new subscription was createdplan_id, gateway
subscription.plan_changedPlan was upgraded or downgradedold_plan_id, new_plan_id, change_type
subscription.cancelledSubscription was cancelledreason, cancel_at_period_end
subscription.payment_failedA payment attempt failedinvoice_id, invoice_number, amount_cents, reason
subscription.expiredSubscription expired after grace periodreason, days_overdue

Domains​

EventDescriptionMetadata
domain.addedA new sending domain was registereddomain, status
domain.verifiedDomain verification succeeded via DNS checkdomain, dkim_verified
domain.removedA sending domain was deleteddomain, was_verified

Webhooks​

EventDescriptionMetadata
webhook.createdA new webhook endpoint was configuredurl, events
webhook.updatedWebhook configuration was modifiedurl, events, active
webhook.deletedA webhook endpoint was removedurl

API Reference​

List Audit Logs​

Retrieve audit logs for a tenant with optional filtering.

GET /api/internal/audit-logs

Query Parameters​

ParameterTypeRequiredDescription
tenant_idstringYesFilter logs by tenant ID
actionstringNoFilter by specific action (e.g., api_key.created)
resource_typestringNoFilter by resource type (e.g., api_key, team_member)
actor_typestringNoFilter by actor type: user, system, or api_key
limitintegerNoNumber of records to return (default: 50, max: 200)

Example Request​

curl -X GET "https://api.notifica.app/api/internal/audit-logs?tenant_id=abc123&action=api_key.created&limit=10" \
-H "Authorization: Bearer your-admin-token"

Example Response​

{
"audit_logs": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "abc123",
"actor_id": "def456",
"actor_type": "user",
"action": "api_key.created",
"resource_type": "api_key",
"resource_id": "789xyz",
"metadata": {
"environment": "production",
"key_type": "publishable",
"scopes": ["notifications:send"]
},
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"inserted_at": "2026-02-12T10:30:45.123456Z"
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"tenant_id": "abc123",
"actor_id": null,
"actor_type": "system",
"action": "subscription.payment_failed",
"resource_type": "subscription",
"resource_id": "sub_abc123",
"metadata": {
"invoice_id": "inv_xyz789",
"invoice_number": "INV-2026-001",
"amount_cents": 9900,
"reason": "card_declined"
},
"ip_address": null,
"user_agent": null,
"inserted_at": "2026-02-12T08:15:22.987654Z"
}
],
"count": 2
}

Response Fields​

FieldTypeDescription
idstringUnique audit log entry ID
tenant_idstringTenant the action was performed on
actor_idstring | nullID of the actor (user, API key, or null for system)
actor_typestringType of actor: user, api_key, or system
actionstringThe action that was performed (see event tables above)
resource_typestringType of resource affected (e.g., api_key, team_member)
resource_idstring | nullID of the affected resource
metadataobjectAdditional context specific to the action
ip_addressstring | nullIP address of the requester (null for system actions)
user_agentstring | nullUser agent of the requester (null for system actions)
inserted_atstringISO 8601 timestamp when the log was created

Actor Types​

Audit logs record three types of actors:

  • user — A dashboard user (team member) performing an action through the web UI
  • api_key — An API key used to make a programmatic request
  • system — Automated system actions (e.g., subscription expiration, payment failures)

Retention Policy​

Audit logs are retained indefinitely to support compliance requirements (LGPD, GDPR, SOC 2). They cannot be deleted except as part of a full account deletion request.

If you require audit log exports for compliance or archival purposes, contact support.

Use Cases​

Compliance & Security​

  • LGPD/GDPR compliance: Track all access to personal data and demonstrate accountability
  • Security audits: Monitor API key creation, rotation, and revocation
  • Access reviews: Verify who has access to your workspace and when permissions changed

Debugging & Troubleshooting​

  • Payment failures: Identify when and why subscription payments failed
  • Domain verification issues: Track domain registration and verification attempts
  • Webhook debugging: See when webhook configurations were changed

Operational Monitoring​

  • Team changes: Monitor when team members are added, removed, or role changes occur
  • Subscription lifecycle: Track plan changes, cancellations, and reactivations
  • API usage patterns: Analyze API key usage by examining audit logs

SDK Examples​

Audit logs are accessible via all official Notifica SDKs. Note that audit log access requires admin authentication (bearer token from backoffice login), not regular API keys.

Node.js​

import { NotificaAdmin } from '@notifica/node';

const admin = new NotificaAdmin({
token: process.env.NOTIFICA_ADMIN_TOKEN,
});

// List audit logs with filters
const { auditLogs } = await admin.auditLogs.list({
tenantId: 'your-tenant-id',
action: 'api_key.created',
limit: 50,
});

for (const log of auditLogs) {
console.log(`${log.insertedAt} | ${log.actorType} | ${log.action}`);
}

// Filter by resource type
const apiKeyLogs = await admin.auditLogs.list({
tenantId: 'your-tenant-id',
resourceType: 'api_key',
});

Python​

from notifica import NotificaAdmin

admin = NotificaAdmin(token="your-admin-token")

# List audit logs
audit_logs = admin.audit_logs.list(
tenant_id="your-tenant-id",
action="api_key.created",
limit=50
)

for log in audit_logs:
print(f"{log.inserted_at} | {log.actor_type} | {log.action}")

# Filter by date range
recent_logs = admin.audit_logs.list(
tenant_id="your-tenant-id",
actor_type="user",
limit=100
)

Go​

package main

import (
"context"
"fmt"
"github.com/notifica-tech/notifica-go"
)

func main() {
client := notifica.NewAdminClient("your-admin-token")

logs, err := client.AuditLogs.List(context.Background(), &notifica.AuditLogListParams{
TenantID: "your-tenant-id",
Action: notifica.String("api_key.created"),
ResourceType: notifica.String("api_key"),
Limit: notifica.Int(50),
})
if err != nil {
panic(err)
}

for _, log := range logs.AuditLogs {
fmt.Printf("%s | %s | %s\n", log.InsertedAt, log.ActorType, log.Action)
}
}

Java​

import com.notifica.NotificaAdmin;
import com.notifica.model.AuditLog;
import com.notifica.param.AuditLogListParams;

NotificaAdmin admin = NotificaAdmin.builder()
.token("your-admin-token")
.build();

AuditLogListParams params = AuditLogListParams.builder()
.tenantId("your-tenant-id")
.action("api_key.created")
.limit(50L)
.build();

List<AuditLog> logs = admin.auditLogs().list(params).getAuditLogs();

for (AuditLog log : logs) {
System.out.printf("%s | %s | %s%n",
log.getInsertedAt(), log.getActorType(), log.getAction());
}

Raw API Examples​

If you're not using an SDK, you can access audit logs directly via HTTP:

Export Recent Audit Logs​

import requests

API_URL = "https://app.usenotifica.com.br/api/internal/audit-logs"
ADMIN_TOKEN = "your-admin-token"
TENANT_ID = "your-tenant-id"

response = requests.get(
API_URL,
params={"tenant_id": TENANT_ID, "limit": 100},
headers={"Authorization": f"Bearer {ADMIN_TOKEN}"}
)

audit_logs = response.json()["audit_logs"]
print(f"Retrieved {len(audit_logs)} audit log entries")

for log in audit_logs:
print(f"{log['inserted_at']} | {log['actor_type']} | {log['action']}")

Monitor Critical Actions​

const axios = require('axios');

const CRITICAL_ACTIONS = [
'api_key.revoked',
'team_member.removed',
'subscription.cancelled',
'domain.removed',
'webhook.deleted'
];

async function checkCriticalActions(tenantId) {
const response = await axios.get('https://app.usenotifica.com.br/api/internal/audit-logs', {
params: { tenant_id: tenantId, limit: 50 },
headers: { Authorization: `Bearer ${process.env.ADMIN_TOKEN}` }
});

const criticalLogs = response.data.audit_logs.filter(log =>
CRITICAL_ACTIONS.includes(log.action)
);

if (criticalLogs.length > 0) {
console.warn(`⚠️ Found ${criticalLogs.length} critical actions:`);
criticalLogs.forEach(log => {
console.warn(` - ${log.action} by ${log.actor_type} at ${log.inserted_at}`);
});
}
}

Best Practices​

  1. Regular Reviews: Review audit logs weekly to catch unauthorized changes
  2. Alerting: Set up automated alerts for critical actions (key revocation, member removal)
  3. Compliance: Export and archive audit logs quarterly for compliance documentation
  4. Investigation: When investigating issues, filter by resource_id to trace a specific resource's history
  5. Team Awareness: Share audit log access with your security and compliance teams