Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Get Fabric Certified for FREE during Fabric Data Days. Don't miss your chance! Request now

Reply
GauravSinghPBI
Helper II
Helper II

Pwer BI to Jira Integration

Hi Team,

 

We ae trying to import the data from Jira Cloud to Power BI. 

 

Our Major requirements are as follows.

 

1. We would like to fetch the jiras dynamically and in live/Direct/Import Modes.

2. We should be able to fetch all the jira assigned to any individual or basis on any jira project (jiras created in last one year for ex.)

3. Should be able to fetch the fields configured in jira projects with all issues/stories/epic etc

4. Can we have the main work request number (Story’s) and the Impact Assessments (subtasks) linking to the main work reception ticket

5. Will it be possible to show the name of the individual the impact assessment is assigned too or the team area it is attached too

6. Is it possible to see why something has not went ahead – can we get details on closed work requests that have not been completed

7. Will it be possible for PowerBI to give a full report from when he board was created to present day

 

Thanks,

Gaurav

1 ACCEPTED SOLUTION

Hi @GauravSinghPBI ,

We are following up once again regarding your query. Could you please confirm if the issue has been resolved through the support ticket with Microsoft?

If the issue has been resolved, we kindly request you to share the resolution or key insights here to help others in the community.


Thank you.

View solution in original post

34 REPLIES 34
OscarTh
Helper I
Helper I

I’ve dealt with similar Jira-to-Power BI setups - handling pagination and date filters is key. For incremental loads and snapshots, I’ve used Skyvia to sync the data into a database first, then connected Power BI to that. It simplified things a lot.

Nandhini_Palani
New Member

Could you please tell me if the REST API end points are still usable?
I see that they are depreciated as per: https://developer.atlassian.com/changelog/#CHANGE-2046

Hi @Nandhini_Palani 

 

yes i am still able to use API based connectivity.

jaineshp
Memorable Member
Memorable Member

Hey @GauravSinghPBI,

That's expected behavior! The API returns empty because you haven't provided any search parameters yet.

Quick Fix Steps:

1. Add JQL Query Parameter In Power Query Editor:

  • Go to Advanced Editor
  • Modify your URL to include JQL:

https://xxxxxxx.atlassian.net/rest/api/3/search?jql=project="YOUR_PROJECT_KEY"

 

  • Replace YOUR_PROJECT_KEY with actual project key (like "PROJ" or "DEV")

2. Basic JQL Examples to Try:

  • All issues: ?jql=order by created DESC
  • Recent issues: ?jql=created >= -30d
  • Specific assignee: ?jql=assignee=currentUser()

3. Authentication Check Make sure you're using:

  • Username: Your Atlassian email
  • Password: Your API token (not your login password)

4. Expand the Data Once you get results:

  • Click on "issues" column header
  • Select "Expand to New Rows"
  • Then expand individual fields like key, summary, status

5. Test Connection First Try this simple URL to verify connection:

 

https://xxxxxxx.atlassian.net/rest/api/3/myself

 

This should return your user info if auth is working.

The empty result you're seeing just means "no search criteria = no results". Add the JQL parameter and you'll see your data flowing in.

Let me know if you hit any snags!

 

Fixed? ✓ Mark it • Share it • Help others!


Best Regards,
Jainesh Poojara | Power BI Developer

@jaineshp - I tested the link point no. 5 and working for me.

 

https://xxxx.atlassian.net/rest/api/3/myself

 

I went to Power BI Desktop - Get Data - Web - with Basic option put the below URL and click ok

 

https://xxxxxxx.atlassian.net/rest/api/3/search

 

Power Query Editor opens and Query named "search" is appearing but there is no data except one row with below columns and values

 

startAt     maxResults    total          issues

0               50                  0

 

After that i went to advance editor and change 

from

Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search")),

to

 Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project="PPPP"")),

 

when i click ok - it provides some error "Expression.SyntaxError: Token Comma expected."

 

Kindly help.

 

Thanks,

Gaurav

 

@GauravSinghPBI,

It's a simple syntax issue with the quotes in your JQL parameter.

Try the below one: -

Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=""PPPP""")),

  • Use double quotes "" to escape quotes inside the string
  • So project = "PPPP" becomes project ""PPPP""

Alternative Approach: If you keep getting syntax errors, try this simpler JQL first:

 

Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=order by created DESC")),

After fixing the syntax, you should see:

  • total > 0
  • issues column with actual data
  • Click on "issues" to expand and see your Jira tickets

The syntax error happens because Power Query needs proper quote escaping for nested strings.

Fixed? ✓ Mark it • Share it • Help others!


Best Regards,
Jainesh Poojara | Power BI Developer

 

Thanks @jaineshp 

 

After i changed the Project within ""PPPP""

Web.Contents failed to get contents from 'https://xxxx.atlassian.net/rest/api/3/search?jql=project=%22PPPP%22' (400): Bad Request

 

But when i followed the alternative approach

https://xxxx.atlassian.net/rest/api/3/search?jql=order by created DESC"

 

It provides

  • total = 0
  • issues column with null

 

Don't know what mistake i am doing. Till now i have not followed any other steps on auth etc.

 

Thanks

Gaurav

Hey @GauravSinghPBI,

The 400 Bad Request and total = 0 clearly indicates authentication issues. You can't access Jira REST API without proper auth.

Quick Fix Steps:

  1. Add Basic Auth to your Web.Contents:

Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=order by created DESC",
[Headers=[Authorization="Basic " & Binary.ToText(Text.ToBinary("your-email@domain.com:your-api-token"), BinaryEncoding.Base64)]]))

  1. Get your API Token:
    • Go to Atlassian Account Settings → Security → API Tokens
    • Create new token and copy it
  2. Test with simple query first:
    • Use: jql=order by created DESC
    • Once auth works, then try project filter

Why it's failing:

  • Jira API requires authentication (email + API token)
  • Without auth = 400 error or empty results

Try the auth fix first - that should resolve both issues!


Best Regards,
Jainesh Poojara | Power BI Developer

Thanks @jaineshp 

 

I have used authorization and other details and able to fetch the data but records are not matching perfectly for ex.

 

"https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP order by created DESC"

 

is returning 838 rows (in Jira Application) and total column in PBI also shows 838 value.

 

but when i added created >= -30d as below

"https://natwest.atlassian.net/rest/api/3/search?jql=project=FNWR&created >= -30d order by created DESC"

 

query should retun 23 records as i see in jira tool but total column still shows 838 in PBI.

 

In above both scenarios - i am getting only 50 rows in PBI and maxResults column also shows 50

 

Thanks,

Gaurav

Hey @GauravSinghPBI,

Looking at Gaurav's response, there are two separate issues here:

Issue 1: JQL Query Syntax Error

The query created >= -30d has incorrect syntax. In JQL, you need quotes around the date value:


Wrong:  jql=project=PPPP&created >= -30d order by created DESC

 

Correct: jql=project=PPPP AND created >= "-30d" ORDER BY created DESC

 

Fix the JQL syntax: 

Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP AND created >= ""-30d"" ORDER BY created DESC", [Headers=[Authorization="Basic " & Binary.ToText(Text.ToBinary("your-email@domain.com:your-api-token"), BinaryEncoding.Base64)]]))

 

Issue 2: Pagination Limit (50 records max)

Jira API returns maximum 50 results per call by default. To get all 838 records, you need pagination.

Add these parameters:

  • maxResults=1000 (or however many you want per page)
  • startAt=0 for first page

Updated Query:

 

Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP ORDER BY created DESC&maxResults=1000&startAt=0", [Headers=[Authorization="Basic " & Binary.ToText(Text.ToBinary("your-email@domain.com:your-api-token"), BinaryEncoding.Base64)]]))

For complete pagination in Power BI: You'll need a custom function to loop through all pages if you have more than 1000 records.

Quick test: Try the corrected JQL syntax first with maxResults=100 to see if you get the right filtered count!

Fixed? ✓ Mark it • Share it • Help others!


Best Regards,
Jainesh Poojara | Power BI Developer

@jaineshp Thanks for the response.

 

  • With the below query - able to get the 100 rows but not more than that.

let
Source = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP order by created DESC&maxResults=1000&startAt=0",
[Headers=[Authorization="Basic " & Binary.ToText(Text.ToBinary("mail id:API token"), BinaryEncoding.Base64)]])),
#"Converted to Table" = Table.FromRecords({Source}),
#"Expanded issues" = Table.ExpandListColumn(#"Converted to Table", "issues"),
#"Changed Type" = Table.TransformColumnTypes(#"Expanded issues",{{"startAt", Int64.Type}, {"maxResults", Int64.Type}, {"total", Int64.Type}, {"issues", type any}})
in
#"Changed Type"

 

  • with the below query, getting 50 records while in jira board i have 11 only created in last 10 days.

"https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP&created >= ""-10d"" order by created DESC"

 

  • Will this solution using API method, won't work with direct query and refresh can not happen automatically?

 

Thanks,

Gaurav

Hey @GauravSinghPBI,

Looking at your responses, I can see 3 specific issues that need addressing:

Issue 1: 100 records limit despite maxResults=1000 This suggests your Jira instance has a server-side limit. Many organizations set max limits around 100-200. Solution: Contact your Jira admin to check the server configuration or use pagination with smaller batches (maxResults=50-100).


Issue 2: Date filter returning wrong count (50 vs 11 expected)
Your JQL syntax is still incorrect - you're missing AND operator: Wrong: jql=project=PPPP&created >= "-10d" Correct: jql=project=PPPP AND created >= "-10d"

Fixed Query:

 

"https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP AND created >= ""-10d"" ORDER BY created DESC"

Issue 3: Direct Query & Auto Refresh Limitations You're right - API method won't support DirectQuery mode. Here are your options:

Option A: Import Mode with Scheduled Refresh

  • Use Import mode in Power BI Service
  • Set up scheduled refresh (up to 48x daily with Premium)
  • Data gets refreshed automatically

Option B: Power BI Dataflows

  • Create a dataflow with your Jira API connection
  • Schedule dataflow refresh independently
  • Connect Power BI report to dataflow (supports DirectQuery to dataflow)

Option C: Jira Connector (if available)

  • Check if your organization has official Jira connector
  • May support better refresh options

Immediate Action Plan:

  1. Fix the JQL syntax with proper AND operator
  2. Test with maxResults=50 to confirm data accuracy
  3. Implement Option A for scheduled refresh initially

Quick Test: Try this corrected query first:

jql=project=PPPP AND created >= "-10d" ORDER BY created DESC&maxResults=50

 

Fixed? ✓ Mark it • Share it • Help others!


Best Regards,
Jainesh Poojara | Power BI Developer

@jaineshp Thanks for the response.

 

  • with the below sql, able to fetch only 11 records which is same in jira board. But maxResults column in data still shows 50 and total column shwos 11 only. Sql is returnig correct results but why maxResults has 50 value?.

https://xxxx.atlassian.net/rest/api/3/search?jql=project=PPPP AND created >= ""-10d"" order by created DESC

 

  • Below sql retuns only 100 rows while in jira boards 111 rows are there. But maxResults column in data still shows 100 and total column shwos 111. It means there is a limitation of 100 rows in jira tool.

https://xxxx.atlassian.net/rest/api/3/search?jql=project=FNWR AND created >= ""-365d"" order by created DESC&maxResults=1000&startAt=0

 

  • How can i use pagination with smaller batches to fetch around 1k rows? Have you achieved that?

 

Thanks,

Gaurav

@GauravSinghPBI 

1. Why maxResults shows 50 when no maxResults parameter specified: When you don't specify maxResults in your URL, Jira API defaults to 50. The API response always shows what limit was applied, even if fewer records exist. So:

  • No maxResults parameter = Jira defaults to 50
  • total=11 = actual matching records
  • This is expected behavior

2. 100 row server limitation confirmed: Yes, your Jira instance has a hard limit of 100 records per API call. Even though you requested maxResults=1000, the server only returned 100. The total=111 confirms there are more records available.

3. Pagination implementation: Here's how to fetch all 1k+ rows using pagination:

 

Multiple Web.Contents calls in Power Query M:

let
Page1 = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=FNWR AND created >= ""-365d""&maxResults=100&startAt=0")),
Page2 = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=FNWR AND created >= ""-365d""&maxResults=100&startAt=100")),
Page3 = Json.Document(Web.Contents("https://xxxx.atlassian.net/rest/api/3/search?jql=project=FNWR AND created >= ""-365d""&maxResults=100&startAt=200")),

CombinedIssues = Page1[issues] & Page2[issues] & Page3[issues],
ConvertToTable = Table.FromList(CombinedIssues, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
in
ConvertToTable

 

Fixed? ✓ Mark it • Share it • Help others!


Best Regards,
Jainesh Poojara | Power BI Developer

@jaineshp Thanks for the response.

 

I used Copilot to prepare the script (under Script ----------->). It created the script and fetching 200+ records now. Nor i have Key, Summary, Status Name etc column. But all column values are Error (hyperlink) and when i click beside the Error value in cell I get. DOn't know how to concert this in simple table which gives me values from jira board. Please help.

 

"DataFormat.Error: There were more columns in the result than expected.
Details:
Count=1"

 

Script ----------->


let
// === Configuration ===
BaseUrl = "https://xxxx.atlassian.net/rest/api/3/search?",
JQL = "jql=project=PPPP AND created >= -365d",
PageSize = 100,
Email = "my email", // Replace with your Atlassian email
APIToken = "Actual APi token", // Replace with your API token

// === Function to Get a Page of Issues ===
GetPage = (StartAt as number) =>
let
Url = BaseUrl & JQL & "&startAt=" & Number.ToText(StartAt) & "&maxResults=" & Number.ToText(PageSize),
Source = Json.Document(Web.Contents(Url, [
Headers = [
#"Authorization" = "Basic " & Binary.ToText(Text.ToBinary(Email & ":" & APIToken), BinaryEncoding.Base64),
#"Accept" = "application/json"
]
])),
Issues = Source[issues]
in
Issues,

// === Generate All Pages ===
Pages = List.Generate(
() => [i = 0, data = GetPage(0)],
each List.Count([data]) > 0,
each [i = [i] + PageSize, data = GetPage([i])],
each [data]
),

// === Flatten and Convert to Table ===
Flattened = List.Combine(Pages),
Table = Table.FromList(Flattened, Record.FieldValues, {"Issue"}),

// === Expand Fields ===
Expanded = Table.ExpandRecordColumn(Table, "Issue", {
"key", "fields"
}),

FieldsExpanded = Table.ExpandRecordColumn(Expanded, "fields", {
"summary", "status", "assignee", "created", "updated", "customfield_10007"
}, {
"Summary", "Status", "Assignee", "Created", "Updated", "Sprint"
}),

StatusExpanded = Table.ExpandRecordColumn(FieldsExpanded, "Status", {"name"}, {"Status Name"}),
AssigneeExpanded = Table.ExpandRecordColumn(StatusExpanded, "Assignee", {"displayName"}, {"Assignee Name"}),

FinalTable = AssigneeExpanded
in
FinalTable

Hi @GauravSinghPBI ,

Thanks for reaching out to the Microsoft fabric community forum. 

 

I would also take a moment to thank @jaineshp , for actively participating in the community forum and for the solutions you’ve been sharing in the community forum. Your contributions make a real difference. 


By default, Jira’s REST API only returns 50 issues per request. You can increase this limit in your query string

.../rest/api/3/search?jql=project=FNWR AND created >= -30d order by created DESC&maxResults=1000

Replace 1000 with the number you need (maximum allowed is usually 1000).

 

If you need more than that, you’ll need to retrieve data in pages using the startAt parameter and combine the results in Power Query.

When combining multiple filters, join them with AND . This ensures Jira interprets both filters correctly.

To avoid pulling all records every time, configure Incremental Refresh in Power BI:

 

Create RangeStart and RangeEnd parameters in Power Query (type: Date/Time).

 

Filter your Jira dataset so that [created] is between these parameters.

 

Enable Incremental Refresh on the table from the Model view.

 

Publish and set up a refresh schedule in the Power BI Service.

If I misunderstand your needs or you still have problems on it, please feel free to let us know.   

Best Regards, 
Community Support Team  

Hey @v-menakakota,

Thank you for the kind recognition - always happy to contribute to our community's success!

Best Regards,
Jainesh Poojara | Power BI Developer

@jaineshp Thanks for the response.

 

The code which i pasted on last week Tuesday as below. I am facing below issues still.

 

  • If i go to jira project and extract the jira created >= -10d, jira project returns 14 records while below code returns 28 records.
  • When in jira project and extract the jira created >= -30d, jira project returns 34 records while below code returns 68 records.
  • When in jira project and extract the jira created >= -365d, jira project returns 120 records while below code returns 220 records.
  • This data discrepancy - i am not able to solve.
  • Another isuue is - I am getting Error value in all fields and whn i click on any value - error appears in bottom.

 

 

let
// === Configuration ===
BaseUrl = "https://natwest.atlassian.net/rest/api/3/search?",
JQL = "jql=project=PPPP AND created >= -365d",
PageSize = 100,
Email = "my email", // Replace with your Atlassian email
APIToken = "Actual API token", // Replace with your API token

// === Function to Get a Page of Issues ===
GetPage = (StartAt as number) =>
let
Url = BaseUrl & JQL & "&startAt=" & Number.ToText(StartAt) & "&maxResults=" & Number.ToText(PageSize),
Source = Json.Document(Web.Contents(Url, [
Headers = [
#"Authorization" = "Basic " & Binary.ToText(Text.ToBinary(Email & ":" & APIToken), BinaryEncoding.Base64),
#"Accept" = "application/json"
]
])),
Issues = Source[issues]
in
Issues,

// === Generate All Pages ===
Pages = List.Generate(
() => [i = 0, data = GetPage(0)],
each List.Count([data]) > 0,
each [i = [i] + PageSize, data = GetPage([i])],
each [data]
),

// === Flatten and Convert to Table ===
Flattened = List.Combine(Pages),
Table = Table.FromList(Flattened, Record.FieldValues, {"Issue"}),

// === Expand Fields ===
Expanded = Table.ExpandRecordColumn(Table, "Issue", {
"key", "fields"
}),

FieldsExpanded = Table.ExpandRecordColumn(Expanded, "fields", {
"summary", "status", "assignee", "created", "updated", "customfield_10007"
}, {
"Summary", "Status", "Assignee", "Created", "Updated", "Sprint"
}),

StatusExpanded = Table.ExpandRecordColumn(FieldsExpanded, "Status", {"name"}, {"Status Name"}),
AssigneeExpanded = Table.ExpandRecordColumn(StatusExpanded, "Assignee", {"displayName"}, {"Assignee Name"}),

FinalTable = AssigneeExpanded
in
FinalTable

 

 

 

 

 

Hey @GauravSinghPBI,

Try this: -

let
// === Configuration ===
BaseUrl = "https://natwest.atlassian.net/rest/api/3/search?",
JQL = "jql=project=PPPP AND created >= -365d ORDER BY created ASC",
PageSize = 100,
Email = "my email", // Replace with your Atlassian email
APIToken = "Actual API token", // Replace with your API token

// === Function to Get a Page of Issues ===
GetPage = (StartAt as number) =>
let
Url = BaseUrl & JQL & "&startAt=" & Number.ToText(StartAt) & "&maxResults=" & Number.ToText(PageSize),

// Add error handling for API calls
Source = try Json.Document(Web.Contents(Url, [
Headers = [
#"Authorization" = "Basic " & Binary.ToText(Text.ToBinary(Email & ":" & APIToken), BinaryEncoding.Base64),
#"Accept" = "application/json"
]
])) otherwise [issues = {}, total = 0],

Issues = if Record.HasFields(Source, "issues") then Source[issues] else {},
Total = if Record.HasFields(Source, "total") then Source[total] else 0
in
[issues = Issues, total = Total, startAt = StartAt],

// === Get First Page to Determine Total Count ===
FirstPage = GetPage(0),
TotalRecords = FirstPage[total],

// === Generate All Pages Without Duplication ===
AllPages = List.Generate(
() => [currentStart = 0, pageData = FirstPage],
each [currentStart] < TotalRecords,
each [
currentStart = [currentStart] + PageSize,
pageData = if [currentStart] < TotalRecords then GetPage([currentStart]) else [issues = {}]
],
each [pageData][issues]
),

// === Flatten All Issues ===
AllIssues = List.Combine(AllPages),

// === Process Data Only If Issues Exist ===
FinalResult = if List.Count(AllIssues) > 0 then
let
// === Convert to Table ===
IssuesTable = Table.FromList(AllIssues, Splitter.SplitByNothing(), {"Issue"}),

// === Expand Main Fields ===
ExpandedIssues = Table.ExpandRecordColumn(IssuesTable, "Issue", {"key", "fields"}),

// === Add Derived Columns with Safe Field Access ===
WithKey = Table.AddColumn(ExpandedIssues, "Key", each
if Record.HasFields([fields], "key") then [key] else null, type text),

WithSummary = Table.AddColumn(WithKey, "Summary", each
if Record.HasFields([fields], "summary") then [fields][summary] else null, type text),

WithCreated = Table.AddColumn(WithSummary, "Created", each
if Record.HasFields([fields], "created") then
try DateTime.FromText([fields][created]) otherwise null
else null, type nullable datetime),

WithUpdated = Table.AddColumn(WithCreated, "Updated", each
if Record.HasFields([fields], "updated") then
try DateTime.FromText([fields][updated]) otherwise null
else null, type nullable datetime),

WithStatus = Table.AddColumn(WithUpdated, "Status Name", each
if Record.HasFields([fields], "status") and [fields][status] <> null then
if Record.HasFields([fields][status], "name") then [fields][status][name] else null
else null, type text),

WithAssignee = Table.AddColumn(WithStatus, "Assignee Name", each
if Record.HasFields([fields], "assignee") and [fields][assignee] <> null then
if Record.HasFields([fields][assignee], "displayName") then [fields][assignee][displayName] else null
else null, type text),

WithSprint = Table.AddColumn(WithAssignee, "Sprint", each
if Record.HasFields([fields], "customfield_10007") then
// Sprint field can be complex, handle accordingly
let SprintValue = [fields][customfield_10007]
in if SprintValue <> null then Text.From(SprintValue) else null
else null, type text),

// === Remove Intermediate Columns ===
CleanedTable = Table.RemoveColumns(WithSprint, {"Issue", "fields"})
in
CleanedTable
else
// === Return Empty Table with Correct Schema ===
Table.FromRecords({}, type table [
Key = text,
Summary = text,
Created = nullable datetime,
Updated = nullable datetime,
#"Status Name" = text,
#"Assignee Name" = text,
Sprint = text
])

in
FinalResult

 

Fixed? ✓ Mark it • Share it • Help others!


Best Regards,
Jainesh Poojara | Power BI Developer

@jaineshp 

Code is not comipiling 

 

Expression.Error: The column 'Issue' of the table wasn't found.
Details:
Issue

Helpful resources

Announcements
Fabric Data Days Carousel

Fabric Data Days

Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

Check out the October 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Solution Authors