Account Audit Logs
View audit logs for account activity. Audit logs provide a record of all actions taken on account resources over the past 30 days.
Overview
Access audit logs through cf.AuditLogs:
public class AuditService(ICloudflareApiClient cf)
{
public async Task<IReadOnlyList<AuditLog>> GetRecentLogsAsync(string accountId)
{
var result = await cf.AuditLogs.GetAccountAuditLogsAsync(accountId,
new ListAuditLogsFilters(Limit: 100));
return result.Items;
}
}
Note
Audit logs are only available for the past 30 days. This is a beta API.
Listing Audit Logs
var result = await cf.AuditLogs.GetAccountAuditLogsAsync(accountId,
new ListAuditLogsFilters(
Since: DateTime.UtcNow.AddDays(-7),
Limit: 100
));
foreach (var log in result.Items)
{
Console.WriteLine($"{log.Action.Time}: {log.Action.Type}");
Console.WriteLine($" Actor: {log.Actor.Email}");
Console.WriteLine($" Result: {log.Action.Result}");
}
// Check for more pages
if (result.CursorInfo?.Cursor is not null)
{
var nextPage = await cf.AuditLogs.GetAccountAuditLogsAsync(accountId,
new ListAuditLogsFilters(Cursor: result.CursorInfo.Cursor));
}
List All Logs
var filters = new ListAuditLogsFilters(
Since: DateTime.UtcNow.AddDays(-7)
);
await foreach (var log in cf.AuditLogs.GetAllAccountAuditLogsAsync(accountId, filters))
{
Console.WriteLine($"{log.Action.Time}: {log.Action.Type} by {log.Actor.Email}");
}
Filtering Logs
By Time Range
var filters = new ListAuditLogsFilters(
Since: DateTime.UtcNow.AddDays(-7), // Start time
Before: DateTime.UtcNow.AddDays(-1) // End time
);
var logs = await cf.AuditLogs.GetAccountAuditLogsAsync(accountId, filters);
By Actor
var filters = new ListAuditLogsFilters(
ActorEmail: "[email protected]"
);
await foreach (var log in cf.AuditLogs.GetAllAccountAuditLogsAsync(accountId, filters))
{
Console.WriteLine($"{log.Action.Type}: {log.Action.Description}");
}
By Action Type
var filters = new ListAuditLogsFilters(
ActionType: "zone_create"
);
var logs = await cf.AuditLogs.GetAccountAuditLogsAsync(accountId, filters);
By Result (Success/Failure)
// Get failed actions only
var filters = new ListAuditLogsFilters(
ActionResults: new[] { "failure" }
);
await foreach (var log in cf.AuditLogs.GetAllAccountAuditLogsAsync(accountId, filters))
{
Console.WriteLine($"Failed: {log.Action.Type} - {log.Action.Description}");
}
By Resource
var filters = new ListAuditLogsFilters(
ResourceId: zoneId // Filter by specific resource
);
var logs = await cf.AuditLogs.GetAccountAuditLogsAsync(accountId, filters);
Models Reference
AuditLog
| Property |
Type |
Description |
Id |
string |
Unique log identifier |
Action |
AuditAction |
Details about the action taken |
Actor |
AuditActor |
Who performed the action |
Owner |
AuditOwner |
Account that owns the resource |
Resource |
AuditResource |
The resource affected |
When |
DateTime |
When the action occurred |
AuditAction
| Property |
Type |
Description |
Type |
string |
Action type (e.g., "zone_create", "dns_record_delete") |
Result |
string |
Result ("success" or "failure") |
Time |
DateTime |
When the action was performed |
Description |
string? |
Human-readable description |
AuditActor
| Property |
Type |
Description |
Id |
string |
Actor identifier |
Email |
string? |
Actor's email address |
Type |
string |
Actor type (e.g., "user", "token") |
Ip |
string? |
IP address of the actor |
ListAuditLogsFilters
| Property |
Type |
Description |
Since |
DateTime? |
Start of time range |
Before |
DateTime? |
End of time range |
ActorEmail |
string? |
Filter by actor email |
ActorIp |
string? |
Filter by actor IP |
ActionType |
string? |
Filter by action type |
ActionResults |
string[]? |
Filter by result ("success", "failure") |
ResourceId |
string? |
Filter by resource ID |
ResourceType |
string? |
Filter by resource type |
Limit |
int? |
Maximum results per page |
Cursor |
string? |
Cursor for pagination |
Direction |
string? |
Sort direction ("asc" or "desc") |
Common Patterns
Security Audit Report
public async Task GenerateSecurityReportAsync(string accountId)
{
var filters = new ListAuditLogsFilters(
Since: DateTime.UtcNow.AddDays(-30),
ActionResults: new[] { "failure" }
);
Console.WriteLine("=== Security Audit Report ===");
Console.WriteLine($"Period: Last 30 days");
Console.WriteLine();
var failedByActor = new Dictionary<string, int>();
await foreach (var log in cf.AuditLogs.GetAllAccountAuditLogsAsync(accountId, filters))
{
var email = log.Actor.Email ?? "unknown";
failedByActor.TryGetValue(email, out var count);
failedByActor[email] = count + 1;
}
Console.WriteLine("Failed Actions by Actor:");
foreach (var (email, count) in failedByActor.OrderByDescending(x => x.Value))
{
Console.WriteLine($" {email}: {count} failures");
}
}
Monitor Specific Action Types
public async Task MonitorZoneChangesAsync(string accountId, TimeSpan lookback)
{
var filters = new ListAuditLogsFilters(
Since: DateTime.UtcNow - lookback
);
var zoneActions = new[] { "zone_create", "zone_delete", "zone_update" };
await foreach (var log in cf.AuditLogs.GetAllAccountAuditLogsAsync(accountId, filters))
{
if (zoneActions.Contains(log.Action.Type))
{
Console.WriteLine($"[{log.Action.Time}] {log.Action.Type}");
Console.WriteLine($" By: {log.Actor.Email} from {log.Actor.Ip}");
Console.WriteLine($" Resource: {log.Resource.Id}");
}
}
}
Required Permissions
| Permission |
Scope |
Level |
| Audit Logs |
Account |
Read |