Overview
Welcome to the GalateaBio Ancestry API!
You can use our API to access GalateaBio Ancestry API endpoints.
| Environment | API URL |
|---|---|
| Prod | https://api.galatea.bio/api/v1 |
| Sandbox | https://api.sandbox.galatea.bio/api/v1 |
API reference
References for API endpoints with descriptions and usage examples.
Recipes
Recipes for common operations.
API reference
GalateaBio Ancestry API endpoints.
API authorization endpoints
| Method | Endpoint | Reference |
|---|---|---|
| POST | users/auth | Login |
| POST | users/logout | Logout |
| POST | users/refresh | Refresh token |
API endpoints for working with user profile
| Method | Endpoint | Reference |
|---|---|---|
| GET | users/me | Info about you and your organization |
API endpoints for working with source and result files
| Method | Endpoint | Reference |
|---|---|---|
| GET | data/files | List files |
| GET | data/results/{order_id}/download | Get result file |
| GET | data/results/{order_id}/json | Get result json |
| POST | data/files/upload | Upload file |
| DELETE | data/files/{source_file_id} | Delete file |
API endpoints for working with execution orders
| Method | Endpoint | Reference |
|---|---|---|
| GET | exec/orders | List orders |
| GET | exec/orders?{params} | Order details |
| POST | exec/orders | Submit order |
| PATCH | exec/orders/{order_id} | Update order |
| POST | exec/cancel | Cancel order |
| GET | exec/tags | List tags |
| GET | exec/tags/{tag_id} | Get tag |
| POST | exec/tags | Create tag |
| PUT | exec/tags/{tag_id} | Edit tag |
| DELETE | exec/tags/{tag_id} | Delete tag |
Auth
GalateaBio Ancestry API Auth endpoints.
| Method | Endpoint | Reference |
|---|---|---|
| POST | users/auth | Login |
| POST | users/logout | Logout |
| POST | users/refresh | Refresh token |
POST users/auth
Use this code to obtain access token via API:
import requests
url = "https://api.dev.galatea.bio/api/v1/users/auth"
payload = {
"email": "[email protected]",
"password": "Your_password"
}
headers = {
"content-type": "application/json",
"accept": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
# authentication with API key
base_url = "https://api.dev.galatea.bio"
api_key = 'Octopod API Key'
octopod_client = OctopodClient(base_url=base_url, api_key=api_key)
# authentication with username and password
base_url = "https://api.dev.galatea.bio"
auth_json = OctopodClient.authenticate(
username='[email protected]',
password='Your_password',
base_url=base_url,
)
api_key = auth_json.get('access') # fetched api_key has short lifetime!
octopod_client = OctopodClient(base_url=base_url, api_key=api_key)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/users/auth' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"email": "[email protected]",
"password": "Your_password"
}'
# authentication with API key
octo set-config \
--api_mode=1 \
--api_base_url="https://api.dev.galatea.bio" \
--api_key="<api_key>"
# authentication with username and password
octo set-config \
--api_mode=2 \
--api_base_url="https://api.dev.galatea.bio" \
--api_username="[email protected]" \
--api_password="Your_password"
Make sure to replace
[email protected]andYour_passwordwith your personal credentials.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"refresh": "refresh_token",
"access": "access_token",
"websocket_access": "websocket_access_token"
}
Endpoint for getting personal API access token.
POST users/logout
Use this code to logout via API:
import requests
url = "https://api.dev.galatea.bio/api/v1/users/logout"
payload = {
"refresh": "<<refresh_token>>"
}
headers = {
"content-type": "application/json",
"accept": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/users/logout' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"refresh": "<<refresh_token>>"
}'
The above command returns HTTP CODE 200 on success logout.
Endpoint for log out, requires refresh_token from Authentication step.
POST users/refresh
Use this code to renew access and refresh tokens via API:
import requests
url = "https://api.dev.galatea.bio/api/v1/users/refresh"
payload = {
"refresh": "<<refresh_token>>",
"access": "<<access_token>>"
}
headers = {
"content-type": "application/json",
"accept": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/users/refresh' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"refresh": "<<refresh_token>>",
"access": "<<access_token>>"
}'
The above command returns JSON:
{
"refresh": "refresh_token",
"access": "access_token"
}
Endpoint for renewing auth tokens, requires refresh_token from Authentication step.
Users
GalateaBio Ancestry API Users endpoints.
| Method | Endpoint | Reference |
|---|---|---|
| GET | users/me | Info about you |
GET users/me
Use this code to get information about your profile via API:
import requests
url = "https://api.dev.galatea.bio/api/v1/users/me"
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.text)
octopod_client.organization_api.get_organization_info()
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1/users/me' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
octo get-organization-info
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"id": "11111111-1111-1111-1111-111111111111",
"email": "[email protected]",
"first_name": "First Name",
"last_name": "Last Name",
"role": "OrgUser",
"is_active": true,
"created_at": "2023-05-10T10:17:49.344128Z",
"deleted_at": null,
"updated_at": "2025-07-09T10:36:44.174576Z",
"org": {
"id": "12332112-3321-2233-1122-123432345648",
"name": "Organization name",
"domains": [
"example.com",
"example-second.com"
],
"available_models": [
"ancestry data model one",
"ancestry data model two",
"ancestry pdf model",
"prs ruo model",
"prs clinical model",
],
"webhooks_enabled": true,
"webhooks_secret": "e2Bib57PYkkTFCs7utEfSZd6yGZCmGYX",
"report_ancestry_enabled": true,
"report_prs_ruo_cardio_enabled": true,
"report_prs_ruo_cancer_enabled": true,
"report_prs_clinical_cardio_enabled": true,
"report_prs_clinical_cancer_enabled": true
}
}
Endpoint for getting information about your profile.
It includes information about your organization and available execution models.
Data
GalateaBio Ancestry API Data endpoints.
| Method | Endpoint | Reference |
|---|---|---|
| GET | data/files | List files |
| GET | data/results/{order_id}/download | Get result file |
| GET | data/results/{order_id}/json | Get result json |
| GET | data/results/{order_id}/pdf_report | Get PDF reports list |
| POST | data/files/upload | Upload file |
| DELETE | data/files/{source_file_id} | Delete file |
GET Source files
Use this code to get list of source files via API:
import requests
file_name = 'filename.txt.zip' # or file_id
url = f"https://api.dev.galatea.bio/api/v1/data/files?file={file_name}"
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.text)
file_name = 'filename.txt.zip' # or file_id
files_objs = octopod_client.file_api.list_files(**{'file': file_name})
if files_objs.get('count', 0) > 0:
file_id = files_objs.get('results', [])[0].get('id')
file_obj = octopod_client.file_api.find_file_by_id(file_id)
file_name='filename.txt.zip' # or file_id
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1/data/files?file=${file_name}' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
octo find-file --file_id="<file_id>"
octo find-file --file_name="<file_name>"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"count": 2,
"next": "https://api.dev.galatea.bio/api/v1/data/files?page=2",
"previous": null,
"results": [
{
"id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"status": "VALID",
"src_file_name": "filename.txt.zip",
"src_short_file_path": "web-upload/2025-06-20-092716/filename.txt.zip",
"file_size_bytes": 5795952,
"created_at": "2025-06-20T09:27:17.344081Z",
"check_sum": "feee6f11ade6b8b4ee28e12801211d07",
"acceptable": true,
"purged_from_storage": false,
"orders_count": 0,
"genome_type": "GNT",
"amount_of_samples": 1,
"deleted_at": null,
"org_name": "Organization name",
"check_completed": true,
"sample_alias": null,
"check_information": null,
"virtual": false
},
{
"id": "51f1ad10-1111-2222-3333-ddb50b37a40d",
"status": "VALID",
"src_file_name": "filename.txt.zip",
"src_short_file_path": "web-upload/2025-07-14-103020/filename.txt.zip",
"file_size_bytes": 34843764,
"created_at": "2025-07-14T10:30:20.433081Z",
"check_sum": "2b103756484ad1a5e691c756898b3310",
"acceptable": true,
"purged_from_storage": false,
"orders_count": 0,
"genome_type": "GNT",
"amount_of_samples": 1,
"deleted_at": null,
"org_name": "Organization name",
"check_completed": true,
"sample_alias": null,
"check_information": null,
"virtual": false
}
]
}
Endpoint for getting list of source files.
Optional query parameters:
- file: (string) - search by id or filename
- only_acceptable: (bool) - search in not deleted and acceptable files
Example:
https://api.dev.galatea.bio/api/v1/data/files?file=filename.txt.zip&only_acceptable=true
POST Upload file
Use this code to upload file via API:
import requests
url = "https://api.dev.galatea.bio/api/v1/data/files/upload"
headers = {
'accept': 'application/json',
'Authorization': 'Bearer <<access_token>>'
}
with open('filename.txt.zip', 'rb') as file_for_upload:
response = requests.post(url, headers=headers, files={'file': file_for_upload})
print(response.text)
file_name = 'filename.txt.zip'
file_obj = octopod_client.file_api.upload_file(file_name)
# or
file_name = 'filename.txt.zip'
with open(file_name, "rb") as fh:
buf = BytesIO(fh.read())
file_obj = octopod_client.file_api.upload_file_from_io(buf, file_name)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/data/files/upload' \
-H 'accept: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: multipart/form-data' \
-F '[email protected];type=application/x-zip-compressed'
full_file_name='/full/path/to/filename.txt.zip'
octo api-upload-file --file_name="${full_file_name}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"status": "PENDING",
"src_file_name": "filename.txt.zip",
"src_short_file_path": "web-upload/2025-07-16/075700/filename.txt.zip",
"file_size_bytes": 5219426,
"created_at": "2025-07-16T07:57:06.855150Z",
"check_sum": "bba8c0456b0ad6e754eadbce921a7531",
"acceptable": true,
"purged_from_storage": false,
"orders_count": 0,
"genome_type": "GNT",
"amount_of_samples": 0,
"deleted_at": null,
"org_name": "Organization name",
"check_completed": false,
"sample_alias": null,
"check_information": null,
"virtual": false
}
Endpoint for uploading source files.
With this endpoint can be uploaded files with size less than 50MB.
For uploading files more than 50MB use SFTP upload instruction.
If configured websocket notifications will be sent message with status when a file will be validated.
More information about using websocket notification
DELETE Source files
Use this code to delete source file via API:
import requests
source_file_id = '9085d0d2-3333-1111-2222-4114602c2aa6'
url = f'https://api.dev.galatea.bio/api/v1/data/files/{source_file_id}'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.status_code)
source_file_id = '9085d0d2-3333-1111-2222-4114602c2aa6'
octopod_client.file_api.delete_file(source_file_id)
curl -X 'DELETE' \
'https://api.dev.galatea.bio/api/v1/data/files/9085d0d2-3333-1111-2222-4114602c2aa6' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
source_file_id='9085d0d2-3333-1111-2222-4114602c2aa6'
octo delete-file --file_id="${source_file_id}"
Use access_token from Authentication step.
Instruction to Configure wrapper and client
Endpoint for deleting source files by file id.
GET Download results
Use access_token from Authentication step.
Instruction to Configure wrapper and clientUse order_id from Execution submit order endpoint.
or from Get orders
import requests
import shutil
order_id = '1234567d-1111-2222-3333-12345abcd123'
result_type = 'SUMMARY_CHROMS'
url = f'https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type={result_type}'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers, stream=True)
filename = response.headers['content-disposition'].split('; ')[1].split('=')[1].replace('"', '')
with open(filename, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
print(response.status_code)
# single pdf report file
result_type = 'PDF_REPORT'
pdf_request_id = '11112222-1111-1111-1111-4f7992dea817'
url = f'https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type={result_type}&pdf_request_id={pdf_request_id}'
response = requests.get(url, headers=headers, stream=True)
filename = response.headers['content-disposition'].split('; ')[1].split('=')[1].replace('"', '')
with open(filename, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
print(response.status_code)
order_id = '1234567d-1111-2222-3333-12345abcd123'
result_type = 'SUMMARY_CHROMS'
result_file_content: BytesIO, result_file_name: str = octopod_client.result_api.download_result_file(
order_id=order_id,
result_type=result_type,
)
with open(result_file_name, "wb") as f:
f.write(result_file_content.getbuffer())
# single pdf report file
result_type_reports = 'PDF_REPORT'
pdf_request_id = '11112222-1111-1111-1111-4f7992dea817'
result_file_content: BytesIO, result_file_name: str = octopod_client.result_api.download_result_file(
order_id=order_id,
result_type=result_type,
pdf_request_id=pdf_request_id,
)
with open(result_file_name, "wb") as f:
f.write(result_file_content.getbuffer())
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1data/results/1234567d-1111-2222-3333-12345abcd123/download?result_type=SUMMARY_CHROMS' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-o result_filename.tsv
# single pdf report file
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1data/results/1234567d-1111-2222-3333-12345abcd123/download?result_type=PDF_REPORT&pdf_request_id=11112222-1111-1111-1111-4f7992dea817' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-o result_filename.tsv
order_id='1234567d-1111-2222-3333-12345abcd123'
result_type="SUMMARY_CHROMS"
pdf_request_id=11112222-1111-1111-1111-4f7992dea817
octo download-result-file --order_id="${order_id}" --result_type="${result_type}"
# single pdf report file
octo download-result-file --order_id="${order_id}" --result_type=PDF_REPORT --pdf_request_id="${pdf_request_id}"
Endpoint for getting result files of an execution order or errors occured during execution.
List of available result types for downloading is shown in GET order details
Query parameters:
| Results type | Description |
|---|---|
| SUMMARY_CHROMS | Summary set of chromosomes, tsv file |
| SUMMARY_SUPERSET | Summary superset of labels, tsv file |
| DETAILED_CHROMS | Detailed set of labels by chromosome |
| DETAILED_SUPERSET | Detailed superset of labels by chromosome, zip archive |
| EXEC_ERRORS | Execution errors, contains errors about data processing |
| PDF_REPORT | All generated PDF reports in zip archive |
| PRS_JSON_DATA | PRS data in json files per report type, zip archive |
| PRS_IMAGES | PRS diagrams in png for high risk items, zip archive |
- pdf_request_id: (string) - pdf report request id, for downloading single pdf report file
Example:
https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type=SUMMARY_CHROMS
https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type=PDF_REPORT&pdf_request_id=11112222-1111-1111-1111-4f7992dea817
GET Result in json
Use this code to download result json via API:
import requests
order_id = '1234567d-1111-2222-3333-12345abcd123'
url = f'https://api.dev.galatea.bio/api/v1/data/results/{order_id}/json'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.text)
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1data/results/1234567d-1111-2222-3333-12345abcd123/json' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: multipart/form-data'
Use access_token from Authentication step.
Instruction to Configure wrapper and clientUse order_id from Execution orders endpoint.
Endpoint for getting result in JSON format, returns only results of type SUMMARY_CHROMS, SUMMARY_SUPERSET, DETAILED_CHROMS, DETAILED_SUPERSET.
GET list PDF reports
Use this code to get list of PDF reports available for order via API:
import requests
order_id = '1234567d-1111-2222-3333-12345abcd123'
url = "https://api.dev.galatea.bio/api/v1/data/results/{order_id}/pdf_report?page_size=1000"
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.text)
order_id = '1234567d-1111-2222-3333-12345abcd123'
octopod_client.result_api.list_pdf_reports(order_id=order_id)
octopod_client.result_api.list_pdf_reports(order_id=order_id, request_version=2)
octopod_client.result_api.list_pdf_reports(order_id=order_id, sample_id="sandbox.34.4503157")
order_id='1234567d-1111-2222-3333-12345abcd123'
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1/data/results/{$order_id}/pdf_report?page_size=1000' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
order_id='1234567d-1111-2222-3333-12345abcd123'
octo list-result-pdf-reports --order_id="${order_id}"
octo list-result-pdf-reports --order_id="${order_id}" --request_version=2
octo list-result-pdf-reports --order_id="${order_id}" --sample_id="sandbox.34.4503157"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": "11112222-1111-1111-1111-4f7992dea817",
"status": "COMPLETED",
"sample_id": "sandbox.34.4503157",
"order_id": "1234567d-1111-2222-3333-12345abcd123",
"result_id": "22222222-2222-1111-1111-222222222222",
"org_name": "Organization name",
"request_type": "ORDER",
"request_version": 1,
"report_version": "GalaxyBio Vader 2024-Jan-01 11112222",
"pdf_file_name": "11112222-1111-1111-1111-4f7992dea817_sandbox.34.4503157.pdf",
"file_size_bytes": 3019238,
"check_sum": "ee309c64c793995e91876817d47e9f02",
"started_at": "2024-02-08T06:56:15.668489Z",
"completed_at": "2024-02-08T06:57:37.515947Z"
},
{
"id": "33333333-3333-3333-1111-c21745d2f1ac",
"status": "COMPLETED",
"sample_id": "sandbox.34.4503157",
"order_id": "12312312-1111-2222-3333-456456456456",
"result_id": "22222222-2222-1111-1111-22222222222",
"org_name": "Organization name",
"request_type": "SAMPLE",
"request_version": 2,
"report_version": "GalaxyBio Vader 2024-Mar-07 22223333",
"pdf_file_name": "33333333-3333-3333-1111-c21745d2f1ac_sandbox.34.4503157.pdf",
"file_size_bytes": 1935233,
"check_sum": "0ae482fe89eb6d4b9f9b237a4d74a857",
"started_at": "2024-03-08T06:56:15.652829Z",
"completed_at": "2024-03-08T06:57:26.142578Z"
}
]
}
Endpoint for getting list of PDF reports generated in execution order.
PDF reports can be downloaded individually or as a zip archive with all reports via Download result with result_type=PDF_REPORT
For downloading single pdf report file use additional parameter pdf_request_id with result_type=PDF_REPORT in Download result
https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type=PDF_REPORT&pdf_request_id=33333333-3333-3333-1111-c21745d2f1ac
Optional query parameters:
- request_version: (int) - search by request version number
- report_version: (string) - search by report generator version
- sample_id: (string) - search by sample_id
Example:
https://api.dev.galatea.bio/api/v1/data/results/{order_id}/pdf_report?page_size=1000&request_version=2&sample_id=sandbox.34.4503157https://api.dev.galatea.bio/api/v1/data/results/{order_id}/pdf_report?page_size=1000&request_version=1https://api.dev.galatea.bio/api/v1/data/results/{order_id}/pdf_report?page_size=1000&report_version=GalaxyBio+Vader+2024-Mar-07+22223333
Exec
GalateaBio Ancestry API Exec endpoints.
| Method | Endpoint | Reference |
|---|---|---|
| GET | exec/orders | List orders |
| GET | exec/orders?{params} | Order details |
| POST | exec/orders | Submit order |
| PATCH | exec/orders/{order_id} | Update order |
| POST | exec/cancel | Cancel order |
| GET | exec/tags | List tags |
| GET | exec/tags/{tag_id} | Get tag |
| POST | exec/tags | Create tag |
| PUT | exec/tags/{tag_id} | Edit tag |
| DELETE | exec/tags/{tag_id} | Delete tag |
GET exec/orders
Use this code to get list of orders via API:
import requests
# all orders without filtering
url = 'https://api.dev.galatea.bio/api/v1/exec/orders'
# orders by status group
status_group = 'completed'
url = f'https://api.dev.galatea.bio/api/v1/exec/orders?status_group={status_group}'
# orders filtered by tags
tag_ids='12312312-1111-4444-9999-456456456456,11111111-b183-4217-9b89-222222222222'
url = f'https://api.dev.galatea.bio/api/v1/exec/orders?tag_ids={tag_ids}'
headers = {
'accept': 'application/json',
'Authorization': 'Bearer <<access_token>>'
}
response = requests.get(url, headers=headers)
print(response.text)
# all orders without filtering
order_obj = octopod_client.order_api.list_orders()
# orders by status
status_group = 'completed'
order_obj = octopod_client.order_api.list_orders(status_group=status_group)
# orders filtered by tags
tag_ids='12312312-1111-4444-9999-456456456456,11111111-b183-4217-9b89-222222222222'
order_obj = octopod_client.order_api.list_orders(tag_ids=tag_ids)
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1/exec/orders' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
# use shell or python examples
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"count": 2,
"next": "https://api.dev.galatea.bio/api/v1/exec/orders?page=2",
"previous": null,
"results": [
{
"id": "fc79a3e0-60db-452b-9fc4-506897b4f808",
"status": "Completed",
"src_file_id": "9085d0d2-3333-1111-2222-4114602c2444",
"src_file_short_path": "somepath/filename.gvcf.gz",
"src_file_name": "filename.gvcf.gz",
"started_at": "2025-07-14T09:06:26.146529Z",
"amount_of_samples": 1,
"execution_time": 96.496678,
"submitted_by": "[email protected]",
"model": "prs ruo model",
"type": "WGS",
"org_name": "Organization name",
"tags": [
{
"id": "12312312-1111-4444-9999-456456456456",
"name": "test tag"
}
],
"result_types": [
{
"type": "SUMMARY_SUPERSET",
"label": "Summary superset"
},
{
"type": "DETAILED_SUPERSET",
"label": "Detailed superset by chromosome"
},
{
"type": "PRS_JSON_DATA",
"label": "PRS json data zip"
},
{
"type": "PRS_IMAGES",
"label": "PRS images zip"
},
{
"type": "PDF_REPORT",
"label": "PDF reports zip"
},
{
"type": "PDF_REPORT",
"label": "View PDF reports"
}
],
"can_request_pdf": true,
"virtual": false
},
{
"id": "22233344-1111-2222-3333-555666777888",
"status": "Completed",
"src_file_id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"src_file_short_path": "web-upload/2025-02-20/012716/filename.txt.zip",
"src_file_name": "filename.txt.zip",
"started_at": "2025-06-21T08:27:20.133904Z",
"amount_of_samples": 1,
"execution_time": 112.13555,
"submitted_by": "[email protected]",
"model": "ancestry data model one",
"type": "GNT",
"org_name": "Organization name",
"tags": [
{
"id": "12312312-b183-4217-9b89-456456456456",
"name": "SANDBOX"
}
],
"result_types": [
{
"type": "SUMMARY_SUPERSET",
"label": "Summary superset"
},
{
"type": "DETAILED_SUPERSET",
"label": "Detailed superset by chromosome"
},
],
"can_request_pdf": false,
"virtual": false
},
]
}
Endpoint for getting list of execution orders submitted by users related to your organization.
More datailed information for search in Order details
Optional query parameters:
- filter: (string) - Source File name or Source File ID or Order ID for search
- status: (string) - search by order's status, available values:
Running,Completed,Failed,Canceled - status_group: (string) - search by status group:
initializing,running,completed,failed - tags_ids: list - search by comma separated list of tag_ids
Examples:
https://api.dev.galatea.bio/api/v1/exec/orders
https://api.dev.galatea.bio/api/v1/exec/orders?status_group=completed
https://api.dev.galatea.bio/api/v1/exec/orders?status=Completed
https://api.dev.galatea.bio/api/v1/exec/orders?tags_ids=12312312-1111-4444-9999-456456456456,11111111-b183-4217-9b89-222222222222
GET exec/orders?params
Use this code to get list of orders via API:
import requests
# by order_id
search_for = 'fc79a3e0-60db-452b-9fc4-506897b4f808'
# or by source file name
search_for = 'filename.gvcf.gz'
# or by source file id
search_for = '9085d0d2-3333-1111-2222-4114602c2444'
url = f'https://api.dev.galatea.bio/api/v1/exec/orders?filter={search_for}'
headers = {
'accept': 'application/json',
'Authorization': 'Bearer <<access_token>>'
}
response = requests.get(url, headers=headers)
print(response.text)
# by order_id
search_for = 'fc79a3e0-60db-452b-9fc4-506897b4f808'
# or by source file name
search_for = 'filename.gvcf.gz'
# or by source file id
search_for = '9085d0d2-3333-1111-2222-4114602c2444'
order_obj = octopod_client.order_api.find_order_by_id_or_file_id(search_for)
order_status = order_obj.get('status')
order_result_types = order_obj.get('result_types')
# by order_id
search_for='fc79a3e0-60db-452b-9fc4-506897b4f808'
# or by source file name
search_for='filename.gvcf.gz'
# or by source file id
search_for='9085d0d2-3333-1111-2222-4114602c2444'
curl -X 'GET' \
"https://api.dev.galatea.bio/api/v1/exec/orders?filter=${search_for}" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
# by order_id
search_for='fc79a3e0-60db-452b-9fc4-506897b4f808'
# or by source file name
search_for='filename.gvcf.gz'
# or by source file id
search_for='9085d0d2-3333-1111-2222-4114602c2444'
octo find-order --order_id_or_file_id="$search_for"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"count": 1,
"next": "https://api.dev.galatea.bio/api/v1/exec/orders?page=2",
"previous": null,
"results": [
{
"id": "fc79a3e0-60db-452b-9fc4-506897b4f808",
"status": "Completed",
"src_file_id": "9085d0d2-3333-1111-2222-4114602c2444",
"src_file_short_path": "somepath/filename.gvcf.gz",
"src_file_name": "filename.gvcf.gz",
"started_at": "2025-07-14T09:06:26.146529Z",
"amount_of_samples": 1,
"execution_time": 96.496678,
"submitted_by": "[email protected]",
"model": "prs ruo model",
"type": "WGS",
"org_name": "Organization name",
"tags": [
{
"id": "12312312-1111-4444-9999-456456456456",
"name": "test tag"
}
],
"result_types": [
{
"type": "SUMMARY_SUPERSET",
"label": "Summary superset"
},
{
"type": "DETAILED_SUPERSET",
"label": "Detailed superset by chromosome"
},
{
"type": "PRS_JSON_DATA",
"label": "PRS json data zip"
},
{
"type": "PRS_IMAGES",
"label": "PRS images zip"
},
{
"type": "PDF_REPORT",
"label": "PDF reports zip"
},
{
"type": "PDF_REPORT",
"label": "View PDF reports"
}
],
"can_request_pdf": true,
"virtual": false
},
]
}
Endpoint for getting list of execution orders submitted by users related to your organization.
Optional query parameters:
- filter: (string) - Source File name or Source File ID or Order ID for search
- status: (string) - search by order's status, available values:
Running,Completed,Failed,Canceled - status_group: (string) - search by status group:
initializing,running,completed,failed - tags_ids: list - search by comma separated list of tag_ids
Examples:
https://api.dev.galatea.bio/api/v1/exec/orders?filter=fc79a3e0-60db-452b-9fc4-506897b4f808
https://api.dev.galatea.bio/api/v1/exec/orders?filter=filename.gvcf.gz
POST exec/orders
Use this code to submit order via API:
import requests
url = 'https://api.dev.galatea.bio/api/v1/exec/orders'
payload = {
"source_file_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"model_name": "ancestry data model one",
"tags_ids": [
"9085d0d2-3333-1111-2222-4114602c2aa6"
],
}
headers = {
'accept': 'application/json',
'Authorization": 'Bearer <<access_token>>'
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
source_file_id = '3fa85f64-5717-4562-b3fc-2c963f66afa6'
model_name = 'ancestry data model one'
order_obj = octopod_client.order_api.submit_order(file_id=source_file_id, model_name=model_name)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/exec/orders' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"source_file_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"model_name": "ancestry data model one",
"tags_ids": ["9085d0d2-3333-1111-2222-4114602c2aa6"]
}'
source_file_id='3fa85f64-5717-4562-b3fc-2c963f66afa6'
model_name='ancestry data model one'
octo submit-order --file_id="${source_file_id}" --model="${model_name}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
[
{
"id": "22334545-6ca1-4492-94b0-112345002211",
"status": "Registered",
"src_file_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"src_file_short_path": "web-upload/2023-09-20-092716/filename.txt.zip",
"src_file_name": "filename.txt.zip",
"started_at": "2023-09-25T08:45:38.652925Z",
"amount_of_samples": 1,
"submitted_by": "[email protected]",
"model": "ancestry data model one",
"type": "GNT",
"org_name": "Organization name",
"tags": []
}
]
Endpoint for submitting execution order.
If configured websocket notifications will be sent message with status when execution order will be done.
More information about using websocket notification
- Required fields:
- source_file_id
- model_name
- Optional:
- tags_ids
- pdf_metadata
- pdf_report_types
More examples for submitting order:
Submit ancestry data order
Submit ancestry PDF order
Submit PRS PDF order
PATCH exec/orders/{order_id}
Use this code to update order tags via API:
import requests
order_id='22334545-6ca1-4492-94b0-112345002211'
url = f'https://api.dev.galatea.bio/api/v1/exec/orders/{order_id}'
payload = {
"tags_ids": [
"11111111-b183-4217-9b89-222222222222",
"33333333-1111-2222-9b89-222222222222"
]
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)
order_id = '22334545-6ca1-4492-94b0-112345002211'
tags_ids = ['11111111-b183-4217-9b89-222222222222', '33333333-1111-2222-9b89-222222222222']
order_obj = octopod_client.order_api.update_order_tags(order_id=order_id, tags_ids=tags_ids)
curl -X 'PATCH' \
'https://api.dev.galatea.bio/api/v1/exec/orders/22334545-6ca1-4492-94b0-112345002211' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"tags_ids": [
"11111111-b183-4217-9b89-222222222222",
"33333333-1111-2222-9b89-222222222222"
]
}'
order_id='22334545-6ca1-4492-94b0-112345002211'
tags_ids='11111111-b183-4217-9b89-222222222222,33333333-1111-2222-9b89-222222222222'
octo update-order-tags --order_id="${order_id}" --tags_ids="${tags_ids}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"id": "22334545-6ca1-4492-94b0-112345002211",
"status": "Completed",
"src_file_id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"src_file_short_path": "web-upload/2023-09-20-092716/filename.txt.zip",
"src_file_name": "filename.txt.zip",
"started_at": "2023-09-25T08:45:38.652925Z",
"amount_of_samples": 1,
"execution_time": 161.882115,
"submitted_by": "[email protected]",
"model": "ancestry data model one",
"type": "GNT",
"has_error_log": false,
"org_name": "Organization name",
"result_json": [
{
"details": "Download via result endpoint."
}
],
"tags": [
{
"id": "11111111-b183-4217-9b89-222222222222",
"name": "SANDBOX"
},
{
"id": "33333333-1111-2222-9b89-222222222222",
"name": "SANDBOX test"
}
],
"result_types": [
"DETAILED_CHROMS",
"SUMMARY_CHROMS"
]
}
Endpoint for updating execution order's tags.
Order can be updated with tags at any time.
POST exec/cancel
Use this code to Cancel submitted order via API:
import requests
url = "https://api.dev.galatea.bio/api/v1/exec/cancel"
payload = {
"order_id": "22334545-6ca1-4492-94b0-112345002211"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
order_id = '22334545-6ca1-4492-94b0-112345002211'
octopod_client.order_api.cancel_order(order_id=order_id)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/exec/cancel' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"order_id": "22334545-6ca1-4492-94b0-112345002211"
}'
order_id='22334545-6ca1-4492-94b0-112345002211'
octo cancel-order --order_id="${order_id}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"details": "Request to cancel execution id 22334545-6ca1-4492-94b0-112345002211 accepted"
}
Endpoint for cancelling submited execution order.
Note: It is possible to cancel only orders in Registered and Submitted status.
GET exec/tags
Use this code to get list of execution tags via API:
import requests
# list all tags
url = 'https://api.dev.galatea.bio/api/v1/exec/tags'
# filter by name
url = 'https://api.dev.galatea.bio/api/v1/exec/tags?name=tag-name'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.text)
# list all tags
octopod_client.tag_api.list_tags()
# filter by name
octopod_client.tag_api.list_tags(name="tag-name")
# list all tags
url = 'https://api.dev.galatea.bio/api/v1/exec/tags'
# filter by name
url = 'https://api.dev.galatea.bio/api/v1/exec/tags?name=tag-name'
curl -X 'GET' \
"${url}" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
# list all tags
octo list-tags
# filter by name
octo list-tags --name="tag-name"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "11111111-711a-4027-bc6b-111111111111",
"name": "Demo",
"org_id": "12332112-3321-2233-1122-123432345648"
},
{
"id": "11111111-b183-4217-9b89-222222222222",
"name": "SANDBOX",
"org_id": "12332112-3321-2233-1122-123432345648"
}
]
}
Endpoint for getting list of execution tags created by users realted to your organization.
Optional query parameters:
- name: (string) - Tag name for search
Examples:
https://api.dev.galatea.bio/api/v1/exec/tags?name=Demo
GET exec/tags/{tag_id}
Use this code to get execution Tag by tag id via API:
import requests
tag_id = '11111111-b183-4217-9b89-222222222222'
url = f'https://api.dev.galatea.bio/api/v1/exec/tags/{tag_id}'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers)
print(response.text)
tag_id = '11111111-b183-4217-9b89-222222222222'
octopod_client.tag_api.get_tag_by_id(tag_id=tag_id)
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1/exec/tags/11111111-b183-4217-9b89-222222222222' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
tag_id='11111111-b183-4217-9b89-222222222222'
octo find-tag --tag_id="${tag_id}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"id": "11111111-b183-4217-9b89-222222222222",
"name": "SANDBOX",
"org_id": "12332112-3321-2233-1122-123432345648"
}
Endpoint for getting execution tag by tag_id related to your organization.
POST exec/tags
Use this code to create new execution Tag via API:
import requests
url = 'https://api.dev.galatea.bio/api/v1/exec/tags'
payload = {
"name": "Demo Tag"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
tag_name = 'Demo Tag'
octopod_client.tag_api.create_tag(name=tag_name)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/exec/tags' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"name": "Demo Tag"
}'
tag_name='Demo Tag'
octo create-tag --name="${tag_name}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"id": "11111111-711a-4027-bc6b-111111111111",
"name": "Demo Tag",
"org_id": "12332112-3321-2233-1122-123432345648"
}
Endpoint for creating new execution Tag.
PUT exec/tags/{tag_id}
Use this code to edit execution Tag via API:
import requests
tag_id = '11111111-711a-4027-bc6b-111111111111'
new_tag_name = 'Demo Test Tag'
url = f'https://api.dev.galatea.bio/api/v1/exec/tags/{tag_id}'
payload = {
"name": new_tag_name
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)
tag_id = '11111111-711a-4027-bc6b-111111111111'
new_tag_name = 'Demo Test Tag'
octopod_client.tag_api.update_tag(tag_id=tag_id, new_name=new_tag_name)
curl -X 'PUT' \
'https://api.dev.galatea.bio/api/v1/exec/tags/11111111-711a-4027-bc6b-111111111111' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"name": "Demo Test Tag"
}'
tag_id='11111111-711a-4027-bc6b-111111111111'
new_tag_name='Demo Test Tag'
octo update-tag --tag_id="${tag_id}" --name="${new_tag_name}"
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"id": "11111111-711a-4027-bc6b-111111111111",
"name": "Demo Test Tag",
"org_id": "12332112-3321-2233-1122-123432345648"
}
Endpoint for edit execution Tag.
DELETE exec/tags/{tag_id}
Use this code to edit execution Tag via API:
import requests
tag_id = '11111111-711a-4027-bc6b-111111111111'
url = f'https://api.dev.galatea.bio/api/v1/exec/tags/{tag_id}'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.delete(url, headers=headers)
print(response.status_code)
# use python or shell code
curl -X 'DELETE' \
'https://api.dev.galatea.bio/api/v1/exec/tags/11111111-711a-4027-bc6b-111111111111' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
# use python or shell code
Use access_token from Authentication step.
Instruction to Configure wrapper and clientThe above command returns status:
200
Endpoint for edit execution Tag.
Recipes
Recipes for Galatea ancestry API usage.
Authentication
To get authorization token, use this code:
import requests
url = "https://api.dev.galatea.bio/api/v1/api/v1/users/auth"
payload = {
'email': '[email protected]',
'password': 'Your password'
}
headers = {
'content-type': 'application/json',
'accept': 'application/json'
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
access_token = json.loads(response.text)['access']
auth_token = f'Bearer {access_token}'
# authentication with API key
base_url = "https://api.dev.galatea.bio"
api_key = 'Octopod-API-Key'
octopod_client = OctopodClient(base_url=base_url, api_key=api_key)
# authentication with username and password
base_url = "https://api.dev.galatea.bio"
auth_json = OctopodClient.authenticate(
username='[email protected]',
password='Your_password',
base_url=base_url,
)
api_key = auth_json.get('access') # fetched api_key has short lifetime!
octopod_client = OctopodClient(base_url=base_url, api_key=api_key)
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/api/v1/users/auth' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"email": "[email protected]",
"password": "Your password"
}'
# authentication with API key
octo set-config \
--api_mode=1 \
--api_base_url="https://api.dev.galatea.bio" \
--api_key="<Octopod-API-Key>"
# authentication with username and password
octo set-config \
--api_mode=2 \
--api_base_url="https://api.dev.galatea.bio" \
--api_username="[email protected]" \
--api_password="Your_password"
Replace
[email protected]andYour passwordwith your personal credentials.
Instruction to Configure wrapper and clientThe above command returns JSON:
{
"refresh": "refresh_token",
"access": "access_token",
"websocket_access": "websocket_access_token"
}
GalateaBio Ancestry API uses personal access_token to allow access to the API.
GalateaBio Ancestry API requires authorization, API expects for the access_token included to all requests to API in a header:
Authorization: Bearer access_token
Install and configure octopod wrapper and client
# using PyPI
pip install galatea-cli
# using github repo
git clone https://github.com/GalateaBio/octopod-cli
pip install octopod file://octopod-cli
# authentication with API key
base_url = "https://api.dev.galatea.bio"
api_key = 'Octopod-API-Key'
octopod_client = OctopodClient(base_url=base_url, api_key=api_key)
# authentication with username and password
base_url = "https://api.dev.galatea.bio"
username = '[email protected]'
password = 'Your_password'
from octopod import OctopodClient
# fetched access_token has short lifetime!
auth_json = OctopodClient.authenticate(
base_url=base_url,
username=username,
password=password,
)
access_token = auth_json.get('access')
octopod_client = OctopodClient(base_url=base_url, api_key=access_token)
# using PyPI
pip install galatea-cli
# using github repo
git clone https://github.com/GalateaBio/octopod-cli
pip install octopod file://octopod-cli
# authentication with API key
base_url = "https://api.dev.galatea.bio"
api_key = 'Octopod-API-Key'
octopod_client = OctopodClient(base_url=base_url, api_key=api_key)
# authentication with username and password
base_url = "https://api.dev.galatea.bio"
username = '[email protected]'
password = 'Your_password'
from octopod import OctopodClient
# fetched access_token has short lifetime!
auth_json = OctopodClient.authenticate(
base_url=base_url,
username=username,
password=password,
)
access_token = auth_json.get('access')
octopod_client = OctopodClient(base_url=base_url, api_key=access_token)
# using PyPI
pip install galatea-cli
# using github repo
git clone https://github.com/GalateaBio/octopod-cli
pip install octopod file://octopod-cli
# authentication with API key
base_url="https://api.dev.galatea.bio"
api_key="Octopod-API-Key"
octo set-config \
--api_mode=1 \
--api_base_url="${base_url}" \
--api_key="${api_key}"
# authentication with username and password
base_url="https://api.dev.galatea.bio"
username='[email protected]'
password='Your_password'
octo set-config \
--api_mode=2 \
--api_base_url="${base_url}" \
--api_username="${username}" \
--api_password="${password}"
# to check and review config
octo get-config
# using PyPI
pip install galatea-cli
# using github repo
git clone https://github.com/GalateaBio/octopod-cli
pip install octopod file://octopod-cli
# authentication with API key
base_url="https://api.dev.galatea.bio"
api_key="Octopod-API-Key"
octo set-config \
--api_mode=1 \
--api_base_url="${base_url}" \
--api_key="${api_key}"
# authentication with username and password
base_url="https://api.dev.galatea.bio"
username='[email protected]'
password='Your_password'
octo set-config \
--api_mode=2 \
--api_base_url="${base_url}" \
--api_username="${username}" \
--api_password="${password}"
# to check and review config
octo get-config
For working with GalateaBio API are available 'octopod wrapper' and 'octopod client'.
Requirements:
- python 3
Content:
GalateaBio Octopod client includes python lib and shell client to work with GalateaBio Ancestry API.
- python lib, octopod-wrapper:
OctopodClient()
- shell client, octopod-client:
octo <command> <params>
Installation:
- using pypi (recommended)
pip install galatea-cli - installing from github repository
git clone https://github.com/GalateaBio/octopod-cli
pip install octopod file://octopod-cli
Initial configuration:
Authentication can be made with api-key or with user credentials.
Authentication with user credentials is optional and providing short time access_token.
For correct working with GalateaBio API it is recommended to use api-key.
- GalateaBio API url
- user credentials
- api-key
Octopod-client config
octo set-config
| parameter | description |
|---|---|
| --api_mode=1 | mode 1 - using API key, mode 2 - login and password |
| --api_key="api_key" | auth api key, using with api_mode=1 |
| --api_username="user_username" | user login, using with api_mode=2 |
| --api_password="user_password" | user password, using with api_mode=2 |
| --api_base_url="api_base_url" | Galatea Ancestry API url |
| --sftp_host="sftp_host" | Galatea Ancestry API sftp host |
| --sftp_user="sftp_user" | sftp user |
| --sftp_keyfile="/path/sftp_keyfile" | path to ssh key file |
| --download_folder="/some/path" | folder for storing downloaded files, if not set files will be stored in current path |
Upload file
Supported 2 types of upload:
- using API for web upload files less than 50MB;
- using SFTP for all files;
Upload file with API and check status
Step 1. Use access_token from Authentication step.
Instruction to Configure wrapper and clientStep 2. Upload file less than 50MB
url_api = 'https://api.dev.galatea.bio/api/v1'
url_upload = f'{url_api}/data/files/upload'
headers = {
'accept': 'application/json',
'Authorization': Bearer <<access_token>>
}
with open('filename.txt.zip', 'rb') as file_for_upload:
response = requests.post(url_upload, headers=headers, files={'file': file_for_upload})
file_id = json.loads(response.text)['id']
file_name = 'filename.txt.zip'
file_obj = octopod_client.file_api.upload_file(file_name)
# or
file_name = 'filename.txt.zip'
with open(file_name, "rb") as fh:
buf = BytesIO(fh.read())
file_obj = octopod_client.file_api.upload_file_from_io(buf, file_name)
# For uploading file use auth_token from previous step.
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/data/files/upload' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: multipart/form-data' \
-F '[email protected];type=application/x-zip-compressed'
full_file_name='/full/path/to/filename.txt.zip'
octo api-upload-file --file_name="${full_file_name}"
JSON response:
{
"id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"status": "PENDING",
"src_file_name": "filename.txt.zip",
"src_short_file_path": "web-upload/2025-07-16/075700/filename.txt.zip",
"file_size_bytes": 5219426,
"created_at": "2025-07-16T07:57:06.855150Z",
"check_sum": "bba8c0456b0ad6e754eadbce921a7531",
"acceptable": true,
"purged_from_storage": false,
"orders_count": 0,
"genome_type": "GNT",
"amount_of_samples": 0,
"deleted_at": null,
"org_name": "Organization name",
"check_completed": false,
"sample_alias": null,
"check_information": null,
"virtual": false
}
Step 3. Wait 2-5 minutes for completing validation before checking the file status.
Use file id from results in previous step.
url_api = 'https://api.dev.galatea.bio/api/v1'
url_get = f'{url_api}/data/files?file={file_id}'
response = requests.get(url_get, headers=headers)
if len(json.loads(response.text)['results']) == 1:
status: bool = json.loads(response.text)['results'][0]['status']
if status == 'PENDING':
print('File registered, waiting for validation, check status in 30-60 seconds.')
if status == 'VALID':
print('File is valid, order can be submitted.')
if status in ['NOT_VALID', 'FAILED']:
print('File is not valid.')
print(f'Errors: {json.loads(response.text)['results'][0]['check_information']}')
else:
print('No such file on the server.')
file_obj = octopod_client.file_api.find_file_by_id(file_id)
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1/data/files?file={file_id}' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
octo find-file --file_id="<file_id>"
JSON response:
{
"count":1,
"next":null,
"previous":null,
"results":[
{
"id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"status": "VALID",
"src_file_name": "filename.txt.zip",
"src_short_file_path": "web-upload/2025-07-16/075700/filename.txt.zip",
"file_size_bytes": 5219426,
"created_at": "2025-07-16T07:57:06.855150Z",
"check_sum": "bba8c0456b0ad6e754eadbce921a7531",
"acceptable":true,
"purged_from_storage":false,
"orders_count":0,
"genome_type":"GNT",
"amount_of_samples":1,
"deleted_at":null,
"org_name":"Organization name",
"check_completed":true,
"sample_alias":null,
"check_information":null,
"virtual":false
}
]
}
All uploaded files go through validation.
Execution order can be submitted only for sucessfully validated files with status VALID.
Validation takes up to 2-5 minutes.
Web upload for files with size less than 50MB:
Authorize.
Note: with using API-keys periodical authentication for obtaining token is not needed.Upload a file.
Files with size less than 50MB can be uploaded with API.
All other files can be uploaded with SFTP.Wait 2-5 minutes and check file status.
On validation it checks file has correct name and correct content and can be accepted for executing order.
On this step we cannot check that data in file is correct.
Alternatively to Step 3 can be configured websocket notifications.
Once a file will be validated will be sent a message with file info:
- new_status: VALID or FAILED
- source_file_id
- source_file_name
Upload file with SFTP and check status
Instruction to Configure wrapper and client
Connect to SFTP and upload a file
import paramiko as paramiko
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sftp_host = 'sftp.dev.galatea.bio'
sftp_user = 'sftp-user-5c9a4f01'
ssh_key_file = '~/.ssh/id_rsa_private_sftp-user-5c9a4f01'
ssh_client.connect(hostname=sftp_host, username=sftp_user key_filename=ssh_key_file)
sftp_client = ssh_client.open_sftp()
# Create folder for uploading files
sftp.mkdir('2025-Feb-27')
# Upload file to created folder
file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
remote_file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
sftp.chdir('2025-Feb-27')
sftp.put(file_name, remote_file_name)
sftp_host = 'sftp.dev.galatea.bio'
sftp_user = 'sftp-user-5c9a4f01'
ssh_key_file = '~/.ssh/id_rsa_private_sftp-user-5c9a4f01'
sftp_octopod_client = OctopodSftpClient(
sftp_host=sftp_host,
sftp_user=sftp_user,
sftp_password=None,
sftp_keyfile=ssh_key_file,
)
file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
remote_file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
remote_folder = '2025-Feb-27'
uploaded_path_file: str = sftp_octopod_client.upload_file(
file_name=file_name,
remote_filename=remote_file_name,
remote_folder=remote_folder,
)
sftp_host='sftp.dev.galatea.bio'
sftp_user='sftp-user-5c9a4f01'
ssh_key_file='~/.ssh/id_rsa_private_sftp-user-5c9a4f01'
$ sftp -i $ssh_key_file $sftp_user@$sftp_host
# Create folder for uploading files
$ sftp> mkdir 2025-Feb-27
$ sftp> cd 2025-Feb-27
# Upload file to created folder
$ sftp> put d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz
Uploading d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz to /2025-Feb-27/d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz
d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz 100% 525MB 4.6MB/s 00:05
# or single command with already created folder
$ sftp -i $ssh_key_file $sftp_user@$sftp_host>:/2025-Feb-27/ <<< $'put d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
sftp_host='sftp.dev.galatea.bio'
sftp_user='sftp-user-5c9a4f01'
ssh_key_file='~/.ssh/id_rsa_private_sftp-user-5c9a4f01'
# set config for sftp
octo set-config
--sftp_host="${sftp_host}"
--sftp_user="${sftp_user}"
--sftp_keyfile="${ssh_key_file}"
# upload file
file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
remote_file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
remote_folder = '2025-Feb-27'
octo sftp-upload-file --file_name="${file_name}" --remote_folder="${remote_folder}" --remote_file_name="${remote_file_name}"
Wait 2-3 minutes while file will be registered in the system.
file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
url_get = f'{url_api}/data/files?file={file_name}'
response = requests.get(url_get, headers=headers)
if len(json.loads(response.text)['results']) == 1:
status: bool = json.loads(response.text)['results'][0]['status']
if status == 'PENDING':
print('File registered, waiting for validation, check status in 30-60 seconds.')
if status == 'VALID':
print('File is valid, order can be submitted.')
if status in ['NOT_VALID', 'FAILED']:
print('File is not valid.')
print(f'Errors: {json.loads(response.text)['results'][0]['check_information']}')
else:
print('No such file on the server.')
file_name = 'd101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
files_objs = octopod_client.file_api.list_files(**{'file': file_name})
if files_objs.get('count', 0) > 0:
file_id = files_objs.get('results', [])[0].get('id')
file_obj = octopod_client.file_api.find_file_by_id(file_id)
file_name='d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
curl -X 'GET' \
"https://api.dev.galatea.bio/api/v1/data/files?file=${file_name}" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
file_name='d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz'
octo find-file --file_name="${file_name}"
Returned JSON response
{
"count":1,
"next":null,
"previous":null,
"results":[
{
"id":"7e53320c-c631-45ec-bad6-c88bb9d30960",
"src_file_name":"d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz",
"src_short_file_path":"2025-Feb-27/d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz",
"file_size_bytes":26708788,
"created_at":"2025-02-27T07:49:01.278404Z",
"check_sum":"116e0f98dcda9666723e17b7d4aef490-6",
"acceptable":true,
"purged_from_storage":false,
"orders_count":0,
"genome_type":"GNT",
"amount_of_samples":0,
"deleted_at":null,
"org_name":"Organization name",
"check_completed":false,
"sample_alias":null,
"check_information":null,
"status":"PENDING",
"virtual":false
}
]
}
All uploaded files go through validation.
Execution order can be submitted only for sucessfully validated files with status VALID.
Validation takes up to 2-5 minutes.
- Contact GalateaBio admins to obtain SFTP user and ssh keys and parameters for connection.
- Upload file via any sftp or scp client.
Common recommendations:
- use folders by date (2025-Feb-01) instead of uploading into root folder;
- try to set unique name for files like uuid key.
- Wait 2-5 minutes.
- List files with filter by file name.
- Check file status.
Steps 3, 4, 5 can be skipped if websocket notifications is configured.
Once a file will be validated will be sent a message with file info:
- new_status: VALID or FAILED
- source_file_id
- source_file_name
Submit order
Submit execution order.
Ancestry data order
Use access_token from Authentication step.
Instruction to Configure wrapper and clientSubmit execution order using source_file_id and model name.
url_api = 'https://api.dev.galatea.bio/api/v1'
url_orders = f'{url_api}/exec/orders'
payload = {
'source_file_id': source_file_id,
'model_name': 'ancestry data model one',
'tags_ids': ['9085d0d2-3333-1111-2222-4114602c2aa6']
}
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.post(url_orders, json=payload, headers=headers)
print(response.text)
source_file_id = '3fa85f64-5717-4562-b3fc-2c963f66afa6'
model_name = 'ancestry data model one'
tags_ids = ['9085d0d2-3333-1111-2222-4114602c2aa6']
order_obj = octopod_client.order_api.submit_order(file_id=source_file_id, model_name=model_name, tags_ids=tags_ids)
source_file_id="3fa85f64-5717-4562-b3fc-2c963f66afa6"
model_name="ancestry data model one"
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/exec/orders' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"source_file_id": "${source_file_id}",
"model_name": "${model_name}",
"tags_ids": ["9085d0d2-3333-1111-2222-4114602c2aa6"]
}'
source_file_id="3fa85f64-5717-4562-b3fc-2c963f66afa6"
model_name="ancestry data model one"
tags_ids='9085d0d2-3333-1111-2222-4114602c2aa6,12345672-1111-2222-3333-456789012345'
octo submit-order --file_id="${source_file_id}" --model="${model_name}" --tags_ids="${tags_ids}"
Response
{
"id": "1234567d-1111-2222-3333-12345abcd123",
"amount_of_samples": 1,
"model": "ancestry data model one",
"org_name": "your org name",
"src_file_id": "b91dc168-5720-4f04-911f-a1c5aa14606d",
"src_file_name": "filename.txt.zip",
"src_file_short_path": "web_upload/2023-09-25/filename.txt.zip",
"status": "Registered",
"started_at": "2023-09-25T08:38:46.649136Z",
"submitted_by": "your@email",
"tags": [],
"type": "GNT"
}
Submit execution order with model without reports.
All available models for your organization can be get in about me
Model API without report generation
- Skywalker
- Hutt
- Palpatine
| Possible results | Description |
|---|---|
| SUMMARY_CHROMS | Summary set of chromosomes, tsv file |
| SUMMARY_SUPERSET | Summary superset of labels, tsv file |
| DETAILED_CHROMS | Detailed set of labels by chromosome |
| DETAILED_SUPERSET | Detailed superset of labels by chromosome, zip archive |
| EXEC_ERRORS | Execution errors, contains errors about data processing |
Payload fields:
- Required fields:
- source_file_id
- model_name
- Optional fields:
- tags_ids
| Payload example: |
|---|
| { 'source_file_id': source_file_id, 'model_name': 'ancestry data model one', 'tags_ids': ['9085d0d2-3333-1111-2222-4114602c2aa6'] } |
Ancestry PDF order
Use access_token from Authentication step.
Instruction to Configure wrapper and clientSubmit execution order using source_file_id and model name.
url_api = 'https://api.dev.galatea.bio/api/v1'
url_orders = f'{url_api}/exec/orders'
payload = {
'source_file_id': source_file_id,
'model_name': 'ancestry pdf model',
'tags_ids': ['9085d0d2-3333-1111-2222-4114602c2aa6'],
'pdf_metadata': {'patient_name': 'Patient Name'},
}
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.post(url_orders, json=payload, headers=headers)
print(response.text)
source_file_id = '3fa85f64-5717-4562-b3fc-2c963f66afa6'
model_name = 'ancestry pdf model'
tags_ids = ['9085d0d2-3333-1111-2222-4114602c2aa6']
pdf_metadata = {'patient_name': 'Patient Name'}
order_obj = octopod_client.order_api.submit_order(
file_id=source_file_id,
model_name=model_name,
tags_ids=tags_ids,
pdf_metadata=pdf_metadata,
)
source_file_id="3fa85f64-5717-4562-b3fc-2c963f66afa6"
model_name="ancestry pdf model"
pdf_metadata="{\"patient_name\": \"Patient Name\"}"
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/exec/orders' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"source_file_id": "${source_file_id}",
"model_name": "${model_name}",
"tags_ids": ["9085d0d2-3333-1111-2222-4114602c2aa6"],
"pdf_metadata": "${pdf_metadata}"
}'
source_file_id="3fa85f64-5717-4562-b3fc-2c963f66afa6"
model_name="ancestry pdf model"
tags_ids='9085d0d2-3333-1111-2222-4114602c2aa6,12345672-1111-2222-3333-456789012345'
pdf_metadata="{\"patient_name\": \"Patient Name\"}"
octo submit-order --file_id="${source_file_id}" --model="${model_name}" --tags_ids="${tags_ids}" --pdf_metadata="${pdf_metadata}"
Response
{
"id": "1234567d-1111-2222-3333-12345abcd123",
"amount_of_samples": 1,
"model": "ancestry pdf model",
"org_name": "your org name",
"src_file_id": "b91dc168-5720-4f04-911f-a1c5aa14606d",
"src_file_name": "filename.txt.zip",
"src_file_short_path": "web_upload/2023-09-25/filename.txt.zip",
"status": "Registered",
"started_at": "2023-09-25T08:38:46.649136Z",
"submitted_by": "your@email",
"tags": [],
"type": "GNT",
"pdf_metadata": "{\"patient_name\": \"Patient Name\"}"
}
Submit execution order with ancestry report model.
All available models for your organization can be get in about me
Model API with ancestry PDF report generation
- Vader
| Possible results | Description |
|---|---|
| SUMMARY_CHROMS | Summary set of chromosomes, tsv file |
| SUMMARY_SUPERSET | Summary superset of labels, tsv file |
| DETAILED_CHROMS | Detailed set of labels by chromosome |
| DETAILED_SUPERSET | Detailed superset of labels by chromosome, zip archive |
| EXEC_ERRORS | Execution errors, contains errors about data processing |
| PDF_REPORT | All generated PDF reports in zip archive |
Payload fields:
- Required fields:
- source_file_id
- model_name
- Optional fields:
- tags_ids
- pdf_metadata
| pdf_metadata acceptable format | type | requirement |
|---|---|---|
| patient_name | 'string' | required |
| Payload example: |
|---|
| { 'source_file_id': source_file_id, 'model_name': 'ancestry pdf model', 'tags_ids': ['9085d0d2-3333-1111-2222-4114602c2aa6'], 'pdf_metadata': {'patient_name': 'Patient Name'} } |
PRS PDF order
Use access_token from Authentication step.
Instruction to Configure wrapper and clientSubmit execution order using source_file_id and model name.
url_api = 'https://api.dev.galatea.bio/api/v1'
url_orders = f'{url_api}/exec/orders'
payload = {
'source_file_id': source_file_id,
'model_name': 'prs clinical model',
'tags_ids': ['9085d0d2-3333-1111-2222-4114602c2aa6'],
'pdf_report_types': ['PRS_RUO_CARDIO', 'PRS_RUO_CANCER', 'PRS_CLINICAL_CARDIO', 'PRS_CLINICAL_CANCER'],
'pdf_metadata': {
'patient_name': 'Patient Name',
'dob': '2000-01-30',
'sex': 'Female',
'patient_id': '111-222-333-444-abc',
'accession': '123str',
'sample_id': 'sample-id-123',
'collected': '2025-07-01',
'received': '2025-07-15',
'specimen_type': 'specimen type',
'provider_name': 'Provider Name',
'referring_facility': '123-456-789',
'address': '777888 street',
},
}
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.post(url_orders, json=payload, headers=headers)
print(response.text)
source_file_id = '3fa85f64-5717-4562-b3fc-2c963f66afa6'
model_name = 'prs clinical model'
tags_ids = ['9085d0d2-3333-1111-2222-4114602c2aa6']
pdf_report_types = ["PRS_RUO_CARDIO", "PRS_RUO_CANCER", "PRS_CLINICAL_CARDIO", "PRS_CLINICAL_CANCER"]
pdf_metadata = {
'patient_name': 'Patient Name',
'dob': '2000-01-30',
'sex': 'Female',
'patient_id': '111-222-333-444-abc',
'accession': '123str',
'sample_id': 'sample-id-123',
'collected': '2025-07-01',
'received': '2025-07-15',
'specimen_type': 'specimen type',
'provider_name': 'Provider Name',
'referring_facility': '123-456-789',
'address': '777888 street',
}
order_obj = octopod_client.order_api.submit_order(
file_id=source_file_id,
model_name=model_name,
tags_ids=tags_ids,
pdf_report_types=pdf_report_types,
pdf_metadata=pdf_metadata,
)
source_file_id="3fa85f64-5717-4562-b3fc-2c963f66afa6"
model_name="prs clinical model"
pdf_metadata = "{\"patient_name\":\"Patient Name\",\"dob\":\"2000-01-30\",\"sex\":\"Female\",\"patient_id\":\"111-222-333-444-abc\",\"accession\":\"123str\",\"sample_id\":\"sample-id-123\",\"collected\":\"2025-07-01\",\"received\":\"2025-07-15\",\"specimen_type\":\"specimen type\",\"provider_name\":\"Provider Name\",\"referring_facility\":\"123-456-789\",\"address\":\"777888 street\"}"
curl -X 'POST' \
'https://api.dev.galatea.bio/api/v1/exec/orders' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json' \
-d '{
"source_file_id": "${source_file_id}",
"model_name": "${model_name}",
"tags_ids": ["9085d0d2-3333-1111-2222-4114602c2aa6"],
"pdf_report_types": "${pdf_report_types}",
"pdf_metadata": "${pdf_metadata}"
}'
source_file_id="3fa85f64-5717-4562-b3fc-2c963f66afa6"
model_name="prs clinical model"
tags_ids='9085d0d2-3333-1111-2222-4114602c2aa6,12345672-1111-2222-3333-456789012345'
pdf_report_types = "PRS_RUO_CARDIO,PRS_RUO_CANCER,PRS_CLINICAL_CARDIO,PRS_CLINICAL_CANCER"
pdf_metadata = "{\"patient_name\":\"Patient Name\",\"dob\":\"2000-01-30\",\"sex\":\"Female\",\"patient_id\":\"111-222-333-444-abc\",\"accession\":\"123str\",\"sample_id\":\"sample-id-123\",\"collected\":\"2025-07-01\",\"received\":\"2025-07-15\",\"specimen_type\":\"specimen type\",\"provider_name\":\"Provider Name\",\"referring_facility\":\"123-456-789\",\"address\":\"777888 street\"}"
octo submit-order --file_id="${source_file_id}" --model="${model_name}" --tags_ids="${tags_ids}" --pdf_report_types="${pdf_report_types}" --pdf_metadata="${pdf_metadata}"
Response
{
"id": "1234567d-1111-2222-3333-12345abcd123",
"amount_of_samples": 1,
"model": "prs clinical model",
"org_name": "your org name",
"src_file_id": "b91dc168-5720-4f04-911f-a1c5aa14606d",
"src_file_name": "filename.txt.zip",
"src_file_short_path": "web_upload/2023-09-25/filename.txt.zip",
"status": "Registered",
"started_at": "2023-09-25T08:38:46.649136Z",
"submitted_by": "your@email",
"tags": [],
"type": "GNT",
"pdf_metadata": "{\"patient_name\":\"Patient Name\",\"dob\":\"2000-01-30\",\"sex\":\"Female\",\"patient_id\":\"111-222-333-444-abc\",\"accession\":\"123str\",\"sample_id\":\"sample-id-123\",\"collected\":\"2025-07-01\",\"received\":\"2025-07-15\",\"specimen_type\":\"specimen type\",\"provider_name\":\"Provider Name\",\"referring_facility\":\"123-456-789\",\"address\":\"777888 street\"}"
}
Submit execution order with PRS reports model.
All available models for your organization can be get in about me
Model API with PRS PDF report generation
- Mysterio
| Possible results | Description |
|---|---|
| SUMMARY_SUPERSET | Summary superset of labels, tsv file |
| DETAILED_SUPERSET | Detailed superset of labels by chromosome, zip archive |
| EXEC_ERRORS | Execution errors, contains errors about data processing |
| PDF_REPORT | All generated PDF reports in zip archive |
| PRS_JSON_DATA | PRS data in json files per report type, zip archive |
| PRS_IMAGES | PRS diagrams in png for high risk items, zip archive |
Payload fields:
- Required fields:
- source_file_id
- model_name
- pdf_report_types
- pdf_metadata
- Optional fields:
- tags_ids
| Acceptable values for pdf_report_types | Description |
|---|---|
| PRS_RUO_CARDIO | Research usage cardiometabolic report |
| PRS_RUO_CANCER | Research usage cancer report |
| PRS_CLINICAL_CARDIO | Clinical usage cardiometabolic report |
| PRS_CLINICAL_CANCER | Clinical usage cancer report |
IMPORTANT: For cancer reports (PRS_RUO_CANCER, PRS_CLINICAL_CANCER) biological sex is required field with acceptable values Male or Female only and case insensitive.
| pdf_metadata acceptable format | type | requirement |
|---|---|---|
| patient_name | 'string' | optional |
| dob | 'string, date format(YYYY-MM-DD)' | optional |
| sex | 'string' | optional for cardio, required for cancer |
| patient_id | 'string' | optional |
| accession | 'string' | optional |
| sample_id | 'string' | optional |
| collected | 'string, date format(YYYY-MM-DD)' | optional |
| received | 'string, date format(YYYY-MM-DD)' | optional |
| specimen_type | 'string' | optional |
| provider_name | 'string' | optional |
| referring_facility | 'string' | optional |
| address | 'string' | optional |
| Payload examples: |
|---|
| { 'source_file_id': source_file_id, 'model_name': 'prs clinical model', 'tags_ids': ['9085d0d2-3333-1111-2222-4114602c2aa6'], 'pdf_report_types': ['PRS_CLINICAL_CARDIO', 'PRS_CLINICAL_CANCER'], 'pdf_metadata': { 'patient_name': 'Patient Name', 'dob': '2000-01-30', 'sex': 'Female', 'patient_id': '111-222-333-444-abc', 'accession': '123str', 'sample_id': 'sample-id-123', 'collected': '2025-07-01', 'received': '2025-07-15', 'specimen_type': 'specimen type', 'provider_name': 'Provider Name', 'referring_facility': '123-456-789', 'address': '777888 street', } |
| { 'source_file_id': source_file_id, 'model_name': 'prs clinical model', 'pdf_report_types': ['PRS_CLINICAL_CARDIO', 'PRS_CLINICAL_CANCER'], 'pdf_metadata': { 'sex': 'male' } |
Get order info and get results
Use access_token from Authentication step.
Instruction to Configure wrapper and client
import requests
order_id = 'fc79a3e0-2222-3333-4444-506897b4f808'
url_api = 'https://api.dev.galatea.bio/api/v1'
url_orders = f'{url_api}/exec/orders?filter={order_id}'
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.get(url_orders, headers=headers)
print(f'order status: {json.loads(response.text)['results'][0]['status']}')
print(f'order result types: {json.loads(response.text)['results'][0]['result_types']}')
order_id = 'fc79a3e0-2222-3333-4444-506897b4f808'
order_obj = octopod_client.order_api.find_order_by_id_or_file_id(order_id)
order_status = order_obj.get('status')
order_result_types = order_obj.get('result_types')
order_id='fc79a3e0-2222-3333-4444-506897b4f808'
curl -X 'GET' \
"https://api.dev.galatea.bio/api/v1/exec/orders?filter=${order_id}" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
order_id='fc79a3e0-2222-3333-4444-506897b4f808'
octo find-order --order_id_or_file_id="$order_id"
Response
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "fc79a3e0-2222-3333-4444-506897b4f808",
"status": "Completed",
"src_file_id": "9085d0d2-3333-1111-2222-4114602c2aa6",
"src_file_short_path": "web-upload/2025-02-20/012716/filename.gvcf.gz",
"src_file_name": "filename.gvcf.gz",
"started_at": "2025-07-04T17:53:57.871506Z",
"amount_of_samples": 1,
"execution_time": 109.817911,
"submitted_by": "[email protected]",
"model": "ancestry data model one",
"type": "WGS",
"org_name": "Organization name",
"tags": [],
"result_types": [
{
"type": "SUMMARY_SUPERSET",
"label": "Summary superset"
},
{
"type": "DETAILED_SUPERSET",
"label": "Detailed superset by chromosome"
},
{
"type": "SUMMARY_CHROMS",
"label": "Summary chromosomes"
},
{
"type": "DETAILED_CHROMS",
"label": "Detailed labels by chromosome"
}
],
"can_request_pdf": false,
"virtual": false
}
]
}
Use one of result_types from the response to download it.
import requests
import shutil
order_id = 'fc79a3e0-2222-3333-4444-506897b4f808'
result_type = 'SUMMARY_CHROMS'
url_api = 'https://api.dev.galatea.bio/api/v1'
url = f'{url_api}/data/results/{order_id}/download?result_type={result_type}'
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.get(url, headers=headers, stream=True)
filename = response.headers['content-disposition'].split('; ')[1].split('=')[1].replace('"', '')
with open(filename, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
print(response.status_code)
order_id = 'fc79a3e0-2222-3333-4444-506897b4f808'
result_type = 'SUMMARY_CHROMS'
result_file_content: BytesIO, result_file_name: Optional[str] = octopod_client.result_api.download_result_file(
order_id=order_id,
result_type=result_type,
)
with open(result_file_name, "wb") as f:
f.write(result_file_content.getbuffer())
order_id='fc79a3e0-2222-3333-4444-506897b4f808'
result_type='SUMMARY_CHROMS'
curl -X 'GET' \
"https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type=${result_type}" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-o result_filename.tsv
order_id='fc79a3e0-2222-3333-4444-506897b4f808'
result_type='SUMMARY_CHROMS'
octo download-result-file --order_id="${order_id}" --result_type="${result_type}"
Avalable results of an order are related to configuration of your organization.
Results of order can be downloaded when order has one of statuses:
- Completed
- Failed
- Reports failed
- Get order info, all available results for downloading are in result_types section.
- Download result file using order_id and one of result types from the order.
If order has status Failed, errors can be downloaded with result_type='EXEC_ERRORS'.
Possible result types for downloading:
| Results type | Description |
|---|---|
| SUMMARY_CHROMS | Summary set of chromosomes, tsv file |
| SUMMARY_SUPERSET | Summary superset of labels, tsv file |
| DETAILED_CHROMS | Detailed set of labels by chromosome |
| DETAILED_SUPERSET | Detailed superset of labels by chromosome, zip archive |
| EXEC_ERRORS | Execution errors, contains errors about data processing |
| PDF_REPORT | All generated PDF reports in zip archive |
| PRS_JSON_DATA | PRS data in json files per report type, zip archive |
| PRS_IMAGES | PRS diagrams in png for high risk items, zip archive |
If configured websocket notifications for orders,
once an order will reach final status will be sent notification about it.
Download PDF reports
Supported 2 types of download:
- downloading all results as ZIP archive
- downloading one of reports from order by pdf_report_id
Get ZIP with PDF reports
Use auth_token from Authentication step.
Instruction to Configure wrapper and client
import requests
import shutil
order_id = '1234567d-1111-2222-3333-12345abcd123'
result_type = 'PDF_REPORT'
url = f'https://api.dev.galatea.bio/api/v1/data/results/{order_id}/download?result_type={result_type}'
headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Bearer <<access_token>>"
}
response = requests.get(url, headers=headers, stream=True)
filename = response.headers['content-disposition'].split('; ')[1].split('=')[1].replace('"', '')
with open(filename, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
print(response.status_code)
order_id = '1234567d-1111-2222-3333-12345abcd123'
result_type = 'PDF_REPORT'
result_file_content: BytesIO, result_file_name: Optional[str] = octopod_client.result_api.download_result_file(
order_id=order_id,
result_type=result_type,
)
with open(result_file_name, "wb") as f:
f.write(result_file_content.getbuffer())
curl -X 'GET' \
'https://api.dev.galatea.bio/api/v1data/results/1234567d-1111-2222-3333-12345abcd123/download?result_type=PDF_REPORT' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-o result_filename.tsv
order_id='1234567d-1111-2222-3333-12345abcd123'
result_type="PDF_REPORT"
octo download-result-file --order_id="${order_id}" --result_type="${result_type}"
When an order is completed, all pdf reports are stored into 1 zip archive.
result_type parameter for downloading zip archive: result_type=PDF_REPORT
Get single PDF report file
Use auth_token from Authentication step.
Instruction to Configure wrapper and clientGet list of PDF reports for order
import requests
order_id = '1234567d-1111-2222-3333-12345abcd123'
url_api = 'https://api.dev.galatea.bio/api/v1'
url_order_pdf = f'{url_api}/data/results/{order_id}/pdf_report?page_size=1000'
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.get(url_order_pdf, headers=headers)
print(response.text)
order_id = '1234567d-1111-2222-3333-12345abcd123'
octopod_client.result_api.list_pdf_reports(order_id=order_id)
order_id='1234567d-1111-2222-3333-12345abcd123'
curl -X 'GET' \
"https://api.dev.galatea.bio/api/v1/data/results/{$order_id}/pdf_report?page_size=1000" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-H 'Content-Type: application/json'
order_id='1234567d-1111-2222-3333-12345abcd123'
octo list-result-pdf-reports --order_id="${order_id}"
Response:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "91e29ebd-e0b2-46bf-b060-8b1b9be42612",
"status": "COMPLETED",
"sample_id": "sandbox-0-fb82245c-3708",
"order_id": "1234567d-1111-2222-3333-12345abcd123",
"result_id": "b27d241d-1022-4104-b99a-6f57fdfdf09c",
"org_name": "Organization Name",
"report_type": "PRS_RUO_CANCER",
"request_type": "ORDER",
"request_version": 1,
"report_version": "",
"pdf_file_name": "91e29ebd-e0b2-46bf-b060-8b1b9be42612_sandbox-0-fb82245c-3708_prs-ruo-cancer.pdf",
"file_size_bytes": 1009409,
"check_sum": "bf32dd3fb73694892f0c775fa95ad63a",
"started_at": "2025-07-04T17:56:32.933564Z",
"completed_at": "2025-07-04T17:56:46.138287Z"
},
{
"id": "5639d15b-0dc8-4c61-ada0-ec39b1ad5417",
"status": "COMPLETED",
"sample_id": "sandbox-0-fb82245c-3708",
"order_id": "1234567d-1111-2222-3333-12345abcd123",
"result_id": "b27d241d-1022-4104-b99a-6f57fdfdf09c",
"org_name": "Organization Name",
"report_type": "PRS_RUO_CARDIO",
"request_type": "ORDER",
"request_version": 1,
"report_version": "",
"pdf_file_name": "5639d15b-0dc8-4c61-ada0-ec39b1ad5417_sandbox-0-fb82245c-3708_prs-ruo-cardio.pdf",
"file_size_bytes": 3193962,
"check_sum": "421373d67eaa44a249ee56bebd3529ed",
"started_at": "2025-07-04T17:56:06.027039Z",
"completed_at": "2025-07-04T17:56:28.092727Z"
}
]
}
Download one completed PDF report file.
import requests
import shutil
order_id = '1234567d-1111-2222-3333-12345abcd123'
pdf_request_id = '91e29ebd-e0b2-46bf-b060-8b1b9be42612'
url_api = 'https://api.dev.galatea.bio/api/v1'
url = f'{url_api}/data/results/{order_id}/download?result_type=PDF_REPORT&pdf_request_id={pdf_request_id}'
headers = {
'accept': 'application/json',
'Authorization': auth_token
}
response = requests.get(url, headers=headers, stream=True)
filename = response.headers['content-disposition'].split('; ')[1].split('=')[1].replace('"', '')
with open(filename, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
print(response.status_code)
order_id = '1234567d-1111-2222-3333-12345abcd123'
pdf_request_id = '91e29ebd-e0b2-46bf-b060-8b1b9be42612'
result_type = 'PDF_REPORT'
result_file_content: BytesIO, result_file_name: str = octopod_client.result_api.download_result_file(
order_id=order_id,
result_type=result_type,
pdf_request_id=pdf_request_id,
)
with open(result_file_name, "wb") as f:
f.write(result_file_content.getbuffer())
order_id='1234567d-1111-2222-3333-12345abcd123'
pdf_request_id='91e29ebd-e0b2-46bf-b060-8b1b9be42612'
curl -X 'GET' \
"https://api.dev.galatea.bio/api/v1/data/results/{$order_id}/download?result_type=PDF_REPORT&pdf_request_id={$pdf_request_id}" \
-H 'accept: application/json' \
-H 'Authorization: Bearer <<access_token>>' \
-o result_filename.tsv
order_id='1234567d-1111-2222-3333-12345abcd123'
pdf_request_id='91e29ebd-e0b2-46bf-b060-8b1b9be42612'
result_type="PDF_REPORT"
octo download-result-file --order_id="${order_id}" --result_type="${result_type} --pdf_request_id="${pdf_request_id}"
To download single completed report:
1. Get list of pdf reports in order results.
2. Download PDF report using pdf_request_id.
Handling webhooks deliveries
Prepare FastAPI webserver
import base64
import hashlib
import hmac
import json
import uvicorn
from fastapi import FastAPI, Request, Depends, Response
app = FastAPI()
async def get_body(request: Request):
return await request.body()
@app.post("/webhook_handler/")
async def webhook_handler(request: Request, payload: bytes = Depends(get_body)):
signature_header = request.headers.get('X-Octopod-Signature')
if signature_header is None:
print('Incorrect webhook: signature header is missed.')
return Response(status_code=422)
payload_str = payload.decode("utf-8")
sender_host = 'api.dev.galatea.bio'
signature_data = sender_host + payload_str
webhooks_secret = 'webhooks-secret'
signature = base64.b64encode(
hmac.new(
key=bytes(webhooks_secret, 'utf-8'),
msg=bytes(signature_data, 'utf-8'),
digestmod=hashlib.sha256
).digest()
).decode()
if signature == signature_header:
print('signature is valid, processing webhook data')
payload_dict = json.loads(payload_str)
if payload_dict is None or payload_dict == {}:
print(f'Incorrect webhook: {payload_str}')
return Response(content='Incorrect webhook payload.', status_code=422)
# webhook for order
if 'order_id' in payload_dict and 'new_status' in payload_dict and 'source_file_id' in payload_dict and 'source_file_name' in payload_dict:
order_id = payload_dict.get('order_id', None)
new_status = payload_dict.get('new_status', None)
source_file_id = payload_dict.get('source_file_id', None)
source_file_name = payload_dict.get('source_file_name', None)
print(f'Received webhook for order:\n'
f'order_id: {order_id}\n'
f'new_status: {new_status}\n'
f'source_file_id: {source_file_id}\n'
f'source_file_name: {source_file_name}')
return Response(status_code=200)
# webhook for source file
if 'new_status' in payload_dict and 'source_file_id' in payload_dict and 'source_file_name' in payload_dict:
new_status = payload_dict.get('new_status', None)
source_file_id = payload_dict.get('source_file_id', None)
source_file_name = payload_dict.get('source_file_name', None)
print(f'Received webhook for source file:\n'
f'new_status: {new_status}\n'
f'source_file_id: {source_file_id}\n'
f'source_file_name: {source_file_name}')
return Response(status_code=200)
return Response(status_code=422)
# use python code example
# use python code example
# use python code example
Start FastAPI webserver
fastapi dev main.py --host 0.0.0.0 --port 8888
# use python code example
# use python code example
# use python code example
Source file validation JSON response
{
"source_file_id": "7e53320c-c631-45ec-bad6-c88bb9d30960",
"new_status": "VALID",
"source_file_name": "d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz"
}
Order completion JSON payload
{
"order_id": "c1ea8279-25c2-4a36-9ea6-41e54239f17b",
"new_status": "COMPLETED",
"source_file_id": "7e53320c-c631-45ec-bad6-c88bb9d30960",
"source_file_name": "d101979c-348c-44cd-8279-e9207b5a67a7.vcf.gz"
}
This example is based on FastAPI.
Assuming webserver is available on public address and routes to FastAPI server.
Organization Admins can configure webhooks for source files and orders.
webhooks-secret is available on Intergations -> Webhooks tab.
sender_host is api.dev.galatea.bio
Note: for sandbox use host api.sandbox.galatea.bio
- Available 2 types of events for webhooks:
- Source file validation completed
- Order moved to completed stay
Source file validation completed: once validation for uploaded file completed, notification will be sent with results.
Order moved to completed stay: once order passed to one of final stay - Completed or Failed, notification will be sent.
Example:
| Webhook type | Address |
|---|---|
| Source file validation completed | https://webhooks.example.com/webhook_handler/ |
| Order moved to completed stay | https://webhooks.example.com/webhook_handler/ |
On Test webhook will be send messages with fake data:
| Webhook type | Message |
|---|---|
| Source file validation completed | { "new_status": "VALID", "source_file_id": "11111111-1111-1111-1111-111111111111", "source_file_name": "test_message_source_file_validated.vcf.gz" } |
| Order moved to completed stay | { "order_id": "22222222-2222-2222-2222-222222222222", "new_status": "COMPLETED", "source_file_id": "33333333-3333-3333-3333-333333333333", "source_file_name": "test_message_order_completed.vcf.gz" } |
Errors
The GalateaBio Ancestry API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request is invalid. |
| 401 | Unauthorized -- Your API key is wrong. |
| 403 | Forbidden -- The information requested is hidden for administrators only. |
| 404 | Not Found -- The specified information could not be found. |
| 405 | Method Not Allowed -- You tried to access an information with an invalid method. |
| 406 | Not Acceptable -- You requested a format that isn't json. |
| 422 | Unprocessable Entity -- Your request contains incorrect data. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |