Get a list of customer organizations and their users in a Jira service project
Platform Notice: Cloud Only - This article only applies to Atlassian products on the cloud platform.
Summary
This article provides a solution using a Python script to export a list of organizations and the customers in those organizations for a specific service project.
No built-in feature to export organizations and their associated customers
Currently, Jira has no native solution to export organizations and customers within the organizations for a particular service project. There are open feature requests for this:
JSDCLOUD-6160 - Ability to export users and organization per projects
JSDCLOUD-8037 - Ability to export organization members per project
Solution
Use a script to get organizations and their customers
It is possible to use the Organization endpoints related to the Jira Service Management Cloud REST APIs in order to get the information about all Organizations and users within that Organization for a particular service project.
This script is provided as-is without warranties and is unsupported. Use at your own discretion and test in a non-production environment. Scripts and custom development are not in the scope of Atlassian Support Offerings.
Expected Output
The script will create a CSV file named organizations_users.csv in the current directory where the script is run.
This file will contain columns for "Organization ID", "Organization Name", "User Account ID", "User Name", and "User Email".
Each row represents a user associated with an organization in the specified Service Desk project.
Requirements
Python Libraries
requests
: This library is used to make HTTP requests to the Jira API. You can install it using pip:pip install requests
pandas:
This library is used to handle data and export it to a CSV file. You can install it using pip:pip install pandas
Jira Account and API Token You need an Atlassian Cloud account with access to Jira Service Management. Generate an API token for authentication. You can do this by logging into your Atlassian account and navigating to the API token section.
Variables to Change
JIRA_BASE_URL: Replace [CHANGE-INSTANCE-NAME] with your Jira instance's base URL.
SERVICE_DESK_ID: Replace [CHANGE-ME] with the ID of the Service Desk project you wish to query. You can use the API to get the Service Desk ID, or you can get this information from the portal URL of the project (for example for https://<your-site>.atlassian.net/servicedesk/customer/portal/3 the Service Desk ID will be 3).
USERNAME: Replace [CHANGE-ME] with your Jira account email.
API_TOKEN: Replace [CHANGE-ME] with your generated Jira API token.
Script
Notice that there might be many organizations and/or users within each organization. It's important that your script considers rate limiting and pagination by default in order to avoid issues.
The following Python code uses the above endpoints and has pagination and rate limiting handling implemented to export the Organizations and customers within Organizations for a particular service project that is identified via the Service Desk ID related to the service project you're interested in within your instance.
import requests
import time
import pandas as pd
# Constants
JIRA_BASE_URL = 'https://[CHANGE-INSTANCE-NAME].atlassian.net' #Change for your Atlassian Cloud URL related to your instance.
ORGANIZATIONS_API_ENDPOINT = '/rest/servicedeskapi/organization'
USERS_API_ENDPOINT = '/rest/servicedeskapi/organization/{organization_id}/user'
SERVICE_DESK_ID = '[CHANGE-ME]' # Service Desk ID related to the Jira Service Management project.
USERNAME = '[CHANGE-ME]' # Replace with your Jira account email
API_TOKEN = '[CHANGE-ME]' # Replace with your Jira API token
def fetch_data(url):
while True:
response = requests.get(
url,
auth=(USERNAME, API_TOKEN),
headers={"Accept": "application/json"}
)
if response.status_code == 429: # Rate limiting
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Retrying after {retry_after} seconds.")
time.sleep(retry_after)
continue
elif response.status_code != 200:
print(f"Failed to retrieve data: {response.status_code} {response.text}")
return None
return response.json()
def get_organizations():
organizations = []
start_at = 0
max_results = 50 while True:
url = f"{JIRA_BASE_URL}{ORGANIZATIONS_API_ENDPOINT}?start={start_at}&limit={max_results}&serviceDeskId={SERVICE_DESK_ID}"
data = fetch_data(url)
if data is None:
break
organizations.extend(data.get('values', []))
if not data.get('isLastPage', True):
start_at = data.get('nextPageStart', start_at + max_results)
else:
break
return organizations
def get_users_in_organization(organization_id):
users = []
start_at = 0
max_results = 50
while True:
url = f"{JIRA_BASE_URL}{USERS_API_ENDPOINT.format(organization_id=organization_id)}?start={start_at}&limit={max_results}"
data = fetch_data(url)
if data is None:
break
users.extend(data.get('values', []))
if not data.get('isLastPage', True):
start_at = data.get('nextPageStart', start_at + max_results)
else:
break
return users
def main():
organizations = get_organizations()
all_data = []
for org in organizations:
org_id = org['id']
org_name = org['name']
users = get_users_in_organization(org_id)
for user in users:
user_data = {
'Organization ID': org_id,
'Organization Name': org_name,
'User Account ID': user['accountId'],
'User Name': user.get('displayName', ''),
'User Email': user.get('emailAddress', '')
}
all_data.append(user_data)
# Create a DataFrame and save to CSV
df = pd.DataFrame(all_data)
df.to_csv('organizations_users.csv', index=False)
if __name__ == "__main__":
main()
By running this script with the correct configuration and credentials, you can efficiently export organization and user data from Jira Service Management to a CSV file for analysis or record-keeping.
Was this helpful?