Skip to main content

Imports

Settings → System → Imports shows every import file that has been submitted, what became of it, and what you can still do about it.

It is also where files are submitted from the app. What each file must contain is described in the bulk import guides for Organization, Planning, PPM and Product Management, and the same files can be posted straight to each area's import endpoint instead.

Importing a file​

Select Import, then choose what you are importing. The list is grouped by area — Organization, Planning, Project Portfolio Management (which includes strategic themes) and Product Management — and searching it matches import names. It holds only the kinds of import you are allowed to submit, and the button is hidden when there are none.

For the kind you choose, the dialog shows:

  • What the import does, and whether it is all-or-nothing, applied row by row, or applied group by group, with its row cap.
  • Every column the file must carry, whether a row may leave it empty, and what it accepts — a date, an id, or one of a fixed set of values such as a status. The file needs every header even where a cell is blank.
  • Download Template, a CSV holding just the header row, ready to fill in.

An import that takes more than one file — release packages and their manifest, releases and their contents, strategic initiatives and their KPIs — asks for each separately, and says which are optional.

The column lists come from the API's own description of each import, so they cannot drift from what the server reads.

Checking a file first​

Check File, next to Import, runs a preflight: every row goes through the same checks a real import runs, in the same order, against your data as it stands — and nothing is imported. Use it before any file you could not easily undo, such as a migration of history from another system.

A preflight answers what the file would do:

  • Each row's outcome. Rows that would be imported show as Passed, with any warning the import would record (an employee whose manager could not be found, say). Rows that would be refused show as Rejected, with the reason.
  • Every rejection at once. An all-or-nothing import stops at the first step that rejects a row, so fixing a file against it can take several attempts. A preflight carries the rows that passed on through the later steps, so the rejections from all of them show up together. Its status still says what the import would have done — Failed, saying the file would apply none of it until every rejected row is fixed — when any row is rejected.
  • Rows that depend on each other. A row that refers to another row in the same file — an employee whose manager is further down, a team that belongs to another — is checked against that row, exactly as the import would.

A preflight becomes a run like any other, marked Preflight in the list and on its page, with the same row filters and export. It creates no records, records no activity, sends nothing to other areas of Wayd, and does not use up any record numbers.

A preflight is advice, not a promise

It reports what would have happened when it ran. Someone can create a record with the same name, or remove one your file refers to, before you import. The import checks every row again, so it may still reject something the preflight passed.

When you are ready, Import File on the preflight's page imports exactly the rows it checked, without choosing the file again. Every row is included — the rejected ones too, as uploading the file again would — so fix the data those rows depend on first, or submit a corrected file instead. A preflight cannot be resumed or retried; it can be imported until its row data passes the 30-day retention window.

Once imported, the preflight's page says so and links to the import it became. Import File stays available, because that import may have failed for a reason you have since fixed, but it asks first: importing the same rows again rejects the records the first import created as duplicates, or — for an import with no natural key, such as deployments — creates them a second time.

Why a run exists at all​

Every file is handed to a background worker, and submitting waits a few seconds for it. A small file is usually finished by then, so you get its outcome straight away; a large one is still queued or running, so you are told it was accepted rather than finished. Either way the file becomes a run with its own page and a row in this list, so there is one place to look — the only difference is whether the run is already finished by the time you look.

Importing from within the app shows the outcome in the import dialog. A file that is still running takes you to its page, which follows it to the end; one that finished with rejected rows links there so you can see which and why.

What you see​

Each run shows the kind of import, who submitted it, when, and four counts:

CountMeaning
RowsLines in the submitted file.
AppliedRows the import finished with. These are never applied a second time.
RejectedRows that changed nothing, each with a reason.
Not AppliedRows the run did not finish, because it was stopped or failed partway. Some may be partly done — an employee created but not yet linked to their manager — and a resume carries them on from there.

Files submitted together show as one batch. A caller that posts several files under one submissionGroupId — the wayd-data seed does, and so does an export split to fit the row cap — gets a single collapsed row for the batch: "11 imports submitted together", with the rows, applied, rejected and not-applied counts summed across its files, and a status that is Succeeded only when every file's status is. The batch is dated by its newest file, so it sits where that file would in the list. Expand it to see the files themselves, each with its own actions. The Batch column carries the short form of the group id and filters like any other column; a file submitted on its own has none.

Open a run to go to its page, which shows each row's outcome and updates while the run is still going. It opens on the rejected rows when there are any, since that is usually why you came, and each carries the reason it was refused and the line it came from. The page lists up to 500 rows for each filter; a larger run says how many more there are. The page has its own address, so a run can be bookmarked or shared with someone who may see that kind of import. A run that was submitted as part of a batch lists the batch's other files under Submitted With, each with its status, so a seed or a split export can be walked file by file from any of them.

"0 of 40 applied" is not always a bug

Some imports are all-or-nothing — a team hierarchy, for instance, because half an imported hierarchy is worse than none. One rejected row in those means nothing is written. The run shows which import behaves this way.

Others apply group by group: every row for the same record goes in together or not at all, and the other groups are still imported. Every PPM import applies by the record its rows build — a project, or the project a task or stage belongs to — and every Product Management import but deployments applies by a product tree, a product, a package, a release or an environment; deployments apply row by row. The run says what a group is. A row kept out only because another row in its group was rejected says so — "Not applied: another row for the same … was rejected" — and names the row that was, so the fix is always to that one row. Retrying the failed rows puts the whole group through again.

Status​

StatusMeaning
QueuedAccepted, waiting for a worker.
ProcessingBeing applied now. Counts move as it goes.
StoppingA stop was requested; the worker finishes its current batch and stops.
SucceededEvery row applied.
Partially SucceededSome rows applied, some were rejected.
FailedNothing usable came of it — either every row was rejected, or the run could not continue.
CancelledStopped before it finished. Rows already applied stay applied.

What you can do​

Actions appear on a run only when they apply to it, and only if you may submit that kind of import. A preflight offers only Import File — see Checking a file first.

Stop a run that is still going. It is a request, not an undo: the worker stops at its next batch boundary, and rows already applied stay applied. The rest are left for a resume.

Resume a run that stopped partway to apply the rows it never reached. Rows that already succeeded are skipped.

Retry rejected rows once you have fixed whatever they were rejected for — a missing team, a name that did not resolve. Only the rejected rows are reattempted; successful ones are never reapplied, so this cannot duplicate them.

Both resume and retry report how many rows were queued, and how many could not be.

When a run fails unexpectedly​

Rejected rows are expected and are yours to fix. An unexpected failure — the database briefly unavailable, the server restarting mid-run — is handled for you. Wayd saves how far each row has got along with the work itself, so whatever picks a run up again carries on from there and never applies a row twice.

  • The run is tried again automatically, up to three attempts in all, each carrying on where the last one stopped. If every attempt fails, the run ends as Failed: rows it applied stay applied, its error carries a reference your administrator can find in the logs, and Resume picks up the rest once the cause is fixed.
  • If the worker disappears entirely, a maintenance job ends the run once it has gone quiet for 30 minutes, and republishes any run that has sat queued for 15. Resume carries an ended run on from where it stopped. That job is scheduled to run every five minutes by default; it appears in Settings → System → Background Jobs as import-stall-recovery, where its schedule can be changed. If it is deleted, it is scheduled again the next time the server starts.
Row data is kept for 30 days

Retrying re-applies the data you submitted, which is held for 30 days after a run finishes and then discarded — it is a copy of your file, and keeping it forever would mean holding that data forever. After that the run's history remains, but its rows can no longer be retried and the file must be submitted again. The job that discards them runs once a night by default; it appears in Settings → System → Background Jobs as import-retention-sweep, and like the recovery job above it is scheduled again on the next start if it is deleted.

Limits and rules​

The per-import row caps live in each area's bulk import guide. These rules apply to every file, whatever kind it is.

Submitting a file

RuleValue
Rows per file50,000 for an import applied row by row (employees) or group by group (product dependencies); 10,000 for an all-or-nothing import, which is one database transaction, and for the PPM imports and every other Product Management import, which apply group by group (deployments row by row) but keep the lower cap until a larger file has been proven. Over the cap, the file is rejected before anything is queued.
Request sizeAbout 30 MB, the web server's default. A 50,000-row file is a few megabytes.
Empty fileRejected: a file with no rows never becomes a run. A missing file returns 422.
ImportIdOptional. At most 128 characters, trimmed, and unique within the file compared case-insensitively (abc and ABC collide). Blank uses the row's position, counting from one.
submissionGroupIdOptional query parameter, any GUID you choose, recorded on the run. An empty GUID is rejected rather than filed as a group.
validateOnlyOptional query parameter on every import endpoint. true submits the file as a preflight. A preflight is capped at 10,000 rows wherever the import itself accepts more (employees), because it holds its database locks for the whole file instead of releasing them chunk by chunk the way a real run does; product dependencies are cheap enough per row to check 50,000 at a time. POST /api/imports/{id}/apply imports a finished preflight's rows for real and answers the same way a submission does.
The post's wait5 seconds by default (Imports:ResponseWaitSeconds). A run that finishes within it comes back 200; otherwise 202 with the run still queued or running and a Location to follow.

While a run is applied

RuleValue
ChunkingA row-by-row import saves every 500 rows and records progress after each chunk; a stop takes effect at the next chunk boundary. A group-by-group import does the same without ever splitting a group across two chunks, so a group larger than 500 rows is a chunk of its own. An all-or-nothing import saves once, at the end — as does a group-by-group import whose step needs the whole file at once (PPM finalize), which still keeps each group whole within that one save.
Automatic attempts3. An attempt that fails unexpectedly hands the run back to the queue, and the next carries on from the saved progress. After the third the run ends as Failed, and Resume takes it on from there.
Stalled runsA run queued for 15 minutes with no worker is republished; one with no progress for 30 minutes is failed so it can be resumed. Checked every five minutes by import-stall-recovery. A preflight records no progress until it finishes, so one that runs longer than 30 minutes is failed the same way — split the file.
RetentionSubmitted row data is discarded 30 days after a run finishes, nightly, by import-retention-sweep. The run and its per-row outcomes stay; the rows can no longer be retried.
ListingThe imports list and a run's row list each return at most 500 entries per request; a larger run says how many more there are.

Who sees what​

There is no single "imports" permission that grants the page. Being allowed to submit a kind of file is what entitles you to see how it went, so you see the import types you can submit — and nothing else. The menu entry appears only when there is at least one.

View Imports is a separate, optional grant for oversight: it shows every import type, including ones you cannot submit yourself, and it is read-only. Stopping, resuming or retrying a run changes the records that run created, so those still require the permission that gates submitting that kind of file.

You holdYou seeYou can act
Import EmployeesEmployee importsYes, on those
View Imports onlyEvery import typeNo
BothEverythingOnly the types you can submit

Two scheduled maintenance jobs act on runs listed here. Import Stall Recovery reclaims runs no worker will finish — re-queueing one whose message never arrived, and failing one that stopped reporting progress so its remaining rows can be resumed. Import Retention Sweep discards submitted row data once a run is more than 30 days old, keeping the run and its per-row outcomes. Both are scheduled by default — every five minutes and nightly — and both are configured under Settings → System → Background Jobs.