Jira API (Python)

raw JSON →
3.10.5 (jira) / 4.0.7 (atlassian-python-api) verified Tue May 12 auth: no python install: verified quickstart: stale

Two separate community-maintained Python libraries exist for Jira: 'jira' (pip install jira, v3.10.5) and 'atlassian-python-api' (pip install atlassian-python-api, v4.0.7). Neither is an official Atlassian SDK. They have different APIs, auth patterns, and JQL methods. Agents frequently mix them up.

pip install jira
error jira.exceptions.JIRAError: JiraError HTTP 401 url: <JIRA_URL> text: Client must be authenticated to access this resource.
cause This error typically occurs when the authentication credentials provided are incorrect, such as using a password instead of an API token, an incorrect email/username, or an expired/revoked API token, or due to insufficient permissions.
fix
For Jira Cloud, use your Atlassian email address as the username and a generated API token as the password. Ensure the API token has the necessary permissions. Example for 'jira' library: jira = JIRA(server='https://your-domain.atlassian.net', basic_auth=('your_email@example.com', 'YOUR_API_TOKEN')). Example for 'atlassian-python-api' library: jira = Atlassian(url='https://your-domain.atlassian.net', username='your_email@example.com', password='YOUR_API_TOKEN')
error ModuleNotFoundError: No module named 'jira'
cause The Python interpreter cannot find the 'jira' module because it is either not installed in the active environment or the environment path is incorrectly configured.
fix
Install the required library using pip. If using the 'jira' library: pip install jira. If using 'atlassian-python-api': pip install atlassian-python-api. Ensure you install it in the correct virtual environment if one is being used.
error AttributeError: '<class 'jira.resources.Issue'> object has no attribute 'fields'
cause This error often indicates that you are attempting to access an attribute (like `fields`) on an object that is not a valid `jira.resources.Issue` instance, or an attribute that is lazily loaded and not retrieved by default. A related common error is `AttributeError: 'NoneType' object has no attribute 'name'` when an optional field (like assignee) is not present on an issue.
fix
Verify that the object you are calling .fields on is indeed a jira.resources.Issue instance. For attributes that might be None, add explicit checks: if issue.fields.assignee: print(issue.fields.assignee.displayName). For fields that require explicit loading (like 'worklog'), use the expand parameter when fetching the issue: issue = jira.issue('ISSUE-KEY', expand='changelog,worklog').
error jira.exceptions.JIRAError: JiraError HTTP 400 url: <JIRA_URL> text: <Specific Jira API error message>
cause This 'Bad Request' error means the data sent to the Jira API is malformed, incomplete, or violates Jira's validation rules for the specific operation (e.g., missing a required field, invalid field format, or an issue type that does not exist in the project).
fix
Examine the text portion of the error message for specific details on what is incorrect. Adjust your payload to include all mandatory fields with correct data types and formats as per your Jira instance's configuration (e.g., provide values for all required custom fields for the issue type being created).
error jira.exceptions.JIRAError: JiraError HTTP 410 url: <JIRA_URL>/rest/api/2/search text: The requested API has been removed. Please migrate to the /rest/api/3/search/jql API.
cause This error occurs because Jira Cloud has deprecated and removed its API v2 search endpoint. Your current code or an older version of the `jira` Python library is still attempting to use this retired endpoint.
fix
Upgrade the 'jira' Python library to the latest version using pip install --upgrade jira. If the problem persists after upgrading, review your code to ensure it's not explicitly targeting API v2 endpoints and is compatible with the API v3 changes, particularly for search queries.
breaking Two competing packages: 'jira' (imports as JIRA) and 'atlassian-python-api' (imports as Jira). Tutorials and LLM-generated code mix them constantly. They are not interchangeable.
fix Pick one. 'jira' is better for pure Jira work. 'atlassian-python-api' covers Confluence/Bitbucket/ServiceDesk too.
breaking Jira Cloud blocks password auth. API token must be passed as the password field, not an actual password. Regular account passwords return 401 or 404 (often with 'Issue does not exist or you do not have permission to see it' and 'X-Seraph-Loginreason: AUTHENTICATED_FAILED' headers).
fix Generate token at id.atlassian.com/manage-profile/security/api-tokens. Pass as password= (jira pkg) or password= (atlassian pkg).
breaking atlassian-python-api: cloud=True is required for Jira Cloud. Omitting it causes requests to fail against Cloud endpoints silently or with confusing 404s.
fix Always pass cloud=True when connecting to *.atlassian.net
breaking atlassian-python-api: jql() method is deprecated for Jira Cloud. Use enhanced_jql() instead.
fix Replace jira.jql(...) with jira.enhanced_jql(...) for Cloud instances.
gotcha Jira Server/Data Center uses Personal Access Token (PAT) via token= parameter. Jira Cloud uses API token via username+password. The auth pattern differs by deployment type.
fix Server/DC: Jira(url=..., token=pat_token). Cloud: Jira(url=..., username=email, password=api_token, cloud=True)
gotcha jira package: search_issues() returns max 50 results by default. Silent truncation — no error raised if results exceed limit.
fix Pass maxResults=False or paginate with startAt parameter to retrieve all results.
gotcha Neither package is an official Atlassian product. Atlassian has no official Python SDK. Both are community-maintained.
fix For production use, pin versions. Both packages have had breaking changes between minor versions.
pip install atlassian-python-api
python os / libc variant status wheel install import disk
3.10 alpine (musl) atlassian-python-api - - - -
3.10 alpine (musl) jira - - 0.59s 25.0M
3.10 slim (glibc) atlassian-python-api - - - -
3.10 slim (glibc) jira - - 0.43s 25M
3.11 alpine (musl) atlassian-python-api - - - -
3.11 alpine (musl) jira - - 0.84s 27.5M
3.11 slim (glibc) atlassian-python-api - - - -
3.11 slim (glibc) jira - - 0.70s 28M
3.12 alpine (musl) atlassian-python-api - - - -
3.12 alpine (musl) jira - - 0.73s 19.2M
3.12 slim (glibc) atlassian-python-api - - - -
3.12 slim (glibc) jira - - 0.76s 20M
3.13 alpine (musl) atlassian-python-api - - - -
3.13 alpine (musl) jira - - 0.69s 18.8M
3.13 slim (glibc) atlassian-python-api - - - -
3.13 slim (glibc) jira - - 0.71s 19M
3.9 alpine (musl) atlassian-python-api - - - -
3.9 alpine (musl) jira - - 0.63s 41.6M
3.9 slim (glibc) atlassian-python-api - - - -
3.9 slim (glibc) jira - - 0.54s 43M

Both packages side-by-side. Pick one and stay consistent.

# --- Option A: jira package (pycontribs) ---
from jira import JIRA

jira = JIRA(
    server='https://your-domain.atlassian.net',
    basic_auth=('your-email@example.com', 'your-api-token')
)
issue = jira.issue('PROJ-1')
print(issue.fields.summary)

# --- Option B: atlassian-python-api ---
from atlassian import Jira

jira = Jira(
    url='https://your-domain.atlassian.net',
    username='your-email@example.com',
    password='your-api-token',
    cloud=True  # required for Cloud
)
data = jira.enhanced_jql('project = PROJ ORDER BY created DESC')
print(data)