You can use the Retention API to decide how long the archive keeps your packages, and to review the packages whose time is up before anything is deleted. All paths start with /v2, and every call needs the headers in Common headers.
Your role decides which endpoints you can call. Permissions on each package still apply on top of that.
How retention works
A retention rule keeps a package for a set time, and then runs its end action. Here's the path a package takes:
-
You create a retention rule, and then you apply it to a package. A package can have only one rule: you can't apply a rule to a package that's already under retention or on legal hold.
-
The retention period starts when you apply the rule, or on a date in the package's metadata. The rule's duration decides when the period ends.
-
When the period ends, the archive runs the rule's end actions. It can delete the package, delete its content and keep its metadata, move it to the trash, or put it on a deletion list.
-
A deletion list collects the packages of one rule that reach the list in the same day, week, month, or year. Every night, the archive starts the review of each list whose period is over. You can also start a review sooner.
-
The reviewers that the rule names approve or deny the list, one after the other. When every reviewer approves, the archive runs the list's end action on each package on it.
A legal hold comes before retention. The archive doesn't run the end actions of a package on legal hold, and it waits until the hold is lifted. If you place a legal hold on a package that's on a deletion list, or extend its retention, the archive takes the package off the list.
Tip: To place or lift a legal hold, go to the Archive API.
List retention rules
Returns the retention rules in the archive, sorted by title.
GET /v2/retention/rules
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
integer |
No |
The page to return, starting at 0. Default: |
|
|
integer |
No |
The number of rules per page. Default: |
Response: 200 OK with a paged list of RetentionRule objects.
Get a retention rule
Returns one retention rule.
GET /v2/retention/rules/{ruleId}
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
Response: 200 OK with a RetentionRule.
-
404 Not Found: there's no rule with this ID.
Create a retention rule
Creates a retention rule. After you create it, you can apply it to packages.
POST /v2/retention/rules
Required role: archive-records-manager
The body is a RetentionRule without the id. You always need startingPointPolicy. If endActions contains Document.DeletionList, you also need:
-
deletionList.period -
deletionList.endAction -
At least one entry in
deletionList.reviewers
This rule keeps a package for seven years after you apply it, and then puts it on a monthly deletion list. After two reviewers approve the list, the archive deletes the packages on it:
{
"title": "Invoices, 7 years",
"description": "Keep invoices for seven years, then review them before deletion.",
"enabled": true,
"startingPointPolicy": "immediate",
"duration": {
"years": 7
},
"endActions": ["Document.DeletionList"],
"deletionList": {
"period": "Period.Monthly",
"reviewers": ["group:finance-records", "user:jdoe"],
"userCanApproveMultiple": false,
"endAction": "Document.Delete",
"metadata": [
{
"label": "Title",
"property": "dc:title"
}
]
}
}
Response: 200 OK with the RetentionRule that the archive created, including its id.
-
400 Bad Requestwith the reasonREQUIRED_FIELD:startingPointPolicyis missing, orendActionscontainsDocument.DeletionListand the deletion list settings aren't complete. -
400 Bad Requestwith the reasonINVALID_FORMAT: adeletionList.metadataproperty isn't in theprefix:fieldform. -
400 Bad Requestwith the reasonUNKNOWN_QUERY_FIELD: adeletionList.metadataproperty isn't a field that packages have. -
400 Bad Request:startingPointPolicyhas a value that isn't allowed.
Update a retention rule
Changes a retention rule. Send the full rule every time, with every field that you want it to keep, including the complete deletionList. To get the rule as it is, use Get a retention rule.
PUT /v2/retention/rules/{ruleId}
Required role: archive-records-manager
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
The body has the same fields and the same required fields as in Create a retention rule.
Response: 200 OK with the updated RetentionRule.
-
400 Bad Request: the same validation errors as when you create a rule. -
404 Not Found: there's no rule with this ID.
Delete a retention rule
Deletes a retention rule. You can delete a rule when no package outside the trash has it, and when all its deletion lists are REMOVED.
DELETE /v2/retention/rules/{ruleId}
Required role: archive-records-manager
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
Response: 204 No Content.
-
404 Not Found: there's no rule with this ID. -
409 Conflictwith the reasonRETENTION_RULE_IN_USE: the rule is still in use. TheusedByparameter says why:packagesordeletionLists.
Apply a retention rule to a package
Puts a package under retention with the rule that you name.
POST /v2/archive/{packageId}/retention
Required role: archive-records-manager
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
Path parameter. The package ID. |
|
|
string |
Yes |
Body field. The |
{
"ruleId": "6f1d2c8e-3b4a-4c5d-9e8f-0a1b2c3d4e5f"
}
For a metadata_based rule, the package must have a value in the date field that the rule's metadataXPath names. If that date plus the rule's duration is already in the past, the package is eligible for its end actions right away.
Response: 204 No Content.
-
400 Bad Requestwith the reasonMETADATA_FIELD_NOT_SET: the rule ismetadata_based, and the package doesn't have the field. ThefieldandpackageIdparameters name them. -
404 Not Found: there's no package with this package ID. -
409 Conflict: the package is already under retention or on legal hold.
Extend a package's retention
Sets a new end date for a package's retention. If the package is on a deletion list, the archive takes it off the list.
POST /v2/archive/{packageId}/retention/extend
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
Path parameter. The package ID. |
|
|
string (date-time) |
Yes |
Body field. The date and time when the retention ends, in ISO 8601 with a time zone offset. |
{
"newExpiryDate": "2034-12-31T23:00:00Z"
}
Response: 204 No Content.
-
400 Bad Request:newExpiryDateis missing or isn't a valid date and time. -
404 Not Found: there's no package with this package ID.
List deletion lists
Returns the deletion lists, newest first. You can filter them by status, by rule, or by both.
GET /v2/retention/deletion-lists
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
integer |
No |
The page to return, starting at 0. Default: |
|
|
integer |
No |
The number of lists per page. Default: |
|
|
string |
No |
Only lists with this status: |
|
|
string |
No |
Only the lists of this retention rule. |
Response: 200 OK with a paged list of DeletionList objects.
Get a deletion list
Returns one deletion list, with its status and its review steps.
GET /v2/retention/deletion-lists/{listId}
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
Response: 200 OK with a DeletionList.
-
404 Not Found: there's no deletion list with this ID.
List the packages on a deletion list
Returns the packages on a deletion list. Each package on a list is a record, with the date when its retention ended and the metadata values that the rule keeps.
GET /v2/retention/deletion-lists/{listId}/records
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
|
|
integer |
No |
The page to return, starting at 0. Default: |
|
|
integer |
No |
The number of records per page. Default: |
Response: 200 OK with a paged list of DeletionListRecord objects.
-
404 Not Found: there's no deletion list with this ID.
Export a deletion list as CSV
Downloads the records of a deletion list as a CSV file, for example to check the list outside the archive before you approve it.
GET /v2/retention/deletion-lists/{listId}/export
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
curl -o deletion-list.csv \
-H "Authorization: Bearer $TOKEN" \
-H "tenant: $TENANT" \
"https://archive.example.com/v2/retention/deletion-lists/$LIST_ID/export"
The file has one row per record, and these columns:
|
Column |
What it holds |
|---|---|
|
|
The package's title. |
|
|
The package ID. |
|
|
The date when the package's retention ended, as |
|
One column per kept field |
The value of each metadata field that the rule keeps, with the field's label as the column name. |
Response: 200 OK with the text/csv file as an attachment.
-
404 Not Found: there's no deletion list with this ID.
Start the review of a deletion list
Moves a deletion list from DRAFT to REVIEW. The archive does this every night for each list whose period is over, so you only need this call to start a review sooner.
POST /v2/retention/deletion-lists/{listId}/review
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
The |
There's no request body. The list gets one review step for each entry in the rule's deletionList.reviewers, in the same order, and each step starts as OPEN.
Response: 200 OK with the DeletionList, with the status REVIEW.
-
400 Bad Request: the list isn't inDRAFT. -
404 Not Found: there's no deletion list with this ID.
Approve or deny a deletion list
Records your decision for the review step that's waiting on the list. When the last step is approved, the archive runs the list's end action in the background, so the call returns before that's done. To follow it, get the list and check its status.
PUT /v2/retention/deletion-lists/{listId}/review
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
string |
Yes |
Path parameter. The |
|
|
string |
Yes |
Body field. |
|
|
string |
No |
Body field. Why you deny the list. The archive keeps the reason only for a denial. |
{
"result": "DENIED",
"reason": "Two invoices are part of an open audit."
}
The waiting step is the first one that isn't approved yet. You can decide on it if it names you (user:<username>), or a group that you're in (group:<group name>). Here's what each decision does:
-
APPROVED: the step is approved, and the next step waits. After the last step, the list moves toAPPROVED. When the end action has run on each package, the list showsREMOVED, with the time inremovalTime. -
DENIED: the step is denied with your reason, and nothing is deleted. The list stays inREVIEW, and the same step keeps waiting, so a reviewer can still approve it later.
Response: 200 OK with the updated DeletionList.
-
400 Bad Request:resultis missing, the list isn't inREVIEW, or the waiting step doesn't name you or one of your groups. -
404 Not Found: there's no deletion list with this ID. -
409 Conflictwith the reasonSTATE_CONFLICT: you already approved another step of this list, and the rule'suserCanApproveMultipleisfalse.
List active legal holds
Returns the packages that are on legal hold at the moment.
GET /v2/retention/legal-holds
Required role: archive-records-manager or archive-records-reviewer
|
Name |
Type |
Required |
Description |
|---|---|---|---|
|
|
integer |
No |
The page to return, starting at 0. Default: |
|
|
integer |
No |
The number of holds per page. Default: |
|
|
string |
No |
|
|
|
string |
No |
|
Response: 200 OK with a paged list of LegalHold objects.
-
400 Bad Requestwith the reasonINVALID_SORT:sortOrderisn'tascordesc.
Schemas
RetentionRule
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
The rule's ID. Read-only: the archive sets it. |
|
|
string |
The rule's name. |
|
|
string |
A description of the rule. |
|
|
boolean |
Whether you can apply the rule to packages. Default: |
|
|
string |
When the retention period starts. |
|
|
string |
For |
|
|
How long the archive keeps the package after the starting point. |
|
|
|
array of strings |
Actions that run on the package when you apply the rule. |
|
|
array of strings |
Actions that run when the retention period ends. |
|
|
The deletion list settings. Required when |
RetentionDuration
The parts add up to one duration. A part that you leave out counts as 0.
|
Field |
Type |
Description |
|---|---|---|
|
|
integer |
Years. |
|
|
integer |
Months. |
|
|
integer |
Days. |
|
|
integer |
Milliseconds. |
DeletionListDefinition
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
How long one list collects packages: |
|
|
array of strings |
The review steps, in order. Each entry is one user, as |
|
|
boolean |
Whether one person can approve more than one step of the same list. If you leave it out, they can. |
|
|
string |
What the archive does with each package after every step approves: |
|
|
array of objects |
The metadata fields to keep with each record on the list and in the CSV export. Each object has a |
DeletionList
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
The list's ID. |
|
|
string |
The list's title. |
|
|
string |
|
|
|
The time span that the list covers. |
|
|
|
string |
The |
|
|
string |
The action that runs on each package after approval. |
|
|
string (date-time) |
When the end action finished. Only for |
|
|
integer |
The number of packages on the list. |
|
|
array of DeletionListReview |
The review steps, in order. Not set until the review starts. |
DeletionListPeriod
|
Field |
Type |
Description |
|---|---|---|
|
|
string (date-time) |
The first day of the period. |
|
|
string (date-time) |
The last day of the period. |
|
|
string |
|
DeletionListReview
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
Who decides on this step: |
|
|
string |
The username of the person who decided. |
|
|
string (date-time) |
When they decided. |
|
|
string |
|
|
|
string |
The reason for a denial. |
DeletionListRecord
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
The archive's internal ID of the package. To work with the package, use |
|
|
string |
The package's title. |
|
|
string |
The package ID. |
|
|
string (date-time) |
When the package's retention ended. |
|
|
array of objects |
The values of the rule's |
LegalHold
|
Field |
Type |
Description |
|---|---|---|
|
|
string |
The package ID. |
|
|
string |
The package's title. |
|
|
string (date-time) |
The date and time of the package's last change, which isn't always the moment of the hold. |
|
|
string |
The username of the person who last changed the package, not always the person who placed the hold. |
Paged lists
Every list endpoint in the Retention API returns the same wrapper around its items.
|
Field |
Type |
Description |
|---|---|---|
|
|
array |
The items on this page. When there are no results, |
|
|
number |
The page that you asked for. |
|
|
number |
The page size that you asked for. |
|
|
number |
The number of items across all pages. |