Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ekso.dev/llms.txt

Use this file to discover all available pages before exploring further.

ekso migrate jira pulls projects, issues, comments, worklogs, attachments, and links from Atlassian Jira (Cloud) into your Ekso tenant. Two commands — collect and apply. Read Migrate overview and Before you start first.

What gets imported

Jira conceptEkso shape
ProjectDataContainer (Code = ACME, Name = ACME Platform)
Issue (any type — Bug, Task, Story, Epic)DataItem
CommentDataAnnotation
AttachmentDataFile (multipart upload)
WorklogDataItem.Time[] (in the same item POST)
Issue link (relates, blocks, subtask, …)DataLink
Sprint (GreenHopper)DataCycle
Fix VersionDataCycle
ComponentConfigLabel (prefix component:) + item Tags
User (assignee, reporter, commenter)DataUser (matched or minted)
Story Points custom fieldDataItem.Field[] (via --field-map)
Other custom fieldsDataItem.Field[] (via --field-map) or Meta
Affects VersionDataItem.Meta.jira_affects_versions[] (lossless)
Authoring fidelity is preserved: every comment, every worklog, every item is attributed to the original Atlassian user (matched by email, or minted via identity resolution).

What does NOT get imported

  • Workflow definitions / transition rules. The migrator snapshots the current status of each issue. Build the workflow on the Ekso side.
  • Dashboards, filters, JQL queries. Migrate operationally, then re-author in Ekso.
  • Automations (Jira Automation rules). Re-author as Ekso rules.
  • Permission schemes / project roles. Configure access on the Ekso side.
  • Brand customisation, themes, project icons. Atlassian-specific.

Before you start

Pre-flight checklist on top of the general one:
  • An Atlassian account with read access to the projects you want to migrate.
  • An Atlassian API token (free).
  • Your Atlassian site URL — e.g. https://acme.atlassian.net.
Add a jira block to your migration.config.json:
{
  "ekso": { "tenant": "acme", "apiKey": "ek_live_..." },

  "source": "jira",

  "jira": {
    "url": "https://acme.atlassian.net",
    "username": "[email protected]",
    "apiToken": "ATATT3..."
  }
}
Or use the env-var override EKSO_MIGRATE_JIRA_TOKEN for CI use cases.

Step 1 — list projects

Verify your credentials work and see what Jira shows you:
ekso migrate jira list-projects \
    --config migration.config.json \
    --tenant acme
Sample output:
NAME              KEY    ID       LEAD
ACME Platform     ACME   10001    Jane Doe
ACME Mobile       ACMEM  10002    John Smith
If this exits with code 3, your Atlassian credentials are wrong — check the API token. Pass --exclude-closed to filter projects in archived state.

Step 2 — collect

Pull a single project’s issues, comments, worklogs, and attachments into a local SQLite cache:
ekso migrate jira collect \
    --config migration.config.json \
    --project ACME \
    --tenant acme
Repeat --project for multiple. Sample run:
fetching projects... 1 fetched
fetching ACME items... 1247/1247  ok
fetching comments... 4083/4083  ok
fetching worklogs... 891/891  ok
fetching attachments... 312/312  ok
saved cache: ~/.ekso/migrate/jira-2026-04-29T143205.sqlite
Useful flags:
  • --no-attachments — skip binary download. ~10x faster on attachment-heavy projects.
  • --no-comments — skip comments.
  • --exclude-closed — JQL-filter out resolved issues at the source.
  • --resume — pick up where a killed collect left off.
Expect roughly 200 issues/minute on a good network. A 10,000-issue project takes ~50 minutes including comments and attachments.

Step 3 — dry-run apply

Before writing anything to your Ekso tenant, walk the cache and see what would happen:
ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --tenant acme \
    --dry-run
Sample output:
DRY-RUN — no writes.
would create:  1 container, 47 users, 1247 items, 4083 annotations,
               312 files, 89 links, 8 cycles
field-map check: ok (3 process fields would be auto-created)
If field-map check fails (e.g. picker without a value list), exit code is 2 and apply won’t run for real until you fix the YAML.

Step 4 — apply for real

ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --tenant acme
Sample run:
applying container ACME...               ok
applying users (47)...                   ok (45 created, 2 matched)
applying items (1247)...                 ok (1247 created)
applying annotations (4083)...           ok
applying files (312)...                  ok
applying links (89)...                   ok
applying cycles (8)...                   ok (5 sprints, 3 fix-versions)
done in 7m43s — exit 0
If the run is interrupted, re-run with --resume:
ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --resume

Identity resolution for Jira

Atlassian users have email — --user-strategy match-or-create (the default) is reliable. Source authors are matched against your Ekso tenant; users without a match are minted with no invite email. Read Identity resolution for the full mechanics.

Custom fields for Jira

Story Points, Sprint, custom Severity — these are Jira customfield_* fields. Map them to Ekso process fields with a migration.fields.yaml:
jira:
  customfield_10026: { ekso: StoryPoints, kind: decimal }
  customfield_10018: { ekso: Sprint,      kind: text }
  customfield_10031:
    ekso: Severity
    kind: picker
    picker:
      Critical: P0
      High:     P1
      Medium:   P2
      Low:      P3
Pass it to apply:
ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --field-map migration.fields.yaml
ProcessFieldApplier runs first; any field referenced by the YAML that doesn’t exist on proc_engineering is auto-created via POST /api/field before any item write. See Field mapping for the full format and how to discover your custom-field IDs. Without --field-map, custom fields fall through to DataItem.Meta losslessly (e.g. Meta.jira_customfield_10026).

Sprints, Fix Versions, Components

Per the migrator’s design, every Jira concept maps. There are no opt-in flags:
JiraEkso
Sprint (GreenHopper)DataCycle (one cycle per sprint, items linked)
Fix VersionDataCycle (sprint-shaped: name + dates + member items)
Affects VersionDataItem.Meta.jira_affects_versions[]
ComponentConfigLabel (component:Backend) + DataItem.Tags
Release (a closed Fix Version)DataCycle
Cycles attach to a board on the Ekso side. Pass --board <BOARD_ID> if the tenant has more than one board; the CLI auto-discovers when there’s exactly one.

Issue type → Process

Multiple Jira issue types (Bug, Task, Story, Epic) feed into a single Ekso DataProcess per apply invocation. The mapping is one-way; the issue type is preserved in DataItem.Meta.jira_issuetype. If you need separate processes per issue type, run apply multiple times with different --process values and JQL-filtered caches.

Iron rule — Atlassian’s date format

Jira returns timestamps in the form 2024-08-21T16:33:21.000+0000 — note the +0000 offset has no colon. The standard .NET DateTime parser trips on this. The CLI’s JiraDateTimeNormaliser handles it correctly, and there’s a regression test pinning the behaviour. If you ever see “Date format unparseable” in apply output, the cache was generated by an older CLI version. Re-collect with the latest CLI.

Troubleshooting Jira-specific issues

SymptomFix
exit 3 — Jira credentials invalidRegenerate the API token. Check the email matches the token owner.
exit 7 — Jira rate-limit exceededWait a few minutes; Atlassian’s rate limits are per-tenant. Re-run with --resume.
Item created with empty bodyAtlassian returned no rendered HTML for an ADF description. Original ADF is preserved in Meta.jira_description_html.
Custom field unknown to field-mapCheck the customfield_* ID exists on this Jira tenant.
See Troubleshooting for the full per-source error table.

Why migrate to Ekso

Once you’ve moved a Jira project to Ekso, you get financial intelligence (cost / profitability) and AI-native primitives (MCP) that don’t exist on the Jira side. See Ekso vs Jira for the broader comparison.

Where to next