API Reference
Synthyra API
Build with protein AI. Annotate protein function, generate sequences, and train chemical language models through a unified REST API.
Quick Start
1
Generate an API key at synthyra.com/settings?section=api-keys after signing in. Treat it like a password, do not commit it to git or share it publicly.
2
Paste the key directly into your script (assign it to a variable) or export it as an environment variable, both patterns are shown below.
3
Pass the key in the Authorization header (Bearer token) on every request:
import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post(
"https://api.synthyra.com/v1/translator/run",
headers={"Authorization": f"Bearer {api_key}"},
json={"sequences": ["MEEPQSDPSV..."], "ids": ["TP53"]},
)
print(response.json())Authentication
Every authenticated endpoint expects an Authorization: Bearer <your-key> header. Requests without a valid key return 401 Unauthorized. Generate a key at synthyra.com/settings?section=api-keys. Only /health and the Protify metadata GETs accept unauthenticated reads.
# Python: paste your key into the api_key variable, send as a header
import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post(
"https://api.synthyra.com/v1/translator/run",
headers={"Authorization": f"Bearer {api_key}"},
json={"sequences": ["MEEPQSDP..."], "ids": ["TP53"]},
)
# curl: same Bearer header, key passed inline or as $SYNTHYRA_API_KEY env var
curl -H "Authorization: Bearer sk-..." \
https://api.synthyra.com/v1/jobsPricing
Token-metered calls are priced per million tokens, the way language-model APIs are. In the prices below a token is one amino acid of a protein or one token of a ligand. Annotation routes count the amino acids of every sequence they run. Atlas scoring counts each distinct input once per request, so its cost grows with your sequences, not with the pairs you score. Every call's cost appears on its job in /v1/jobs as cost (dollars) and cost_tokens, the billing units behind it at $0.00025 each: two 400-residue proteins scored against each other are 800 amino acids, $0.04, 160 billing tokens.
| Endpoints | Billed by | Price |
|---|---|---|
| /v1/atlas-ppi/score, /v1/atlas-pli/score and their /batch routes | Tokens of each distinct input, counted once per request | $50 per 1M tokens |
| /v1/translator/run, /v1/translator/batch | Amino acids of every sequence | $300 per 1M tokens |
| /v1/oracles/run, /v1/oracle/run, /v1/oracle/{probe}, and their /batch routes | Amino acids of every sequence | $800 per 1M tokens |
| /v1/camp/run, /v1/camp/batch | Amino acids of every sequence | $300 per 1M tokens |
| /v1/deep-research/generate | Protein analyzed | $25 per protein |
12 endpoints
Protein Intelligence Platform
Protein interaction scoring and functional annotation. Score protein-protein interaction pairs, annotate sequences with Translator, oracle probes and CAMP, track jobs, and produce AI-driven deep research reports.
Interaction Scoring
/v1/atlas-ppi/score
Score protein-protein interaction pairs
Scores each pair (inputs_a[i], inputs_b[i]) with Atlas-PPI and returns one interaction probability per pair, in order. Synchronous: at most 1,000 pairs and 400 distinct sequences per request; larger requests return 413. Sequences use one-letter amino-acid codes in either case, and codes outside the 20 canonical residues are read as X. If the model is starting cold and does not answer within about 85 seconds, the call returns 503 warming_up with a Retry-After header and nothing is billed; retry after the suggested delay. Billed by input tokens, not pairs: the residues of each distinct sequence in the request count once, however many pairs it appears in, at $50 per million tokens. Two 400-residue proteins scored against each other are 800 tokens, $0.04.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
inputs_a required | string[] | - | A-side protein sequences. Same length as inputs_b. |
inputs_b required | string[] | - | B-side protein sequences. Pair i is (inputs_a[i], inputs_b[i]). |
ids_a optional | string[] | - | Optional IDs for inputs_a, echoed back. One per input. |
ids_b optional | string[] | - | Optional IDs for inputs_b, echoed back. One per input. |
both_directions optional | boolean | - | Score each pair as A->B and B->A and average the two. Defaults to the deployed model setting. |
cross_reference optional | boolean | false | Also look each pair up in STRING, BioGRID and BioGRID-MV. Requires ids_a and ids_b as UniProt accessions. |
Response
{
"ids_a": ["P0CG48"],
"ids_b": ["P01308"],
"scores": [0.0521],
"all_vs_all": false,
"both_directions": true,
"score_kind": "probability",
"model_path": "Synthyra/Atlas-PPI",
"job_id": "x1o0vhOPbRNCVSIPTvVI"
}Examples
curl -X POST https://api.synthyra.com/v1/atlas-ppi/score \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"inputs_a": ["MQIFVKTLTG..."], "inputs_b": ["FVNQHLCGSH..."], "ids_a": ["P0CG48"], "ids_b": ["P01308"], "both_directions": true}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post(
"https://api.synthyra.com/v1/atlas-ppi/score",
headers={"Authorization": f"Bearer {api_key}"},
json={
"inputs_a": ["MQIFVKTLTG..."],
"inputs_b": ["FVNQHLCGSH..."],
"ids_a": ["P0CG48"],
"ids_b": ["P01308"],
"both_directions": True,
},
)
print(response.json()["scores"])Jobs
/v1/jobs
List your jobs
Lists jobs newest first: every job in your active organization, or your own jobs if you have no organization. Synchronous calls such as /v1/atlas-ppi/score also appear here as completed jobs with their cost. Paginate by passing next_cursor back as cursor.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
status optional | string | - | Filter by status, e.g. queued, running, complete, failed. |
type optional | string | - | Filter by job type, e.g. atlas_ppi_score, network, batch. |
page_size optional | number | 20 | Jobs per page (1-100). |
cursor optional | string | - | The next_cursor from the previous page. |
Response
{
"jobs": [
{
"jobId": "x1o0vhOPbRNCVSIPTvVI",
"status": "complete",
"jobType": "atlas_ppi_score",
"name": "Atlas-PPI score: 1 pairs",
"createdAt": "2026-09-26T20:39:06.508000+00:00",
"completedAt": "2026-09-26T20:39:06.508000+00:00",
"queryProteins": ["P0CG48"],
"cost": 0.04,
"costTokens": 160,
"withinPlan": false
}
],
"next_cursor": "x1o0vhOPbRNCVSIPTvVI"
}Examples
curl "https://api.synthyra.com/v1/jobs?page_size=20" \
-H "Authorization: Bearer $SYNTHYRA_API_KEY"import requests
api_key = "sk-..."
response = requests.get(
"https://api.synthyra.com/v1/jobs",
headers={"Authorization": f"Bearer {api_key}"},
params={"page_size": 20},
)
for job in response.json()["jobs"]:
print(job["jobId"], job["jobType"], job["status"])/v1/job/{job_id}
Get job status
Returns one job. Poll this for async jobs until status is complete or failed. Small results come back inline in result; fetch large ones from /v1/job/{job_id}/result. cost is the charge in dollars and cost_tokens the billing units behind it, at $0.00025 each; the per-million-token prices on this page count amino acids, so two 400-residue proteins scored against each other (800 amino acids, $0.04) show cost_tokens: 160.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Path parameter: the job_id returned when the job was created. |
Response
{
"job_id": "x1o0vhOPbRNCVSIPTvVI",
"status": "complete",
"job_type": "atlas_ppi_score",
"name": "Atlas-PPI score: 1 pairs",
"result": null,
"output_url": null,
"error": null,
"stage": null,
"created_at": "2026-09-26T20:39:06.508000+00:00",
"completed_at": "2026-09-26T20:39:06.508000+00:00",
"query_proteins": ["P0CG48"],
"job_config": null,
"cost": 0.04,
"cost_tokens": 160,
"within_plan": false
}Examples
curl https://api.synthyra.com/v1/job/JOB_ID \
-H "Authorization: Bearer $SYNTHYRA_API_KEY"import time
import requests
api_key = "sk-..."
headers = {"Authorization": f"Bearer {api_key}"}
while True:
job = requests.get(f"https://api.synthyra.com/v1/job/{job_id}", headers=headers).json()
if job["status"] in ("complete", "failed"):
break
time.sleep(5)/v1/job/{job_id}/result
Get a completed job result
Returns the full result of a completed job, whether it was stored inline or in storage. Returns 409 while the job is still running, and 404 if the job produced no stored result.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Path parameter: the job ID. |
Response
{ "...": "job-type-specific result JSON" }Examples
curl https://api.synthyra.com/v1/job/JOB_ID/result \
-H "Authorization: Bearer $SYNTHYRA_API_KEY"import requests
api_key = "sk-..."
result = requests.get(
f"https://api.synthyra.com/v1/job/{job_id}/result",
headers={"Authorization": f"Bearer {api_key}"},
).json()/v1/job/{job_id}
Delete a job
Deletes a job you can access. Returns 204 with no body.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Path parameter: the job ID. |
Response
(empty, HTTP 204)Examples
curl -X DELETE https://api.synthyra.com/v1/job/JOB_ID \
-H "Authorization: Bearer $SYNTHYRA_API_KEY"import requests
api_key = "sk-..."
requests.delete(
f"https://api.synthyra.com/v1/job/{job_id}",
headers={"Authorization": f"Bearer {api_key}"},
).raise_for_status()Translator
/v1/translator/run
Annotate sequences with functional terms
For each input sequence, returns top-K natural-language functional annotations (GO biological process, GO molecular function, GO cellular component, EC numbers, family memberships, etc.) with confidence scores 0-100. Powered by the Translator model trained on the Annotation Vocabulary. Billed by the amino acids of every sequence annotated, at $300 per million tokens. Batched: pass up to 64 sequences per call.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
sequences required | string[] | - | Protein sequences in single-letter amino-acid codes (1-64 per call, max 2048 residues each) |
ids required | string[] | - | Caller-supplied IDs, same length as sequences. Echoed back in each result row. |
num_annotations optional | number | 32 | Number of annotation positions to decode per sequence (1-64). |
top_k optional | number | 3 | Top-K annotation candidates per position; deduplicated across positions (1-10). |
Response
{
"job_id": "abcd1234...",
"results": [
{
"protein_id": "TP53",
"annotations": [
{ "annotation_id": "GO:0006915", "name": "apoptotic process", "aspect": "Biological Process", "confidence": 97 },
{ "annotation_id": "GO:0003700", "name": "DNA-binding transcription factor activity", "aspect": "Molecular Function", "confidence": 94 },
{ "annotation_id": "GO:0005634", "name": "nucleus", "aspect": "Cellular Component", "confidence": 91 }
]
}
]
}Examples
curl -X POST https://api.synthyra.com/v1/translator/run \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sequences": ["MEEPQSDPSV..."], "ids": ["TP53"], "top_k": 3}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post(
"https://api.synthyra.com/v1/translator/run",
headers={"Authorization": f"Bearer {api_key}"},
json={"sequences": ["MEEPQSDPSV..."], "ids": ["TP53"], "top_k": 3},
)
for row in response.json()["results"]:
print(row["protein_id"], row["annotations"][:3])Oracles
/v1/oracles/run
Run all 14 InterpNet probes on each sequence
For each input sequence, runs all 14 InterpNet oracle probes and returns a per-oracle prediction per sequence. Valid probe identifiers: realness, solubility, soluprot, temperature-stability, ecoli-expression, kcat, ph, Subcellular, taxon, homodimer, ec_rigor, ec_general, go_rigor, go_general. Billed by the amino acids of every sequence, at $800 per million tokens for all 14 probes. Batched: pass up to 64 sequences per call.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
sequences required | string[] | - | Protein sequences (1-64 per call) |
ids required | string[] | - | Caller-supplied IDs, same length as sequences. Echoed back in each result row. |
Response
{
"job_id": "abcd1234...",
"results": [
{
"protein_id": "TP53",
"predictions": [
{ "oracle_name": "realness", "score": 0.97, "score_mode": "binary_prob", "label_names": ["Synthetic", "Natural"] },
{ "oracle_name": "solubility", "score": 0.62, "score_mode": "binary_prob", "label_names": ["Insoluble", "Soluble"] },
{ "oracle_name": "Subcellular", "score": [0.05, 0.78, 0.02, ...], "score_mode": "multilabel_sigmoid", "label_names": ["Cytoplasm", "Nucleus", ...] },
{ "oracle_name": "ec_general", "score": [...], "score_mode": "multiclass_prob", "label_names": [...] }
]
}
]
}Examples
curl -X POST https://api.synthyra.com/v1/oracles/run \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sequences": ["MEEPQSDPSV..."], "ids": ["TP53"]}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post(
"https://api.synthyra.com/v1/oracles/run",
headers={"Authorization": f"Bearer {api_key}"},
json={"sequences": ["MEEPQSDPSV..."], "ids": ["TP53"]},
)
for row in response.json()["results"]:
for pred in row["predictions"]:
print(row["protein_id"], pred["oracle_name"], pred["score"])Function
/v1/camp/run
Score sequences against functional annotations
Atlas Function, served under its model name CAMP: scores protein sequences against pre-embedded SwissProt functional annotations by vector retrieval. Returns top-K annotation hits with similarity scores for each input sequence. Billed by the amino acids of every sequence scored, at $300 per million tokens. Batched: pass up to 64 sequences per call.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
sequences required | string[] | - | Protein sequences to annotate (1-64 per call) |
ids required | string[] | - | Identifiers for each sequence (same length as sequences) |
top_k optional | number | 10 | Number of top annotation hits to return per sequence (1-50) |
Response
{
"job_id": "abcd1234...",
"results": [
{
"protein_id": "P04637",
"annotations": [
{"annotation_id": "GO:0006915", "name": "apoptotic process", "aspect": "Biological Process", "score": 0.94},
{"annotation_id": "GO:0005634", "name": "nucleus", "aspect": "Cellular Component", "score": 0.89}
]
}
]
}Examples
curl -X POST https://api.synthyra.com/v1/camp/run \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sequences": ["MEEPQSDPSVEPPLSQETFSDLWKLLPENN..."],
"ids": ["P04637"],
"top_k": 10
}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post(
"https://api.synthyra.com/v1/camp/run",
headers={"Authorization": f"Bearer {api_key}"},
json={
"sequences": ["MEEPQSDPSVEPPLSQETFSDLWKLLPENN..."],
"ids": ["P04637"],
"top_k": 10,
},
)
for result in response.json()["results"]:
print(f"{result['protein_id']}: {result['annotations'][0]['name']}")/v1/camp/msa
Run MSA on query + CAMP hit sequences
Perform multiple sequence alignment between a query protein and sequences retrieved from CAMP hits. Useful for validating functional similarity through sequence conservation.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
query_name required | string | - | Identifier for the query sequence |
query_sequence required | string | - | Query protein sequence |
hit_names required | string[] | - | Identifiers for the CAMP hit sequences |
hit_sequences required | string[] | - | Protein sequences from CAMP hits |
Response
{
"alignment": {
"sequences": [
{"name": "P04637", "aligned": "MEEPQSDP--SVEPPL..."},
{"name": "Q9Y6K9", "aligned": "M--PQSDPAVSVEPPL..."}
],
"conservation": [1.0, 0.8, 0.6, ...]
}
}Examples
curl -X POST https://api.synthyra.com/v1/camp/msa \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query_name": "P04637",
"query_sequence": "MEEPQSDP...",
"hit_names": ["Q9Y6K9", "P10415"],
"hit_sequences": ["MPQSDPAV...", "MSQSNREL..."]
}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post("https://api.synthyra.com/v1/camp/msa",
headers={"Authorization": f"Bearer {api_key}"},
json={
"query_name": "P04637",
"query_sequence": "MEEPQSDP...",
"hit_names": ["Q9Y6K9", "P10415"],
"hit_sequences": ["MPQSDPAV...", "MSQSNREL..."],
})
alignment = response.json()["alignment"]Deep Research
/v1/deep-research/generate
ASYNCGenerate Atlas Deep Research report (async)
Launch an AI agent that orchestrates all Atlas APIs (network analysis, enrichment, oracle probes, CAMP, structure prediction) for comprehensive protein analysis and produces a detailed PDF report.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
proteins required | string[] | - | List of UniProt accessions to analyze |
input_type optional | string | "uniprot" | Input identifier type |
organism optional | string | "human" | Reference organism |
include_structure optional | boolean | true | Include ESMFold2 structure prediction |
include_oracles optional | boolean | true | Include oracle probe predictions |
Response
{"job_id": "abc123...", "status": "Waiting"}Examples
curl -X POST https://api.synthyra.com/v1/deep-research/generate \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"proteins": ["P04637"], "organism": "human"}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post("https://api.synthyra.com/v1/deep-research/generate",
headers={"Authorization": f"Bearer {api_key}"},
json={
"proteins": ["P04637"],
"organism": "human",
})
job_id = response.json()["job_id"]/v1/deep-research/job/{job_id}
Poll deep research job status
Check the status of a deep research generation job. Returns progress information including current step and completion percentage.
Response
{
"job_id": "abc123",
"status": "Running",
"summary_status": "executing",
"current_step": "Running network analysis",
"steps_completed": 3,
"total_steps": 8
}Examples
curl -H "Authorization: Bearer $SYNTHYRA_API_KEY" https://api.synthyra.com/v1/deep-research/job/abc123import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/deep-research/job/abc123",
headers={"Authorization": f"Bearer {api_key}"})/v1/deep-research/download/{job_id}
Download deep research PDF
Download the completed deep research report as a PDF file.
Response
Binary PDF file (application/pdf)Examples
curl -H "Authorization: Bearer $SYNTHYRA_API_KEY" -o report.pdf https://api.synthyra.com/v1/deep-research/download/abc123import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/deep-research/download/abc123",
headers={"Authorization": f"Bearer {api_key}"})
with open("report.pdf", "wb") as f:
f.write(response.content)12 endpoints
Chemical Language Model Training
Train and evaluate chemical language model probes on custom datasets. Choose from multiple backbones (ESM2, ProtTrans, Ankh, and more) and probe architectures (linear, transformer, Lyra). Jobs run on A100 GPUs with real-time log streaming.
Discovery
/v1/protify/models
List available base models
Returns all available protein language model backbones with their HuggingFace paths and supported probe types.
Response
{
"models": [
{
"family": "esm2",
"name": "ESM2-650M",
"hf_path": "facebook/esm2_t33_650M_UR50D",
"parameters": "650M",
"supported_probe_types": ["linear", "transformer", "lyra"]
}
]
}Examples
curl https://api.synthyra.com/v1/protify/modelsimport requests
response = requests.get("https://api.synthyra.com/v1/protify/models")
for model in response.json()["models"]:
print(f"{model['name']}: {model['hf_path']}")/v1/protify/probes
List available probe types
Returns all available probe architectures that can be trained on top of PLM backbones.
Response
{
"probes": [
{"name": "linear", "description": "Linear probe on frozen embeddings", "supports_lora": false},
{"name": "transformer", "description": "Transformer probe with attention layers", "supports_lora": true},
{"name": "lyra", "description": "Lyra probe with lightweight attention", "supports_lora": true}
]
}Examples
curl https://api.synthyra.com/v1/protify/probesimport requests
response = requests.get("https://api.synthyra.com/v1/protify/probes")/v1/protify/benchmarks
List available benchmark suites
Returns available benchmark suites for model evaluation including standard benchmarks, vector benchmarks, and ProteinGym.
Response
{
"benchmarks": [
{"name": "standard", "description": "Standard benchmark (12 tasks)", "task_type": "mixed", "num_sequences": 12},
{"name": "vector", "description": "Vector representation benchmark (28 tasks)", "task_type": "mixed", "num_sequences": 28},
{"name": "proteingym", "description": "ProteinGym DMS zero-shot scoring", "task_type": "regression", "num_sequences": 217}
]
}Examples
curl https://api.synthyra.com/v1/protify/benchmarksimport requests
response = requests.get("https://api.synthyra.com/v1/protify/benchmarks")/v1/protify/datasets
List available datasets
Returns all supported training/evaluation datasets with their HuggingFace paths.
Response
{
"datasets": [
{"name": "thermostability", "hf_path": "Synthyra/thermostability"}
]
}Examples
curl https://api.synthyra.com/v1/protify/datasetsimport requests
response = requests.get("https://api.synthyra.com/v1/protify/datasets")Jobs
/v1/protify/train
ASYNCSubmit training job (async)
Submit a Protify training job. Configure the base model, probe type, dataset, and training hyperparameters. Jobs run on A100 GPUs with up to 24 hours of compute time. Optionally auto-push trained weights to HuggingFace Hub.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
config required | object | - | Serialized ProtifyJobConfig with model, probe, dataset, and training parameters |
Response
{"job_id": "abc123...", "status": "Waiting"}Examples
curl -X POST https://api.synthyra.com/v1/protify/train \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"config": {
"base_model": "ESM2-650M",
"probe_type": "transformer",
"dataset_name": "thermostability",
"learning_rate": 1e-4,
"epochs": 10,
"batch_size": 32,
"gpu": "A100"
}
}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post("https://api.synthyra.com/v1/protify/train",
headers={"Authorization": f"Bearer {api_key}"},
json={
"config": {
"base_model": "ESM2-650M",
"probe_type": "transformer",
"dataset_name": "thermostability",
"learning_rate": 1e-4,
"epochs": 10,
},
})
job_id = response.json()["job_id"]/v1/protify/evaluate
ASYNCSubmit evaluation job (async)
Score a packaged probe export on a labelled split. Set config.job_type to "evaluate_model" and point config.model_path at the HuggingFace repo a training job pushed with hf_push enabled; a bare model_name cannot identify a trained probe. Returns a job_id you poll with /v1/protify/job.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
config required | object | - | Serialized ProtifyJobConfig with job_type="evaluate_model", model_path (packaged probe repo), and dataset_name |
Response
{"job_id": "abc123...", "status": "queued"}Examples
curl -X POST https://api.synthyra.com/v1/protify/evaluate \
-H "Authorization: Bearer $SYNTHYRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"config": {
"job_type": "evaluate_model",
"model_path": "your-org/esm2-650m-thermostability-probe",
"dataset_name": "thermostability",
"dataset_config": {"split": "test"}
}
}'import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post("https://api.synthyra.com/v1/protify/evaluate",
headers={"Authorization": f"Bearer {api_key}"},
json={
"config": {
"job_type": "evaluate_model",
"model_path": "your-org/esm2-650m-thermostability-probe",
"dataset_name": "thermostability",
"dataset_config": {"split": "test"},
},
})
job_id = response.json()["job_id"]/v1/protify/download/{job_id}
Download job artifacts (zip)
Download all artifacts for a completed Protify job (metrics, plots, and any trained weights) as a single zip archive. Only the job owner / org can download; the job must be complete.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Job ID (path parameter) |
Response
<binary application/zip stream>Examples
curl -L -H "Authorization: Bearer $SYNTHYRA_API_KEY" \
"https://api.synthyra.com/v1/protify/download/abc123" -o protify_abc123.zipimport requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/protify/download/abc123",
headers={"Authorization": f"Bearer {api_key}"})
with open("protify_abc123.zip", "wb") as f:
f.write(response.content)/v1/protify/job
Poll job status
Check the status of a Protify training or evaluation job. Returns phase information (embedding, training, evaluating, pushing_to_hub).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Job ID to check |
Response
{
"job_id": "abc123",
"status": "running",
"phase": "training",
"gpu_type": "A100",
"has_checkpoint": true,
"result": null,
"error": null
}Examples
curl -H "Authorization: Bearer $SYNTHYRA_API_KEY" "https://api.synthyra.com/v1/protify/job?job_id=abc123"import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/protify/job",
headers={"Authorization": f"Bearer {api_key}"}, params={"job_id": "abc123"})/v1/protify/jobs
List all Protify jobs
Returns a list of all Protify jobs sorted by creation time (newest first).
Response
{
"jobs": [
{
"job_id": "abc123",
"job_type": "protify",
"status": "Complete",
"created_at": "2025-01-15T12:00:00Z",
"phase": "complete",
"gpu_type": "A100"
}
]
}Examples
curl -H "Authorization: Bearer $SYNTHYRA_API_KEY" https://api.synthyra.com/v1/protify/jobsimport requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/protify/jobs",
headers={"Authorization": f"Bearer {api_key}"})
for job in response.json()["jobs"]:
print(f"{job['job_id']}: {job['status']}")/v1/protify/logs
Read job log delta
Stream training logs from a running or completed Protify job. Supports chunked reading with offset for real-time log tailing.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Job ID |
offset optional | number | 0 | Character offset to read from |
max_chars optional | number | 50000 | Maximum characters to return |
Response
{
"job_id": "abc123",
"content": "Epoch 1/10: loss=0.453 ...",
"offset": 0,
"next_offset": 1234,
"total_size": 5678
}Examples
curl -H "Authorization: Bearer $SYNTHYRA_API_KEY" "https://api.synthyra.com/v1/protify/logs?job_id=abc123&offset=0"import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/protify/logs",
headers={"Authorization": f"Bearer {api_key}"}, params={
"job_id": "abc123", "offset": 0,
})
print(response.json()["content"])/v1/protify/results
Fetch job results
Retrieve complete results for a finished Protify job including metrics TSV, plot images (base64-encoded), and HuggingFace Hub URL if weights were pushed.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Job ID |
Response
{
"job_id": "abc123",
"status": "Complete",
"results_tsv": "metric\tvalue\n...",
"images": [
{"filename": "loss_curve.png", "data": "base64..."}
],
"hub_url": "https://huggingface.co/Synthyra/...",
"weights_path": "/synth-protify/weights/abc123"
}Examples
curl -H "Authorization: Bearer $SYNTHYRA_API_KEY" "https://api.synthyra.com/v1/protify/results?job_id=abc123"import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.get("https://api.synthyra.com/v1/protify/results",
headers={"Authorization": f"Bearer {api_key}"}, params={"job_id": "abc123"})
result = response.json()
if result["hub_url"]:
print(f"Model published at: {result['hub_url']}")/v1/protify/cancel
Cancel a running job
Cancel a running Protify job. Only jobs in Waiting or Running status can be cancelled.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
job_id required | string | - | Job ID to cancel |
Response
{"job_id": "abc123", "status": "Cancelled"}Examples
curl -X POST "https://api.synthyra.com/v1/protify/cancel?job_id=abc123" -H "Authorization: Bearer $SYNTHYRA_API_KEY"import requests
api_key = "sk-..." # paste your key from synthyra.com/settings?section=api-keys
response = requests.post("https://api.synthyra.com/v1/protify/cancel",
headers={"Authorization": f"Bearer {api_key}"},
params={"job_id": "abc123"})Base URL: https://api.synthyra.com
All endpoints accept and return JSON unless otherwise noted.