Audit (.NET)

The Audit APIs available through .NET include methods that you can use to programmatically revert, retrieve, and search Relativity audit records stored in Elasticsearch. These services support interactions with both instance-level and workspace-level audit records. The following APIs provide methods for this functionality:

  • Audit Metrics API - includes a method for retrieving information about the number and size of the audits in a specific workspace.
  • Audit Revert API - includes methods for reverting document update actions. It provides methods for reverting a single action or list of actions, and for verifying whether the revert operation can be performed on an action.
  • Audit Pivot API - includes methods for running pivot queries on audit data. It supports querying with group by and pivot on operations for object type, action, username, and timestamp fields.
  • Reviewer Statistics API - includes methods for retrieving information about reviewer actions, such as the number of actions performed by a reviewer on a document, the usage time per review, a summary report of reviewer actions, and others.
  • Audit Query API - includes a method for querying on a specific audit record.
  • Audit Object Manager UI API - includes methods for querying on audit details to display in the Relativity UI, including filtering on the returned data.

Note: These APIs don't support working with audit records stored in an SQL Server database.

Sample use cases for the Audit APIs include building custom applications to perform the following tasks:

  • Transfer data to other applications and tools for analysis and reporting, such as a third-party software applications or web-based visualization tools.
  • Implement an audit record query as part of a larger solution that captures query results and then manipulates the results using a visualization solution.
  • Programmatically generate a reviewer statistics report.
  • Retrieve or aggregate audit data or execute pivot queries on the data.

Additionally, you can access the Audit API services through REST. These services support the same functionality as the .NET interfaces. For more information, see Audit (REST).

The Relativity.Audit.Services.SDK contains this API. For compatibility and package installation instructions, see Download the SDKs and NuGet packages.

Fundamentals for Audit APIs

Click the following drop-down links to learn about the methods and classes used by the Audit APIs.

Note: The <VersionNumber> variable in the namespace indicates the version number of the API. The version number uses the format uppercase V and an integer version number, such as V1 in .NET.

Guidelines for the Audit APIs

Review the following guidelines for working with the Audit APIs.

Operations supported by the Audit APIs

The following table lists a summary of operations that you can perform using the Audit APIs.

API name Method name Code samples
Audit Metrics GetWorkspaceAuditMetricsAsync() Retrieve the total number and size of audits
Audit Revert ValidateRevertAuditAsync() Validate a revert operation for an audit
RevertAuditAsync() Revert an audit
MassRevertAuditAsync() Mass revert a list of audits
Audit Pivot PivotAsync() Query with Pivot on audit data
Reviewer Statistics GetDocumentActionCountsAsync() Retrieve action counts for updated documents
GetUsageTimesAsync() Retrieve the usage time per reviewer
GetTotalReviewedDocumentSizesAsync() Retrieve extracted text size of reviewed documents
GetDocumentActionsPerHourOfDayAsync() Retrieve an aggregate of user actions by hour
GetReviewerChoicesAsync() Retrieve choices reviewed by users
GetReviewerStatsAsync() Retrieve a summary report of reviewer statistics
Audit Query GetAuditAsync() Query for an audit record
Audit Object Manager UI QueryAsync() Query on audit fields
QuerySlimAsync() Query on audit fields and return a smaller payload

Admin-level context

To work with audits at the admin-level context, set the workspace ID in a method call -1. For example, the workspaceID the following code could be set to -1, so this call would retrieve number and size of the audits for a Relativity instance. See Retrieve the total number and size of audits.

Copy
AuditMetricsAggregateResponse workspaceMetrics = await auditMetricsService.GetWorkspaceAuditMetricsAsync(workspaceId);

Query conditions

You can specify conditions for an audit query in the Condition or RowCondition properties of a request object. Setting these properties is equivalent to using conditions and list filtering in the Relativity UI. For information about rendering audit details in the Relativity UI, see Audit in the Relativity Documentation site.

Audit Metrics API

The Audit Metrics API supports the retrieval of information about the number and size of the audits in a specific workspace.

Retrieve the total number and size of audits

To retrieve the total count of all audits in a workspace, and the total size of the audits in bytes, call the GetWorkspaceAuditMetricsAsync() method by passing the Artifact ID of a workspace. This method returns an AuditMetricsAggregateResponse object. See the following code sample:

Copy
using (var auditMetricsService = proxy.GetClient<IAuditMetricsService>()) {
    AuditMetricsAggregateResponse workspaceMetrics = await auditMetricsService.GetWorkspaceAuditMetricsAsync(workspaceId);
}

Audit Revert API

The Audit Revert API supports reverting document update actions. It provides methods for reverting a single action or list of actions, and for verifying whether the revert operation can be performed on an action.

For example, you can use a method on this service as a programmatic shortcut for reverting incorrect coding decisions.

Validate a revert operation for an audit

To confirm that an audit action can be reverted, call the ValidateRevertAuditAsync() method by passing the Artifact ID of a workspace and an RevertAuditRequest object to it. It returns a ValidateRevertAuditResponse object that contains the IsRevertable property, which indicates whether the operation can be completed. See the following code sample:

Copy
using (var revertService = proxy.GetClient<IAuditRevertService> ()) {
var request = new RevertAuditRequest
{
    AuditId = "1409184",
    Timestamp = "2019-05-22T15:10:42.877"
};
    ValidateRevertAuditResponse validateResponse = await revertService.ValidateRevertAuditAsync(workspaceId, request);
}

Revert an audit

To revert an audit action, call the RevertAuditAsync() method by passing the Artifact ID of a workspace and an RevertAuditRequest object to it. It returns a RevertAuditResponse object, which contains a Success property indicating the status of the operation.

    Notes:
  • Before reverting an action, consider calling the ValidateRevertAuditAsync() method to verify that the revert operation can succeed.
  • You must set both the Timestamp and Id properties on the request to uniquely identify the audit record.

See the following code sample:

Copy
using (var revertService = proxy.GetClient<IAuditRevertService>())
{
    var request = new RevertAuditRequest
    {
        AuditId = "1409184",
        Timestamp = "2019-05-22T15:10:42.877"
    };
    RevertAuditResponse revertResponse = await revertService.RevertAuditAsync(workspaceId, request);
}

Mass revert a list of audits

You can control the maximum number of Audits that can be reverted during a mass operation by updating the RevertMaxAuditCount instance setting. For more information, see Instance settings descriptions on the Relativity Documentation site.

The following code sample illustrates how to instantiate a list of RevertAuditRequest objects, and then call the MassRevertAuditAsync() method by passing the Artifact ID of a workspace and the request object. This method returns a MassRevertAuditResponse object.

    Notes:
  • The MassRevertAuditAsync() method validates that each action can be successfully reverted before performing this operation.
  • You must set both the Timestamp and Id properties on the request to uniquely identify the audit record.
Copy
using (var revertService = proxy.GetClient<IAuditRevertService>())
{
    var request = new MassRevertAuditRequest
    {
        RevertAuditRequests = new List<RevertAuditRequest>
        {
            new RevertAuditRequest
            {
                AuditId = "1409184",
                Timestamp = "2019-05-22T15:10:42.877"
            },
            new RevertAuditRequest
            {
                AuditId = "1409411",
                Timestamp = "2019-05-22T15:35:01.947"
            },
        }
    };
    MassRevertAuditResponse massRevertResponse = await revertService.MassRevertAuditAsync(workspaceId, request);
}

Audit Pivot API

The Audit Pivot service supports running pivot queries on audit data. You can query with the group by and pivot on operations for object type, action, username, and timestamp fields.

After the call returns the pivot results, you can render them as graphs and charts with third-party visualization tools. Pivot queries on audit records use the same query pattern as Relativity Pivot. For more information, see Pivot Manager (REST).

Query with Pivot on audit data

The following code sample illustrates how to instantiate a PivotSettings object by setting the pivot and query conditions. Call the PivotAsync() method by passing the Artifact ID of a workspace, and the PivotSettings, CancellationToken, and IProgress objects. This method returns a PivotResultSet. For more information, see Query conditions.

Note: The method signature for the PivotAsync() method includes the CancellationToken and IProgress<ProgressReport> objects. However, they aren't supported but must be passed to the method as required.

Copy
using (var pivotService = proxy.GetClient<IAuditPivotService>())
{
    var cancellationToken = new CancellationToken(); // required but not supported
    var progressToken = new Progress<string>(); // required but not supported
    var settings = new PivotSettings
    {
        // Field Artifact ID
        GroupBy = new FieldRef(1039619),
        PivotOn = new FieldRef(1039617),
        ObjectSetQuery = new global::Relativity.Services.Query
        {
            // Filter conditions
            Condition = "((('Audit ID' LIKE ['1413541'])))",
            RowCondition = ""
        },
        ConvertNumberFieldValuesToString = true,
        MaximumNumberOfColumns = 10,
        MaximumNumberOfRows = 10,
        Timeout = 10,
        RawDataOnly = false,
        TimeZone = "America/Chicago"
    };
    Console.WriteLine(JsonConvert.SerializeObject(settings));
    PivotResultSet pivotResponse = await pivotService.PivotAsync(workspaceId, settings, cancellationToken, progressToken);
}

Reviewer Statistics API

The Reviewer Statistics API provides methods for returning information about reviewer actions, such as the number of actions performed by a reviewer on a document, the usage time per review, a summary report of reviewer actions, and others.

Review the following guidelines for setting properties on the request objects:

  • If you pass an empty array for the UserIDs property on the request object, the report is computed for all the users in the workspace.
  • The StartDate and EndDate properties determine the timeframe used to generate a report. Only audits within this timeframe are included in the report.
  • The TimeZone property for the reviews included in the summary report is specified as a UTC offset. See Retrieve a summary report of reviewer statistics.

Retrieve action counts for updated documents

You can retrieve the total action counts for all the updated documents in a workspace for a specified time frame. Additionally, you can list specific actions that you want counted per document.

The following code sample illustrates how to instantiate DocumentActionCountCriteria object, and then call the GetDocumentActionCountsAsync() method by passing the Artifact ID of a workspace and the request object.

Copy
using (var reviewerStats = proxy.GetClient<IReviewerStatisticsService>())
{
    var request = new DocumentActionCountCriteria
    {
        AuditActionIds = new int[] { 1, 2, 3},
        UserIds = new int[] {9, 777},
        StartDate = new DateTimeOffset(DateTime.Now.AddDays(-5)),
        EndDate = new DateTimeOffset(DateTime.Now),
        TimeZone = "America/Chicago"
    };
 
    DocumentActionCountResponse actionCounts = await reviewerStats.GetDocumentActionCountsAsync(workspaceId, request);
}

Retrieve the usage time per reviewer

Use the GetUsageTimesAsync() method to compute the total usage time in seconds per reviewer.

Note: In the request, the Downtime property indicates the number of seconds used to determine whether a null session action should be joined to a non-null session action. If the time difference for the performance of a null session action is larger than this maximum duration, the null session is counted as one minute.

The following code sample illustrates how to instantiate UsageTimeCriteria object, and then call the GetUsageTimesAsync() method by passing the Artifact ID of a workspace and the request object.

Copy
using (var reviewerStats = proxy.GetClient<IReviewerStatisticsService>())
{
    var request = new UsageTimeCriteria
    {
        AuditActionIds = new int[] { 1, 2, 3 },
        UserIds = new int[] { 9, 777 },
        StartDate = new DateTimeOffset(DateTime.Now.AddDays(-5)),
        EndDate = new DateTimeOffset(DateTime.Now),
        TimeZone = "America/Chicago",
        DownTimeThresholdSeconds = 900 // seconds
    };

    UsageTimeResponse usageTime = await reviewerStats.GetUsageTimesAsync(workspaceId, request);
}

Retrieve extracted text size of reviewed documents

Use the GetTotalReviewedDocumentSizesAsync() method to retrieve the size of the extracted text for all documents reviewed per reviewer.

The following code sample illustrates how to instantiate ReviewedDocumentSizeCriteria object, and then call the GetTotalReviewedDocumentSizesAsync() method by passing the Artifact ID of a workspace and the request object.

Copy
using (var reviewerStats = proxy.GetClient<IReviewerStatisticsService>())
{
    var request = new ReviewedDocumentSizeCriteria
    {
        AuditActionIds = new int[] {1, 2, 3},
        UserIds = new int[] {9, 777},
        StartDate = new DateTimeOffset(DateTime.Now.AddDays(-5)),
        EndDate = new DateTimeOffset(DateTime.Now),
        TimeZone = "America/Chicago",
        ExtractedTextFieldArtifactId = 1003668,
    };
 
    ReviewedDocumentSizeResponse documentSize = await reviewerStats.GetTotalReviewedDocumentSizesAsync(workspaceId, request);
}

Retrieve an aggregate of user actions by hour

Use the GetDocumentActionsPerHourOfDayAsync() method to aggregate the total distinct document actions performed by each reviewer, grouped by the hour of the day in which the action was performed.

The following code sample illustrates how to instantiate DocumentActionPerHourOfDayCriteria object, and then call the GetDocumentActionsPerHourOfDayAsync() method by passing the Artifact ID of a workspace and the request object.

Copy
using (var reviewerStats = proxy.GetClient<IReviewerStatisticsService>())
{
    var request = new DocumentActionPerHourOfDayCriteria
    {
        AuditActionIds = new int[] { 1, 2, 3 },
        UserIds = new int[] { 9, 777 },
        StartDate = new DateTimeOffset(DateTime.Now.AddDays(-5)),
        EndDate = new DateTimeOffset(DateTime.Now),
        TimeZone = "America/Chicago",
    };
 
    DocumentActionPerHourOfDayResponse documentActionPerHourOfDayResponse = await reviewerStats.GetDocumentActionsPerHourOfDayAsync(workspaceId, request);
}

Retrieve choices reviewed by users

Use the GetReviewerChoicesAsync() method to retrieve information about choices reviewed by users in a specific workspace. This method supports retrieving statistics for single choice fields, multiple choice fields, and Yes/No fields. Set the FieldIds property to the Artifact IDs of the fields that you want used to compute the choices selected by reviewers.

Note: If you pass an empty array for the UserIdsToExcludeInReport or the UserIdsToIncludeInReport field, the report is computed for all the users in the workspace.

The following code sample illustrates how to instantiate ReviewerChoicesCriteria object, and then call the GetReviewerChoicesAsync() method by passing the Artifact ID of a workspace and the request object.

Copy
using (var reviewerStats = proxy.GetClient<IReviewerStatisticsService>())
{
    var request = new ReviewerChoicesCriteria
    {
        FieldIds = new int[] { 1035357 },
        UserIdsToIncludeInReport = new int[]{9},
        UserIdsToExcludeInReport = new int[]{777},
        StartDate = new DateTimeOffset(DateTime.Now.AddDays(-5)),
        EndDate = new DateTimeOffset(DateTime.Now),
        TimeZone = "America/Chicago",
    };
 
    ReviewedFieldChoicesPerUserResponse reviewerChoice = await reviewerStats.GetReviewerChoicesAsync(workspaceId, request);
}

Retrieve a summary report of reviewer statistics

Use the GetReviewerStatsAsync() method to programmatically generate a report similar to the reviewer statistics report available through the Relativity UI. For more information, see Reviewer statistics on the Relativity Documentation site.

On the ReviewerStatsDataRequest object, set the NonAdmin to false if you want to include system admin statistics in the data. Additionally, set the AdditionalActions property to one of the following values:

  • None - include view and update actions.
  • Mass Edit - include view, update, and mass edit actions.
  • Propagation - include propagation actions.
  • Mass Edit and Propagation - include view, update, mass edit, and propagation actions.

The following code sample illustrates how to instantiate ReviewerStatsDataRequest object, and then call the GetReviewerStatsAsync() method by passing the Artifact ID of a workspace and the request object.

Copy
using (var reviewerStats = proxy.GetClient<IReviewerStatisticsService>())
{
    var request = new ReviewerStatsDataRequest
    {
        StartDate = "2019-01-01T00:00:00Z",
        EndDate = "2019-10-05T00:00:00Z",
        TimeZone = -6.0,
        NonAdmin = false,
        AdditionalActions = "Mass Edits"
    };
 
    IEnumerable<ReviewersStats> reviewerMetrics = await reviewerStats.GetReviewerStatsAsync(workspaceId, request);
}

Audit Query API

The Audit Query service supports querying for a specific audit record.

Note: You must set both the Timestamp and Id properties on the request to uniquely identify the audit record.

Query for an audit record

The following code sample illustrates how to instantiate a GetAuditRequest object, and then pass the GetAuditAsync() method the Artifact ID of a workspace and the request object. This method returns an AuditLogItem object. See the following code sample:

Copy
using (IAuditQueryService auditQueryService = Helper.GetServicesManager().CreateProxy<IAuditQueryService>(Relativity.API.ExecutionIdentity.System))
{
    var request = new GetAuditRequest
    {
        Id = "484127",
        Timestamp = "2019-04-26T15:56:53.427"
    };
    AuditLogItem queryResults = await auditQueryService.GetAuditAsync(workspaceId, request);
}

Audit Object Manager UI API

The Audit Object Manager UI service supports querying on audit details for display in the Relativity UI. It provides two overloaded methods for querying:

  • QueryAsync() method - This overloaded method returns detailed information about the field-value pairs returned by the query on the audit, including complete field details. For samples, see Query on audit fields.
  • QuerySlimAsync() method - This overloaded method returns a smaller payload to save bandwidth. It returns only the values of the fields specified in the request without the detailed field information. For samples, see Query on audit fields and return a smaller payload.

Review the following guidelines for Audit Object Manager UI API:

  • Sorting is only supported for the TimeStamp and ExecutionTime properties.
  • Use Condition and RowCondition properties on the request object for filtering. For more information, see Query conditions.
  • Review the following information about paging:
    • Query tokens aren't supported for audit record result set paging.
    • Check the value of the TotalCount field on the initial response. If it is greater than the specified Length field in the request, adjust the value of the Start field on the subsequent query requests to page through results.

      Note: In Relativity instances with a very large number of audit records (1,000,000 or more), paging towards the end of the result set can cause a Deep Paging Exception.

  • The Audit record query uses the Relativity Object Manager query pattern. For more information, see Object Manager (.NET).
  • Call the overloaded method with the auditQueryOptions argument if you want to perform additional analysis on the audit data. This method returns the data as an escaped JSON string instead of HTML. For more information, see Query for an audit record.

Query on audit fields

The overloaded QueryAsync() method takes the following arguments:

  • workspaceID - an integer representing the Artifact ID of a workspace, or -1 to indicate the admin-level context.
  • request - an instance of the QueryRequest class.
  • start - an integer representing the index of the first artifact in the result set.
  • length - an integer representing the number of items to return in the query result, beginning with index in the start argument.
  • auditQueryOptions - an optional AuditQueryOptions object, which contains a Boolean value indicating whether the Details field should contain an escaped JSON string instead of HTML. Set this field to true if you want to perform further analysis on the audit data. Otherwise, the data is returned as HTML for display on the Audit tab in the Relativity UI. For more information, see Audit in the Relativity Documentation site.

Query on audit fields and return a smaller payload

The overloaded QuerySlimAsync() method takes the following arguments:

  • workspaceID - an integer representing the Artifact ID of a workspace, or -1 to indicate the admin-level context.
  • request - an instance of the QueryRequest class.
  • start - an integer representing the index of the first artifact in the result set.
  • length - an integer representing the number of items to return in the query result, beginning with index in the start argument.

Note: The method signatures for the overloaded QuerySlimAsync() method include the CancellationToken and IProgress<ProgressReport> objects. However, they aren't supported but must be passed to the methods as required.