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.

GET/v2/molecules/om-space/export

Download 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
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"
Response
{
  "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 release parameter. 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 in files; saving the JSON response alone does not download the molecules.
  • If next_part_offset is not null, request that value as part_offset, and pass the first page's manifest_sha256 as expected_manifest_sha256 on every subsequent request. Continue until next_part_offset is null.
  • The equivalent Om MCP tool is molecule_accessible_space_export with tier=om_50 and part_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_sha256 to 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 sha256 before adding it to a local index.
GET/v2/molecules/fulfillment/pricing

Fulfillment Pricing

Return the current plan-specific Molecule Fulfillment price and order policy.

cURL
curl -G https://api.omtx.ai/v2/molecules/fulfillment/pricing \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "usage_type": "molecule_fulfillment_standard",
  "plan_key": "team",
  "fulfillment_type": "standard",
  "provider": "om",
  "unit_price_cents": 15000,
  "base_unit_price_cents": 15000,
  "currency": "usd"
}
POST/v2/molecules/search

Search Molecules

Search candidate molecule matches before quoting or ordering arbitrary submitted SMILES.

cURL
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"
  }'
Response
{
  "provider": "om",
  "response": {
    "queries": [
      {
        "query_smiles": "CC(=O)Oc1ccccc1C(=O)O",
        "available": true,
        "results": [
          {
            "smiles": "CC(=O)Oc1ccccc1C(=O)O",
            "similarity": 1.0
          }
        ]
      }
    ]
  }
}
  • smiles_list accepts 1 to 100 SMILES strings.
  • max_results accepts 1 to 100.
  • max_depth is currently fixed to 1.
  • max_supplier_risk and max_chemistry_risk accept low, medium, or high.
  • Search results are exploratory; quote and order creation decide final orderability.
POST/v2/molecules/quote

Quote Molecules

Quote exact-match Molecule Fulfillment before placing an arbitrary-SMILES order.

cURL
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"
      }
    ]
  }'
Response
{
  "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
    }
  ]
}
  • items accepts 1 to 1000 line items.
  • Each item requires smiles; quantity defaults to 1 and accepts 1 to 1000.
  • name is optional and limited to 200 characters.
POST/v2/molecules/fulfillment/orders

Order Molecules

Create a Wallet Credits-funded order for Molecule Fulfillment.

cURL
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"
  }'
Response
{
  "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_id must 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.
GET/v2/molecules/fulfillment/shipping-addresses

Shipping Addresses

List saved Molecule Fulfillment shipping addresses for the authenticated user.

cURL
curl -G https://api.omtx.ai/v2/molecules/fulfillment/shipping-addresses \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "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_id when it is present, or pass any saved addresses[].id.
  • Order creation requires a saved shipping address id.
GET/v2/molecules/fulfillment/orders

List Orders

List recent Molecule Fulfillment orders for the authenticated user.

cURL
curl -G https://api.omtx.ai/v2/molecules/fulfillment/orders \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "limit=20"
Response
{
  "orders": [],
  "count": 0
}
  • limit accepts 1 to 100 and defaults to 20.
GET/v2/molecules/fulfillment/order-status

Order Status

Retrieve one Molecule Fulfillment order with billing and shipment status.

cURL
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"
Response
{
  "order": {
    "order_number": "MF-20260527-ABC123EF",
    "status": "pending_submission",
    "provider": "om"
  }
}

Python SDK

Order selected Om Accessible Space rowsPython
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"])
Score locally with open-weight LULA, then order Om rowsPython
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"])
Search, quote, and order arbitrary submitted SMILESPython
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.