Molecule Fulfillment
Order selected Om Accessible Space score rows with Wallet Credits, check arbitrary SMILES before ordering, and inspect fulfillment status through the Om API.
Molecule Fulfillment routes are user-scoped. Selected Om Accessible Space
score rows can move directly into Wallet Credits-funded order creation.
For that path, score with source="om", choose the rows you want, and
order them directly; no quote or upstream vendor selection is required.
Search and quote remain checks for arbitrary submitted SMILES; order
creation uses Wallet Credits. Rows scored from Om Accessible Space include
the order metadata needed to place selected hits directly.
Provider-backed availability, pricing, quote, and status information can
change. Om manages the order flow and strives to work with reputable
providers, but Om does not guarantee provider availability, exact match,
synthesis success, identity, purity, yield, delivery timing, regulatory
suitability, fitness for intended use, or downstream experimental results.
Consult the applicable provider's documentation, specifications, terms,
and compliance guidance for provider-specific claims.
/v2/molecules/om-space/exportDownload Om 50 for local integration
Return a bounded page of verified, expiring Parquet links from the current customer-safe Om 50 release. Follow every page to download the complete catalog.
curl -G https://api.omtx.ai/v2/molecules/om-space/export \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode "tier=om_50" \
--data-urlencode "part_limit=1"{
"schema_version": 1,
"kind": "om_accessible_space_customer_export",
"release": "enumerated_v2_1_price_verified",
"dataset": "om_50",
"tier": "om_50",
"format": "parquet",
"compression": "zstd",
"row_count": 5635938,
"part_count": 57,
"columns": [
"schema_version",
"kind",
"release",
"dataset",
"tier",
"compound_id",
"canonical_smiles_hash",
"canonical_smiles",
"smiles",
"customer_wallet_credits",
"om_tier"
],
"source_manifest_sha256": "<sha256>",
"inventory_sha256": "<sha256>",
"manifest_sha256": "<sha256>",
"expires_at": "2026-09-18T16:00:00Z",
"part_offset": 0,
"returned_part_count": 1,
"next_part_offset": 1,
"files": [
{
"path": "part-00000.parquet",
"row_count": 100000,
"size_bytes": 12345678,
"sha256": "<sha256>",
"download_url": "https://..."
}
]
}- This route is read-only and does not place a Wallet hold, charge Wallet Credits, launch scoring, or order molecules.
- The server selects the published release. Do not send a
releaseparameter. The response names the concrete immutable release; the example above shows OM_50 v2.1 as of September 18, 2026. - The example requests one part to keep the response short. For a full download, use
part_limit=100(the default and maximum). The illustrated 57-part release fits in one response. Download every file infiles; saving the JSON response alone does not download the molecules. - If
next_part_offsetis not null, request that value aspart_offset, and pass the first page'smanifest_sha256asexpected_manifest_sha256on every subsequent request. Continue untilnext_part_offsetis null. - The equivalent Om MCP tool is
molecule_accessible_space_exportwithtier=om_50andpart_limit=100; it uses the same pagination and manifest consistency fields. - For the STAT6 Discovery Challenge, choose candidates from the current OM_50 v2 catalog and validate them against the challenge before submission. Membership in a previous export does not establish current challenge eligibility.
- The Parquet files contain molecule identity, SMILES, tier, and order metadata only. Supplier identity, supplier IDs, internal COGS, lead time, procurement priority, credentials, and raw internal catalog locations are excluded.
- Download URLs expire after at most one hour. Request the page again with
expected_manifest_sha256to obtain fresh links while checking that the published export is unchanged. If the manifest has changed, refresh the catalog instead of mixing releases. - Verify each downloaded part against its
sha256before adding it to a local index.
/v2/molecules/fulfillment/pricingFulfillment Pricing
Return the current plan-specific Molecule Fulfillment price and order policy.
curl -G https://api.omtx.ai/v2/molecules/fulfillment/pricing \
-H "x-api-key: YOUR_API_KEY"{
"usage_type": "molecule_fulfillment_standard",
"plan_key": "team",
"fulfillment_type": "standard",
"provider": "om",
"unit_price_cents": 15000,
"base_unit_price_cents": 15000,
"currency": "usd"
}/v2/molecules/searchSearch Molecules
Search candidate molecule matches before quoting or ordering arbitrary submitted SMILES.
curl -X POST https://api.omtx.ai/v2/molecules/search \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: molecule-search-demo-001" \
-H "Content-Type: application/json" \
-d '{
"smiles_list": ["CC(=O)Oc1ccccc1C(=O)O"],
"max_results": 5,
"substructure_search": false,
"max_depth": 1,
"include_chemistry_risk": true,
"include_chemistry_risk_score": true,
"max_price": 25.0,
"max_supplier_risk": "medium",
"max_chemistry_risk": "medium"
}'{
"provider": "om",
"response": {
"queries": [
{
"query_smiles": "CC(=O)Oc1ccccc1C(=O)O",
"available": true,
"results": [
{
"smiles": "CC(=O)Oc1ccccc1C(=O)O",
"similarity": 1.0
}
]
}
]
}
}smiles_listaccepts 1 to 100 SMILES strings.max_resultsaccepts 1 to 100.max_depthis currently fixed to1.max_supplier_riskandmax_chemistry_riskacceptlow,medium, orhigh.- Search results are exploratory; quote and order creation decide final orderability.
/v2/molecules/quoteQuote Molecules
Quote exact-match Molecule Fulfillment before placing an arbitrary-SMILES order.
curl -X POST https://api.omtx.ai/v2/molecules/quote \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: molecule-quote-demo-001" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"smiles": "CC(=O)Oc1ccccc1C(=O)O",
"quantity": 1,
"name": "aspirin"
}
]
}'{
"usage_type": "molecule_fulfillment_standard",
"plan_key": "team",
"fulfillment_type": "standard",
"provider": "om",
"unit_price_cents": 15000,
"base_unit_price_cents": 15000,
"currency": "usd",
"molecule_count": 1,
"total_amount_cents": 15000,
"items": [
{
"smiles": "CC(=O)Oc1ccccc1C(=O)O",
"name": "aspirin",
"quantity": 1,
"unit_price_cents": 15000,
"subtotal_cents": 15000
}
]
}itemsaccepts 1 to 1000 line items.- Each item requires
smiles;quantitydefaults to1and accepts 1 to 1000. nameis optional and limited to 200 characters.
/v2/molecules/fulfillment/ordersOrder Molecules
Create a Wallet Credits-funded order for Molecule Fulfillment.
curl -X POST https://api.omtx.ai/v2/molecules/fulfillment/orders \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: molecule-wallet-order-demo-001" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"smiles": "CC(=O)Oc1ccccc1C(=O)O",
"quantity": 1,
"name": "selected hit",
"source_metadata": {
"schema_version": 1,
"kind": "om_accessible_space",
"release": "enumerated_v2_1_price_verified",
"dataset": "om_50",
"tier": "om_50",
"selection_policy": "random",
"seed": 42,
"offset": 0,
"n": 50000,
"compound_id": "om:compound:example",
"canonical_smiles_hash": "abc123...",
"customer_wallet_credits": 5000,
"om_tier": "om_50"
}
}
],
"shipping_address_id": "addr_123"
}'{
"order_number": "MF-20260527-ABC123EF",
"status": "payment_complete",
"molecule_count": 1,
"total_amount_cents": 5000,
"provider": "om",
"wallet_staged_transaction_id": "txn_123",
"balance_after": 495000
}- Public API Molecule Fulfillment uses Wallet Credits. Fund credits first through Wallet top-up or an active subscription.
shipping_address_idmust reference a saved shipping address for the user.- For selected rows from Om Accessible Space LULA scoring, pass the returned row into the corresponding order item so Om can validate the fixed Wallet Credit cost and route fulfillment. Preserve that row's actual release and identity metadata; do not replace them with the illustrative values above.
/v2/molecules/fulfillment/shipping-addressesShipping Addresses
List saved Molecule Fulfillment shipping addresses for the authenticated user.
curl -G https://api.omtx.ai/v2/molecules/fulfillment/shipping-addresses \
-H "x-api-key: YOUR_API_KEY"{
"addresses": [
{
"id": "addr_123",
"recipient_name": "Jane Scientist",
"company": "Example Bio",
"address_line1": "1 Main St",
"city": "Boston",
"state_province": "MA",
"postal_code": "02110",
"country": "US",
"phone": "+1 555 0100",
"is_default": true
}
],
"count": 1,
"default_shipping_address_id": "addr_123"
}- Use
default_shipping_address_idwhen it is present, or pass any savedaddresses[].id. - Order creation requires a saved shipping address id.
/v2/molecules/fulfillment/ordersList Orders
List recent Molecule Fulfillment orders for the authenticated user.
curl -G https://api.omtx.ai/v2/molecules/fulfillment/orders \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode "limit=20"{
"orders": [],
"count": 0
}limitaccepts 1 to 100 and defaults to 20.
/v2/molecules/fulfillment/order-statusOrder Status
Retrieve one Molecule Fulfillment order with billing and shipment status.
curl -G https://api.omtx.ai/v2/molecules/fulfillment/order-status \
-H "x-api-key: YOUR_API_KEY" \
--data-urlencode "order_number=MF-20260527-ABC123EF"{
"order": {
"order_number": "MF-20260527-ABC123EF",
"status": "pending_submission",
"provider": "om"
}
}Python SDK
from pathlib import Path
from uuid import uuid4
import polars as pl
from omtx import OmClient
with OmClient(api_key="YOUR_API_KEY") as client:
job = client.lula2.score(
protein_sequence="YOUR_JAK2_V617F_PROTEIN_SEQUENCE",
source="om",
tier=50,
n=50_000,
top_k=10_000,
idempotency_key="jak2-v617f-lula2-r1",
)
artifact_paths = []
result_dir = Path("outputs/jak2-v617f-lula2-r1")
for job_id in job["job_ids"]:
client.jobs.wait(job_id, poll_interval=5, timeout=3600)
artifact_paths.extend(
client.jobs.download_all_artifacts(
job_id,
output_dir=result_dir / job_id,
overwrite=True,
)
)
score_tables = [
pl.read_parquet(path)
for path in artifact_paths
if path.name == "top_hits.parquet"
]
score_rows = pl.concat(score_tables).sort("score", descending=True)
selected_hits = score_rows.head(100).to_dicts()
addresses = client.molecules.shipping_addresses()
order = client.molecules.order(
items=selected_hits,
shipping_address_id=addresses["default_shipping_address_id"],
idempotency_key=f"jak2-v617f-round-1-{uuid4()}",
)
print(order["order_number"])from uuid import uuid4
from omtx import OmClient
from omtx.lula import load_model
with OmClient(api_key="YOUR_API_KEY") as client:
model = load_model("lula1.1")
scores = model.score(
protein_sequence="YOUR_PROTEIN_SEQUENCE",
source="om",
tier=50,
n=50_000,
client=client,
)
selected_hits = scores[:96]
addresses = client.molecules.shipping_addresses()
order = client.molecules.order(
items=selected_hits,
shipping_address_id=addresses["default_shipping_address_id"],
idempotency_key=f"local-lula-order-{uuid4()}",
)
print(order["order_number"])from omtx import OmClient
with OmClient(api_key="YOUR_API_KEY") as client:
pricing = client.molecules.pricing()
hits = client.molecules.search(
smiles_list=["CC(=O)Oc1ccccc1C(=O)O"],
max_results=5,
)
quote = client.molecules.quote(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}],
)
order = client.molecules.order(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}],
shipping_address_id="addr_123",
idempotency_key="molecule-wallet-order-001",
)
print(pricing["provider"], quote["total_amount_cents"], order["order_number"])Access and data boundaries
- Molecule Fulfillment does not expose Generated Data shards.
- Matching and orderability checks are performed by Om Gateway and Wallet services.
- Molecule Fulfillment does not grant raw Om Data, Generated Data, model weights, or broader platform rights.
- The SDK molecule namespace is a thin wrapper over the canonical
/v2/molecules/*routes.