API 레퍼런스

BioQ의 모든 답변은 HTTPS를 통해 JSON으로 받을 수 있습니다. 앱과 같은 엔드포인트를 어떤 언어로든 호출하세요.

엔드포인트 레퍼런스는 영어로 작성되어 있습니다.

API 키 만들기OpenAPI 명세

빠른 시작

Create an API key in your account, keep it in an environment variable, and call any endpoint with it as a bearer token. Responses are JSON. Every response that reads data says where it was read from.

export BIOQ_KEY="bq_..."
curl "https://bioq.bio/api/v1/depmap?gene=KRAS" -H "Authorization: Bearer $BIOQ_KEY"

Python, with nothing but requests:

import os, requests

BIOQ = "https://bioq.bio/api/v1"
H = {"Authorization": f"Bearer {os.environ['BIOQ_KEY']}"}

dep = requests.get(f"{BIOQ}/depmap", params={"gene": "KRAS"}, headers=H).json()
for row in dep["by_lineage"][:5]:
    print(row["lineage"], row["n_dependent"], "/", row["n"])

R, with httr2:

library(httr2)

bioq <- function(path, ...) {
  request(paste0("https://bioq.bio/api/v1", path)) |>
    req_url_query(...) |>
    req_auth_bearer_token(Sys.getenv("BIOQ_KEY")) |>
    req_perform() |>
    resp_body_json()
}

v <- bioq("/variant", gene = "BRCA1", pathogenic_only = 1)
v$significance_histogram

인증

Send Authorization: Bearer <key> with every request. Keys are created and revoked on the API keys page; the full key is shown once. A key acts as you and shares your plan’s daily limits. Requests from a signed-in browser session are also accepted, so the same URLs work in the address bar while you are signed in.

Missing or revoked keys get 401 with {"error": "sign_in_required"}. GET /api/v1/status is the only endpoint that works without a key.

한도와 오류

Limits are counted per account per UTC day, in three separate buckets: database queries, sequence searches (/search), and agent questions (/agent; the queries the agent makes on your behalf are not counted again).

PlanQueriesSequence searchesAgent questions
Free5002520
Pro20,0001,000500
Lab100,0005,0002,500

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (ISO time) and X-Request-Id. Bursts above 30 requests in 10 seconds get 429 with Retry-After.

StatusMeaning
200Answered. Read the body: several endpoints answer 200 with an unresolved list or a status other than found.
202Sequence search queued. Poll /search/result?id=… after poll_after_seconds.
400A parameter is missing or malformed. The body names it.
401No valid key or session.
404The identifier is not in that layer. The body says what was searched.
429quota_exceeded (daily limit, see resets_at) or slow_down (burst).
503 / 504The layer is not loaded, or the engine took too long. Retry; long lookups are cached once they finish.

Some lookups are slow the first time. A UniProt TrEMBL record is read from a large compressed file and can take a few minutes on first access; the same record is instant afterwards. Set your client timeout to at least 200 seconds for /lookup and /whereis.

Identity & sequences

GET

/api/v1/whereis

Ask every database layer at once whether it knows an identifier or a protein sequence.

Give either an identifier (MGnify MGYP id, UniProt accession, PDB code, Pfam accession or gene symbol) or a protein sequence, never both. Each layer answers with a status (hit, miss, unavailable, timeout, error, not_applicable) and a claim type: same_bytes means the exact record or sequence is present, similar_sequence means an aligner found a relative (not presence), annotation and coverage are statements about the identifier. A miss is a real absence; unavailable or timeout means nothing was searched, and not_applicable means that layer cannot address this kind of identifier at all. The call returns 200 even when nothing is found; read summary.absent_everywhere_is_proven before concluding absence. A homolog search that misses the default 8 s deadline keeps running and is cached, so retrying (or raising timeout_ms) usually returns it.

매개변수

이름타입설명
idstringIdentifier to locate: MGYP…, UniProt accession, PDB code, Pfam accession (PF00069) or gene symbol. Give id or seq, not both.
seqstringProtein sequence in one-letter code (whitespace ignored). Give id or seq, not both.
genestringGene symbol used to consult the symbol-keyed layers (affinity, ClinVar). An accession cannot be turned into a symbol automatically.
timeout_msintegerPer-layer deadline in milliseconds. Values outside 50-180000 are clamped. 기본값: 8000
max_hitsintegerSequence mode only: maximum homolog hits. Clamped to 1-200. 기본값: 10
homolog_timeout_msintegerSequence mode only: separate deadline for the homolog layer. Defaults to timeout_ms.

요청 예시

curl "https://bioq.bio/api/v1/whereis?id=P04637" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • verdict id mode: found | known_by_annotation_only | not_found_anywhere_loaded | not_found_in_what_answered; sequence mode: exact_sequence_present | not_found_anywhere_loaded | not_found_in_what_answered
  • answers.<layer>.status hit | miss | unavailable | timeout | error | not_applicable | queued; only hit and miss are answers
  • answers.<layer>.claim same_bytes | similar_sequence | annotation | coverage; similar_sequence is never presence
  • summary.absent_everywhere_is_proven true only when every applicable layer answered and none had it
  • summary.unavailable_or_incomplete layers that searched nothing; their absence is unmeasured
  • answer one plain-language sentence summarising what the layers established
  • query.id_kind how the identifier was classified (mgnify, uniprot, pfam, pdb, gene, unknown)
  • claim_legend, rules, ready also returned (omitted from the sample): definitions of each claim type and the engine's loaded-layer map
응답 예시
{
  "endpoint": "/whereis",
  "mode": "id",
  "query": {
    "id": "P04637",
    "id_kind": "uniprot",
    "gene": null
  },
  "verdict": "known_by_annotation_only",
  "answers": {
    "trembl": {
      "claim": "same_bytes",
      "claim_meaning": "this UniProt accession is a record in TrEMBL, sequence reconstructed from the indexed byte offsets",
      "status": "miss",
      "count": 0,
      "searched": "TrEMBL accession index",
      "means": "the TrEMBL index was searched and does not carry this accession. TrEMBL is the UNREVIEWED half of UniProt — a reviewed (Swiss-Prot) accession correctly misses here, and that is an answer, not an error",
      "latency_ms": 0.2
    },
    "structure": {
      "claim": "annotation",
      "claim_meaning": "the structure index holds metadata about this accession (an AlphaFold model: pLDDT and residue count, no residues). That is a statement about the identifier, not its bytes",
      "status": "hit",
      "count": 1,
      "structure_id": "P04637",
      "evidence": {
        "kind": "predicted",
        "method": "ALPHAFOLD",
        "model_version": "4",
        "variant": "F1",
        "mean_plddt": 74.33,
        "frac_plddt_gt90": 0.514,
        "frac_plddt_gt70": 0.5776,
        "quality_call": "confident",
        "quality_rule": "confident if mean_plddt >= 70; low_confidence if >= 50; very_low_confidence below 50",
        "usable_for_claims": true,
        "comparable_with": "nothing experimental — pLDDT is a model's self-estimate, not a measurement error"
      },
      "sequence_available": false,
      "latency_ms": 0.7
    },
    "mgnify_c2": {
      "claim": "same_bytes",
      "claim_meaning": "this exact identifier is a record in the MGnify30-C2 representative store, and the sequence was read back from it",
      "status": "not_applicable",
      "count": null,
      "why": "the C2 store is keyed by MGnify protein id (MGYP...). This identifier is not one, so no lookup is possible now or after mounting it",
      "means": "no lookup was possible, so this is neither a hit nor a miss. Mounting the layer would not change that.",
      "latency_ms": 0.01
    }
  },
  "summary": {
    "present_in": [
      "structure"
    ],
    "absent_from": [
      "trembl"
    ],
    "unavailable_or_incomplete": [],
    "not_applicable": [
      "mgnify_c2",
      "mgnify_members",
      "pfam_domains",
      "pfam_reverse",
      "assemblies",
      "affinity",
      "clinvar"
    ],
    "n_layers": 9,
    "n_hit": 1,
    "n_miss": 1,
    "n_incomplete": 0,
    "absent_everywhere_is_proven": false,
    "absent_everywhere": null
  },
  "answer": "no layer holds this with the same bytes; structure know(s) it by annotation. An annotation or coverage answer is a statement ABOUT the identifier, not the presence of its sequence",
  "elapsed_seconds": 0.001,
  "timeout_ms": 8000
}
GET

/api/v1/lookup

Fetch the stored sequence for an MGnify protein id or a UniProt TrEMBL accession.

Returns the exact sequence read back from the source record. MGYP ids are looked up in the MGnify representative store first and then in the full 5.74-billion-protein member table; other accessions are looked up in UniProt TrEMBL (the unreviewed half of UniProt). Reviewed Swiss-Prot accessions such as P69905 are not in this lookup layer and answer 404 — use /search or /structure for those. A 404 says whether it is proof of absence (not_found_is_proof_of_absence) or only 'not in what is loaded'. TrEMBL lookups replay a compressed stream, so latency grows with the record's position and can reach minutes; the response carries a cost_model saying so.

매개변수

이름타입설명
id필수stringMGnify protein accession (MGYP000000149140) or UniProt TrEMBL accession.

요청 예시

curl "https://bioq.bio/api/v1/lookup?id=MGYP000000149140" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • hit.sequence the stored amino-acid sequence, read back from the record
  • hit.source mgnify30-c2 (representative store), mgnify-members or trembl
  • hit.length sequence length in residues
  • hit.provenance where in the source file the record was read
  • hit.cached true when served from the engine's in-memory cache
  • hit.c2_missed MGYP only: true when the representative store missed and the full member table answered
  • hit.cost_model TrEMBL only: latency grows with record offset; a fast answer does not mean the next one will be fast
응답 예시
{
  "hit": {
    "accession": "MGYP000000149140",
    "sequence": "MQGLGDWGFPQKFKKSRIVRDDPLTNFDLFKNSIWVPKCYACQKKRGLAPQSRNSRTEVM…",
    "length": 88,
    "source": "mgnify30-c2",
    "provenance": {
      "part": 0,
      "anchor_offset": 0,
      "window_bytes": 63313,
      "anchor_id": 149140
    },
    "c2_missed": false,
    "cached": true,
    "elapsed_seconds": 0.000005
  }
}
GET

/api/v1/search/result

Poll a queued sequence search by its job id.

Use the job_id returned by a 202 from /search. While the job is queued or running the answer is 202 with hits null; when done it is 200 with the same body shape as /search plus the job record, cost_of_first_query_seconds and corpus_current. If the corpus changed after the job ran, corpus_warning says the answer describes the build that was searched. A failed job answers 503 with hits null, which is not a negative result. Pass the same corpus you submitted with, because job ids are only unique within a corpus.

매개변수

이름타입설명
id필수stringjob_id from the 202 response of /search.
corpusstringCorpus the job was submitted to. 기본값: sprot

요청 예시

curl "https://bioq.bio/api/v1/search/result?id=0" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • status queued | running (202), ok (200), failed | done_but_unreadable (503)
  • hits null until the search completes; then the same hit objects as /search
  • waited_seconds / estimated_seconds progress information while queued or running
  • cost_of_first_query_seconds how long the original search took
  • corpus_current false when the corpus was rebuilt after the job ran (see corpus_warning)
  • The sample shows the 404 for an unknown job id; real ids come from a 202 on /search
응답 예시
{
  "error": "unknown job id",
  "id": "0",
  "hits": null
}

Genes & disease

GET

/api/v1/gene

Summarise what the engine holds about a human gene symbol, starting with its ClinVar records.

Returns the ClinVar significance histogram for the gene, a five-row sample of records, and a discovery_readiness verdict. ClinVar counts are submissions, not independent observations, so the verdict says whether a distribution may be described at all. clusters is always null: MGnify proteins carry no gene symbol, so a gene cannot be mapped to metagenomic clusters by name. An unknown symbol still answers 200, with the reason in unresolved and verdict absent.

매개변수

이름타입설명
symbol필수stringGene symbol, e.g. EGFR, BRCA1 (case-insensitive).

요청 예시

curl "https://bioq.bio/api/v1/gene?symbol=EGFR" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • variants.n_matched ClinVar records for this symbol (submissions, not patients)
  • variants.significance_histogram counts per clinical significance over all matched records
  • variants.sample up to 5 records (chrom, pos, gene, sig, review)
  • clusters always null; see unresolved
  • unresolved[] what could not be answered and why
  • discovery_readiness.verdict testable | weak | no_claim | absent | unknown; claim_allowed is true only for testable and weak
응답 예시
{
  "gene": "EGFR",
  "variants": {
    "n_returned": 20,
    "n_matched": 4141,
    "truncated": true,
    "significance_histogram": {
      "Uncertain_significance": 1899,
      "Likely_benign": 1527,
      "Conflicting_classifications_of_pathogenicity": 254,
      "Benign/Likely_benign": 132,
      "Benign": 95,
      "": 72,
      "Pathogenic": 60,
      "drug_response": 48,
      "Likely_pathogenic": 39,
      "not_provided": 7,
      "Likely_pathogenic|drug_response": 6,
      "Uncertain_significance|drug_response": 1,
      "Pathogenic|drug_response": 1
    },
    "sample": [
      {
        "chrom": "7",
        "pos": 55018796,
        "gene": "EGFR",
        "sig": "Likely_benign",
        "review": "criteria_provided,_single_submitter"
      },
      {
        "chrom": "7",
        "pos": 55019062,
        "gene": "EGFR",
        "sig": "Benign/Likely_benign",
        "review": "criteria_provided,_multiple_submitters,_no_conflicts"
      }
    ]
  },
  "clusters": null,
  "unresolved": [
    "MGnify clusters carry no gene symbol, so a gene cannot be mapped to clusters by name; use /lookup with a cluster id, or a homology search"
  ],
  "discovery_readiness": {
    "verdict": "testable",
    "claim_allowed": true,
    "n_records": 4141,
    "n_distinct_values": 12,
    "min_records_required": 3,
    "why": "4141 records with 12 distinct values: describing the distribution is possible, but these are submissions, not independent samples",
    "can_do": [
      "the 4141 records can describe a distribution (e.g. the pathogenic fraction)",
      "these are submission counts, not independent samples; do not use them as n for confidence intervals or significance tests"
    ]
  }
}
GET

/api/v1/variant

List ClinVar variants for a gene or around a GRCh38 position.

Query by gene symbol, or by chromosome plus position with a window in base pairs. A chromosome without a position (or the reverse) is refused rather than answered with unrelated rows. matched and significance_histogram cover every matching record; results is one page of at most 50 rows sorted by position, and truncated says when more exist. Uncertain significance (VUS) and conflicting classifications are not pathogenic, and review status is shown because evidence tiers differ.

매개변수

이름타입설명
genestringGene symbol (case-insensitive).
chromstringChromosome name as in ClinVar, e.g. 17 or X. Requires pos.
posinteger1-based GRCh38 position. Requires chrom.
windowintegerHalf-width in base pairs around pos. 기본값: 100
pathogenic_onlybooleanKeep only Pathogenic, Likely_pathogenic and Pathogenic/Likely_pathogenic records (1 or true). 기본값: 0

요청 예시

curl "https://bioq.bio/api/v1/variant?gene=BRCA1&pathogenic_only=1" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • matched number of records that met the filter (not the page size)
  • n_returned rows in this page (at most 50)
  • truncated true when matched exceeds the page
  • significance_histogram counts per significance over all matched records; sums to matched
  • results[] chrom, pos, gene, sig (clinical significance), review (review status)
  • caveat reminder that VUS and conflicting records are not pathogenic
응답 예시
{
  "matched": 4118,
  "n_returned": 50,
  "truncated": true,
  "significance_histogram": {
    "Pathogenic": 3613,
    "Likely_pathogenic": 277,
    "Pathogenic/Likely_pathogenic": 228
  },
  "caveat": "VUS and Conflicting are not pathogenic; review status is shown because evidence tiers differ",
  "results": [
    {
      "chrom": "17",
      "pos": 43041660,
      "gene": "BRCA1",
      "sig": "Pathogenic",
      "review": "no_assertion_criteria_provided"
    },
    {
      "chrom": "17",
      "pos": 43041662,
      "gene": "BRCA1",
      "sig": "Pathogenic",
      "review": "criteria_provided,_single_submitter"
    },
    {
      "chrom": "17",
      "pos": 43044293,
      "gene": "BRCA1",
      "sig": "Pathogenic",
      "review": "criteria_provided,_single_submitter"
    }
  ]
}
GET

/api/v1/depmap

Look up CRISPR dependency (DepMap Chronos gene effect) by gene, by lineage, or both.

With gene only, returns the gene's dependency profile across all cell lines and per lineage (most dependent lineage first). With lineage only, ranks genes by how lineage-specific the dependency is (selectivity), excluding common-essential genes unless asked. With both, lists the individual cell lines and their effect. mutations=1 lists cell lines with a HIGH-impact somatic variant in the gene. More negative gene effect means knocking the gene out hurt viability more; a line counts as dependent at effect <= -0.5, a named threshold rather than a property of the data. Unknown genes or lineages answer 404 with what was searched.

매개변수

이름타입설명
genestringGene symbol (case-insensitive).
entrezintegerEntrez gene id, as an alternative to gene.
lineagestringLineage name; exact, case-insensitive, or a unique substring (e.g. Pancreas, lung).
topintegerRows to return (lineages, genes or cell lines depending on mode). Clamped to 1-500. 기본값: 25
allbooleanGene mode: return every lineage instead of the top ones. Pass 1 to enable. 기본값: 0
include_pan_essentialbooleanLineage mode: keep common-essential genes in the ranking. Pass 1 to enable. 기본값: 0
mutationsbooleanList lines with a HIGH-impact somatic variant in gene (requires gene; lineage optional). Pass 1 to enable. 기본값: 0

요청 예시

curl "https://bioq.bio/api/v1/depmap?gene=KRAS" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • corpus.n_dependent / n_lines lines at or below the dependency threshold, over lines assayed
  • corpus.profile.bins histogram of gene effect across all lines
  • by_lineage[] n, n_dependent, frac_dependent, mean, median, sd, selectivity per lineage, most negative mean first
  • selectivity lineage mean minus all-lines mean; near zero for pan-essential genes
  • thresholds.dependent_if_effect_le the dependency cut-off (-0.5)
  • Lineage mode returns genes[] ranked by selectivity; gene+lineage returns lines[] with effect and is_dependent; mutations=1 returns lines[] (up to 100)
응답 예시
{
  "gene": {
    "symbol": "KRAS",
    "entrez": 3845,
    "gene_idx": 7807,
    "is_common_essential": false,
    "is_nonessential": false
  },
  "corpus": {
    "n_lines": 1178,
    "n_dependent": 399,
    "mean_effect": -0.5572,
    "median_effect": -0.3732,
    "profile": {
      "n": 1178,
      "bins": {
        "[-9,-1.0)": 168,
        "[-1.0,-0.5)": 231,
        "[-0.5,-0.1)": 698,
        "[-0.1,0.1)": 72,
        "[0.1,9)": 9
      },
      "min": -4.143,
      "max": 0.326
    }
  },
  "by_lineage": [
    {
      "lineage": "Pancreas",
      "n": 47,
      "n_dependent": 43,
      "frac_dependent": 0.9149,
      "mean": -1.7898,
      "median": -1.758,
      "sd": 0.8157,
      "selectivity": -1.2326
    },
    {
      "lineage": "Bowel",
      "n": 63,
      "n_dependent": 48,
      "frac_dependent": 0.7619,
      "mean": -1.1779,
      "median": -1.0111,
      "sd": 0.797,
      "selectivity": -0.6206
    },
    {
      "lineage": "Eye",
      "n": 15,
      "n_dependent": 6,
      "frac_dependent": 0.4,
      "mean": -0.7888,
      "median": -0.39,
      "sd": 0.7294,
      "selectivity": -0.2315
    }
  ],
  "thresholds": {
    "dependent_if_effect_le": -0.5,
    "min_lines_for_lineage_row": 5,
    "mutation_impacts_kept": [
      "HIGH"
    ]
  },
  "meaning": "mean is the Chronos gene effect; MORE NEGATIVE means knocking the gene out reduced viability more. selectivity is the lineage mean minus the corpus mean, so a pan-essential gene has a very negative mean but selectivity near zero.",
  "elapsed_ms": 0.21,
  "index": "depmap_24q4 — Chronos gene effect; a dependency is effect <= dependent_if_effect_le, which is a named constant, not a property of the data"
}
GET

/api/v1/omics

Get a gene's expression or copy number across DepMap cell lines, or correlate two genes.

layer=expr is expression as log2(TPM+1); layer=cn is absolute copy number on a linear scale. They are different quantities and are never pooled. With one gene you get the distribution overall, per lineage, and the lowest and highest lines; with two genes you get Pearson r over the lines where both are measured. Unmeasured lines are NaN, never zero, and are reported as n_unmeasured. Some lines carry an empty lineage string. An unknown gene in single-gene mode answers 404, but in two-gene mode it answers 200 with an error field (unknown gene) — check for it.

매개변수

이름타입설명
layerstringexpr (log2(TPM+1)) or cn (absolute linear copy number). 기본값: expr
genestringGene symbol for a single-gene profile (alias: a).
bstringSecond gene symbol; with gene/a, returns a correlation.
comparestringAlternative spelling of a two-gene request: compare=ERBB2&compare=EGFR.
topintegerRows in by_lineage, lowest and highest. Clamped to 1-200. 기본값: 15

요청 예시

curl "https://bioq.bio/api/v1/omics?gene=EGFR&top=5" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • n_measured / n_unmeasured lines with and without a value for this gene
  • overall mean, median, sd over measured lines
  • by_lineage[] n, mean, median, sd, min, max per lineage
  • lowest[] / highest[] extreme cell lines (ModelID, lineage, value)
  • value_meaning the unit of every value in this response
  • Two-gene mode: pearson_r and n_shared_lines (lines where both genes are measured)
응답 예시
{
  "layer": "expr",
  "gene": "EGFR",
  "n_models": 1987,
  "n_measured": 1673,
  "n_unmeasured": 314,
  "overall": {
    "mean": 3.3837,
    "median": 3.9523,
    "sd": 2.3654
  },
  "by_lineage": [
    {
      "lineage": "Head and Neck",
      "n": 61,
      "mean": 5.7235,
      "median": 5.9991,
      "sd": 1.687,
      "min": 0.0144,
      "max": 9.3546
    },
    {
      "lineage": "Bladder/Urinary Tract",
      "n": 34,
      "mean": 5.7135,
      "median": 5.5229,
      "sd": 1.3177,
      "min": 3.4777,
      "max": 10.0761
    }
  ],
  "lowest": [
    {
      "ModelID": "ACH-003463",
      "lineage": "",
      "value": 0
    },
    {
      "ModelID": "ACH-003273",
      "lineage": "",
      "value": 0
    }
  ],
  "highest": [
    {
      "ModelID": "ACH-001523",
      "lineage": "Skin",
      "value": 10.5319
    },
    {
      "ModelID": "ACH-000741",
      "lineage": "Bladder/Urinary Tract",
      "value": 10.0761
    }
  ],
  "value_meaning": "log2(TPM+1) as shipped by the release",
  "elapsed_ms": 19.19,
  "index": "depmap_24q4 omics side-car — expr is log2(TPM+1), cn is ABSOLUTE linear copy number; a NaN is an unmeasured line, never a zero"
}

Drugs & interactions

GET

/api/v1/affinity

List measured drug-target binding and potency values (ChEMBL, DrugCentral, Guide to Pharmacology).

Query by target gene symbol, by drug name, or both. Every measurement keeps its own type (IC50, Ki, Kd, …), unit and unit_class; molar and log values are never averaged together, and p_value (-log10 molar) is the only column comparable across classes. The list is sorted by p_value, highest first, so a limited page is the most potent slice, not a sample; summary is always computed over all matches (see summary_basis). assay_type separates binding (B) from functional (F) and ADME (A) assays; rows from sources without an assay type are excluded when it is set. An empty list with 200 means the layer answered and nothing matched; a 503 with measurements null means the layer is off.

매개변수

이름타입설명
genestringTarget gene symbol (case-insensitive).
drugstringDrug name (case-insensitive exact match).
typestringMeasured type, e.g. IC50, Ki, Kd, EC50, pIC50 (case-insensitive).
assay_typestringChEMBL assay type letter (case-insensitive), e.g. B binding, F functional, A ADME.
limitintegerRows in the measurement list; 0 or negative returns all rows. Does not affect summary. 기본값: 100

요청 예시

curl "https://bioq.bio/api/v1/affinity?gene=EGFR&drug=gefitinib&limit=5" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • total_matched / n / truncated all matches vs rows in this page
  • measurements[] measured_type, value, unit, unit_class (molar | log), relation, assay_type, p_value, drug_name, gene, source, source_key
  • p_value -log10 molar; the only value comparable across unit classes
  • summary.per_unit_class min/median/max per unit class, never pooled
  • summary.per_type_and_class, per_type_and_assay_type the same, split further
  • summary_basis states that the summary covers all matches, not the page
  • empty_because present when no measurement matched (layer loaded and answered)
응답 예시
{
  "query": {
    "gene": "EGFR",
    "drug": "gefitinib",
    "type": null,
    "assay_type": null,
    "limit": 5
  },
  "n": 5,
  "total_matched": 328,
  "truncated": true,
  "measurements": [
    {
      "target_id": "CHEMBL203",
      "target_name": "Epidermal growth factor receptor",
      "gene": "EGFR",
      "genes_all": [
        "EGFR"
      ],
      "drug_name": "gefitinib",
      "drug_id": "CHEMBL939",
      "measured_type": "IC50",
      "value": 0.1,
      "unit": "nM",
      "unit_class": "molar",
      "unit_inferred": null,
      "unit_basis": "source_stated_molar_unit",
      "relation": "=",
      "assay_type": "B",
      "standard_flag": null,
      "p_value": 10,
      "source": "chembl",
      "source_key": "chembl_37.db|activity_id=13297481",
      "row_ref": 13297481,
      "sha256": "4be13df3b68e25dcd0bff44bf094033b5aebe98f415acdc8c1cdf380e0c15142",
      "file": "chembl_37.db"
    },
    {
      "target_id": "CHEMBL203",
      "target_name": "Epidermal growth factor receptor",
      "gene": "EGFR",
      "genes_all": [
        "EGFR"
      ],
      "drug_name": "gefitinib",
      "drug_id": "CHEMBL939",
      "measured_type": "IC50",
      "value": 0.1,
      "unit": "nM",
      "unit_class": "molar",
      "unit_inferred": null,
      "unit_basis": "source_stated_molar_unit",
      "relation": "=",
      "assay_type": "B",
      "standard_flag": null,
      "p_value": 10,
      "source": "chembl",
      "source_key": "chembl_37.db|activity_id=13380887",
      "row_ref": 13380887,
      "sha256": "4be13df3b68e25dcd0bff44bf094033b5aebe98f415acdc8c1cdf380e0c15142",
      "file": "chembl_37.db"
    }
  ],
  "summary": {
    "n_measurements": 328,
    "per_unit_class": {
      "log": {
        "n": 7,
        "min": 7.230000019073486,
        "median": 8.300000190734863,
        "max": 9.4,
        "unit_class": "log",
        "span_orders_of_magnitude": 2.17
      },
      "molar": {
        "n": 321,
        "min": 0.1,
        "median": 14.4,
        "max": 22800,
        "unit_class": "molar",
        "span_orders_of_magnitude": 5.36
      }
    },
    "per_type_and_class": {
      "IC50/molar": {
        "n": 269,
        "min": 0.1,
        "median": 20,
        "max": 22800,
        "unit_class": "molar",
        "span_orders_of_magnitude": 5.36
      },
      "KD/molar": {
        "n": 38,
        "min": 0.52,
        "median": 1.1,
        "max": 470,
        "unit_class": "molar",
        "span_orders_of_magnitude": 2.96
      },
      "PIC50/log": {
        "n": 2,
        "min": 7.230000019073486,
        "median": 8.149999618530273,
        "max": 8.149999618530273,
        "unit_class": "log",
        "span_orders_of_magnitude": 0.92
      }
    },
    "per_type_and_assay_type": {
      "AC50/assay=F": {
        "n": 1,
        "min": 3.8,
        "median": 3.8,
        "max": 3.8,
        "unit_class": "molar",
        "span_orders_of_magnitude": 0
      },
      "EC50/assay=A": {
        "n": 1,
        "min": 2162,
        "median": 2162,
        "max": 2162,
        "unit_class": "molar",
        "span_orders_of_magnitude": 0
      }
    },
    "p_value": {
      "n": 328,
      "min": 4.64,
      "median": 7.85,
      "max": 10,
      "unit_class": "log",
      "span_orders_of_magnitude": 5.36,
      "note": "p_value is -log10 molar, so its span is max-min and is comparable across sources"
    },
    "warning": "value is NOT comparable across unit_class; never average them. p_value (-log10 molar) is the only cross-class comparable column."
  },
  "summary_basis": "all 328 matches (the list is a page of 5)",
  "layer": {
    "rows": 5153526,
    "genes": 6682,
    "drugs": 29967,
    "built_at": "2026-10-21T08:57:39Z",
    "sources": {
      "chembl": {
        "file": "chembl_37.db",
        "rows_kept": 5113551,
        "rows_read": 5210648,
        "rows_refused": 97097,
        "sha256": "4be13df3b68e25dcd0bff44bf094033b5aebe98f415acdc8c1cdf380e0c15142"
      },
      "drugcentral": {
        "file": "drugcentral.tsv.gz",
        "rows_kept": 20685,
        "rows_read": 22364,
        "rows_refused": 1679,
        "sha256": "1908684983a79a067a44da952e1f6fd26b0f34cc36560cd9be0f0843bbfee1e1"
      },
      "gtopdb": {
        "file": "gtopdb.csv",
        "rows_kept": 19290,
        "rows_read": 24959,
        "rows_refused": 5669,
        "sha256": "c1b81895f520bd2b29b5631224320da4047a7d175dc06ba2adcc60f1a9e1ffa1"
      }
    }
  },
  "elapsed_seconds": 0.008
}
GET

/api/v1/interaction

Get protein-protein interaction partners from STRING v12 or BioGRID, or test a single pair.

By default this reads STRING v12: partners sorted by combined_score, which is a confidence on a 0-1000 scale, not a probability. source=biogrid reads curated BioGRID records instead; each names an experimental system and a publication, and its score is free text ('-' in most rows) that must not be sorted or averaged. The two sources are never merged. A protein that is not in the species dictionary, an ambiguous symbol (candidates are listed) or a pair with no edge answers 404; an absent edge means 'not in this release at this threshold', not evidence of no interaction. STRING interaction is a different claim from metagenomic co-occurrence (/cooccur).

매개변수

이름타입설명
proteinstringGene symbol, UniProt accession, Ensembl protein id or STRING id. Aliases: id or gene for STRING; gene or symbol for BioGRID (uppercase exact symbol match).
astringFirst protein of a single-pair query (use with b).
bstringSecond protein of a single-pair query.
sourcestringstring (STRING v12) or biogrid (BioGRID 4.4). 기본값: string
speciesstringNCBI taxonomy id (alias: taxid). STRING only; unknown ids answer 404 with the available list. 기본값: 9606
min_scoreintegerSTRING only: minimum combined_score on the 0-1000 scale (not clamped). 기본값: 0
limitintegerMaximum partners (STRING) or records (BioGRID). 기본값: 50
channelsbooleanSTRING only: include per-channel scores (experimental, database, textmining, …) where available. Pass 1 to enable. 기본값: 0
uniprotstringBioGRID only: query by UniProt accession.
typestringBioGRID symbol queries only: physical or genetic (exact, lowercase; other values return zero records). Ignored with uniprot.

요청 예시

curl "https://bioq.bio/api/v1/interaction?protein=TP53&species=9606&min_score=900&limit=5" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • partners[] partner (STRING id), partner_name, partner_uniprot, combined_score
  • score_scale combined_score is 0-1000 confidence, not a probability
  • degree_total / degree_at_or_above_min_score partner counts before the limit
  • resolution how the query was matched (symbol, uniprot, ensembl, string_id)
  • Single pair (a, b): found, combined_score, channels; same_node true when both tokens are the same protein
  • BioGRID: interactions[] with system, pubmed, throughput, score_text; by_experimental_system_top10; n_distinct_publications
  • absence_note an absent edge is not evidence of no interaction
응답 예시
{
  "query": "TP53",
  "found": true,
  "string_id": "9606.ENSP00000269305",
  "preferred_name": "TP53",
  "uniprot": "P04637",
  "resolution": "symbol",
  "degree_total": 7443,
  "degree_at_or_above_min_score": 283,
  "min_score_filter": 900,
  "returned": 5,
  "score_name": "combined_score",
  "score_scale": "0-1000 (STRING v12 combined_score; a confidence, not a probability)",
  "channels_available": [
    "neighborhood",
    "fusion",
    "cooccurence",
    "coexpression",
    "experimental",
    "database",
    "textmining"
  ],
  "partners": [
    {
      "partner": "9606.ENSP00000212015",
      "partner_name": "SIRT1",
      "partner_uniprot": "Q96EB6",
      "score_name": "combined_score",
      "combined_score": 999,
      "score_scale": "0-1000 (STRING v12 combined_score; a confidence, not a probability)"
    },
    {
      "partner": "9606.ENSP00000254719",
      "partner_name": "RPA1",
      "partner_uniprot": "P27694",
      "score_name": "combined_score",
      "combined_score": 999,
      "score_scale": "0-1000 (STRING v12 combined_score; a confidence, not a probability)"
    },
    {
      "partner": "9606.ENSP00000258149",
      "partner_name": "MDM2",
      "partner_uniprot": "Q00987",
      "score_name": "combined_score",
      "combined_score": 999,
      "score_scale": "0-1000 (STRING v12 combined_score; a confidence, not a probability)"
    }
  ],
  "layer": "string_ppi",
  "source": "STRING v12",
  "taxid": "9606",
  "claim": "a STRING interaction edge (curated/detected association), NOT an assembly co-occurrence",
  "sibling_sources": {
    "biogrid": "/interaction?source=biogrid&protein=<SYMBOL> - curated experiments with a PubMed id; keyed by gene symbol and UniProt accession, which is the join our layers use",
    "string_node_count": 19699,
    "note": "STRING and BioGRID are different evidence types; neither replaces the other and this endpoint never merges them"
  },
  "absence_note": "an absent edge means 'not in this release at this threshold'; STRING lists positive associations only",
  "elapsed_seconds": 0.0002
}

Proteins & domains

GET

/api/v1/domains

List the Pfam domains annotated on an MGnify protein.

The Pfam table covers about 2.99 billion of the 5.74 billion MGnify proteins. A protein that is not in it returns domains null and no_annotation true, which means unannotated, not 'has no domains'. Domains are listed in the source's row order and are not ranked by e-value: the index keeps only (protein, domain) pairs, so a marginal hit and a certain one look the same. discovery_readiness says how many independent assemblies the protein was observed in.

매개변수

이름타입설명
protein필수stringMGnify protein id, as MGYP000000000001 or the bare integer 1 (alias: cluster).

요청 예시

curl "https://bioq.bio/api/v1/domains?protein=1" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • domains Pfam accessions, or null when the protein is unannotated
  • no_annotation true when the protein is not in the Pfam table
  • note domains are not ranked by e-value
  • unit the ids are proteins (MGYP accessions), not cluster representatives
  • discovery_readiness.verdict testable | weak | no_claim | absent | unknown, with n_assemblies and n_independent_runs
응답 예시
{
  "cluster": 1,
  "domains": [
    "PF02566"
  ],
  "n_domains": 1,
  "unit": "protein (MGYP accession); the index is keyed by annotated protein, 2,985,942,516 of 5,739,566,171, not by the 1,661,142,385 cluster representatives",
  "unresolved": [],
  "no_annotation": false,
  "note": "domains are listed in the source's row order, NOT ranked by e-value — the index keeps only (protein, domain) pairs, so a marginal hit and a certain one are indistinguishable",
  "discovery_readiness": {
    "verdict": "testable",
    "claim_allowed": true,
    "n_assemblies": 282,
    "n_independent_runs": 59,
    "min_assemblies_required": 3,
    "why": "282 assemblies across 59 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid"
  }
}
GET

/api/v1/domain

List MGnify proteins that carry a given Pfam domain.

Returns MGnify protein ids carrying the domain, with the exact total (n_total). The key is named clusters but the entries are protein (MGYP) ids. Ids come in ascending order: this is neither a ranking by e-value nor a random sample. discovery_readiness is computed only over the returned page, so it is a lower bound (coverage: lower_bound). An accession that is not in Pfam answers 200 with an empty list and the reason in unresolved, not 404.

매개변수

이름타입설명
acc필수stringPfam accession, e.g. PF00069 (bare digits are zero-padded).
limitintegerMaximum ids to return; n_total is always exact. 기본값: 20

요청 예시

curl "https://bioq.bio/api/v1/domain?acc=PF00069&limit=5" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • clusters MGnify protein ids (integers), ascending
  • n_total exact number of proteins carrying the domain
  • n_returned / truncated page size and whether more exist
  • note ids are not ranked by e-value
  • discovery_readiness verdict over the returned page only (coverage: lower_bound)
  • unresolved[] set when the accession is unknown
응답 예시
{
  "domain": "PF00069",
  "clusters": [
    1344,
    14050,
    21406,
    22244,
    23853
  ],
  "unresolved": [],
  "n_returned": 5,
  "n_total": 6299635,
  "truncated": true,
  "unit": "protein (MGYP accession). The index is keyed by annotated protein, 2,985,942,516 of 5,739,566,171, not by the 1,661,142,385 cluster representatives",
  "note": "ids are in ascending order, NOT ranked by e-value - the index keeps only (protein, domain) pairs, so a marginal hit and a certain one are indistinguishable here",
  "discovery_readiness": {
    "verdict": "testable",
    "claim_allowed": true,
    "n_assemblies": 36,
    "n_independent_runs": 17,
    "min_assemblies_required": 3,
    "why": "36 assemblies across 17 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid",
    "coverage": "lower_bound",
    "n_total_proteins": 6299635,
    "coverage_note": "The assembly count is a lower bound over only the 5 returned proteins (of 6,299,635). They are the first ids in ascending order, not a sample, so do not estimate prevalence from it for large domains. The lower bound already meets the minimum, so reading more cannot overturn this verdict"
  }
}
GET

/api/v1/structure

Look up an experimental PDB structure or an AlphaFold model and how far it can be trusted.

Accepts a PDB code (experimental) or a UniProt accession (AlphaFold model). evidence.kind says which, and the two are never comparable: an experimental entry carries resolution_a, a model carries mean_plddt and a quality_call (confident if mean pLDDT >= 70, low_confidence if >= 50, otherwise very_low_confidence). pLDDT is the model's own estimate, not a measurement error. Model entries usually carry no sequence (sequence_available false). A 404 means the loaded layer was searched and holds nothing for this id; the body gives the table sizes searched.

매개변수

이름타입설명
idstringPDB code (1AKE) or UniProt accession (P69905).
inventorybooleanWith no id, return the layer inventory instead. Pass 1 to enable.

요청 예시

curl "https://bioq.bio/api/v1/structure?id=P69905" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • entry.evidence.kind experimental | predicted; never compare across kinds
  • entry.evidence.resolution_a experimental only: resolution in Ångström
  • entry.evidence.mean_plddt / quality_call / quality_rule predicted only
  • entry.evidence.usable_for_claims false for low-confidence models
  • entry.sequence_length / sequence_available sequence may be null for models
  • entry.fetch archive member name of the original coordinate file
응답 예시
{
  "entry": {
    "id": "P69905",
    "evidence": {
      "kind": "predicted",
      "method": "ALPHAFOLD",
      "model_version": "4",
      "variant": "F1",
      "mean_plddt": 98.05,
      "frac_plddt_gt90": 0.993,
      "frac_plddt_gt70": 0.993,
      "quality_call": "confident",
      "quality_rule": "confident if mean_plddt >= 70; low_confidence if >= 50; very_low_confidence below 50",
      "usable_for_claims": true,
      "comparable_with": "nothing experimental — pLDDT is a model's self-estimate, not a measurement error"
    },
    "title": null,
    "sequence": null,
    "sequence_length": 142,
    "sequence_available": false,
    "fetch": {
      "tar": "swissprot_pdb_v4.tar",
      "member": "AF-P69905-F1-model_v4.pdb.gz"
    }
  },
  "elapsed_ms": 0.58
}
GET

/api/v1/organism

Count UniProt TrEMBL proteins for an NCBI taxonomy id, or list the largest organisms.

count is exact: every record in UniProt TrEMBL (unreviewed entries) was parsed once. accessions is a sample of up to 256, not the full set; accessions_are states how many of the total are shown. Swiss-Prot (reviewed) entries are not part of this count. With top instead of taxid, returns organisms ranked by protein count. A 404 means the taxid had zero records in the full pass — a real absence, not an unloaded layer.

매개변수

이름타입설명
taxidintegerNCBI taxonomy id, e.g. 9606.
topintegerWithout taxid: number of organisms to list, by protein count. Clamped to 1-1000. Ignored when taxid is given. 기본값: 20

요청 예시

curl "https://bioq.bio/api/v1/organism?taxid=9606" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • count exact number of TrEMBL proteins for this taxid
  • accessions a sample (sample_size of count), not the complete list
  • truncated true when count exceeds the sample
  • count_is / accessions_are plain statements of what each number means
  • source.bytes_scanned / bytes_total proof the whole file was read
  • top mode: organisms[] with taxid, organism, count
응답 예시
{
  "taxid": 9606,
  "organism": "Homo sapiens",
  "count": 190275,
  "accessions": [
    "Q29VG3",
    "Q6VHB0",
    "Q6ZWB5",
    "U5ZAD9",
    "A0A5C2G0E2"
  ],
  "sample_size": 256,
  "truncated": true,
  "count_is": "exact — every record in the scanned TrEMBL object was parsed",
  "accessions_are": "256 of 190,275 accessions — a sample, not the full set",
  "source": {
    "key": "uniprot_trembl.fasta.gz",
    "bytes_scanned": 40628134612,
    "bytes_total": 40628134612
  }
}

Genomes

GET

/api/v1/dna

Fetch nucleotide bases for a region of the human genome (GRCh38) or a RefSeq sequence.

Coordinates are 1-based and inclusive: region=chr11:1000000-1000100 returns 101 bases. Human chromosome names are tried against GRCh38 first; any other name (e.g. NC_045512.2) is served from RefSeq nucleotide FASTA (archaea, fungi, mitochondrion, protozoa, viral, and mouse GRCm39). layer, assembly and division always say which genome the bases came from. Bare names like 1 exist in both human and mouse; ask for mouse as mm39:1. If end runs past the sequence the answer is clamped and marked truncated; a start past the end, or a name neither layer holds, is an error.

매개변수

이름타입설명
region필수stringname:start-end, 1-based inclusive (commas allowed in numbers). Examples: chr11:1000000-1000100, NC_045512.2:21563-21600, mm39:1:3000000-3000100.

요청 예시

curl "https://bioq.bio/api/v1/dna?region=NC_045512.2:21563-21600" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • sequence the bases as stored in the source FASTA
  • start / end / length the span actually returned (1-based, inclusive)
  • layer human-grch38 or refseq
  • assembly / division / organism which genome the bases are from
  • truncated / returned_end present when end exceeded the sequence length
  • sequence_length RefSeq only: full length of the sequence
응답 예시
{
  "region": "NC_045512.2:21563-21600",
  "chrom": "NC_045512.2",
  "start": 21563,
  "end": 21600,
  "length": 38,
  "sequence": "ATGTTTGTTTTTCTTGTTTTATTGCCACTAGTCTCTAG",
  "elapsed_seconds": 0.0003,
  "source": "RefSeq viral",
  "layer": "refseq",
  "assembly": "NC_045512.2",
  "division": "viral",
  "line_width": 80,
  "sequence_length": 29903
}
GET

/api/v1/synteny

Show where an MGnify protein sits on assembled contigs and which proteins lie within n base pairs.

For each placement of the protein (assembly, contig, start, end, strand) the response lists neighbouring proteins on the same contig within the window, with the gap in base pairs. This is genomic context on one contig, a different claim from assembly-level co-occurrence (/cooccur) or curated interaction (/interaction). An empty neighbour list at the default 5 kb window is mostly a property of short metagenomic contigs (about 91% of placements have none), so re-ask with the suggested window before reading it as 'this protein is alone'. A 404 means the protein has no placement at all.

매개변수

이름타입설명
protein필수stringMGnify protein id, MGYP000187092429 or the bare integer (alias: id).
nintegerWindow in base pairs on each side. Values outside 0-1000000 are refused. 기본값: 5000

요청 예시

curl "https://bioq.bio/api/v1/synteny?protein=MGYP000187092429&n=5000" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • placements[] erz (assembly accession), contig, start, end, strand (+1/-1), neighbours[]
  • neighbours[] protein, start, end, strand, gap (bp)
  • placements_total / truncated at most 64 placements are returned
  • neighbour_total neighbours across returned placements
  • window_interpretation whether an empty list is mostly contig sparsity, and a suggested window
응답 예시
{
  "protein": "MGYP000187092429",
  "n": 5000,
  "placements": [
    {
      "erz": "ERZ22157947",
      "contig": "ERZ22157947.1852784-NODE-1852814-length-597-cov-3.712177",
      "start": 2,
      "end": 595,
      "strand": -1,
      "neighbours": []
    },
    {
      "erz": "ERZ22158282",
      "contig": "ERZ22158282.115901-NODE-115905-length-597-cov-13.690037",
      "start": 2,
      "end": 595,
      "strand": -1,
      "neighbours": []
    }
  ],
  "placements_total": 38,
  "neighbour_total": 0,
  "truncated": false,
  "window_interpretation": {
    "empty_is_mostly_sparsity": true,
    "measured": "gap p50 = 16,355 bp; 91.0% of placements have zero neighbours at n=5000 over 1,911,465 contigs",
    "suggested_n_bp": 50000,
    "note": "an empty list here is predominantly a property of short metagenomic contigs. Re-ask with the suggested window before reading it as 'this protein is alone'."
  },
  "ms": 268.337
}

Metagenomes

GET

/api/v1/biome

Count MGnify protein clusters by habitat (biome lineage), or list the biome vocabulary.

Counts are exact over all 1.66 billion MGnify clusters. clusters includes every deeper lineage under the matched one; clusters_exactly_at_this_lineage is the part assigned to that lineage itself. sample is a bounded sample of cluster ids, never the complete set. Biome membership overlaps (a cluster can be in several biomes), so never subtract counts to get 'in A and not in B'. An ambiguous name (soil matches two environments) or an unknown one answers 404 with options or candidates — a statement about the index vocabulary, not an empty biome. Without lineage, returns the vocabulary ranked by size.

매개변수

이름타입설명
lineagestringBiome lineage, e.g. root:Environmental:Terrestrial:Soil (case-insensitive; a unique suffix also works). Alias: biome.
limitintegerNumber of sample cluster ids to return. Clamped to 0-500. 기본값: 50
childrenbooleanInclude child biomes; 0 to omit. 기본값: 1
topintegerVocabulary mode (no lineage): number of biomes. Clamped to 1-500. 기본값: 25
max_depthintegerVocabulary mode: deepest lineage level listed. Clamped to 1-12. 기본값: 3

요청 예시

curl "https://bioq.bio/api/v1/biome?lineage=root:Environmental:Terrestrial:Soil&limit=3" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • clusters clusters at this lineage and everything under it (exact)
  • clusters_exactly_at_this_lineage the disjoint part assigned to this lineage itself
  • members member proteins in those clusters
  • sample a bounded sample of cluster ids (sample_is_complete is false)
  • children[] child biomes with their own counts; they overlap, do not subtract
  • corpus.fraction_of_corpus share of all clusters
  • 404 body ambiguous, options[] (each with a ready query) or candidates[]
응답 예시
{
  "requested": "root:Environmental:Terrestrial:Soil",
  "matched": true,
  "how": "exact",
  "lineage": "root:environmental:terrestrial:soil",
  "lineage_parts": [
    "root",
    "environmental",
    "terrestrial",
    "soil"
  ],
  "depth": 4,
  "clusters": 49877070,
  "clusters_exactly_at_this_lineage": 25293143,
  "members": 122487759,
  "first_cluster_id": "MGYP000000000012",
  "last_cluster_id": "MGYP011140254586",
  "sample": [
    "MGYP000000000012",
    "MGYP011133358521",
    "MGYP011134264257"
  ],
  "sample_stride": null,
  "sample_thinned": 6755,
  "sample_bounded": false,
  "sample_is_a_sample": true,
  "sample_is_complete": false,
  "corpus": {
    "total_clusters": 1661142385,
    "fraction_of_corpus": 0.030025764
  },
  "children": [
    {
      "prefix": "root:environmental:terrestrial:soil:tropical rainforest",
      "name": "tropical rainforest",
      "clusters": 8188087,
      "clusters_exactly_at_this_lineage": 7730222
    },
    {
      "prefix": "root:environmental:terrestrial:soil:forest soil",
      "name": "forest soil",
      "clusters": 7015265,
      "clusters_exactly_at_this_lineage": 5925088
    },
    {
      "prefix": "root:environmental:terrestrial:soil:agricultural",
      "name": "agricultural",
      "clusters": 5272596,
      "clusters_exactly_at_this_lineage": 4538079
    }
  ],
  "children_sum_note": "children are DISJOINT subtrees of each other, but their sum can exceed `clusters` and that is not an error: 5.5% of clusters are in two or more top-level biomes at once (measured on 10,777,396 clusters), so biome membership OVERLAPS. Never derive 'in A and not in B', or 'everything else', by subtracting these numbers.",
  "prefix_expansion": "lineage prefix expansion is APPLIED: `clusters` counts the matched prefix AND every deeper lineage under it, because the builder indexes every ancestor prefix of every lineage. A query for 'soil' therefore reaches 'soil:Permafrost' and 'soil:Sand'. `clusters_exactly_at_this_lineage` is the disjoint part — clusters whose own lineage is this prefix — so `clusters` >= `clusters_exactly_at_this_lineage` always, and the difference is the subtree.",
  "elapsed_seconds": 0.000056
}
GET

/api/v1/unexplored

List large MGnify protein clusters with little or no Pfam annotation.

Returns annotation-poor clusters, optionally limited to a habitat, sorted by size (number of member sequences). Size is not a measure of how well a candidate is supported: each row's discovery_readiness counts the independent assemblies it was seen in, and most of these clusters sit in a single assembly. Gate on n_claimable, not on matched. pfam_poor describes annotation coverage, not function. Each row costs an index read, so keep top small.

매개변수

이름타입설명
biomestringCase-insensitive text matched inside each cluster's biome lineages, e.g. root:Environmental:Terrestrial:Soil or soil.
min_sizeintegerMinimum member sequences per cluster. 기본값: 5
topintegerRows to return. 기본값: 20

요청 예시

curl "https://bioq.bio/api/v1/unexplored?biome=root:Environmental:Terrestrial:Soil&top=5" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • matched clusters passing min_size and biome
  • n_claimable returned rows whose readiness allows a claim
  • results[].size member sequences, not assemblies
  • results[].biomes / n_biomes every biome lineage the cluster was seen in
  • results[].discovery_readiness verdict, claim_allowed, n_assemblies, n_independent_runs
  • meaning / readiness_note what pfam_poor and the ordering do and do not mean
응답 예시
{
  "matched": 49158,
  "n_returned": 5,
  "truncated": true,
  "meaning": "pfam_poor describes annotation coverage, not function",
  "n_claimable": 0,
  "readiness_note": "size is the number of member sequences in the cluster, not the number of assemblies. Each row's discovery_readiness says how many independent assemblies the candidate was actually observed in; the size ordering is not a ranking of claimability",
  "results": [
    {
      "cluster": "MGYP003380827528",
      "size": 2560,
      "pfam_poor": true,
      "n_biomes": 8,
      "biomes": [
        "root:Host-associated:Human:Digestive system:Large intestine:Fecal",
        "root:Engineered:Biogas plant:Wet fermentation",
        "root:Host-associated:Mammals:Respiratory system"
      ],
      "discovery_readiness": {
        "verdict": "no_claim",
        "claim_allowed": false,
        "n_assemblies": 1,
        "n_independent_runs": 1,
        "min_assemblies_required": 3,
        "why": "One assembly: a single independent observation supports no association claim. The partner list is only neighbours inside the same sample"
      }
    },
    {
      "cluster": "MGYP003545442403",
      "size": 989,
      "pfam_poor": true,
      "n_biomes": 8,
      "biomes": [
        "root:Mixed",
        "root:Host-associated:Mammals:Digestive system:Fecal",
        "root:Host-associated:Birds:Digestive system:Ceca"
      ],
      "discovery_readiness": {
        "verdict": "no_claim",
        "claim_allowed": false,
        "n_assemblies": 1,
        "n_independent_runs": 1,
        "min_assemblies_required": 3,
        "why": "One assembly: a single independent observation supports no association claim. The partner list is only neighbours inside the same sample"
      }
    }
  ]
}
GET

/api/v1/unexplored_with_known

Pair annotation-poor clusters with the clusters they co-occur with across assemblies.

Takes the largest annotation-poor clusters matching the filters, keeps only those seen in at least two assemblies, and lists their co-occurring partners. A partner is a hypothesis about what an unexplored cluster does, not evidence. Each partner carries pair_readiness: pairs whose shared assemblies all come from one collection run are no_claim. The call examines at least 200 candidates and can take tens of seconds; if no candidate survives, meaning explains that this is the shape of the data.

매개변수

이름타입설명
biomestringCase-insensitive text matched inside biome lineages.
min_sizeintegerMinimum member sequences per candidate cluster. 기본값: 50
limitintegerMaximum pairs to return (the candidate pool is max(40 x limit, 200)). 기본값: 10

요청 예시

curl "https://bioq.bio/api/v1/unexplored_with_known?biome=root:Environmental:Terrestrial:Soil&limit=2" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • pairs[].unexplored_cluster / size / n_assemblies the candidate (size = member sequences)
  • pairs[].partners[] cluster, n_both (shared assemblies), n_partner, id_distance, pair_readiness
  • candidates_matched / candidates_examined / survivors how the pool was narrowed
  • min_assemblies assemblies a candidate needs to have partners (2)
  • meaning present when no pair was found
응답 예시
{
  "pairs": [
    {
      "unexplored_cluster": 1004231992,
      "size": 304,
      "size_meaning": "member sequences in this cluster (MGnify 'size'), not assembly count",
      "n_assemblies": 9,
      "n_biomes": 8,
      "partners": [
        {
          "cluster": 1004938243,
          "n_both": 9,
          "n_partner": 9,
          "id_distance": 706251,
          "pair_readiness": {
            "n_shared": 9,
            "n_independent_runs": 1,
            "verdict": "no_claim",
            "claim_allowed": false,
            "why": "All 9 assemblies come from the same collection run (ERZ724…): one sampling event, not independent replication"
          }
        },
        {
          "cluster": 1004937807,
          "n_both": 9,
          "n_partner": 32,
          "id_distance": 705815,
          "pair_readiness": {
            "n_shared": 9,
            "n_independent_runs": 1,
            "verdict": "no_claim",
            "claim_allowed": false,
            "why": "All 9 assemblies come from the same collection run (ERZ724…): one sampling event, not independent replication"
          }
        }
      ],
      "biomes": [
        "root:Engineered:Wastewater",
        "root:Environmental:Terrestrial:Soil:Agricultural",
        "root:Host-associated:Fish:Digestive system"
      ]
    }
  ],
  "unresolved": [],
  "candidates_examined": 200,
  "candidates_matched": 1232,
  "min_assemblies": 2,
  "survivors": 2
}
GET

/api/v1/neighbourhood

Find MGnify proteins that appear in the same assemblies as a given one, with habitat attached.

Partners are scored by shared assemblies (n_both) and come from the queried protein's own index block, i.e. nearby ids. Partners whose shared assemblies span different collection runs (distant) are listed before those explained by one run (adjacent); pairs from one sampling run co-occur because they share genomes, not because they interact. Each partner has its own pair_readiness, and discovery_readiness covers the queried protein. An id absent from the release answers 200 with status other than FOUND, not 404.

매개변수

이름타입설명
cluster필수stringMGnify protein id, MGYP… or the bare integer.
min_bothintegerMinimum shared assemblies for a partner. 기본값: 3
topintegerMaximum partners to return. 기본값: 20

요청 예시

curl "https://bioq.bio/api/v1/neighbourhood?cluster=1&top=5" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • partners[] cluster, n_both, n_partner, id_distance, pair_readiness
  • status FOUND, or an absence status with meaning
  • n_partners_found / n_distant / n_adjacent counts before the top limit
  • n_partners_claimable returned partners whose pair_readiness allows a claim
  • strongest_distant best partner not explained by one collection run
  • biomes / unresolved habitat of the queried protein, or why it is missing
응답 예시
{
  "cluster": 1,
  "partners": [
    {
      "cluster": 80,
      "n_both": 234,
      "n_partner": 1606,
      "id_distance": 79,
      "pair_readiness": {
        "n_shared": 234,
        "n_independent_runs": 55,
        "verdict": "testable",
        "claim_allowed": true,
        "why": "234 assemblies across 55 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid"
      }
    },
    {
      "cluster": 64,
      "n_both": 230,
      "n_partner": 1679,
      "id_distance": 63,
      "pair_readiness": {
        "n_shared": 230,
        "n_independent_runs": 56,
        "verdict": "testable",
        "claim_allowed": true,
        "why": "230 assemblies across 56 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid"
      }
    }
  ],
  "unresolved": [
    "no biome annotation for this cluster"
  ],
  "discovery_readiness": {
    "verdict": "testable",
    "claim_allowed": true,
    "n_assemblies": 282,
    "n_independent_runs": 59,
    "min_assemblies_required": 3,
    "why": "282 assemblies across 59 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid",
    "detail": "The assembly list is the representative protein's, so it is a lower bound for multi-member clusters"
  },
  "status": "FOUND",
  "n_assemblies": 282,
  "n_partners_found": 3399,
  "n_adjacent": 764,
  "n_distant": 2635,
  "n_partners_claimable": 5,
  "partners_readiness_note": "Each partner's pair_readiness counts the independent runs among the assemblies the pair shares. However large n_both is, a pair that comes from one run was observed once",
  "strongest_distant": {
    "cluster": 80,
    "n_both": 234,
    "id_distance": 79,
    "why_it_matters": "no single accession prefix accounts for half the shared assemblies, so one collection run does not explain this pair"
  },
  "biomes": [],
  "note": "id_distance under 1,000,000 usually means the same sampling run; those pairs co-occur because they share genomes, not because they interact"
}
GET

/api/v1/cooccur

Count the assemblies an MGnify protein appears in, and its overlap with a second protein.

With only with, returns how many assemblies the protein was observed in and a sample of them. With without as well, returns the overlap (n_both), the assemblies unique to the first (n_only_with), and readiness for each side and for the pair; the weaker side bounds any claim. An observed/expected ratio is given only when you pass universe, the number of assemblies (universe_assemblies in the response), never the cluster count. Only the depletion direction is meaningful on this corpus; enrichment.quotable says whether the ratio may be quoted. Rows are representative proteins, so for a multi-member cluster the assembly list is a lower bound.

매개변수

이름타입설명
with필수stringMGnify protein id (MGYP… or bare integer).
withoutstringSecond protein id for an overlap query.
universeintegerAssembly count to use as the denominator of an observed/expected ratio (e.g. the universe_assemblies value). Non-integer values are ignored.

요청 예시

curl "https://bioq.bio/api/v1/cooccur?with=1&without=80" \
  -H "Authorization: Bearer $BIOQ_KEY"

주요 필드

  • n_with / n_without assemblies each protein was observed in
  • n_both / n_only_with shared and first-only assemblies
  • discovery_readiness, pair_readiness, weakest_side verdicts for each side and the pair
  • enrichment null unless universe is given; then observed, expected, ratio, quotable
  • universe_assemblies the assembly count of the corpus
  • sample / sample_only_with first 20 assembly accessions
  • unit rows are proteins; assembly lists are lower bounds for clusters
  • status WITHOUT_NOT_IN_RELEASE (still 200) when the second id is absent from the release
응답 예시
{
  "with": 1,
  "n_with": 282,
  "unit": "protein (MGYP accession); for a multi-member cluster this is the representative's assembly list, a lower bound on the cluster's",
  "universe_assemblies": 51274,
  "discovery_readiness": {
    "verdict": "testable",
    "claim_allowed": true,
    "n_assemblies": 282,
    "n_independent_runs": 59,
    "min_assemblies_required": 3,
    "why": "282 assemblies across 59 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid"
  },
  "without": 80,
  "n_without": 1606,
  "n_only_with": 48,
  "n_both": 234,
  "sample_only_with": [
    "ERZ1026854",
    "ERZ1026878",
    "ERZ1030449"
  ],
  "pair_readiness": {
    "verdict": "testable",
    "claim_allowed": true,
    "n_shared": 234,
    "n_independent_runs": 55,
    "bounded_by": "testable",
    "why": "234 assemblies across 55 distinct runs: the minimum for a null contrast is met. The enrichment test on this engine is saturated, so only the depletion direction is valid"
  },
  "weakest_side": {
    "which": "with",
    "verdict": "testable",
    "claim_allowed": true,
    "n_assemblies": 282,
    "n_independent_runs": 59
  },
  "enrichment": null,
  "enrichment_note": "pass &universe=<assembly count> for an observed/expected ratio; it is omitted rather than guessed because a wrong denominator makes the number meaningless",
  "caveat": "a pair present in few assemblies is not evidence whatever the ratio",
  "elapsed_ms": 3.6
}

Agent

POST

/api/v1/agent

Ask a research question in plain language; an agent queries the endpoints above and streams an answer in which every data claim cites a step (beta).

Beta. Send a JSON body; the response is a server-sent event stream. The agent plans, calls BioQ endpoints (in parallel where it can), and writes a markdown answer whose citations [n] refer to step n. Protein sequences in the question are replaced with handles such as [SEQ1] before the language model sees the text, and swapped back only when a step sends them to the BioQ engine. One request counts as one agent question; the queries the agent makes are not counted again. Up to 10 steps per question. Event payloads may change while in beta.

매개변수

이름타입설명
question필수stringJSON body field. The question, in plain language. May include pasted protein sequences or FASTA.
langstringJSON body field. Answer language: en, ko, ja, zh-CN, zh-TW, es, fr or de. 기본값: en
historyarrayJSON body field. Up to 3 previous turns as [{"q": question, "a": answer}] for follow-up questions.

요청 예시

curl -N -X POST "https://bioq.bio/api/v1/agent" \
  -H "Authorization: Bearer $BIOQ_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "Which lineages depend most on KRAS?", "lang": "en"}'

주요 필드

  • start run_id, the question as the model sees it (masked_question), and the sequence handles
  • step one engine call: n, tool, args, status (running, ok, error), and when finished http, ms, query and the full result
  • delta a chunk of text from the model for turn number turn; concatenate in order
  • turn_end kind is tools (the text so far was planning) or final (the text so far is the answer)
  • done run_id, steps, ms
  • error message is agent_failed or timeout
응답 예시
{
  "request": {
    "question": "Which lineages depend most on KRAS?",
    "lang": "en"
  },
  "content_type": "text/event-stream",
  "stream": "event: start\ndata: {\"run_id\":\"a1b2c3d4e5\",\"masked_question\":\"Which lineages depend most on KRAS?\",\"sequences\":[]}\n\nevent: step\ndata: {\"n\":1,\"tool\":\"dependency\",\"args\":{\"gene\":\"KRAS\"},\"status\":\"running\"}\n\nevent: step\ndata: {\"n\":1,\"tool\":\"dependency\",\"args\":{\"gene\":\"KRAS\"},\"status\":\"ok\",\"http\":200,\"ms\":212,\"query\":\"/depmap?gene=KRAS\",\"result\":{\"…\":\"…\"}}\n\nevent: turn_end\ndata: {\"turn\":0,\"kind\":\"tools\",\"note\":\"\"}\n\nevent: delta\ndata: {\"turn\":1,\"text\":\"Pancreatic lines depend most on KRAS: 43 of 47 [1]…\"}\n\nevent: turn_end\ndata: {\"turn\":1,\"kind\":\"final\"}\n\nevent: done\ndata: {\"run_id\":\"a1b2c3d4e5\",\"steps\":1,\"ms\":9120}\n\n"
}

Service

GET

/api/v1/status

Check that the service is up and which data layers are loaded (no authentication).

Public health check. layers maps each data layer to true when it is loaded; an endpoint whose layer is false answers 503 with the reason rather than an empty result. counts gives headline sizes of the loaded datasets. Does not count against any quota.

요청 예시

curl "https://bioq.bio/api/v1/status"

주요 필드

  • status ok when the gateway and engine are reachable
  • layers map of layer name to loaded (true/false)
  • counts headline record counts for loaded datasets
응답 예시
{
  "status": "ok",
  "layers": {
    "mgnify": true,
    "trembl": true,
    "structure": true,
    "taxon": true,
    "c2": true,
    "dna": true,
    "refseq": true,
    "variants": true,
    "unexplored": true,
    "cooccur": true,
    "pfam": true,
    "pfam_reverse": true,
    "homology": true,
    "affinity": true,
    "gdsc": false,
    "string": true,
    "biogrid": true,
    "biome": true,
    "seqhash": false,
    "synteny": true,
    "depmap": true,
    "depmap_omics": true
  },
  "counts": {
    "mgnify_clusters": 1661142385,
    "pfam_annotated_proteins": 2985942516,
    "trembl_accessions": 149430635,
    "structures_experimental": 260621,
    "structures_predicted": 542378,
    "affinity_measurements": 5153526,
    "string_edges": 162725618,
    "biogrid_records": 2804534,
    "synteny_placements": 177896636
  }
}