Unified.to
All articles

How to Integrate with Atlassian Jira


February 26, 2026

A Jira API integration lets your product create issues, sync project data, update comments, transition workflows, and pull structured task data from the system many engineering, product, and IT teams already use to run work.

For B2B SaaS teams, that usually means pushing tickets into Jira from your app, syncing issue status back into your product, surfacing project or sprint context, or automating workflows that would otherwise require manual updates.

But a production-grade Jira integration involves more than sending a request to create an issue. You need to choose the right authentication model, understand Jira Cloud's REST patterns, handle JQL search and pagination correctly, design around rate limits, and use webhooks where real-time updates matter.

This guide covers:

  1. How to integrate directly with the Jira API
  2. The operational complexity you will own
  3. How to integrate Jira using Unified's Task, HRIS, Metadata, and Storage APIs
  4. When to build direct vs use an integration layer

Direct Jira API integration

Step 1: Choose the right authentication model

For Jira Cloud, there are two practical paths for most developers.

For simple internal scripts or one-off admin tooling, basic authentication with an Atlassian API token is still the fastest option. Atlassian documents creating an API token, combining it with the user's email, and sending it in the Authorization: Basic header for REST requests. Manage API tokens and Basic auth for REST APIs

For customer-facing SaaS integrations, OAuth 2.0 (3LO) is the better fit. It lets users authorize your app without sharing credentials, supports scoped access, and is the right pattern when each customer connects their own Jira tenant. Atlassian documents the 3LO flow in its OAuth guide. OAuth 2.0 (3LO) apps

In practice:

  • Use API token auth for internal tools and testing
  • Use OAuth 2.0 (3LO) for multi-user SaaS integrations
  • Use refresh tokens when you need long-lived delegated access

Step 2: Register an OAuth 2.0 app if you are building a SaaS integration

In the Atlassian developer console, create an app, configure OAuth 2.0, and add your callback URL. Atlassian's flow uses an authorization endpoint at https://auth.atlassian.com/authorize, followed by token exchange at https://auth.atlassian.com/oauth/token. OAuth 2.0 (3LO) apps

The authorization request includes:

  • audience=api.atlassian.com
  • client_id
  • scope
  • redirect_uri
  • state
  • response_type=code
  • prompt=consent

After the user approves access, Atlassian redirects back with a code. Your backend exchanges that code for an access token and, if requested, a refresh token.

A direct token exchange looks like this:

POST https://auth.atlassian.com/oauth/token
{
  "grant_type": "authorization_code",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "code": "AUTHORIZATION_CODE",
  "redirect_uri": "YOUR_REDIRECT_URI"
}

Step 3: Resolve the tenant before calling Jira APIs

With Atlassian OAuth, getting an access token is not the final step. You also need the site's cloudId so you can address the correct Jira tenant.

Atlassian documents calling the accessible resources endpoint:

GET https://api.atlassian.com/oauth/token/accessible-resources
Authorization: Bearer ACCESS_TOKEN

Then you call Jira REST APIs using this pattern:

https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/...

That tenant-resolution step is easy to miss if you are used to simpler OAuth flows. OAuth 2.0 (3LO) apps

Step 4: Understand the core Jira REST model

Jira Cloud's main public API surface is REST, not GraphQL. Atlassian's platform docs position the Jira Cloud REST API as the core path for reading and writing issues, projects, users, comments, workflows, and related resources. Jira Cloud platform REST API

At a minimum, most integrations work with:

  • Issues
  • Projects
  • Comments
  • Users
  • Transitions
  • Search via JQL
  • Webhooks

If your use case is customer support escalation, bug tracking, incident management, or product planning sync, these are the objects that matter first.

Core Jira operations

Create an issue

Creating issues is usually the first meaningful integration step. In Jira Cloud, the endpoint is:

POST /rest/api/3/issue

A minimal request body includes fields like project, issue type, and summary:

{
  "fields": {
    "project": { "key": "PROJ" },
    "issuetype": { "name": "Bug" },
    "summary": "Something is broken",
    "description": {
      "type": "doc",
      "version": 1,
      "content": [
        {
          "type": "paragraph",
          "content": [
            { "type": "text", "text": "Detailed bug report goes here." }
          ]
        }
      ]
    }
  }
}

Atlassian's current Jira Cloud examples use Atlassian Document Format for rich-text fields like description and comment bodies, so you should not assume plain strings everywhere. Issues API group

Get an issue

To retrieve a single issue:

GET /rest/api/3/issue/{issueIdOrKey}

You can also control the response with parameters like fields and expand to avoid over-fetching. Get issue

Update an issue

To update an issue:

PUT /rest/api/3/issue/{issueIdOrKey}

You send only the fields you want to change. A typical example is updating summary, description, assignee, due date, or custom fields. Edit issue

Delete an issue

To delete an issue:

DELETE /rest/api/3/issue/{issueIdOrKey}

This should be used carefully, especially in customer-facing integrations, because deleting records can break auditability and downstream sync assumptions. Delete issue

Search issues with JQL

For real integrations, direct issue CRUD is only part of the story. Search matters just as much.

Jira's query language, JQL, is how you find issues by project, status, assignee, priority, labels, custom fields, and date conditions. Atlassian documents the current search endpoints under the Jira REST API. Issue search

A typical search request looks like:

GET /rest/api/3/search/jql?jql=project=PROJ AND status="In Progress"

Or via POST when the query is larger or more structured:

POST /rest/api/3/search/jql
{
  "jql": "project = PROJ AND assignee = currentUser()",
  "maxResults": 50,
  "fields": ["summary", "status", "assignee"]
}

If your integration needs to mirror tickets into your product, generate dashboards, or filter subsets of work, JQL is a core part of the design.

Add and read comments

Comments are another common integration surface, especially in support and collaboration workflows.

To add a comment:

POST /rest/api/3/issue/{issueIdOrKey}/comment

Like descriptions, comment bodies use Atlassian Document Format. Issue comments

To list comments:

GET /rest/api/3/issue/{issueIdOrKey}/comment

Read transitions and move issues through a workflow

Jira workflows are not just labels. They govern how work moves through statuses.

To get the available transitions for an issue:

GET /rest/api/3/issue/{issueIdOrKey}/transitions

To perform a transition:

POST /rest/api/3/issue/{issueIdOrKey}/transitions

With a body like:

{
  "transition": {
    "id": "31"
  }
}

This is the API pattern you use when your product needs to move work to 'In Progress,' 'In Review,' or 'Done' based on events in your own system. Issue transitions

List projects

Projects are another foundational object. To search or list projects:

GET /rest/api/3/project/search

This is useful for setup flows where you need customers to pick a Jira project before issue creation begins. Project API group

Pagination, rate limits, and webhooks

Pagination

Jira REST responses commonly include:

  • startAt
  • maxResults
  • total
  • isLast

You page through large result sets by adjusting startAt and maxResults. Atlassian documents this pagination model across Jira Cloud REST resources. Expansion, pagination, and ordering

For some newer search flows, Atlassian also uses nextPageToken, so you should design your client code to follow the response shape of the specific endpoint rather than assuming a single pagination style everywhere.

Rate limits

Jira Cloud enforces rate limits, and Atlassian documents both burst-based and resource-specific limits. Rate limiting

Important practical points:

  • 429 Too Many Requests is the signal that you hit a limit
  • The Retry-After header tells you how long to wait
  • Atlassian may also return headers like X-RateLimit-Limit and X-RateLimit-Remaining
  • Some write-heavy patterns are additionally constrained on a per-issue basis

For production integrations, you should:

  • respect Retry-After
  • implement exponential backoff
  • avoid bursty sync behavior
  • reduce unnecessary polling
  • batch work where appropriate

Webhooks

Webhooks are the right model when you need near real-time changes without constant polling.

Atlassian documents Jira Cloud webhooks for issue, comment, project, sprint, version, and related events. Webhooks

Important webhook behavior:

  • webhook deliveries are sent to your HTTPS endpoint
  • failures are retried
  • duplicate deliveries are possible
  • ordering is not guaranteed
  • you should treat deliveries as idempotent
  • you should secure your endpoint and validate origin/signature details where applicable

For most SaaS products, the key reason to use webhooks is simple: they let you update your system when Jira changes, instead of repeatedly asking Jira whether anything changed.

Where Jira integrations become operationally complex

A direct Jira integration means you own:

  • API token vs OAuth architecture
  • multi-tenant OAuth flows
  • token refresh and secure storage
  • tenant discovery via cloudId
  • issue field mapping
  • custom field handling
  • JQL query construction
  • pagination logic
  • retry and throttling controls
  • webhook registration and delivery handling
  • workflow transition logic
  • project and user sync behavior

For a simple internal script, this is manageable.

For a multi-tenant B2B SaaS product supporting many customer Jira instances, this becomes real infrastructure.

The complexity tends to show up in three places:

First, field variability. Jira issue types, custom fields, statuses, and workflow transitions differ across tenants.

Second, auth and tenancy. OAuth in Atlassian Cloud is not just 'get a token and call /me.' You need to resolve accessible resources and persist tenant context.

Third, operational reliability. Search, webhooks, retries, backfills, and partial failure handling all become part of the integration surface.

Integrating Jira via Unified

Unified gives you a normalized Jira path across Task, HRIS, Storage, Metadata, and Passthrough APIs.

From the Jira integration details you shared, Unified supports objects such as:

  • task for Jira issues
  • task_project for Jira projects
  • task_comment for issue comments
  • task_change for issue changelog/change history
  • storage_file for attachments
  • hris_group for Jira groups
  • hris_employee for users
  • passthrough for unsupported Jira-specific endpoints

Step 1: Register Jira OAuth for Unified

When integrating Jira through Unified, set the callback URL to:

https://api.unified.to/oauth/code

Unified's Jira integration page also indicates OAuth 2.0 credentials should be registered through the Atlassian developer console. Atlassian developer console and Unified guide to registering an Atlassian developer app

Unified scope mappings for Jira, based on the integration details you shared, include examples like:

  • task_task_readoffline_access, read:jira-work, read:jira-user
  • task_task_writeoffline_access, read:jira-work, read:jira-user, write:jira-work
  • task_project_readoffline_access, read:jira-user, read:jira-work
  • task_project_writeoffline_access, read:jira-user, manage:jira-configuration, manage:jira-project, write:project:jira
  • task_comment_readoffline_access, read:jira-user, read:jira-work
  • task_comment_writeoffline_access, read:jira-user, write:jira-work
  • webhookoffline_access, read:jira-work, manage:jira-webhook

That gives you a much cleaner way to request what you need without hand-building Atlassian scope combinations from scratch.

Step 2: Authorize a Jira connection

With Unified, the end result of authorization is a connection_id. That connection represents one customer's Jira account and is what you use in future API calls.

This is materially simpler than managing raw tenant auth and provider-specific request setup yourself.

Step 3: Use Unified's normalized task APIs

List projects:

GET /task/{connection_id}/project

List tasks:

GET /task/{connection_id}/task

Get a task:

GET /task/{connection_id}/task/{id}

Create a task:

POST /task/{connection_id}/task

Update a task:

PUT /task/{connection_id}/task/{id}

Remove a task:

DELETE /task/{connection_id}/task/{id}

From the coverage you shared, Unified's Jira task object includes readable fields like:

  • id
  • name
  • project_id
  • status
  • priority
  • tags
  • assigned_user_ids
  • creator_user_id
  • due_at
  • updated_at
  • url

And writable fields include practical ones such as:

  • name
  • project_id
  • assigned_user_ids
  • completed_at
  • due_at
  • notes
  • parent_id
  • tags

That means the common issue creation and update path can be handled through one normalized object instead of raw Jira field payloads.

Step 4: Use Unified comments, users, groups, and change history

Unified's Jira coverage also gives you:

  • task_comment for issue comments
  • task_change for issue changelog/history
  • hris_employee for Jira users
  • hris_group for Jira groups
  • storage_file for attachments

That is useful when your app needs not just issue creation, but also:

  • comment sync
  • user assignment flows
  • audit/change tracking
  • attachment retrieval
  • group-aware routing or permissions logic

Step 5: Use Unified webhooks

From the Jira integration details you shared:

  • task supports virtual and native webhooks
  • task_comment supports native webhooks
  • other objects vary in support

This matters because it means you can receive issue and comment updates without building the raw Jira webhook management flow yourself.

Unified's virtual webhook model also gives you fallback coverage in cases where native event behavior is limited or inconsistent across providers.

Step 6: Use passthrough for Jira-specific gaps

Jira is broad. Boards, sprints, agile endpoints, specialized metadata, or tenant-specific features may not always fit perfectly into normalized models.

That is why passthrough matters.

Unified's Jira integration supports passthrough methods:

  • GET
  • POST
  • PUT
  • DELETE

So if you need a Jira-specific endpoint not yet normalized, you can still call it through Unified while keeping the same auth and connection model.

Direct vs Unified: when to choose each

Build directly with Jira if:

  • Jira is a strategic core integration for your product
  • you need deep Jira-specific behavior, including custom field logic and workflow nuance
  • you need direct control over Atlassian auth, tenant routing, and webhook handling
  • you are comfortable owning Jira's operational complexity long term

Use Unified if:

  • Jira is one of several task or work-management integrations on your roadmap
  • your core use cases are issues, projects, comments, users, groups, and attachments
  • you want normalized APIs and simpler auth flows
  • you want built-in webhook coverage where possible
  • you still want passthrough for provider-specific gaps

Final thoughts

A Jira API integration looks straightforward at the first-request level.

The real complexity shows up in:

  • choosing the right auth model
  • handling tenant resolution correctly
  • working with Jira's field and workflow variability
  • using search and pagination efficiently
  • dealing with rate limits
  • keeping data in sync through webhooks

If Jira is central to your product, building directly can make sense. You get maximum flexibility and full access to the platform's native model.

If Jira is one integration among many, a normalized integration layer can reduce engineering drag, shorten time to launch, and still leave you an escape hatch for Jira-specific endpoints when you need them.

Start your 30-day free trial

Book a demo

All articles