Skip to content

Example Use Cases

This section provides example scenarios that demonstrate how the integration can be used.

Use Case 1: Sapio looks up an existing study before submitting a sample

Background

Before Sapio can register work against a study, it needs to confirm the study already exists as a record in Sequencescape and retrieve its canonical identifiers (id, uuid). Sapio does not hold its own copy of study data — Sequencescape remains the system of record.

Objective

Retrieve the Sequencescape study record matching a given name, without Sapio needing to know anything about Sequencescape's underlying API or database.

Solution

Sapio calls the Sapio Studies API with the study name as a query parameter:

curl 'https://api.example.com/sapio/studies/v1?name=Genomic+variation' \
  --header 'Authorization: Bearer <access_token>'

The request passes through XAPI → PAPI → SAPI → Sequencescape, matching by name, and the response is flattened before it reaches Sapio:

{
  "data": [
    {
      "id": "225",
      "name": "Genomic variation in a global set of Salmonella Paratyphi A isolates",
      "uuid": "2b0754a0-a557-11df-8092-00144f01a414",
      "created_at": "2009-01-22T11:47:13+00:00",
      "updated_at": "2024-12-04T11:08:07+00:00",
      "blocked": false,
      "state": "active",
      "ethically_approved": null,
      "enforce_data_release": true,
      "enforce_accessioning": true
    }
  ]
}

Outcome

Sapio now has the study's Sequencescape id and uuid, and can proceed with downstream registration steps using those identifiers, without ever needing direct access to Sequencescape.


Use Case 2: Handling an invalid search request

Background

Sapio's integration code constructs the name query parameter dynamically, and occasionally sends a request with a missing or too-short value (for example, before a user has finished typing a search term).

Objective

Fail fast with a clear reason, rather than passing a malformed request through to Sequencescape.

Solution

The name parameter is validated by the XAPI layer before any downstream call is made. For example, a request with no name at all:

curl 'https://api.example.com/sapio/studies/v1' \
  --header 'Authorization: Bearer <access_token>'

is rejected immediately with 400 Bad Request and a name parameter is required validation message — Sequencescape and the internal PAPI/SAPI layers are never called. The same applies to a name shorter than 4 characters or longer than 50 characters.

Outcome

Sapio's integration can treat a 400 response as a client-side input problem to fix and retry.


Use Case 3: Sapio creates a new study

Background

A researcher registers a new study in Sapio. For that study to be usable elsewhere at Sanger, it needs a matching record in Sequencescape and in the sequencing data warehouse (MLWH) — without anyone re-entering the same details by hand in either system.

Objective

Create the study once, and have it propagate to Sequencescape and MLWH automatically, and receive a 201 Created response. Also, have a way to confirm it landed correctly.

Solution

Sapio submits the study's details:

curl -X POST 'https://api.example.com/sapio/studies/v1' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Covid Genomics Surveillance",
    "description": "Genomic surveillance of SARS-CoV-2 variants",
    "data_release_strategy": "open",
    "faculty_sponsor": "Dr. Jane Smith",
    "program": "Pathogen Genomics",
    "data_release_study_type": "genomic data",
    "type": "whole genome sequencing",
    "lims_id": "SAPIO",
    "study_id": "123456",
    "uuid": "2b0754a0-a557-11df-8092-00144f01a414"
  }'

The request is accepted straight away, before any of the downstream creation has actually happened:

{
  "event_uuid": "8f14e45f-ceea-467e-b1a1-9d8c1e2f4a3b"
}

A short time later, Sapio (or whoever is checking) can confirm the study exists by looking it up directly in Sequencescape, using the same GET /sapio/studies/v1 endpoint from Use Case 1:

curl 'https://api.example.com/sapio/studies/v1?name=Covid+Genomics+Surveillance' \
  --header 'Authorization: Bearer <access_token>'

Outcome

The study now exists in both Sequencescape and MLWH, created from a single submission — Sapio never needed to know how either of those systems stores study data.


Use Case 4: Sapio submits a study with an invalid or incomplete payload

Background

Sapio's integration code builds the request body from fields a researcher has filled in. Occasionally a required field is missing, has the wrong value, or the body includes something the schema doesn't recognise.

Objective

Reject a malformed submission immediately and clearly, rather than letting it fail partway through creating the study in some systems but not others.

Solution

A request missing the required uuid field, or using a data_release_strategy value outside open/managed/not applicable, is rejected with 400 Bad Request before anything is published for downstream processing — no partial creation happens in Sequencescape or MLWH.

Outcome

Sapio's integration can treat a 400 the same way it does for the GET endpoint: a client-side problem to fix and retry, with no cleanup needed on the Hub side since nothing was created.


Use Case 5: A downstream failure is automatically reported

Background

A study submission passes validation and is accepted, but Sequencescape rejects it later — for example, because a study with that name already exists.

Objective

Make sure this failure doesn't go unnoticed just because it happened after Sapio already received its 202.

Solution

When Sequencescape (or MLWH, or the final confirmation back to Sapio) fails, the Hub automatically sends an email alert to the relevant team, without anyone needing to be actively watching for it. The tracking ID from the original submission can be used to look up which stage failed:

curl 'https://api.example.com/sapio/studies_status/v1?event_uuid=8f14e45f-ceea-467e-b1a1-9d8c1e2f4a3b' \
  --header 'Authorization: Bearer <access_token>'

Outcome

The failure is caught and surfaced automatically — Sapio's integration doesn't need to implement its own polling-and-alerting logic on top of this API to know something needs attention.