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.