Start from the filter you already have
Most teams already have a saved Jira filter, or could write the JQL for one in a minute: open issues assigned to a team, everything in the current sprint, a support queue filtered by status. That query is the report. The automation problem isn't finding the right JQL, it's getting Jira's answer to that query into a sheet without re-running it by hand every time someone asks for an update.
What "automatically" needs to cover
- Run the JQL or saved filter itself, not a manually curated subset of it.
- Page through the full result set. Jira's search API returns results a page at a time, and a filter that matches more than one page needs to keep requesting until it's exhausted, not stop at the first response.
- Write the result to a sheet tab on a schedule, hourly, daily, or weekly, without someone remembering to click export.
- Flatten custom fields into readable cells instead of raw API objects, since most saved filters include at least one custom field alongside the standard ones.
Where a plain export falls short
The Issue Navigator's CSV export button, or the older /search endpoint some scripts call, work fine for a one-off download. Neither is built to be a standing report: the CSV button has its own separate cap Atlassian raised to 10,000 issues, and neither one refreshes itself. See why Jira's CSV export still caps at 10,000 issues and how to export more than 1,000 Jira issues for the mechanics of paging past a single response.
Building it against the current search API
Atlassian's REST API v3 offers two ways to run a JQL search: the deprecated offset-based GET /rest/api/3/search, and the current, token-paged POST /rest/api/3/search/jql. The current endpoint is a POST rather than a GET specifically because a long JQL string plus a large field list can exceed the roughly 2,082-character URL limit most HTTP clients and proxies enforce; putting the query in the request body avoids that ceiling entirely. Authentication is HTTP Basic with your Atlassian account email as the username and an API token, generated from id.atlassian.com → Security → API tokens, as the password, not your actual login password. Each response returns a page of issues plus a continuation token; a script has to keep requesting with that token until Jira signals there's no more data, since stopping after the first page silently truncates the result exactly the way a naive CSV pull would.
Native automation tools vs. building it vs. Sheet Sync for Jira
| CSV export button | Build on the API | Sheet Sync for Jira | |
|---|---|---|---|
| Refreshes itself | No | Only if you build the trigger | Yes, hourly/daily/weekly |
| Result size limit | 10,000 issues | None, if pagination is correct | 500 on Free, none on Pro |
| Custom fields readable as text | Partially | Only if you write the flattening logic | Yes, built in |
| Setup | A menu click | An API token, pagination, a trigger | Connect a token, save the query |
Fields still need to come out clean
A JQL result that includes user, option, array, or rich-text custom fields, common in any filter built for reporting rather than a quick lookup, returns those fields as typed objects, not text. Rich-text fields in particular arrive as Atlassian Document Format (ADF), a nested JSON tree describing formatting, not a plain string, so pulling a description or a rich-text custom field means recursively walking that structure to extract readable text rather than reading one property off it. A schedule just repeats whatever the first run produced, so a broken column stays broken on every refresh. See why Jira custom fields export as [object Object] or raw JSON before you set the schedule and forget about it, or pulling Jira issue status into Google Sheets if status specifically is the column that matters.
What "connect a token, save the query" actually involves
Sheet Sync for Jira adds one item under Extensions → Sheet Sync for Jira. Opening it the first time asks for a Jira site URL, an Atlassian account email, and an API token from id.atlassian.com → Security → API tokens, the same token type the manual build above needs; nothing beyond that read-only token leaves the spreadsheet owner's own Google Apps Script project. A new import then picks JQL or a saved filter, the fields to bring across, a destination tab, and a refresh cadence. There's no separate deploy step and no trigger to wire up by hand: saving the import is what creates the shared hourly dispatcher behind the scenes.
Troubleshooting
The sync stops partway through a large filter
Check whether the continuation token from search/jql was actually followed to the end. A script or Zap that reads only the first response's issues array will look like it worked on a small filter and then quietly truncate the moment the same filter matches more than one page.
A 401 or 403 comes back where the query used to work
API tokens can be revoked from id.atlassian.com independently of the account's Jira password, and a token used with the wrong Atlassian account email in the Basic auth header fails the same way a wrong password would.
Point it at a filter, not a script
Sheet Sync for Jira runs JQL or a saved filter directly against the current search/jql endpoint, pages through the full result with a resumable cursor, flattens every field type including ADF rich text, and refreshes on a schedule you set once.