How to retrieve all previous versions of content using the REST API
Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.
Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
This document includes an internal API that also references an experimental endpoint and this information is provided as-is, we're unable to directly assist unless there is a bug or documentation error. However, we can definitely support you if a public REST API call isn't working as expected. See Atlassian Support Offerings for additional information.
Summary
The Confluence Server REST API endpoint for retrieving content history/rest/api/content/{id}/history
only returns limited results including current,
previousVersion,nextVersion,lastUpdated
.
This is especially useful when developing your own apps or updating Confluence with scripts via the REST API or for any other purpose such as auditing or retrieving details from a specific page version.
In Confluence Cloud there is an endpoint that already provides this functionality and returns all versions: /wiki/rest/api/content/{id}/version
Diagnosis
A GET request to /rest/api/content/{id}/history
will only return details of the latest version, previous version and last updated.
Default JSON response with limited version or history details...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{
"previousVersion": {
"by": {
"type": "known",
"username": "<USERNAME>",
"userKey": "abc1234",
...
...
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/{number01}"
},
"_expandable": {
"content": "/rest/api/content/{id}?status=historical&version=2"
}
},
"lastUpdated": {
"by": {
"type": "known",
"username": "<USERNAME>",
"userKey": "abc1234",
},
"_expandable": {
"status": ""
}
},
"when": "2021-02-22T08:28:25.000+01:00",
"message": "",
"number": 3,
"minorEdit": false,
"hidden": false,
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/{number02}"
},
"_expandable": {
"content": "/rest/api/content/{id}"
}
},
"latest": true,
"createdBy": {
"type": "known",
"username": "<USERNAME>",
"userKey": "abc1234",
"profilePicture": {
"path": "/<contextPath>/images/icons/profilepics/default.svg",
"width": 48,
"height": 48,
"isDefault": true
},
"displayName": "<USERNAME>",
"_links": {
"self": "<baseURL>/rest/api/user?key=abc1234"
},
"_expandable": {
"status": ""
}
},
"createdDate": "2021-01-29T11:14:40.302+01:00",
"_links": {
"base": "<baseURL>",
"context": "/<contextPath>",
"self": "<baseURL>/rest/api/content/{id}/history"
},
"_expandable": {
"contributors": ""
}
}
But within that response there is another endpoint that is exposed, it is expermiental
so is not directly supported and cannot be guaranteed to be included in future updates but will provide details on all versions of a page.
1
2
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/{number}"
Solution
As described only the latest, previous and last updated details are returned. However, it turns out it's possible to manipulate the endpoint exposed below and by removing the version/
{number}
the request will return all versions of a page.
Notice the version number has been removed from the endpoint. Instead of /rest/experimental/content/{id}/version/
{number},
if
you make a GET /rest/experimental/content/{id}/
version/
you will receive all content versions.
1
<baseURL>/rest/experimental/content/{id}/version
Experimental JSON response with all previous versions included...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{
"results": [
{
"by": {
"type": "known",
"username": "<USERNAME>",
"userKey": "abc123",
"profilePicture": {
"path": "/<contextPath>/images/icons/profilepics/default.svg",
"width": 48,
"height": 48,
"isDefault": true
},
"displayName": "<USERNAME>",
"_links": {
"self": "<baseURL>/rest/api/user?key=abc123"
},
"_expandable": {
"status": ""
}
},
"when": "2021-02-22T08:28:25.000+01:00",
"message": "",
"number": 3,
"minorEdit": false,
"hidden": false,
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/3"
},
"_expandable": {
"content": "/rest/api/content/{id}"
}
},
{
"by": {
"type": "known",
"username": "<USERNAME>",
"userKey": "abc123",
"profilePicture": {
"path": "/<contextPath>/images/icons/profilepics/default.svg",
"width": 48,
"height": 48,
"isDefault": true
},
"displayName": "<USERNAME>",
"_links": {
"self": "<baseURL>/rest/api/user?key=abc123"
},
"_expandable": {
"status": ""
}
},
"when": "2021-02-22T08:28:13.844+01:00",
"message": "",
"number": 2,
"minorEdit": false,
"hidden": false,
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/2"
},
"_expandable": {
"content": "/rest/api/content/{id}?status=historical&version=2"
}
},
{
"by": {
"type": "known",
"username": "<USERNAME>",
"userKey": "abc123",
"profilePicture": {
"path": "/<contextPath>/images/icons/profilepics/default.svg",
"width": 48,
"height": 48,
"isDefault": true
},
"displayName": "<USERNAME>",
"_links": {
"self": "<baseURL>/rest/api/user?key=abc123"
},
"_expandable": {
"status": ""
}
},
"when": "2021-01-29T11:14:58.827+01:00",
"message": "",
"number": 1,
"minorEdit": false,
"hidden": false,
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/1"
},
"_expandable": {
"content": "/rest/api/content/{id}?status=historical&version=1"
}
}
],
"start": 0,
"limit": 200,
"size": 3,
"_links": {
"self": "<baseURL>/rest/experimental/content/{id}/version/",
"base": "<baseURL>",
"context": "/<contextPath>"
}
}
Was this helpful?