Source platforms have custom fields. Ekso has process fields. The migrator bridges the two with aDocumentation Index
Fetch the complete documentation index at: https://ekso.dev/llms.txt
Use this file to discover all available pages before exploring further.
migration.fields.yaml file you author by hand.
This page is the canonical format reference. Per-source pages link here for examples specific to each source.
What this solves
Every issue tracker has its own custom-field model:- Jira uses
customfield_10026numeric IDs that vary per tenant. - Linear has a single first-class
estimatedecimal. - Azure DevOps uses
Custom.<FieldName>reference names. - Zendesk has typed
ticket_fieldIDs. - Gemini has named custom fields.
DataItem.Meta losslessly — the data is preserved, but not searchable or filterable as a real field. With a field map, each source field maps to an Ekso process field that is searchable, filterable, and editable like any other field.
How auto-create works
When you runapply --field-map migration.fields.yaml, the Apply layer’s ProcessFieldApplier runs before any item writes:
- It reads your YAML.
- For each entry, it queries the destination
DataProcess(the one you passed to--process) for fields with that name. - If the field exists, it’s a no-op.
- If the field doesn’t exist, it calls
POST /api/fieldto create it on the process. The field’skind(text / decimal / picker / toggle) and any picker values come from the YAML. - If field creation fails (permission denied, validation error),
applyexits with code6before writing any items.
apply succeeds, your destination process has every field your YAML promised, populated with the source-platform values. You can audit and remove fields post-migration via the admin UI.
YAML format
jira, linear, devops, zendesk, gemini. The migrator reads only the section matching the source you’re migrating.
Field kinds
kind | Stores | Example source fields |
|---|---|---|
text | Free-form string | Jira sprint name, Linear project label |
decimal | Numeric value | Story points, estimates, custom durations |
picker | One value from a fixed list | Severity, Risk, Phase |
toggle | True / false | ”Has-PR-attached”, “Customer-facing” |
text example
Sprint on the destination process if it doesn’t exist, then writes the source value into it on every item.
decimal example
StoryPoints field — handy when you’re consolidating multiple sources into one Ekso tenant.
picker example
Picker fields are the most expressive. Map source values to Ekso picker values explicitly:
Severity picker field on the process with the four destination values (P0, P1, P2, P3), then maps each Jira severity to its Ekso counterpart on every item. Source values not in the picker mapping fall back to DataItem.Meta.
toggle example
has_attachments boolean becomes an Ekso toggle field. Source values of true / 1 / "yes" / "true" (case-insensitive) become Ekso true; everything else becomes false.
Worked examples per source
Jira
customfield_10026), or via the REST API:
Linear
estimate field is the only thing most teams need to map. Custom fields beyond that are uncommon on Linear.
Azure DevOps
Zendesk
Gemini
dbo.IssueCustomFields; API mode pulls them from the issue payload.
Without a field map
You can runapply without --field-map. Source custom fields fall through to DataItem.Meta losslessly. Each source field becomes a Meta key prefixed with the source name (e.g. Meta.jira_customfield_10026 = "5"). This is fine for archival migrations where the destination process schema doesn’t matter. For active use, write the YAML.
What gets created on the destination process
Afterapply runs with a field map, your destination process has:
- A new field for every entry in the YAML (created if it didn’t already exist).
- Every item populated with values from the source field.
Failure modes
| Situation | Behaviour |
|---|---|
| YAML references a kind the migrator doesn’t support | exit 2 (usage error) before any work happens |
picker field with no picker: value list | exit 6 (validation) — picker fields need values |
| Field creation fails (permission denied) | exit 4 (forbidden), no items written |
| Source value doesn’t match any picker value | the source value is preserved in Meta, the item field is left null, and apply continues |
| Decimal field gets a non-numeric source value | Meta fallback for that item, warn at end |
Where to next
- Identity resolution — author mapping.
- Command reference — every flag.
- Troubleshooting — exit codes.