For the complete documentation index, see llms.txt. This page is also available as Markdown.

Plan a Run via the API

This guide shows you how to use the Run Planning API programmatically — to plan sequencing runs, manage their content, and generate sample sheets without going through the BaseSpace Sequence Hub UI.

Status of this guide: This is the first published cut. It covers the most common starting workflow — get a token, discover catalog IDs, create a planned run, revise it, and generate the sample sheet. We will expand it over time to cover additional endpoints (sample-sheet validation, library / library pool management, analysis configuration templates, run lifecycle, etc.). For the complete endpoint list, see the API Reference link below.


In this guide


Prerequisites

  • An Illumina Platform API Key. See Generate an API Key for instructions on creating one. You can use the same API key you use for ICA / the CLI.

  • Your workgroup ID, if you want the token to be scoped to a specific workgroup (recommended for shared resources). See Workgroup ID below.

  • The base hostname for the regional Illumina Platform gateway your enterprise lives on. The platform is deployed regionally — see BaseSpace Sequence Hub Global Regions for the list of available regions. The hostname you need is not the same as the BaseSpace URLs shown on that page; contact your Illumina representative or support team to obtain it for your enterprise.


About the example code

The examples below use Python with the requests library, but you can use any HTTP client (curl, Postman, etc.). Install Python from https://www.python.org/ and install requests with pip install requests. The inline examples omit timeout= for readability; production scripts should set an explicit timeout on each call to avoid hanging on network issues.


Authenticating

Every call must carry an Illumina Platform JWT in the Authorization header:

To obtain this JWT, call the User Token Provider endpoint. It accepts your Illumina Platform API Key and returns a JWT that the Run Planning API will accept.

Note: This token-exchange flow is specific to the Run Planning API. Other Illumina services (e.g. ICA) have their own authentication flows — see their respective documentation.

Get a token

POST <platform-base>/v1/users/tokenProvider:createToken

Header
Value

X-API-Key

Your raw Illumina Platform API Key. Do not Base64-encode it — the server handles that internally.

Content-Type

application/json

The body is optional. An empty {} works for most cases. The most useful query parameter is cwid — see Workgroup ID below.

A successful response is HTTP 201 Created with:

Pass access_token to every API call as Authorization: Bearer <access_token>.

Scopes

The token will carry the scopes your user is permitted to receive — typically gss.config.* (read-only resource catalog) and gss.sequencing.* (planned runs, samples, libraries, etc.). The example workflow below requires:

  • gss.sequencing.create — to create the planned run

  • gss.sequencing.update — to replace it

  • gss.sequencing.read — to generate the sample sheet

Scope matching is case-insensitive, so the casing of the strings in the JWT does not need to match exactly.

Token lifetime

Tokens are long-lived (currently 7 days; subject to change without notice). Cache the token across calls and only call :createToken again when the token is close to expiry or after a 401 response.

Workgroup ID

Most resources in the Illumina platform — projects, sequencing runs, samples, libraries — belong to a workgroup. A user can belong to multiple workgroups; the workgroup the token is issued for determines which resources the token can see and act on.

  • Where to find it: In the Illumina Platform UI, switch to the workgroup you want to use, then look in the URL or your user profile menu for the workgroup ID (a GUID).

  • If you omit it: The token is issued in your personal context. Resources you create are owned by you (only you can read them) but workgroup-shared resources (which is most production data) will not be visible.

  • Recommendation: Set cwid to the workgroup that owns the planned runs you intend to manage.


API Reference

The complete, always-up-to-date list of endpoints is available as an interactive Swagger UI hosted alongside the API. The exact URL depends on your region, and follows this pattern:

The raw OpenAPI specification is at <platform-base>/gss/swagger/v1/swagger.json. Use Swagger to look up request and response schemas, error codes, and endpoints not yet covered in this guide. Your Illumina representative can provide the exact <platform-base> for your region.

Swagger's Authorize button accepts the JWT obtained in the previous section.


Discovering catalog IDs

The create / replace examples below reference an analysis version definition (AVD) ID and, for genome-aware analyses, a genome ID. You discover them with GET calls before your first :plan.

GSS distinguishes between an analysis definition (AD) — an analysis family such as "BCL Convert" or "DRAGEN Germline" — and an analysis version definition (AVD) — a specific version of that analysis. The :plan payload references AVD IDs, not AD IDs.

Analysis definitions (pipelines)

Required scope for all calls in this subsection: gss.config.read.

List analysis definitions

GET <platform-base>/v1/sequencing/analysisdefinitions

Returns a paginated list of analysis pipelines accessible to the request token. Useful for finding the AD ID of an analysis(e.g. DRAGEN Germline) before drilling into its versions.

Get a single analysis definition

GET <platform-base>/v1/sequencing/analysisdefinitions/{analysisDefinitionId}?Include=AnalysisVersions

Returns details for a single AD and its associated versions

Analysis version definitions

Required scope for all calls in this subsection: gss.config.read.

Get a single AVD by ID

GET <platform-base>/v1/sequencing/analysisdefinitions/versions/{analysisVersionDefinitionId}

Returns the full definition of a single AVD and the following table shows optional Include query flags:

Flag
Effect

CompatibleLibraryPrepKits

Inline the LPKs that are compatible (and any that are explicitly excluded)

CompatibleGenomes

Inline the supported and excluded genomes

JavascriptFunctions

Inline the associated JavaScript functions (onSubmit, onRender, etc.)

CompatibleBclConvertVersions

Inline the BCL Convert versions compatible with this AVD. Requires InstrumentPlatform or InstrumentType as an additional query parameter; the API returns 400 Bad Request if it is missing

Settings in the response

Each AVD response contains three top-level setting fields. The tables below provide further details of these settings and their respective child fields.

Field
What it controls

analysisSettings.fields[]

Analysis-level settings (apply to all samples)

analysisSampleSettings.fields[]

Per-sample settings

runContentSettings.fields[]

Per-library / lane settings consumed by the analysis

Each entry inside fields[] has the following properties (the most relevant ones for an integrator):

Property
Description

id

The setting key. This is what you use as the JSON key when sending settings back to :plan / PUT .../plan.

type

One of textbox, checkbox, radio, select, genome, number, integer, custom, file, fileSelect, section, text, date, referenceFile, sample, fieldgroup

label

Human-readable display name (used by the UI; not a valid settings key)

value

The default value, if any

required

Whether the setting is mandatory

For BCL Convert, sending an empty settings: {} is supported and produces a working sample sheet for the typical default configuration.

Genomes

Required scope: gss.config.read.

For analyses that use reference genomes (e.g. DRAGEN Germline), the ReferenceGenomeDir setting takes a Genome ID (e.g. gen.85b1459dde1c41cca064110602xxxxx) that you can extract from the list of genome objects via:

GET <platform-base>/v1/sequencing/genomes

See Swagger for the full schema and filtering options. There is also GET /v1/sequencing/genomes/{genomeId} for a single-genome lookup once you have the ID.

Library prep kits and index adapter kits

Required scope: gss.config.read.

Looking up a Library Prep Kit (LPK) or Index Adapter Kit (IAK) is an advanced step. The first runnable example below omits all kit fields, which is supported and produces a valid sample sheet. Once you have a working basic flow, see Swagger for:

  • GET /v1/sequencing/libraryPrepKits (camelCase path segment)

  • GET /v1/sequencing/indexadapterkits (all-lowercase path segment)

Note on URL casing. The casing asymmetry between libraryPrepKits and indexadapterkits is intentional and matches the routes registered in the API — it is not a typo. Make sure your client preserves the exact casing.


Combined example — plan a sequencing run end to end

The remainder of this guide walks through a single workflow: create a planned run, revise it, and generate the sample sheet.

1. Create a planned run

POST <platform-base>/v1/sequencing/runs:plan

Required scope: gss.sequencing.create

This endpoint creates a new planned run in the Draft/Planned state, based on the isDraft flag provided in the payload. When a run is in Planned state, an operator will be able to select it from the sequencer to start the sequencing.

The example below uses BCL Convert + DRAGEN Germline with two samples. It uses "Not Specified" Library Prep Kit and "Not Specified" Index Adapter Kit, so you can run it without first looking up kit IDs. The only placeholders you must fill in are the two AVD IDs and the Genome ID — see Discovering catalog IDs.

A successful response is HTTP 201 Created with the full sequencing-run resource. Save its id — you will need it for the next steps.

Important — isDraft and run visibility on the sequencer. Only runs that are saved as Planned (isDraft: false) are surfaced on the sequencer for an operator to select and start. A Draft run (isDraft: true) is persisted on the server but will not appear on the sequencer. For an end-to-end create → sequencer → sequence flow, always send isDraft: false.

2. Replace a planned run

PUT <platform-base>/v1/sequencing/runs/{runId}/plan

Required scope: gss.sequencing.update

Use this when you need to update an existing planned run. The body has the same shape as create, and PUT semantics apply: the run is fully replaced by what you send. Anything you omit (or send as an empty array) is removed.

The example below mirrors the create example but changes the description and flips Sample_002's VariantCallingMode from SmallVariantCaller to AllVariantCallers.

Notes on PUT semantics:

  • Full replace. runConfiguration, runContents, and runAnalysisConfigurations are each replaced by the value you send. To remove an analysis configuration, send the list without it; to keep one unchanged, re-send it as-is.

  • isDraft: false saves the run as Planned and runs full validation. Same behavior as POST :plan, and what makes the run visible to the sequencer.

  • You cannot replace a run that has moved past planning (started, locked, or no longer planned).

3. Generate the sample sheet

POST <platform-base>/v1/sequencing/runs/{runId}:generateSampleSheet

Required scope: gss.sequencing.read

Generates a Sample Sheet CSV (and optionally a structured JSON) from the planned run identified by {runId} in the path. The run configuration, run contents, and analysis configurations are taken from the saved run — you do not resend them in the body. This is the same sample sheet the sequencer will execute, so it is the authoritative artifact for downstream tooling.

The body has only two optional fields:

Field
Type
Meaning

getSampleSheetSnapshotIfExisted

bool

If true and a sample sheet has already been snapshotted for a launched local-analysis run, return that snapshot instead of regenerating

include

array of strings

Extra content to include in the response (see table below)

The include flags let you control what comes back:

Flag
Effect

IncludeJsonFormat

Adds a sampleSheetConfig field with a structured JSON representation of the CSV. Omitted by default.

IncludeFileReferences

Adds a fileReferences array with resolved paths to genomes, reference files, etc. Omitted by default.

IncludeAnalysisReferenceInfo

Populates the analysisReferenceInfos[].downloadableReferenceFiles / nameBasedGenomeInfos / nameBasedReferenceFileInfos arrays. The analysisReferenceInfos[] outer array is always present (one entry per analysis configuration); these inner arrays are populated only when the run uses non-cloud reference files.

IncludeNotMappedFields

Includes analysis fields that are not formally mapped (rare; for advanced workflows)

Use this endpoint to retrieve the sample sheet for a planned run. However, please note that run execution itself does not require calling this endpoint: once a planned run is created, the sequencer fetches the run, and the operator selects it on the sequencer to start the sequencing.


What you'll see in the generated sample sheet

The generated CSV contains content the API auto-populates — you do not (and cannot) supply it in the request. Knowing this avoids surprise during downstream parsing. Below is the actual CSV produced by running the create / generate example above (BCL Convert + DRAGEN Germline, two samples with different variant-calling modes per sample):

Please refer to this GUIDE, if you wish to learn more about our Sample Sheet structure.


Naming and value constraints

The fields below are validated with regular expressions. Common values like sample IDs containing periods or descriptions containing commas will be rejected with 400 Bad Request — validate your inputs before sending.

Field
Allowed

runConfiguration.runName

alphanumeric, _, -, ., space; must start with alphanumeric / _ / -; no trailing whitespace

runConfiguration.description

any character except , * " '; also avoid [ ]

laneLibraries[].sampleName

alphanumeric, _, - only

laneLibraries[].index1Sequence / index2Sequence

A, G, C, T only (uppercase)

laneLibraries[].adapterSequence* (lane- and library-level)

A, G, C, T, +


Troubleshooting

Errors are grouped by the endpoint that returned them.

POST /v1/users/tokenProvider:createToken (Get a token)

Status & message
Cause
Fix

401 Unauthorized — Either X-API-Key header or Authorization header must be provided

None of X-API-Key, Authorization, or the psToken cookie were sent.

Send X-API-Key: <your-raw-api-key> (do not Base64-encode it), or send Authorization: Bearer <psToken> / Basic <base64(username:password)>.

401 Unauthorized — Invalid authorization header format. Expected 'Bearer <token>' or 'Basic <credentials>'

An Authorization header was sent but not in the expected Bearer … / Basic … form.

Fix the header format. For API-key auth use X-API-Key instead — do not put the API key in Authorization.

409 Conflict — Platform Auth request failed. (response details carries Platform Auth's errorCode / message)

Platform Auth rejected the credentials or could not be reached. Common causes: invalid or expired API key; cwid doesn't belong to a workgroup the user is a member of; the user lacks the permissions required for the scopes IMS requests; Platform Auth is unavailable.

Inspect the details.errorCode / details.message returned in the response. Generate a new API key if it's invalid/expired, confirm the cwid is one your user is a member of, and contact your Illumina representative if the user is missing required permissions.

POST /v1/sequencing/runs:plan (Create a planned run)

Status
Cause
Fix

400 Bad Request — does not match regular expression …

A field failed regex validation. Most common: sampleName / libraryName with periods or spaces; index1Sequence / index2Sequence outside A/G/C/T; description containing , * " ' [ ].

Sanitize input. See Naming and value constraints.

401 Unauthorized

JWT is missing, expired, or malformed.

Re-fetch a token via :createToken.

403 Forbidden — (message contains a scope name)

Token lacks gss.sequencing.create, or cwid does not match the workgroup that owns the referenced resources.

Confirm the token's scopes; reissue the token under the correct workgroup.

409 Conflict — One or more unknown settings found: <ids>

A label was sent as a settings key, or an id not defined on the AVD was used.

Use the AVD's field ids (e.g. ReferenceGenomeDir, VariantCallingMode), not the labels. See Discovering catalog IDs.

409 Conflict — Failed BCL Convert data validation check: …

The run failed sample-sheet validation. Common reasons: insufficient index distance between samples, illegal characters in free-text fields (e.g. [, ], tabs in runName, description, sampleName), or inconsistent OverrideCycles / kit settings across libraries on the same lane.

Read the message after the colon — it pinpoints the exact issue.

409 Conflict (other)

Strict validation failed — typically index collisions across libraries on the same lane, kit incompatibility, or cycle counts inconsistent with the read type.

Inspect error details for more information.

PUT /v1/sequencing/runs/{runId}/plan (Replace a planned run)

All errors from create also apply. In addition:

Status
Cause
Fix

403 Forbidden

Token lacks gss.sequencingruns.update (or the parent gss.sequencing.update).

Reissue with the correct scope and / or workgroup.

404 Not Found / 410 Gone

runId doesn't exist (404) or the run was deleted (410).

Verify the run id; deleted runs surface as 410, not 404.

409 Conflict — run is not editable

Run has progressed past planning. Specific error codes: SequencingRunStarted (sequencing has begun), PlannedRunLocked (claimed by a sequencer), SequencingRunNotPlanned (IsPlanned == false).

Replace is allowed while the run was created via run planning (draft or planned), sequencing hasn't started.

POST /v1/sequencing/runs/{runId}:generateSampleSheet (Generate the sample sheet)

Status & message
Cause
Fix

401 Unauthorized

JWT is missing, expired, or malformed.

Re-fetch a token via :createToken.

403 Forbidden — Required scope ...

Token lacks gss.sequencing.read, or cwid does not match the workgroup that owns the run.

Reissue the token with the correct scope and / or workgroup.

404 Not Found

The {runId} does not exist or is not visible in the current workgroup.

Verify the run ID and that the token's cwid matches the workgroup that owns the run.

409 Conflict — <resource> resource '<urn>' is either not found or inaccessible. / Failed to retrieve reference file(s)

A genome, reference file, or other resource the run depends on is no longer accessible to the caller (deleted, moved, or outside the workgroup the token is scoped to).

Confirm the resource ids in the run are still valid and that the workgroup the token represents has access. If a resource was removed, point the run at a replacement via PUT :plan before generating the sample sheet.


Need an endpoint that's not covered yet? Use the API Reference and let us know which workflows you need documented next.

Last updated

Was this helpful?