Research uses and scope
This API is a protein-sequence homology measurement primitive, not a general bioinformatics workbench. It is useful for:- finding candidate remote homologs for follow-up analysis;
- seeding an MSA pipeline with release-pinned, reproducible search lanes;
- measuring sequence similarity and coverage for family curation or dataset deduplication;
- restricting a search to an exact taxonomic or annotation-backed subset;
- comparing approximate retrieval with an exhaustive reference search; and
- collecting auditable alignment and calibrated-null evidence before a caller applies its own scientific threshold.
Query
Use the endpoint that matches the query cardinality:POST /v1/homologyacceptsquery, one typed protein sequence;POST /v1/homology/batchacceptsqueries, 1–16 typed protein sequences that share the same controls;POST /v1/homology/searchescreates one durable, cursor-paginated search.
kind: "protein_sequence" and a sequence. Batch responses stay
in input order. The single endpoint rejects queries, and the batch endpoint
rejects query.
Database
Send at most one of:database— a database ID or slug; the server uses its advertised release;database_release_id— an exact immutable release;target_space_id— the immutable scope returned asdatabase.target_space_idby a prior filtered search.
target_space_id is mutually exclusive with database, database_release_id,
and filter. This makes the filtered-search response itself the bootstrap for
reusing an exact scope; there is no public target-space creation endpoint.
Use the database and release list operations in the
API reference to discover valid identifiers.
Controls
For batches, the aggregate may not exceed 10,000 candidate measurements or
1,000 pairwise alignments. Both synchronous operations also enforce a 16 MiB
encoded-response ceiling because each candidate includes its canonical target
sequence. A valid request can therefore hit the byte ceiling before the row
ceiling when targets or alignments are long.
Retained searches
Create a retained search with a requiredIdempotency-Key. It accepts the same
flat scientific fields as POST /v1/homology; only the delivery model and
limit ceiling differ. Retained limit may be 1–10,000 and defaults to 25.
Add Prefer: respond-async to return after durable acceptance, or omit it to
let the server wait briefly for a terminal result.
GET /v1/homology/searches/{homology_search_id}. Once the status is
succeeded, page GET /v1/homology/searches/{homology_search_id}/results with
limit from 1–100 and pass each opaque next_cursor back as
starting_after. Cursors are bound to the retained result set and expire with
it; do not construct or persist them as scientific identifiers.
Cancel queued or running work with
POST /v1/homology/searches/{homology_search_id}/cancel. Cancellation is
idempotent and the resource remains inspectable with status canceled.
Succeeded and failed resources are immutable and return 409; expired resources
return 410.
The 10,000 ceiling is per search or MSA source lane, not per final MSA. MSA
builders may merge several release-pinned lanes and then deduplicate them, so a
merged MSA can be larger while each underlying search remains independently
bounded and reproducible.
Candidates
A single search returnscandidates. A batch returns one entry in responses for
each input query.
Every candidate includes rank, a stable target.id, and the release-owned
ranking measurement. MaxSim is an order-free retrieval measurement; affine
measurements, pairwise alignment, and significance appear when requested and
supported. A candidate row is not itself an assertion that the sequences are
homologous — that is what object: "homology_candidate_set" means. The response
also records database, execution, ranking, usage, performance, result_sha256, and
warnings.
Reading candidate evidence
Two independent questions, answered by two different parts of the response. Do not blend them. How surprising is this measurement under the qualified null? Readsignificance.measurements.expected_false_hits. It is the expected null-event count for the
declared e_value_estimand, exact searched inventory, and threshold. It has the
same units as a BLAST E-value, but its assumptions are identified by
e_value_method; it is not a posterior probability that the sequences are
homologous. The API deliberately does not turn this measurement into a generic
confidence bucket. Choose and record a threshold appropriate to the caller’s
analysis, then apply it directly to expected_false_hits or
log_expected_false_hits.
Use log_expected_false_hits for thresholds in the deep tail; it remains the
authoritative coordinate when expected_false_hits underflows. The response
also binds e_value_calibration_id, e_value_qualification_id,
e_value_searched_inventory_id, e_value_search_policy_id, and the null and
conditioning identities needed to compare or reproduce the number. A changed
inventory, filter, score, procedure, or conditioning context is a different
estimand, not an interchangeable E-value.
pair_tail_probability answers the smaller, pairwise question: under the
qualified null, how often is one target at least this extreme? Its stable forms
are pair_tail_log_probability and pair_tail_surprisal_bits. Surprisal is
-log2(p) information under the null; it is neither an E-value nor a homology
posterior.
significance.measurements.bit_score is a database-size-independent fitted-tail coordinate.
For the homogeneous tail-times-count construction, the identity
expected_false_hits == searched_sequence_count * 2^-bit_score holds in the
supported fitted-tail regime. Conditional, stratified, and procedure-level
E-values need not obey that shortcut; inspect e_value_method and
e_value_estimand instead.
The E-value binds significance.measurements.searched_sequence_count and
significance.measurements.searched_residue_count, the space actually examined after any filter. A
filter changes both the number and potentially the mixture of target strata,
so clients should use the returned value rather than rescale one from another
search.
significance.status says where the number came from —
supported_empirical when the frozen null contains enough observations to
count it, supported_tail_model when it is extrapolated through the fitted
extreme-value tail below minimum_resolvable_probability, and
insufficient_tail_resolution or out_of_support when the calibration cannot
answer at all. Null numeric values always mean the calibration declined, never
that the hit is insignificant.
An extrapolated value is auditable rather than opaque: significance.measurements.tail_model
carries the fitted parameters, so the probability can be recomputed rather than
taken on trust.
tail_model.threshold_score is the lower bound of the fitted tail region, not
the point where extrapolation takes over. The counted null stays authoritative
above it for as long as it still has observations to count, so check
support_status rather than comparing the score to the threshold yourself.
tail_model.holdout_kolmogorov_smirnov is the goodness-of-fit distance from the
held-out calibration split; read it together with
tail_model.holdout_exceedance_count, since the distance alone means little
without the sample size behind it. A tail that fails that test at
holdout_significance_level is never served — the API reports
insufficient_tail_resolution instead of extrapolating through a bad fit.
Did the search miss anything? An E-value assumes the score was computed.
An approximate guarantee permits a search policy that never scores some
targets, so a per-hit E-value says nothing about what was dropped. Use
guarantee: "exhaustive" when completeness matters. database.searched_target_count
and database.searched_residue_count report the space the search covered — the
same numbers the E-value is scaled to — and execution.policy records the
requested and resolved guarantee and completeness outcome.
To inspect a candidate directly, request pairwise_sequence_alignment and read
alignment.sequence_identity_ratio with query_coverage_ratio and
target_coverage_ratio. Identity over a short local segment is different
evidence from identity spanning most of both sequences. When calibrated
significance is unavailable, the API reports that once in
evidence_summary.significance; it does not silently promote retrieval
candidates into homologs.
evidence_summary.is_requested_evidence_complete answers only whether the
response carried every evidence class the request contracted for. With the
default significance: "if_available", it can be true while
evidence_summary.significance.status is unavailable; inspect both fields.
Retries and contract version
Send an optionalIdempotency-Key of at most 255 characters when retrying the
same synchronous POST after an ambiguous failure. Retained search creation
requires the header. In both cases the replay binding lasts 24 hours. A 429
response includes Retry-After; a successful synchronous response does not.
Every homology operation accepts Rafflesia-API-Version: 2026-08-08 to pin the
current dated contract; omit it to use the current contract. An unsupported value returns
api_version_unsupported before execution. Generated SDK clients should ignore
unknown response fields so additive changes remain safe.
BLAST tabular output
The CLI can emit BLAST-outfmt 6 so existing pipelines work unchanged:
evalue from
significance.measurements.expected_false_hits and bitscore from
significance.measurements.bit_score.
When the selected release has no qualified calibration both are written NA,
not a number. The format has nowhere to say “unknown”, and a numeric stand-in
would be worse than useless: every BLAST pipeline filters on evalue < 1e-5,
which a sentinel like -1 passes, silently promoting uncalibrated rows to
confident hits. NA is what R and pandas already read as missing, and NaN
comparisons are false, so the same filter drops the row instead.
The generated endpoint reference is the source of
truth for schemas and allowed values.