Audit Logs

Audit logs provide a chronological record of user and administrator actions in Synthesia, helping organizations monitor usage, detect anomalies, and demonstrate compliance.

📘

Audit Logs are available on Enterprise plans.

All endpoints require API key authentication.

📌

Note:

Only Organization Admins can access Audit Logs (via Organization Settings or Synthesia API).

The Audit Logs API returns a record of actions taken across your organization and workspaces: who did what, when, and to what. Use it for compliance reporting, security monitoring, and activity tracking.

To browse and filter audit logs in the Synthesia app instead of calling the API, see Audit logs.

Endpoints

MethodEndpointPurpose
GET/v2/auditLogs/eventsQuery audit log events with simple filters.
POST/v2/auditLogs/events/searchAdvanced search with complex filter criteria.
POST/v2/auditLogs/exportExport audit logs as a CSV file.

Query audit log events

GET https://api.synthesia.io/v2/auditLogs/events

Simple query endpoint for retrieving paginated audit events.

Key behavior:

  • Exactly one of workspaceId or organizationId must be provided.
  • Multiple values for actions and actorIds are comma-separated.
  • Dates are Unix timestamps (seconds since epoch).

Query parameters:

ParameterTypeRequiredDescription
workspaceIdstring (UUID)ConditionalFilter by workspace. Mutually exclusive with organizationId.
organizationIdstring (UUID)ConditionalFilter by organization. Mutually exclusive with workspaceId.
actionsstringNoComma-separated action names, for example workspace.user.invited,workspace.invitation.accepted. See Event types for the full list.
actorIdsstringNoComma-separated actor IDs.
targetIdstringNoFilter by a specific target resource.
startDateintegerNoUnix timestamp (seconds). Filters events from this date onwards. Must be before endDate if both are provided.
endDateintegerNoUnix timestamp (seconds). Filters events before this date. Must be after startDate if both are provided.
cursorstringNoPagination cursor from a previous response.
limitintegerNoResults per page, 1 to 200. Default: 50.

Response:

{
  "events": [
    {
      "id": "7d8307d2-63f3-4e86-85db-8feae494f7e2",
      "action": "workspace.license.consumed",
      "status": "success",
      "actor": {
        "type": "user",
        "id": "9a0840a7-a4be-42f7-9d2c-a6d96ccc6ba6",
        "name": "Jamie Rivera",
        "email": "[email protected]"
      },
      "target": {
        "type": "user",
        "id": "91f0be7b-055a-4766-8457-79dbeb1c351d",
        "name": "Alex Chen"
      },
      "context": {
        "workspaceId": "99ba788e-eaeb-4b0c-ae4e-901575d6f28c",
        "organizationId": "73a6bbf3-eed0-4d31-8dd9-16435fe2ee38",
        "ipAddress": null
      },
      "details": {
        "previousLicenseType": "free",
        "newLicenseType": "full",
        "targetUserEmail": "[email protected]",
        "targetUserId": "91f0be7b-055a-4766-8457-79dbeb1c351d",
        "source": "admin_action",
        "workspaceName": "Sales Workspace",
        "organizationName": "Example Org"
      },
      "metadata": {
        "createdAt": "2026-01-11T16:47:57.658000Z",
        "processedAt": "2026-01-11T16:47:58.324000Z"
      }
    }
  ],
  "nextCursor": "51332afa-4419-405f-9a85-fe437ce683aa",
  "hasMore": true
}

Search audit log events

POST https://api.synthesia.io/v2/auditLogs/events/search

Advanced search for complex filtering scenarios. Use this endpoint instead of GET /v2/auditLogs/events when:

  • Filtering by 50 or more actions or actors.
  • You need programmatic access with a JSON request body.
  • Your filter combination is too complex for query parameters.

Request body:

{
  "organizationId": "73a6bbf3-eed0-4d31-8dd9-16435fe2ee38",
  "startDate": 1736524800,
  "endDate": 1736697600,
  "actions": ["billing.credits.consumed", "dubbing.project.created"],
  "actorIds": ["9a0840a7-a4be-42f7-9d2c-a6d96ccc6ba6", "91f0be7b-055a-4766-8457-79dbeb1c351d"],
  "cursor": null,
  "limit": 100
}

Response:

{
  "events": [
    {
      "id": "59fa0207-13d9-45fe-a54c-1799658ccc31",
      "action": "billing.credits.consumed",
      "status": "success",
      "actor": {
        "type": "system",
        "id": "billing_system",
        "name": "Billing System",
        "email": null
      },
      "target": {
        "type": "workspace",
        "id": "1f32e8d4-1594-43e2-8caa-1e0a48e00bcc",
        "name": "Enterprise Workspace"
      },
      "context": {
        "workspaceId": "1f32e8d4-1594-43e2-8caa-1e0a48e00bcc",
        "organizationId": "73a6bbf3-eed0-4d31-8dd9-16435fe2ee38",
        "ipAddress": "internal"
      },
      "details": {
        "feature": "DUBBING_DURATION",
        "amount": 5.845,
        "operationType": "credit"
      },
      "metadata": {
        "createdAt": "2026-01-11T16:49:00.051000Z",
        "processedAt": "2026-01-11T16:49:00.387000Z"
      }
    }
  ],
  "nextCursor": "b8d4c4ed-1682-4831-af22-3723f400119d",
  "hasMore": true
}

Export audit logs as CSV

POST https://api.synthesia.io/v2/auditLogs/export

Exports filtered audit logs as a downloadable CSV file. See CSV structure for the columns it contains.

Key behavior:

  • Maximum of 10,000 events per export. If your filter matches more, the response is truncated and the filename includes a _TRUNCATED suffix.
  • The response is binary CSV data (Content-Type: application/csv).

Request body:

{
  "organizationId": "73a6bbf3-eed0-4d31-8dd9-16435fe2ee38",
  "startDate": 1733932192,
  "endDate": 1736524192,
  "actions": ["billing.credits.consumed"],
  "actorIds": null,
  "targetId": null
}

Response: binary CSV file, with a Content-Disposition header containing the filename, for example audit_logs_export_20260111_165018.csv.

Exporting is itself an audited action. It generates its own event:

{
  "id": "2543a303-74f9-46a1-aba6-9c0538f92a3e",
  "action": "audit_logs.exported",
  "status": "success",
  "actor": {
    "type": "user",
    "id": "91f0be7b-055a-4766-8457-79dbeb1c351d",
    "name": "Jamie Rivera",
    "email": "[email protected]"
  },
  "target": {
    "type": "organization",
    "id": "73a6bbf3-eed0-4d31-8dd9-16435fe2ee38",
    "name": null
  },
  "context": {
    "workspaceId": null,
    "organizationId": "73a6bbf3-eed0-4d31-8dd9-16435fe2ee38",
    "ipAddress": null
  },
  "details": {
    "eventCount": 62,
    "truncated": false,
    "filename": "audit_logs_export_20260111_165018.csv",
    "filters": {
      "start_date": "2025-12-12T16:49:52+00:00",
      "end_date": "2026-01-11T16:49:52+00:00",
      "actor_ids": ["9a0840a7-a4be-42f7-9d2c-a6d96ccc6ba6", "91f0be7b-055a-4766-8457-79dbeb1c351d"]
    }
  },
  "metadata": {
    "createdAt": "2026-01-11T16:50:18.980000Z",
    "processedAt": "2026-01-11T16:50:18.983000Z"
  }
}

Pagination

The Audit Logs API uses cursor-based pagination, which stays stable even when new events are added between requests.

  1. Make an initial request without a cursor parameter.
  2. The response includes nextCursor and hasMore.
  3. Pass nextCursor as the cursor parameter in your next request.
  4. Repeat until hasMore is false.
FieldTypeDescription
nextCursorstring | nullPass this as the cursor parameter in your next request. null if there are no more results.
hasMorebooleanWhether more events exist beyond the current page. false means nextCursor is also null.

Best practices:

  • Check hasMore to decide whether to keep paginating, rather than only checking whether nextCursor is null.
  • Keep filter parameters (startDate, endDate, actions, and so on) identical across all requests in a paginated sequence. Changing filters mid-sequence means starting over without a cursor.
  • If events is empty but hasMore is true, keep paginating. There may be matching results further on.
  • Treat cursors as opaque tokens. Don't parse or modify them.
  • Events are sorted by createdAt descending, then by id descending, for consistent ordering across pages.
  • There's no offset or page-number based pagination, only cursor-based.

Response codes

CodeDescription
200Success.
400Invalid parameters, for example both workspaceId and organizationId provided.
403Forbidden. Invalid API key, or Public API access disabled.
404Workspace or organization not found.
429Rate limit exceeded.
5XXServer error.

Data model reference

Actor types

TypeDescription
userA human user performed the action.
systemSynthesia's systems performed the action automatically, for example the billing system.
serviceAn external service or integration performed the action.

Target types

TypeDescription
workspaceA workspace.
videoA video or dubbing project.
userA user account.
organizationAn organization.
assetA media asset.

CSV structure

Exported files are named audit_logs_export_<YYYYMMDD>_<HHMMSS>.csv. A single export is capped at 10,000 events—if your filtered result has more, the file is truncated and _TRUNCATED is appended to the filename. Narrow your date range or filters to get the rest.

Each row has these columns:

ColumnDescription
event_idUnique identifier for the event.
timestampWhen the event occurred, in ISO 8601 (UTC).
actionThe event, in domain.resource.past_tense_verb format (for example, workspace.user.invited).
actor_typeWho or what performed the action: user or system.
actor_idThe actor's unique identifier.
actor_nameThe actor's display name.
actor_emailThe actor's email address.
target_typeThe kind of thing the action was performed on (for example, workspace, user, video, asset).
target_idThe target's unique identifier.
target_nameThe target's display name.
statusWhether the action succeeded, for example success.
detailsA JSON-encoded string with information specific to that action, such as what changed from and to. Quotes inside it are escaped and need unescaping before you parse it.
workspace_idThe workspace the action occurred in, if applicable.
organization_idThe organization the action occurred in.
ip_addressThe IP address the action came from. Blank for most user actions, and internal for actions performed by Synthesia's systems.
📌

Note:

The CSV flattens the actor, target, and context objects from the JSON response into individual columns, and uses a single timestamp rather than the JSON response's separate createdAt and processedAt.

Event structure

Each event, whether from events, events/search, or a CSV row, records:

  • id: a unique identifier for the event.
  • action: what was done, in domain.resource.past_tense_verb format (for example, workspace.user.invited).
  • status: whether the action succeeded.
  • actor: who or what performed the action.
  • target: what the action was performed on.
  • context: the workspace, organization, and IP address the action occurred in.
  • details: additional information specific to that action, such as what changed from and to.
  • metadata: timestamps for when the event was created and processed.

Event types

Actions follow the domain.resource.past_tense_verb format shown throughout this reference. Each event's Name is the label it appears under in the Synthesia app's Events filter—see Audit logs for how to browse events there. A dash (—) means the event isn't available in the list of filter options.

Authentication

EventNameDescription
user.authentication.loginUser Authentication LoginA user logged in.
user.authentication.logoutUser Authentication LogoutA user logged out.

User

EventNameDescription
user.profile.updatedUser Profile UpdatedA profile field was updated.
user.profile_picture.updatedUser Profile Picture UpdatedA profile picture was uploaded or deleted.
user.email.changedA user's email address was changed. Can be triggered by the user themselves, or automatically, for example by an SSO sync.
user.account.bannedA user account was banned.
user.api_key.createdUser Api Key CreatedAn API key was created.
user.scim.createdUser SCIM CreatedA user was created via SCIM provisioning.
user.scim.updatedUser SCIM UpdatedA user was updated via SCIM provisioning.
user.scim.deletedUser SCIM DeletedA user was deleted via SCIM provisioning.
user.jit.provisionedUser JIT ProvisionedA user was provisioned via Just-in-Time (JIT) provisioning.

Workspace

EventNameDescription
workspace.createdWorkspace CreatedA workspace was created.
workspace.boundWorkspace BoundA workspace was bound to an organization. Performed by Synthesia's systems, not a person.
workspace.unboundWorkspace UnboundA workspace was unbound from an organization. Performed by Synthesia's systems, not a person.
workspace.deletion.scheduledWorkspace Deletion ScheduledWorkspace deletion was scheduled.
workspace.name.changedWorkspace Name ChangedThe workspace name was changed.
workspace.icon.changedWorkspace Icon ChangedThe workspace icon was uploaded or deleted.
workspace.insights.requestedWorkspace Insights RequestedAn Insights report was requested.
workspace.preferences.updatedWorkspace Preferences UpdatedA workspace setting was changed.
workspace.joining_strategy.updatedWorkspace Joining Strategy UpdatedThe workspace's discoverability setting was changed (for example, between invitation-only and open for anyone from listed domains).
workspace.invite_link.updatedWorkspace Invite Link UpdatedThe workspace's invite link was turned on or off.
workspace.invite_link.resetWorkspace Invite Link ResetThe workspace's invite link was reset, invalidating the old one.
workspace.share_page_colors.updatedWorkspace Share Page Colors UpdatedThe share page's primary, secondary, or background color was changed.
workspace.share_page_logo.updatedWorkspace Share Page Logo UpdatedThe share page logo was uploaded or deleted.
workspace.user.invitedWorkspace User InvitedA user was invited to the workspace.
workspace.invitation.acceptedWorkspace Invitation AcceptedA workspace invitation was accepted.
workspace.invitation.revokedWorkspace Invitation RevokedA workspace invitation was revoked.
workspace.user.role_changedWorkspace User Role ChangedA user's role in the workspace was changed.
workspace.user.removedWorkspace User RemovedA user was removed from the workspace.
workspace.user.leftWorkspace User LeftA user left the workspace voluntarily.
workspace.license.changedWorkspace License ChangedA user's license in the workspace was changed.
workspace.license.consumedWorkspace License ConsumedA user's license in the workspace was upgraded to Full.
workspace.license.releasedWorkspace License ReleasedA user's license in the workspace was downgraded to Restricted.

Organization

EventNameDescription
organization.createdAn organization was created.
organization.name.changedOrganization Name ChangedThe organization name was changed.
organization.preferences.updatedOrganization Preferences UpdatedAn organization setting was changed.
organization.workspace_discoverability_domain.addedOrganization Workspace Discoverability Domain AddedAn allowed domain was added for workspace discoverability.
organization.workspace_discoverability_domain.removedOrganization Workspace Discoverability Domain RemovedAn allowed domain was removed from workspace discoverability.
organization.sso_settings.updatedOrganization SSO Settings UpdatedOrganization SSO settings were updated.
organization.invitation.resentOrganization Invitation ResentAn organization invitation was resent.
organization.invitation.revokedOrganization Invitation RevokedAn organization invitation was revoked.
organization.user.role_changedOrganization User Role ChangedA user's role in the organization was changed.
organization.user.removedOrganization User RemovedA user was removed from the organization.
organization.license.changedOrganization License ChangedA user's license in the organization was changed.
organization.license.consumedOrganization License ConsumedA user's license in the organization was upgraded to Full.
organization.license.releasedOrganization License ReleasedA user's license in the organization was downgraded to Restricted.
organization.insights.requestedOrganization Insights RequestedAn Insights report was requested.

Billing

EventNameDescription
billing.credits.consumedBilling Credits ConsumedCredits were consumed by a feature.
billing.credits.allocatedBilling Credits AllocatedCredits were allocated to a workspace.
billing.credits.addedBilling Credits AddedCredits were manually granted to an account, for example by Synthesia support.
billing.credits.purchasedBilling Credits PurchasedCredits were purchased.
billing.credit_allocation_strategy.changedBilling Credit Allocation Strategy ChangedThe organization's credit allocation strategy was changed, between a shared pool across all workspaces and per-workspace allocation.
billing.workspace_allocation.updatedBilling Credits Allocation UpdatedA workspace's specific credit allocation amount was changed.

Email send cap

EventNameDescription
email_send_cap.recipient_exclusion.grantedEmail Send Cap Recipient Exclusion GrantedA recipient was excluded from the email send cap.
email_send_cap.recipient_exclusion.revokedEmail Send Cap Recipient Exclusion RevokedA recipient's exclusion from the email send cap was revoked.

Content

EventNameDescription
dubbing.project.createdDubbing Project CreatedA dubbing project was created.
asset.powerpoint.uploadedAsset Powerpoint UploadedA PowerPoint file was imported.
scorm.package.downloadedA SCORM package was downloaded.

Integrations

Covers HRIS and messaging integrations for the Learner Portal, and other external tool connections.

EventNameDescription
integrations.connection.initiatedA connection to an external tool was started.
integrations.connection.createdA connection to an external tool completed successfully.
integrations.connection.deletedA connection to an external tool was disconnected.

Audit logs

EventNameDescription
audit_logs.exportedAudit Logs ExportedAn audit log export was requested.

Learner Portal

The Learner Portal has its own set of events, covering Learner Groups, content assignment, and role entitlements. These are distinct from the core Admin/Member/Guest model—the Learner Portal has its own roles (Enablement Admin, Organization Admin, Manager, and Learner).

EventNameDescription
entitlement.grantedA Learner Portal role (for example, Enablement Admin) was granted to a user.
entitlement.revokedA Learner Portal role was revoked from a user.
lms.hris_sync_config.createdLMS Hris Sync Config CreatedAn HRIS sync was connected.
lms.hris_sync_config.updatedLMS Hris Sync Config UpdatedAn HRIS sync's configuration was changed.
lms.hris_sync_config.deletedLMS Hris Sync Config DeletedAn HRIS sync was disconnected.
lms.learner_group.createdLMS Learner Group CreatedA Learner Group was created. Groups are either manual (fixed membership) or dynamic (populated automatically based on rules, for example department or email domain).
lms.learner_group.updatedLMS Learner Group UpdatedA Learner Group's name or targeting rule was changed.
lms.learner_group.deletedLMS Learner Group DeletedA Learner Group was deleted.
lms.learner_group_member.addedLMS Learner Group Member AddedA learner was added to a Learner Group.
lms.learner_group_member.removedLMS Learner Group Member RemovedA learner was removed from a Learner Group.
lms.assignment_target.addedA learner was assigned a Roleplay Session.
lms.assignment_target.removedA learner's assignment to a Roleplay Session was removed.