Founding keys are opena year free at 6,000 req/hour, for the first 1,000 developersClaim yours
Documentation 29

Jira quickstart · 3 min read

Keep jira.js. Change one line.

The same simulated data set your git sandboxes serve — as a Jira Cloud site. Sprints, epics, workflow histories, and bounded JQL, all reconciling with the git side: ARGO-59 is the same canonical issue on the pinned Linear host, and the branch it names is the head of a real, merged pull request on the pinned GitHub host.

01Point host at jira.
02Query with JQL as before
03Pin a snapshot for CI

01 / Base URL

One host, provider paths.

Point your client at https://jira.sandboxapis.dev. Paths mirror your-domain.atlassian.net — v3 REST with ADF bodies, the agile API, ErrorCollection error shapes, and the enhanced-search family (the removed classic /search serves its real 410).

request.sh
curl "https://jira.sandboxapis.dev/rest/api/3/search/jql?jql=project%20%3D%20ARGO%20AND%20statusCategory%20!%3D%20Done"

02 / Drop in your client

jira.js works unmodified.

The only change is the host.

typescript
import { createCloudClient, createAgileClient } from "jira.js";

const auth = { type: "basic", email: "you@example.com", apiToken: "any-token" } as const;
const jira = createCloudClient({ host: "https://jira.sandboxapis.dev", auth });

const { issues } = await jira.issueSearch.searchAndReconsileIssuesUsingJql({
  jql: "sprint in openSprints() AND statusCategory != Done",
  fields: ["summary", "status", "assignee", "customfield_10020"], // Sprint field
});

const agile = createAgileClient({ host: "https://jira.sandboxapis.dev", auth });
const boards = await agile.board.getAllBoards();   // one scrum board per team
const sprints = await agile.board.getAllSprints({ boardId: boards.values![0]!.id! });

The Python client is proved end to end rather than described: the jira package's exact snippet is executed against https://jira.sandboxapis.dev by a script that checks its output — including the constructor's own /rest/api/2/serverInfo handshake. Verified quickstarts →

03 / A real response

Live from the universe.

200 · application/json
{
  "issues": [
    {
      "id": "56923",
      "key": "ORCL-84",
      "self": "https://jira.sandboxapis.dev/rest/api/3/issue/56923",
      "fields": {
        "summary": "Proposal: type the event emitter",
        "status": {
          "self": "https://jira.sandboxapis.dev/rest/api/3/status/10002",
          "id": "10002",
          "name": "In Progress",
          "description": "",
          "statusCategory": {
            "self": "https://jira.sandboxapis.dev/rest/api/3/statuscategory/4",
            "id": 4,
            "key": "indeterminate",
            "colorName": "yellow",
            "name": "In Progress"
          }
        },
        "assignee": {
          "self": "https://jira.sandboxapis.dev/rest/api/3/user?accountId=9e1d97b87f6822760dfb91ea",
          "accountId": "9e1d97b87f6822760dfb91ea",
          "accountType": "atlassian",
          "displayName": "Pythia",
          "active": true,
          "timeZone": "UTC",
          "avatarUrls": {
            "48x48": "https://jira.sandboxapis.dev/secure/useravatar?size=large&ownerId=9e1d97b87f6822760dfb91ea",
            "24x24": "https://jira.sandboxapis.dev/secure/useravatar?size=small&ownerId=9e1d97b87f6822760dfb91ea",
            "16x16": "https://jira.sandboxapis.dev/secure/useravatar?size=xsmall&ownerId=9e1d97b87f6822760dfb91ea",
            "32x32": "https://jira.sandboxapis.dev/secure/useravatar?size=medium&ownerId=9e1d97b87f6822760dfb91ea"
          }
        }
      }
    },
    {
      "id": "27725",
      "key": "ORCL-81",
      "self": "https://jira.sandboxapis.dev/rest/api/3/issue/27725",
      "fields": {
        "summary": "Regression: Events dropped during a rebalance",
        "status": {
          "self": "https://jira.sandboxapis.dev/rest/api/3/status/10005",
          "id": "10005",
          "name": "Canceled",
          "description": "",
          "statusCategory": {
            "self": "https://jira.sandboxapis.dev/rest/api/3/statuscategory/3",
            "id": 3,
            "key": "done",
            "colorName": "green",
            "name": "Done"
          }
        },
        "assignee": {
          "self": "https://jira.sandboxapis.dev/rest/api/3/user?accountId=a01d9ade7d681f500bfb8ec4",
          "accountId": "a01d9ade7d681f500bfb8ec4",
          "accountType": "atlassian",
          "displayName": "Atropos",
          "active": true,
          "timeZone": "UTC",
          "avatarUrls": {
            "48x48": "https://jira.sandboxapis.dev/secure/useravatar?size=large&ownerId=a01d9ade7d681f500bfb8ec4",
            "24x24": "https://jira.sandboxapis.dev/secure/useravatar?size=small&ownerId=a01d9ade7d681f500bfb8ec4",
            "16x16": "https://jira.sandboxapis.dev/secure/useravatar?size=xsmall&ownerId=a01d9ade7d681f500bfb8ec4",
            "32x32": "https://jira.sandboxapis.dev/secure/useravatar?size=medium&ownerId=a01d9ade7d681f500bfb8ec4"
          }
        }
      }
    },
    {
      "id": "61963",
      "key": "ORCL-80",
      "self": "https://jira.sandboxapis.dev/rest/api/3/issue/61963",
      "fields": {
        "summary": "Rate limit counting requests twice",
        "status": {
          "self": "https://jira.sandboxapis.dev/rest/api/3/status/10004",
          "id": "10004",
          "name": "Done",
          "description": "",
          "statusCategory": {
            "self": "https://jira.sandboxapis.dev/rest/api/3/statuscategory/3",
            "id": 3,
            "key": "done",
            "colorName": "green",
            "name": "Done"
          }
        },
        "assignee": null
      }
    }
  ],
  "isLast": false,
  "nextPageToken": "bzoz"
}

04 / Pin a snapshot

Deterministic CI.

Same env-var swap, a *.snap. host — byte-identical on every request. Relative JQL dates (updated >= -30d) resolve against the snapshot's anchor, so polling loops are reproducible too.

.env
# reproducible in CI
export JIRA_HOST=https://jira-v3.snap.sandboxapis.dev

Tour the universe → · Coverage manifest → · Versioning & pinning →