Last updatedFeb 28, 2019

Deprecation notice and migration guide for major changes to Jira Cloud REST APIs to improve user privacy

The deprecation period for these changes began on 01 October 2018.

By 29 April 2019, we will remove personal data from the API that is used to identify users, such as username and userKey, and instead use the Atlassian account ID (accountId). Additionally, will be restricting the visibility of other personal data, such as email, in conjunction with a user's profile privacy settings, or in the case of managed account, the visibility settings decided by the site administrator.

This guide shows you how to update your app or integration to adopt the GDPR-related changes for the Jira Cloud REST APIs. It describes how the user privacy improvements affect the REST APIs, provides a migration path to the new REST APIs, and lists all of the REST API changes.

Overview

As previously announced in Major changes to Jira Cloud REST APIs are coming to improve user privacy, Atlassian is making a number of changes to our products and APIs to improve user privacy in accordance with the European General Data Protection Regulation (GDPR).

For Jira Cloud, these changes include:

  • Changes to how users are identified: Personal data that is used to identify users, such as the username and userKey, will be removed from the REST APIs. Users will be identified by their Atlassian account ID (accountId) instead.

  • Changes to the visibility of user information: Users will be able to restrict the visibility of their personal data through their user profile privacy settings, or in the case of a managed account, the visibility settings that are decided by the site administrator. This means that fields such as email will only be returned by the API if the user has permitted that data to be visible. Note that this means that some fields can be null. The REST API changes will be introduced alongside the existing REST API. The existing REST API will be available until the end of the deprecation period. Until this time, you can use either the GDPR-compliant or non-GDPR compliant version of the REST API. An opt-in mechanism is available which will force Jira Cloud to only use the GDPR-compliant version of the REST API (that is, deprecated data is not used).

  • Changes to Atlassian Connect APIs: All personal data will be removed from the Connect REST APIs and replaced with accountId where appropriate. For details on migrating Connect apps to the GDPR-compliant version of the Connect REST APIs, see the Connect migration guide.

Summary of changes

Below is a high-level summary of the REST API changes:

  • Operations that currently accept a username and/or userKey will also accept an Atlassian account ID. (accountId). After the deprecation period ends, only an accountId will be accepted.

  • Operations that currently return a username and/or userKey will also return an Atlassian account ID (accountId). After the deprecation period ends, only an accountId will be returned.

  • Operations that currently use a username and/or userKey as a search clause (for example, JQL queries) will also use an Atlassian account ID (accountId). After the deprecation period ends, only an accountId may be used. To help you update your JQL queries, we’ve introduced a new operation: POST /rest/api/3/jql/pdcleaner which takes one or more JQL queries with user identifiers and converts them to equivalent JQL queries with account IDs.

  • The User object will change: Identifying personal data, such as username and userKey , will be removed and other personal data, such as email, will be displayed according to user settings.

To update your app or integration, read the list of REST API changes in the next section. The changes are listed by resource and include instructions on what you need to update.

Note that both version 2 and version 3 of the Jira Cloud REST API will be updated according to this document. Version 3 was introduced to support the Atlassian Document Format (ADF). With respect to GDPR, there is no difference between these versions.


Component

Resources

  • /api/3/component

Methods

  • GET
  • POST
  • PUT

Request query parameter changes

  • lead, assignee, and realAssignee updated to use the new User object.
  • leadUserName will be removed.
  • leadAccountId will be used.

Response changes

FieldChangeNullableNotes
leadCHANGEDN/AUpdated to use the new User object.
assigneeCHANGEDN/AUpdated to use the new User object.
realAssigneeCHANGEDN/AUpdated to use the new User object.
  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Dashboard

Resources

  • /api/3/dashboard

Methods

  • GET

Request query parameter changes

  • None

Response changes

  • dashboards array updated.
FieldChangeNullableNotes
ownerCHANGEDN/Aowner updated to use the new User object.
  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Filter

Resources

  • /api/3/filter

Methods

  • GET

Request query parameter changes

  • None

Response changes

FieldChangeNullableNotes
ownerCHANGEDN/Aowner updated to use the new User object
  • User object:
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Group

Resources

  • /api/3/groups/picker
  • /api/3/group/user

Methods

  • GET
  • DELETE

Request query parameter changes

  • username and userKey will be removed.
  • accountId will be used instead.
  • query parameter to be used to search for user.

Response changes

FieldChangeNullableNotes
UsersAndGroupsBeanCHANGEDN/AUsers array updated to use the new User object.
  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Issue

Resources

  • /api/3/issue/{issueIdOrKey}
  • /api/3/issue/{issueIdOrKey}/assignee
  • /api/3/issue/{issueIdOrKey}/watchers
  • /api/3/issue/{issueIdOrKey}/changelog
  • /api/3/issue/{issueIdOrKey}/comment
  • /api/3/issue/{issueIdOrKey}/comment/{id}
  • /api/3/issue/{issueIdOrKey}/worklog
  • /api/3/issue/bulk

Methods

  • GET
  • POST
  • PUT
  • DELETE

Request object changes

  • id (for account ID) used instead of name for user fields, such as reporter and assignee.

Request query parameter changes

  • username will be removed.
  • accountId will be used instead.

Response changes

  • fields array updated.
FieldChangeNullableNotes
watchersCHANGEDN/Awatchers array updated to the new User object.
authorCHANGEDN/Aauthor updated to the new User object.
updateAuthorCHANGEDN/AupdateAuthor updated to the new User object.
itemsCHANGEDN/Afrom and to fields will contain accountId instead of userKey.
  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Myself

Resources

  • /api/3/myself

Methods

  • GET

Request query parameter changes

  • None

Response changes

  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Picker

Resources

  • /api/3/user/picker
  • /api/3/issue/picker

Methods

  • GET

Request query parameter changes

  • currentJQL will not allow username or userKey in query. Use accountId instead.

To help you update your JQL queries, we’ve introduced a new operation: POST /rest/api/3/jql/pdcleaner which takes one or more JQL queries with user identifiers and converts them to equivalent JQL queries with account IDs.

Response changes

FieldChangeNullableNotes
usersCHANGEDN/Ausers array updated to use the new User object.
  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Project

Resources

  • /api/3/project/{projectIdOrKey}/role/{id}

Methods

  • GET
  • POST
  • PUT

Request query parameter changes

  • None

Response changes

  • actors array updated.
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
actorUser.accountIdCURRENTNoAlready present.
displayNameCURRENTNoDepends on the privacy setting.

Resources

  • /api/3/search

Methods

  • GET

Request query parameter changes

  • JQL will not allow username or userKey in queries. Use accountId instead.

To help you update your JQL queries, we’ve introduced a new operation: POST /rest/api/3/jql/pdcleaner which takes one or more JQL queries with user identifiers and converts them to equivalent JQL queries with account IDs.

Response changes

FieldChangeNullableNotes
usersCHANGEDN/Ausers array updated to use the new User object.
  • Users object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

User

Resources

  • /api/3/user
  • /api/3/user/search
  • /api/3/user/assignable/search
  • /api/3/user/viewissue/search
  • /api/3/user/permission/search
  • /api/3/user/assignable/multiProjectSearch
  • /api/3/user/columns
  • /api/3/user/properties
  • /api/3/user/properties/{propertyKey}

Methods

  • GET
  • POST
  • DELETE

Request query parameter changes

  • name and key will be removed.
  • accountId parameter must be used to identify a user.
  • query parameter must be used to search for a user.

Response changes

  • User object
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
htmlCURRENTNo
avatarUrlCURRENTNo
accountTypeADDEDNoSee Webhooks below.

Webhooks

User objects in a webhook payload have a new field: accountType. This field is used to distinguish different types of users, such as normal users, app users, and Jira Service Desk customers.

Valid values:

  • atlassian: A regular Atlassian user account.
  • app: A system account used for Connect applications and OAuth 2.0 to represent external systems.
  • customer: A Jira Service Desk account representing an external service desk

In addition, accountType has been added to the User object in the REST API. This means that it can be retrieved via operations such as Get user.

Agile API changes

Resources

  • /rest/agile/1.0/board/{boardId}/issue
  • /rest/agile/1.0/board/{boardId}/backlog
  • /rest/agile/1.0/epic/{epicIdOrKey}/issue
  • /rest/agile/1.0/board/{boardId}/epic/none/issue
  • /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
  • /rest/agile/1.0/issue/{issueIdOrKey}
  • /rest/agile/1.0/sprint/{sprintId}/issue

Methods

  • GET

Request query parameter changes

  • JQL will not allow username or userKey in queries. Use accountId instead.

To help you update your JQL queries, we’ve introduced a new operation: POST /rest/api/3/jql/pdcleaner which takes one or more JQL queries with user identifiers and converts them to equivalent JQL queries with account IDs.

Response changes

  • updateAuthor will contain the updated User object.
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Service Desk API changes

Resources

  • /rest/servicedeskapi/organization/{organizationId}/user
  • /rest/servicedeskapi/request/{issueIdOrKey}/participant
  • /rest/servicedeskapi/servicedesk/{serviceDeskId}/customer
  • /rest/servicedeskapi/request

Methods

  • POST
  • DELETE

Request body changes

  • usernames array will be removed. Use the accountIds array instead.

Request query parameter changes

  • None

Response changes

  • reporter and values array will contain updated User object.
FieldChangeNullableNotes
nameREMOVEDN/AUse accountId instead.
keyREMOVEDN/AUse accountId instead.
accountIdADDED or CURRENTNoThis field is already present in most REST API methods.
emailAddressCURRENTYesDepends on the privacy setting. This can be null.
displayNameCURRENTNoDepends on the privacy setting.
timeZoneCURRENTYesDepends on the privacy setting. This can be null.
localeCURRENTYesDepends on the privacy setting. This can be null.

Examples

Get user

This example illustrates the most common scenario for updating an API call for GDPR: Replacing the username and/or userKey with the Atlassian account ID.

Current request (deprecated)

The current method to fetch a user record by username (GET https://your-domain.atlassian.net/rest/api/3/user?username=your-name) returns:

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
{
  "self": "https://your-domain.atlassian.net//rest/api/3/user?username=your-name",
  "key": "your-name",
  "accountId": "1234567890abcdef12345678",
  "name": "your-name",
  "emailAddress": "your-name@your-domain.com",
  "avatarUrls": {
    "48x48": "http://your-domain.atlassian.net/secure/useravatar?size=large&ownerId=mia",
	"32x32": "http://your-domain.atlassian.net/secure/useravatar?size=medium&ownerId=mia",
    "24x24": "http://your-domain.atlassian.net/secure/useravatar?size=small&ownerId=mia",
    "16x16": "http://your-domain.atlassian.net/secure/useravatar?size=xsmall&ownerId=mia"

  },
  "displayName": "Your Name",
  "active": true,
  "timeZone": "Australia/Sydney",
  "locale": "en_UK",
  "groups": {
    "size": 6,
    "items": []
  },
  "applicationRoles": {
    "size": 3,
    "items": []
  },
  "expand": "groups,applicationRoles"
}

Updated request

You will need to update your code to fetch the user by accountId instead. GET https://your-domain.atlassian.net/rest/api/3/user?accountId=1234567890abcdef12345678 returns:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "self": "https://your-domain.atlassian.net//rest/api/3/user?accountId=1234567890abcdef12345678",
  "accountId": "1234567890abcdef12345678",
  "emailAddress": "your-name@your-domain.com",
  "avatarUrls": {
    "48x48": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=48",
    "32x32": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=32",
	"24x24": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=24",
    "16x16": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=16"
  },
  "displayName": "Your Name",
  "active": true,
  "timeZone": "Australia/Sydney",
  "locale": "en_UK",
  "groups": {
    "size": 6,
    "items": []
  },
  "applicationRoles": {
    "size": 3,
    "items": []
  },
  "expand": "groups,applicationRoles"
}

Find user

When it is necessary to find a user for some particular purpose (that is, searching for users assignable to issues), username will no longer be a valid request parameter. Instead, the query request parameter must be used.

Current request (deprecated)

For example, GET https://your-domain.atlassian.net/rest/api/3/user/assignable/search?project=ABC&username=your-name currently returns:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "self": "https://your-domain.atlassian.net/rest/api/3/user/assignable/search?project=ABC&username=your-name",
  "key": "your-name",
  "accountId": "1234567890abcdef12345678",
  "name": "your-name",
  "emailAddress": "your-name@your-domain.com",
  "avatarUrls": {
    "48x48": "http://your-domain.atlassian.net/secure/useravatar?size=large&ownerId=mia",
	"32x32": "http://your-domain.atlassian.net/secure/useravatar?size=medium&ownerId=mia",
    "24x24": "http://your-domain.atlassian.net/secure/useravatar?size=small&ownerId=mia",
    "16x16": "http://your-domain.atlassian.net/secure/useravatar?size=xsmall&ownerId=mia"

  },
  "displayName": "Your Name",
  "active": true,
  "timeZone": "Australia/Sydney",
  "locale": "en_UK",
}

Updated request

You will need to update your code to use a method that supports the query request parameter, where the value can be an email address, display name, or any other user attribute.

GET https://your-domain.atlassian.net/rest/api/3/user/assignable/search?project=ABC&query=your-user-attribute returns:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "self": "https://your-domain.atlassian.net/rest/api/3/user/assignable/search?project=ABC&query=your-name@your-domain.com",
  "accountId": "1234567890abcdef12345678",
  "emailAddress": "your-name@your-domain.com",
  "avatarUrls": {
    "48x48": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=48",
    "32x32": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=32",
	"24x24": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=24",
    "16x16": "https://avatar-cdn.atlassian.com/5a67d46ef01d171fcf33ce60?by=id&s=16"
  },
  "displayName": "Your Name",
  "active": true,
  "timeZone": "Australia/Sydney",
  "locale": "en_UK",
  "groups": {
    "size": 6,
    "items": []
  }
}

Testing your GDPR changes

If you want to test your changes, you can force the REST APIs to only use GDPR-compliant functionality by including the x-atlassian-force-account-id: true header in any REST API call. For example, if you get a user and set the x-atlassian-force-account-id: true header, then the response will not include a username and userkey. Note that the X-AUSERNAME header is not returned if the request includes the x-atlassian-force-account-id: true header.

You can use this header until the end of the deprecation period, if you want to opt in early to the new GDPR-compliant REST APIs. Once the deprecation period is over, GDPR-compliant functionality will be enforced in the REST APIs, regardless of the x-atlassian-force-account-id: true header.

About the RPC and SOAP APIs

The Jira XML-RPC and SOAP APIs have been deprecated since Jira 6.0 and were removed in Jira 7.0. See the announcement Jira SOAP API is waving goodbye for more information. As a result, these APIs will not be updated for GDPR.