# Available metadata Source: https://docs.synthesize.bio/get-started/available-metadata Browse and download the metadata vocabularies that each Synthesize Bio model accepts. Every model on Synthesize Bio accepts a specific set of metadata fields as inputs — things like cell type, tissue, disease state, and perturbation details. The valid values for each field (e.g. ontology IDs, cell line names) are defined by the model's vocabulary. The vocabulary depends on the **model** you're using, since different model versions and modalities (bulk vs. single-cell) accept different fields and values. ## Browse vocabularies on the platform You can browse and download the vocabulary for any model you have access to at: Pick a model from the dropdown to see every metadata field it accepts, with downloadable JSON files of the valid values. Each field links to a JSON file containing the full list of valid values. Use these lists to validate inputs before you submit a query, or to discover which ontology IDs / cell lines / tissues are supported for a given model. ## From the SDKs Both SDKs let you discover models programmatically with `list_models()`. Once you have a `model_id`, head to the [vocabulary browser](https://app.synthesize.bio/docs/vocab) to see exactly which metadata that model accepts. `list_models()` and `get_example_query(model_id=...)` `list_models()` and `get_example_query(model_id = ...)` ## Next article Learn how public RNA-seq datasets are sourced, processed, and quality-checked. # Public dataset preprocessing Source: https://docs.synthesize.bio/get-started/data-preprocessing Learn how Synthesize Bio sources, processes, and quality-checks public bulk RNA-seq datasets. Synthesize Bio uses public RNA-seq datasets to support model training and platform workflows. This page summarizes how those datasets are selected, processed, and quality-checked before they appear in the platform. ## Data sources All bulk RNA-seq data is sourced from the NCBI Sequence Read Archive ([SRA](https://www.ncbi.nlm.nih.gov/sra)). We select samples that meet these criteria: * Illumina sequencing platform * Transcriptomic library source * Predicted bulk RNA-seq, not single-cell * No fractionation library selection ## Expression data processing Synthesize Bio uses pseudoalignment to quantify transcript-level and gene-level abundance from FASTQ files. When multiple runs correspond to the same sample, we combine the FASTQ files before processing. Reads are trimmed for adapters and sequence quality using `fastp`. Trimmed reads are quantified to genes and transcripts with `kallisto` v0.50.1 against the GRCh38 human or GRCm39 mouse reference genome and the Ensembl r111 transcriptome. Estimated transcript counts are then summed to the gene level based on the transcriptome definition. ## Quality control We use a simple quality-control process across RNA-seq processing stages: * Use `fastp` to evaluate read quality, trim reads, and capture the duplication rate. * Calculate the percent pseudoaligned from `kallisto`. * Calculate the total number of genes with counts greater than 0. In sample selection, we provide a quality flag. The cutoffs are intentionally liberal, so you should compare them against expectations for the protocol used in a study. Data is flagged for these reasons: * Percent aligned reads below 50% * Duplication rate above 80% * Fewer than 10,000 genes with counts greater than 0 ## How to interpret quality flags The best cutoffs depend on the RNA-seq protocol and organism. Total RNA, poly(A)-selected RNA, stranded protocols, and non-stranded protocols can have different expected quality profiles. High duplication rates may indicate over-amplification during PCR steps or poor initial RNA input quality. Higher duplication rates may still be acceptable for some protocols, such as low-input workflows. The number of detected non-zero genes depends on sample complexity, tissue or cell type, and sequencing depth. ## Metadata curation Sample-level annotation is curated through a semi-automated Synthesize Bio process. We curate 15 fields, such as tissue, sex, and disease, and map values to ontologies when available. We do not manually review every harmonized metadata result. Review metadata for accuracy when you need high confidence in a specific sample or study. ## References 1. [fastp](https://github.com/OpenGene/fastp) 2. Shifu Chen. 2023. Ultrafast one-pass FASTQ data preprocessing, quality control, and deduplication using fastp. iMeta 2: e107. [https://doi.org/10.1002/imt2.107](https://doi.org/10.1002/imt2.107) 3. [Ensembl](https://useast.ensembl.org/index.html) 4. [kallisto](https://github.com/pachterlab/kallisto) 5. NL Bray, H Pimentel, P Melsted, and L Pachter. 2016. Near-optimal probabilistic RNA-seq quantification. Nature Biotechnology 34, 525-527. [https://www.nature.com/articles/nbt.3519](https://www.nature.com/articles/nbt.3519) # Quickstart Source: https://docs.synthesize.bio/get-started/quickstart Sign up, get an API key, and make your first request to Synthesize Bio. This guide takes you from zero to a working API call in about five minutes. Pick the SDK or integration that matches your environment at the end. Sign up at [app.synthesize.bio](https://app.synthesize.bio) and verify your email. In the platform, open **Settings → API keys** and click **Create key**. Copy the key somewhere safe — you won't be able to view it again. Treat the key like a password. Set it as an environment variable rather than checking it into source control: ```bash theme={null} export SYNTHBIO_API_KEY="sk-..." ``` ```bash theme={null} pip install pysynthbio ``` ```python theme={null} from pysynthbio import SynthbioClient client = SynthbioClient() # picks up SYNTHBIO_API_KEY models = client.list_models() print(models[0]) ``` See the [Python SDK docs](/pysynthbio) for the full reference. ```r theme={null} install.packages("rsynthbio") library(rsynthbio) models <- list_models() head(models) ``` See the [R SDK docs](/rsynthbio) for the full reference. Configure Synthesize Bio as an MCP server in your client of choice — the [MCP setup guide](/platform) walks through Claude Desktop, Cursor, and other compatible tools. Once `list_models()` returns results, you have a working connection. Pick a `model_id` and use `get_example_query(model_id=...)` to generate a starter request you can adapt to your data. Need to know which metadata fields a model accepts? See [Available metadata](/get-started/available-metadata). Want to understand public dataset inputs? See [Public dataset preprocessing](/get-started/data-preprocessing). ## Next article Browse the metadata vocabularies that each model accepts. ## What's next? Full `pysynthbio` reference and recipes. Full `rsynthbio` reference and recipes. Connect Synthesize Bio to Claude, Cursor, and other MCP clients. # Start generating genomics data with Synthesize Bio Source: https://docs.synthesize.bio/index
Start building
with Synthesize Bio
Generative models for human gene expression — predict bulk and single-cell profiles across tissues, cell types, perturbations, and disease states from metadata alone.
Available through Python and R SDKs, MCP-compatible tools, and the web.
```python theme={null} import pysynthbio # Get an example query query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] # Generate a dataset result = pysynthbio.predict_query(query, model_id="gem-1-bulk") # Access the results metadata = result["metadata"] expression = result["expression"] ``` ```r theme={null} library(rsynthbio) # Get an example query query <- get_example_query(model_id = "gem-1-bulk")$example_query # Generate a dataset result <- predict_query(query, model_id = "gem-1-bulk") # Access the results metadata <- result$metadata expression <- result$expression ```
Python logo Python SDK
Use **pysynthbio** to predict gene expression from your Python notebooks and pipelines. Jump to the [Python SDK](/pysynthbio) or start from the [Quickstart](/get-started/quickstart).
R logo R SDK
Use **rsynthbio** to predict gene expression from your R notebooks and pipelines. Jump to the [R SDK](/rsynthbio) or start from the [Quickstart](/get-started/quickstart).
MCP logo MCP
Use MCP-compatible AI tools to predict gene expression and chat about your results.
Synthesize Bio logo Platform
Low- and no-code exploration in the browser — no local install required.
## About our models Generate synthetic gene expression profiles from metadata alone, then use them in downstream analysis and integration workflows. Baseline model for predicting **bulk** gene expression. Baseline model for predicting **single-cell** gene expression. **Coming soon** — next-generation capabilities. ## Advanced platform capabilities Anchor generation to an existing, real reference sample while you apply perturbations or other modifications. Predict or infer biological characteristics such as cell type, tissue, disease state, and more. Vocabularies and fields are model-specific — see [Available metadata](/get-started/available-metadata). Reach out to [partnerships@synthesize.bio](mailto:partnerships@synthesize.bio) if you are interested in trying out the advanced capabilities. ## Support Email us to set up time with the team. [support@synthesize.bio](mailto:support@synthesize.bio) for product and integration questions. # Authentication Source: https://docs.synthesize.bio/platform/authentication How authentication works for the Synthesize Bio MCP server, including OAuth and API key access. # Authentication The MCP server supports two authentication methods. Most users authenticate through OAuth when their MCP host supports it. API key access is available for programmatic use cases, shared project connections, and hosts that only support key-based authentication. ## OAuth (recommended) The MCP server uses **OAuth 2.0 Authorization Code Flow with PKCE**. When you add the Synthesize Bio Claude Connector from Claude's connector marketplace, the entire flow is handled for you: 1. Claude opens your browser to the Synthesize Bio sign-in page. 2. You sign in with your existing Synthesize Bio account. 3. Claude receives a token and caches it for future requests. No separate credentials or setup is required beyond a Synthesize Bio account. ### Token lifecycle * Access tokens are issued during the OAuth flow and cached by the MCP client. * If a token expires, the client re-authenticates automatically. * Revoking access requires disconnecting the connector in Claude settings. ## API key access If your workflow requires direct API access, a custom MCP client, or a shared connection in a host that supports key-based authentication, you can use a platform API key as a Bearer token. ### Creating an API key 1. Sign in to [app.synthesize.bio](https://app.synthesize.bio). 2. Go to **Account → API Keys**. 3. Create a new key and copy it immediately — it is only shown once. ### Using the key Use this MCP URL: ```text theme={null} https://app.synthesize.bio/api/mcp ``` If your MCP host asks for a key name and key value, enter: ```text theme={null} Key name: Authorization Key value: Bearer YOUR_API_KEY ``` The key name must be `Authorization`. The key value must include the `Bearer ` prefix before the API key. For direct HTTP requests, pass the same value as an `Authorization` header: ```bash theme={null} curl https://app.synthesize.bio/api/mcp \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json, text/event-stream" \ -H "MCP-Protocol-Version: 2024-11-05" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' ``` ### Security * Keep your API key secret. Do not commit it to version control. * Rotate keys periodically from the API Keys page. * Each key is scoped to your account and workspace. # Set up the Claude Connector Source: https://docs.synthesize.bio/platform/connect-in-claude Find the Synthesize Bio Claude Connector in Claude and complete the first-time OAuth flow. # Set up the Claude Connector The Synthesize Bio Claude Connector is available in Claude's connector marketplace. Use these steps to connect your Synthesize Bio account to the MCP without manually entering a server URL. You need a Synthesize Bio account on [app.synthesize.bio](https://app.synthesize.bio). The Claude Connector uses OAuth to authenticate your account to the MCP. ## 1. Open Claude connectors In Claude, open [**Settings** > **Connectors**](https://claude.ai/settings/connectors). ## 2. Find Synthesize Bio Search for **Synthesize Bio** and select the Synthesize Bio Claude Connector from the marketplace. ## 3. Authorize with Synthesize Bio Claude will prompt you to authenticate with your Synthesize Bio account. Complete the OAuth sign-in flow in your browser when prompted. You do not need a separate account just for the connector. Your normal Synthesize Bio account is used for authentication. ## 4. Confirm the connector is available After the connection succeeds, Claude should be able to use the Synthesize Bio analysis tools in a conversation. ## First-use checklist * You found the Synthesize Bio Claude Connector in the marketplace. * You completed the OAuth sign-in flow with your Synthesize Bio account. * Claude shows the connector as connected. Next, read [How It Works](./how-it-works) so users know what to expect after they send a prompt. # How It Works Source: https://docs.synthesize.bio/platform/how-it-works Understand the asynchronous job flow and the analysis stages Synthesize Bio MCP runs for each request. # How It Works Most users never need to think about the MCP internals, but it helps to know why the workflow can take a few minutes. ## Asynchronous job flow Synthesize Bio MCP does not complete the entire analysis in a single instant response. Instead, it uses a background job flow: 1. Claude starts the analysis and receives a job ID immediately. 2. Claude checks the job status while the workflow continues on the Synthesize Bio platform. 3. When the run is complete, Claude returns the finished report and any structured result references. This design keeps the integration responsive even when the underlying analysis takes several minutes. ## Analysis stages Each run moves through three major stages: 1. **`resolve_sample_metadata`** Interprets the natural-language prompt and extracts the sample metadata needed to run the comparison. 2. **GEM model** Runs gene expression model inference for the requested groups and modality. 3. **Differential expression** Performs statistical testing with Welch's t-test and Benjamini-Hochberg false discovery rate correction. ## Behind the scenes The MCP uses several internal tools behind the scenes: * `resolve_sample_metadata` extracts the sample metadata needed for the comparison. * `analyze_gene_expression` starts the job. * `get_analysis_results` checks progress and returns the completion result, including a fenced JSON block of gene-level results and the platform dataset link. * `get_counts_data_url` provides a download URL for the raw counts data. In practice, Claude usually handles this flow for the user. The important thing to remember is that a long-running analysis is expected behavior, not a failed request. ## Result format Completed runs return a Markdown summary that contains: * the analysis metadata (prompt, modality, group counts, significance summary), * a link to the Synthesize Bio platform dataset for the run, and * a fenced ` ```json ` block with up to 1,000 of the most significant differentially expressed genes (under a top-level `results` array), so an LLM can parse the block directly to drive downstream analysis or chart widgets (e.g. a volcano plot with x = `log2FoldChange`, y = -log10(`padj`)). While a run is still in flight, `get_analysis_results` returns short progress messages instead. Continue to [Usage Examples](./usage-examples) for prompt patterns that work well. # Synthesize Bio MCP Source: https://docs.synthesize.bio/platform/index Use Synthesize Bio MCP to run gene expression analyses from natural-language prompts with the Synthesize Bio Claude Connector. # Synthesize Bio MCP Synthesize Bio MCP is a connection that lets AI tools like Claude use Synthesize Bio directly inside a chat. It can start and monitor gene expression analyses from a natural-language request. Use this guide to: * Set up the Claude Connector * Understand what kinds of analyses it supports * Write better prompts * Troubleshoot sign-in or long-running jobs ## Server URL ```text theme={null} https://app.synthesize.bio/api/mcp ``` ## What you can do with it * Compare gene expression between two sample groups such as heart vs liver or tumor vs normal tissue. * Run analyses in bulk or single-cell mode. * Let your AI assistant wait on the long-running workflow and return the completed report when it is ready. ## Before you begin * You need a Synthesize Bio account on [app.synthesize.bio](https://app.synthesize.bio). * You need access to Claude connectors. * The Synthesize Bio Claude Connector uses OAuth to authenticate your account to the MCP. * Most analyses take several minutes to complete, so expect an asynchronous workflow rather than an instant result. Continue with [Overview](./overview) for a quick product summary, or go straight to [Set up the Claude Connector](./connect-in-claude). # Overview Source: https://docs.synthesize.bio/platform/overview Learn what Synthesize Bio MCP does, what inputs it expects, and what results users can expect back. # Overview Synthesize Bio MCP lets an AI tool send a structured request to Synthesize Bio, wait for the analysis to finish, and return the finished result to the user. ## What it analyzes The MCP is built for differential gene expression workflows driven by natural-language prompts. A typical request compares two groups, such as: * heart vs liver * tumor vs normal tissue * CD4+ T cells vs CD8+ T cells ## What Claude does behind the scenes Each analysis runs as a multi-step workflow: 1. Claude submits the request to Synthesize Bio. 2. Synthesize Bio extracts the sample groups described in the prompt. 3. The platform runs gene expression model inference. 4. The platform performs statistical differential expression analysis. 5. Claude returns the completed output when the workflow finishes. ## What to expect from results * Most analyses take about 3 to 5 minutes. * Claude may show progress updates while the job is still running. * Completed results can include a readable report plus a JSON artifact for full technical details. ## Current limits * The workflow performs one pairwise comparison at a time. * If your prompt implies more than two groups, the current behavior compares the first two groups alphabetically. * The statistical testing step uses Welch's t-test with Benjamini-Hochberg correction. For setup instructions, continue to [Set up the Claude Connector](./connect-in-claude). # Privacy and Support Source: https://docs.synthesize.bio/platform/privacy-and-support Find support contact details, privacy links, and account resources for Synthesize Bio MCP. # Privacy and Support ## Privacy Queries and generated expression data are handled under the [Synthesize Bio Privacy Policy](https://synthesize.bio/privacy). ## Account resources * Create or manage platform API keys at [app.synthesize.bio/account/api-keys](https://app.synthesize.bio/account/api-keys) * Visit the main product site at [synthesize.bio](https://synthesize.bio) ## Support * Email: [support@synthesize.bio](mailto:support@synthesize.bio) * Support portal: [synthesize.bio/support](https://synthesize.bio/support) When reporting an issue, include: * the prompt you used * whether the request was bulk or single-cell * whether the issue happened during connection, authentication, or result generation # Tools Reference Source: https://docs.synthesize.bio/platform/tools-reference Complete reference for every tool exposed by the Synthesize Bio MCP server. # Tools Reference The MCP server exposes four tools. A typical analysis uses three of them in sequence — resolve metadata, start the analysis, then poll for results. The remaining tool, `get_counts_data_url`, is a utility for downloading the raw counts data when you want to work with it outside the chat. ## resolve\_sample\_metadata Resolves a natural-language experiment description into structured sample groups for downstream analysis. Always call this **before** `analyze_gene_expression`. ### Parameters | Parameter | Type | Required | Description | | --------------- | -------------------------- | -------- | ----------------------------------------------------------------------- | | `prompt` | string | Yes | Natural-language description of the comparison, e.g. `"heart vs liver"` | | `modality` | `"bulk"` \| `"singleCell"` | No | Sequencing modality. Defaults to `"bulk"`. | | `resolution_id` | string (UUID) | No | Poll a previous resolution that returned `"resolving"` status. | ### Response Returns one of three shapes depending on status: **Complete** — metadata extraction succeeded; review before proceeding. ```json theme={null} { "status": "complete", "resolution_id": "uuid", "groups": [ ... ], "warnings": [ ... ], "messages": [ ... ] } ``` **Resolving** — extraction is still running; call again with the same `resolution_id`. ```json theme={null} { "status": "resolving", "resolution_id": "uuid", "message": "Still resolving metadata..." } ``` **Failed** — extraction could not complete. ```json theme={null} { "status": "failed", "error": "Description of the failure" } ``` ### Warnings The `warnings` array flags issues such as drugs or compounds that were not found in the ontology. Review warnings before proceeding — they may indicate a misspelling or an unsupported perturbation. *** ## analyze\_gene\_expression Starts the differential gene expression analysis pipeline from a confirmed resolution. You must call `resolve_sample_metadata` first and confirm the resolved groups before calling this tool. ### Parameters | Parameter | Type | Required | Description | | --------------- | ------------- | -------- | -------------------------------------------------------------------- | | `resolution_id` | string (UUID) | Yes | The `resolution_id` from a confirmed `resolve_sample_metadata` call. | ### Response ```json theme={null} { "job_id": "uuid", "message": "Analysis started" } ``` After receiving the `job_id`, call `get_analysis_results` immediately to begin polling. *** ## get\_analysis\_results Polls the status of a running analysis. Each call waits server-side for up to approximately 40 seconds and may return earlier if progress is detected. Call this immediately after `analyze_gene_expression` and again after each response — no client-side delay is needed. ### Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------------------- | | `job_id` | string | Yes | The `job_id` returned by `analyze_gene_expression`. | ### Response **Running** — the pipeline is still executing. Call again immediately. ```json theme={null} { "status": "running", "step": "gem_model", "message": "[GENE MODEL] Running inference...", "steps_completed": [] } ``` **Complete** — the pipeline finished successfully. The response is a Markdown summary that inlines the analysis metadata, a link to the platform dataset (when one has been provisioned), and a fenced ` ```json ` block holding up to 1,000 of the most significant differentially expressed genes returned by the backend. Parse the JSON block directly to drive downstream analysis or visualization (e.g. a volcano plot with x = `log2FoldChange`, y = -log10(`padj`)). **Failed** — the pipeline encountered an error. ```json theme={null} { "status": "failed", "error": "Description of the failure", "failure_kind": "unsupported_query", "steps_completed": ["gem_model"], "user_action_required": true, "suggested_queries": ["..."] } ``` ### Pipeline stages The analysis moves through two major computation stages: 1. **GEM model** (`gem_model`) — AI-powered gene expression model inference for the requested sample groups. 2. **Differential expression** (`diff_expr`) — Welch's t-test with Benjamini-Hochberg false discovery rate correction on the top 10,000 most variable genes. ### Result shape When the pipeline completes, the response embeds the analysis summary in Markdown and a fenced ` ```json ` block with up to 1,000 of the most significant gene-level results. The summary fields (`ok`, `reference_level`, `test_level`, `total_samples`, `total_genes_tested`, `significant_genes`, `significant_up`, `significant_down`) are rendered as a Markdown bullet list; the gene-level array is the canonical structured payload for downstream LLM consumption: ```json theme={null} { "results": [ { "gene_id": "ENSG00000141510", "gene_symbol": "TP53", "log2FoldChange": 2.1, "pvalue": 0.0001, "padj": 0.001, "direction": "up", "significant": true } ] } ``` The analysis performs one pairwise comparison. With exactly two groups this is the full comparison. With three or more groups the analysis compares the first two alphabetically — remaining groups are ignored. The platform dataset link returned alongside the results is the canonical place to view, edit metadata, share, or download the underlying counts. *** ## get\_counts\_data\_url Returns a presigned download URL for the raw gene expression counts data generated by a completed analysis job. The file is large (tens of MB) and should be processed with external tools such as `curl` or Python — not loaded into the conversation. ### Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------- | | `job_id` | string | Yes | The `job_id` from a completed analysis. | ### Response Returns a presigned URL for the counts JSON (valid for 1 hour), a second presigned URL for the model's gene-symbol-mapping Parquet, the modality, sample group names, sample counts per group, and documentation of the data format. ### Data format The downloaded JSON file contains: ```json theme={null} { "gene_order": ["ENSG00000141510", "..."], "outputs": [ { "counts": [0.0, 1.2, "..."], "metadata": { "..." } } ], "model_version": "..." } ``` * `gene_order` — array of \~20,000 Ensembl gene IDs. * `outputs` — one entry per sample, with `counts` aligned to `gene_order`. * `model_version` — the GEM model version used. ### Gene symbol mapping Alongside the counts URL, the response includes a presigned URL for a small (\~500 KB) Parquet file with two columns: * `gene_id` — the Ensembl ID (matches an entry in `gene_order`). * `gene_name` — the HGNC gene symbol (e.g. `TP53`). Download both files together and join on `gene_id` to label genes by symbol: ```python theme={null} import polars as pl sym = pl.read_parquet("") gene_id_to_symbol = dict(zip(sym["gene_id"].to_list(), sym["gene_name"].to_list())) gene_symbols = [gene_id_to_symbol.get(gid) for gid in gene_order] ``` # Troubleshooting Source: https://docs.synthesize.bio/platform/troubleshooting Fix common connection, authentication, and analysis-expectation issues when using Synthesize Bio MCP. # Troubleshooting ## Claude cannot connect to the connector Confirm that you selected the Synthesize Bio Claude Connector from [Claude's connector marketplace](https://claude.ai/settings/connectors). Also confirm that: * the connector was saved successfully in Claude * you completed the OAuth sign-in flow * your Synthesize Bio account has access to the platform ## The analysis is taking a long time This is usually expected. Most runs take about 3 to 5 minutes. Synthesize Bio MCP is designed to run asynchronously, so Claude may need to wait and poll for progress before it can return the final result. ## The user expected more than one comparison The current workflow supports one pairwise comparison per run. If a prompt implies more than two groups, the current behavior compares the first two groups alphabetically. If a user needs several comparisons, run them as separate prompts. ## The result is too technical Ask Claude to summarize the output in simpler language, or ask for a focused interpretation such as: * the most important up-regulated genes * the most important down-regulated genes * likely biological pathways or mechanisms ## The user wants the most detailed output Ask Claude for the structured JSON output or the full technical details from the completed run. ## Still need help See [Privacy and Support](./privacy-and-support) for support contact options. # Usage Examples Source: https://docs.synthesize.bio/platform/usage-examples Example prompts and practical guidance for writing better gene expression analysis requests in Claude. # Usage Examples The best prompts clearly state the two groups you want to compare and, when relevant, the sequencing modality. ## Prompt patterns that work well Use prompts like these: ```text theme={null} Use Synthesize Bio to compare gene expression between heart and liver cells. ``` ```text theme={null} Use the Synthesize Bio connector to analyze lung adenocarcinoma tumor vs normal lung tissue. ``` ```text theme={null} Analyze CD4+ T cells vs CD8+ T cells in single-cell RNA-seq mode using Synthesize Bio. ``` ## How to make prompts better Include the details that matter most: * the two groups to compare * whether the request is bulk or single-cell * the tissue, cell type, disease context, or condition ## Tips * Keep the comparison focused on two groups. * Use direct comparison language such as `A vs B`. * If you want biological interpretation after the analysis, ask for it in a follow-up prompt. ## Example follow-up prompts After the analysis is complete, users can continue with questions like: ```text theme={null} Summarize the top up-regulated and down-regulated genes in plain English. ``` ```text theme={null} Explain which pathways seem most relevant based on these differentially expressed genes. ``` ```text theme={null} Turn the result into a short research-style summary I can share with my team. ``` If a user runs into issues, continue to [Troubleshooting](./troubleshooting). # Available metadata Source: https://docs.synthesize.bio/pysynthbio/available-metadata Browse and download the metadata vocabularies that each Synthesize Bio model accepts. Every model on Synthesize Bio accepts specific metadata fields as inputs - things like cell type, tissue, disease state, and perturbation details. The valid values for each field (for example, ontology IDs and cell line names) are defined by the model's vocabulary. You can browse and download the vocabulary for any model you have access to at: [app.synthesize.bio/docs/vocab](https://app.synthesize.bio/docs/vocab) Select a model from the dropdown to see all available fields, and use the download links to get the full list of valid values for each field as JSON. # Getting started Source: https://docs.synthesize.bio/pysynthbio/getting-started Authenticate, list models, and make your first prediction with pysynthbio. `pysynthbio` is a Python package for the [Synthesize Bio](https://www.synthesize.bio/) API. It lets researchers easily access AI-generated transcriptomic data across modalities including bulk and single-cell RNA-seq. To generate datasets without code, use the [web platform](https://app.synthesize.bio/datasets/). ## Authentication ### Get your API key Visit the [API keys page](https://app.synthesize.bio/account/api-keys) to generate a key. Click **+ Create API Key**, then **Create Key**, and copy your key. There are several ways to make `pysynthbio` aware of your token. ```python theme={null} import pysynthbio # Opens a browser to the token creation page and prompts for input pysynthbio.set_synthesize_token(use_keyring=True) ``` With `use_keyring=True`, the token persists across sessions; with `use_keyring=False`, it's only set for the current session. Keyring support is included by default in `pysynthbio` 2.2.1 and later. ```bash theme={null} # macOS / Linux export SYNTHESIZE_API_KEY=your_api_token_here # Windows PowerShell $Env:SYNTHESIZE_API_KEY='your_api_token_here' ``` For scripts running in non-interactive environments: ```python theme={null} import pysynthbio # Avoid hardcoding secrets in source control pysynthbio.set_synthesize_token(token="SECURE_SECRET_HERE") ``` If you've previously stored your token in the system keyring: ```python theme={null} import pysynthbio pysynthbio.load_synthesize_token_from_keyring() ``` ## Available model types Synthesize Bio provides several model types for different use cases. ### Baseline models Generate synthetic gene expression data from metadata alone. Describe the biological conditions and the model generates realistic expression profiles. * **`gem-1-bulk`**: Bulk RNA-seq baseline model * **`gem-1-sc`**: Single-cell RNA-seq baseline model See [Baseline models](/pysynthbio/models/baseline) for detailed usage. ### Reference conditioning models Generate expression data conditioned on a real reference sample. This lets you anchor to an existing expression profile while applying perturbations or modifications. * **`gem-1-bulk_reference-conditioning`**: Bulk RNA-seq reference conditioning model * **`gem-1-sc_reference-conditioning`**: Single-cell RNA-seq reference conditioning model See [Reference conditioning](/pysynthbio/models/reference-conditioning) for detailed usage. ### Metadata prediction models Infer metadata from observed expression data. Given a gene expression profile, predict likely biological characteristics such as cell type, tissue, or disease state. * **`gem-1-bulk_predict-metadata`**: Bulk RNA-seq metadata prediction model * **`gem-1-sc_predict-metadata`**: Single-cell RNA-seq metadata prediction model See [Metadata prediction](/pysynthbio/models/metadata-prediction) for detailed usage. Only baseline models are available to all users. Check programmatically with `list_models()`. Contact [support@synthesize.bio](mailto:support@synthesize.bio) if you have questions. ### Listing available models ```python theme={null} import pysynthbio models = pysynthbio.list_models() print(models) ``` ### Exploring available metadata Each model accepts a specific set of metadata fields with defined vocabularies (valid ontology IDs, cell lines, tissues, etc.). Browse and download these vocabularies at [app.synthesize.bio/docs/vocab](https://app.synthesize.bio/docs/vocab). See [Available metadata](/pysynthbio/available-metadata) for more details. ## Quick start A minimal example using a baseline model: ```python theme={null} import pysynthbio # Get an example query structure query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] # Submit the query and get results result = pysynthbio.predict_query(query, model_id="gem-1-bulk") # Access the results metadata = result["metadata"] expression = result["expression"] ``` For more detailed examples and advanced usage, see the model-specific documentation linked above. ## Security notes * The API token provides full access to your Synthesize Bio account. * When using `use_keyring=True`, your token is stored securely in your system's credential manager. * For production environments, prefer environment variables or a secrets management tool. ## Cleanup When you're done using the API, you can clear the token from your environment: ```python theme={null} # Clear from current session only pysynthbio.clear_synthesize_token() # Clear from both session and system keyring pysynthbio.clear_synthesize_token(remove_from_keyring=True) ``` ## Rate limits Free usage of Synthesize Bio is limited. If you exceed the limit, the API returns an error explaining it. For higher limits, contact [support@synthesize.bio](mailto:support@synthesize.bio). ## Troubleshooting ### Keychain access on Mac If you get this error on macOS when using `use_keyring=True`: ```text theme={null} :1: UserWarning: Failed to store token in keyring: Can't store password on keychain: (-25244, 'Unknown Error') ``` Your IDE or terminal does not have access to Keychain. Open **System Preferences -> Security & Privacy -> Privacy -> Full Disk Access** and add the terminal or IDE you're working from. # Python SDK Source: https://docs.synthesize.bio/pysynthbio/index pysynthbio — the official Python client for the Synthesize Bio platform. `pysynthbio` is a Python package that provides a convenient interface to the [Synthesize Bio](https://www.synthesize.bio/) API. It lets you generate realistic gene expression data for specified biological conditions, work with reference samples, and predict metadata from observed expression, all from Python. If you'd prefer 1-click dataset generation and analysis, try the [web platform](https://app.synthesize.bio/datasets/). Install from PyPI, source, or a GitHub release. Authenticate, list models, and make your first prediction. Generate synthetic expression from metadata alone. Anchor generation to a real reference sample. Infer biological metadata from observed expression. Source code, issues, and releases. ## Quickstart ```python theme={null} import pysynthbio pysynthbio.set_synthesize_token(use_keyring=True) query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] result = pysynthbio.predict_query(query, model_id="gem-1-bulk") metadata = result["metadata"] expression = result["expression"] ``` ## Support Email [support@synthesize.bio](mailto:support@synthesize.bio) or [open an issue](https://github.com/synthesizebio/pysynthbio/issues) on GitHub. # Installation Source: https://docs.synthesize.bio/pysynthbio/installation Install pysynthbio from PyPI, source, or a GitHub release. ## Prerequisites To use `pysynthbio`, first create an account at [app.synthesize.bio](https://app.synthesize.bio/). If you want to store your API token in the system keyring, you'll also need the optional `keyring` package. It's installed by default in `pysynthbio` 2.2.1 and later. ## Standard installation Install the latest stable version from PyPI: ```bash theme={null} pip install pysynthbio ``` Verify the install: ```bash theme={null} pip show pysynthbio ``` ## Development installation Install the latest development version directly from GitHub: ```bash theme={null} git clone https://github.com/synthesizebio/pysynthbio.git cd pysynthbio pip install -e . ``` ## Installing from a GitHub release You can also install a specific tagged version directly from a GitHub release. This is useful for testing pre-releases or pinning to a specific tag. Go to the [releases page](https://github.com/synthesizebio/pysynthbio/releases) and find the tag you want, such as `v3.0.2`. Expand the release's **Assets** section and download the `.whl` (preferred) or `.tar.gz`. ```bash theme={null} # Wheel pip install /path/to/pysynthbio-3.0.2-py3-none-any.whl # Source distribution pip install /path/to/pysynthbio-3.0.2.tar.gz ``` Authenticate and make your first prediction. # License Source: https://docs.synthesize.bio/pysynthbio/license pysynthbio is licensed under the MIT License. `pysynthbio` is licensed under the MIT License. ```text theme={null} MIT License Copyright (c) 2025 Candace Savonen, Alex David Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` # Baseline models Source: https://docs.synthesize.bio/pysynthbio/models/baseline Generate synthetic gene expression data from metadata alone. ## Overview Baseline models generate synthetic gene expression data from metadata alone. You describe the biological conditions, such as tissue type, disease state, perturbations, and cell type, and the model generates realistic expression profiles matching those conditions. This is the most common use case: generating synthetic data for conditions where real data may be scarce or unavailable. ## Available models * **`gem-1-bulk`**: Bulk RNA-seq baseline model * **`gem-1-sc`**: Single-cell RNA-seq baseline model ```python theme={null} import pysynthbio ``` ## Creating a query The structure of the query required by the API is specific to each model. Use `get_example_query()` to get a correctly structured example for your chosen model. ```python theme={null} example_query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] print(example_query) ``` The query consists of: 1. **`sampling_strategy`**: The prediction mode that controls how expression data is generated * `"sample generation"`: Generates realistic-looking synthetic data with measurement error (bulk only) * `"mean estimation"`: Provides stable mean estimates of expression levels (bulk and single-cell) 2. **`inputs`**: A list of biological conditions to generate data for Each input contains `metadata` describing the biological sample and `num_samples` for how many samples to generate. ## Making a prediction Once your query is ready, send it to the API to generate gene expression data: ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] result = pysynthbio.predict_query(query, model_id="gem-1-bulk") ``` The result is a dictionary containing two DataFrames: `metadata` and `expression`. ### Single-cell example ```python theme={null} sc_query = pysynthbio.get_example_query(model_id="gem-1-sc")["example_query"] sc_result = pysynthbio.predict_query(sc_query, model_id="gem-1-sc") ``` Single-cell models only support `"mean estimation"` mode. ## Query parameters ### `sampling_strategy` (str, required) Controls the type of prediction the model generates. Required in all queries. Available modes: * **`"sample generation"`**: The model generates realistic-looking synthetic data that captures measurement error. Useful when you want data that mimics real experimental measurements. **Bulk only** * **`"mean estimation"`**: The model creates a distribution capturing biological heterogeneity consistent with the supplied metadata, then returns the mean of that distribution. Useful when you want a stable estimate of expected expression levels. **Bulk and single-cell** ```python theme={null} # Bulk query with sample generation bulk_query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] bulk_query["sampling_strategy"] = "sample generation" # Bulk query with mean estimation bulk_query_mean = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] bulk_query_mean["sampling_strategy"] = "mean estimation" # Single-cell query (must use mean estimation) sc_query = pysynthbio.get_example_query(model_id="gem-1-sc")["example_query"] sc_query["sampling_strategy"] = "mean estimation" ``` ### `total_count` (int, optional) Library size used when converting predicted log CPM back to raw counts. Higher values scale counts up proportionally. * Default: 10,000,000 for bulk; 10,000 for single-cell ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] query["total_count"] = 5_000_000 ``` ### `deterministic_latents` (bool, optional) If `True`, the model uses the mean of each latent distribution (`p(z|metadata)`) instead of sampling. This removes randomness from latent sampling and produces deterministic outputs for the same inputs. * Default: `False` ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] query["deterministic_latents"] = True ``` ### `seed` (int, optional) Random seed for reproducibility when using stochastic sampling. ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] query["seed"] = 42 ``` ### Combining parameters You can combine multiple parameters in a single query: ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] query["total_count"] = 8_000_000 query["deterministic_latents"] = True query["sampling_strategy"] = "mean estimation" results = pysynthbio.predict_query(query, model_id="gem-1-bulk") ``` ## Valid metadata keys The input metadata is a dictionary. Here are all valid keys. ### Biological * `age_years` * `cell_line_ontology_id` * `cell_type_ontology_id` * `developmental_stage` * `disease_ontology_id` * `ethnicity` * `genotype` * `race` * `sample_type`: `"cell line"`, `"organoid"`, `"other"`, `"primary cells"`, `"primary tissue"`, `"xenograft"` * `sex`: `"male"`, `"female"` * `tissue_ontology_id` ### Perturbational * `perturbation_dose`: number and unit separated by a space, for example `"10 um"` * `perturbation_ontology_id` * `perturbation_time`: number and unit separated by a space, for example `"24 hours"` * `perturbation_type`: one of `"coculture"`, `"compound"`, `"control"`, `"crispr"`, `"genetic"`, `"infection"`, `"other"`, `"overexpression"`, `"peptide or biologic"`, `"shrna"`, `"sirna"` ### Technical * `study`: Bioproject ID * `library_selection`: for example `"cDNA"`, `"polyA"`, `"Oligo-dT"` (see the [ENA documentation](https://ena-docs.readthedocs.io/en/latest/submit/reads/webin-cli.html#permitted-values-for-library-selection)) * `library_layout`: `"PAIRED"` or `"SINGLE"` * `platform`: `"illumina"` ## Valid metadata values The following are the valid values or expected formats for selected metadata keys: | Metadata field | Requirement / example | | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `cell_line_ontology_id` | Requires a [Cellosaurus ID](https://www.cellosaurus.org/) | | `cell_type_ontology_id` | Requires a [CL ID](https://www.ebi.ac.uk/ols4/ontologies/cl) | | `disease_ontology_id` | Requires a [MONDO ID](https://www.ebi.ac.uk/ols4/ontologies/mondo) | | `perturbation_ontology_id` | Must be a valid Ensembl gene ID, [ChEBI ID](https://www.ebi.ac.uk/chebi/), [ChEMBL ID](https://www.ebi.ac.uk/chembl/), or [NCBI Taxonomy ID](https://www.ncbi.nlm.nih.gov/taxonomy) | | `tissue_ontology_id` | Requires a [UBERON ID](https://www.ebi.ac.uk/ols4/ontologies/uberon) | We highly recommend the [EMBL-EBI Ontology Lookup Service](https://www.ebi.ac.uk/ols4/) for finding valid IDs. Models have a limited acceptable range of metadata input values. If you provide a value outside the acceptable range, the API returns an error. ## Modifying query inputs Customize the query inputs to fit your specific research needs: ```python theme={null} # Get a base query query = pysynthbio.get_example_query(model_id="gem-1-bulk")["example_query"] # Adjust number of samples for the first input query["inputs"][0]["num_samples"] = 10 # Add a new condition query["inputs"].append({ "metadata": { "sex": "male", "sample_type": "primary tissue", "tissue_ontology_id": "UBERON:0002371", }, "num_samples": 5, }) ``` ## Working with results ```python theme={null} # Access metadata and expression matrices metadata = result["metadata"] expression = result["expression"] # Check dimensions print(expression.shape) # View metadata sample print(metadata.head()) ``` You may want to process the data or save it for later use: ```python theme={null} # Save results to files expression.to_csv("expression_matrix.csv") metadata.to_csv("sample_metadata.csv") # Or save as pickle for later use import pickle with open("synthesize_results.pkl", "wb") as f: pickle.dump(result, f) ``` # Metadata prediction Source: https://docs.synthesize.bio/pysynthbio/models/metadata-prediction Infer biological metadata from observed expression data. ## Overview Metadata prediction models infer biological metadata from observed expression data. Given a gene expression profile, the model predicts likely biological characteristics such as cell type, tissue, disease state, and more. This is useful when you want to: * Annotate samples of unknown origin * Validate sample labels against expression patterns * Discover potential mislabeled or contaminated samples * Understand the biological characteristics captured in expression data ## Available models * **`gem-1-bulk_predict-metadata`**: Bulk RNA-seq metadata prediction model * **`gem-1-sc_predict-metadata`**: Single-cell RNA-seq metadata prediction model These endpoints may require 1 to 2 minutes of startup time if they have been scaled down. Plan accordingly for interactive use. ```python theme={null} import pysynthbio ``` ## How it works Metadata prediction encodes your expression data into the model's latent space and then uses classifiers to predict the most likely metadata values for each sample. The model returns: 1. **Classifier probabilities**: For each categorical metadata field, the probability distribution over possible values 2. **Predicted labels**: The most likely value for each metadata field 3. **Latent representations**: The biological, technical, and perturbation latent vectors ## Creating a query Metadata prediction queries are simpler than other model types. You only need to provide expression counts: ```python theme={null} example_query = pysynthbio.get_example_query(model_id="gem-1-bulk_predict-metadata")["example_query"] print(example_query) ``` The query structure includes: 1. **`inputs`**: A list of count vectors, where each element is a dictionary with a `counts` field 2. **`seed`** (optional): Random seed for reproducibility ## Example: predicting sample metadata A complete example predicting metadata for expression samples: ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk_predict-metadata")["example_query"] # Replace with your actual expression counts. # Each input should be a dictionary with a counts list. query["inputs"] = [ {"counts": sample1_counts}, {"counts": sample2_counts}, {"counts": sample3_counts}, ] # Optional: set seed for reproducibility query["seed"] = 42 result = pysynthbio.predict_query(query, model_id="gem-1-bulk_predict-metadata") ``` ## Example: single sample prediction For predicting metadata of a single sample: ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk_predict-metadata")["example_query"] query["inputs"] = [ {"counts": my_sample_counts}, ] result = pysynthbio.predict_query(query, model_id="gem-1-bulk_predict-metadata") # Access predictions for the first (and only) sample print(result[0]["metadata"]) ``` ## Query parameters ### `inputs` (list, required) A list of expression count vectors. Each element should be a dictionary containing: * **`counts`**: A list of non-negative integers representing gene expression counts ```python theme={null} query["inputs"] = [ {"counts": [0, 12, 5, 0, 33, 7]}, # Sample 1 {"counts": [3, 0, 0, 7, 1, 0]}, # Sample 2 ] ``` ### `seed` (int, optional) Random seed for reproducibility. ```python theme={null} query["seed"] = 123 ``` ## Understanding the results The results from metadata prediction are returned as a list of output dictionaries, one per input sample. Each output dictionary contains: * `metadata`: Predicted metadata values for the sample * `classifier_probs`: Probability distributions over possible values for each metadata field * `latents`: Latent representations capturing biological, technical, and perturbation information ```python theme={null} print(f"Number of outputs: {len(result)}") # Access the first sample's output first_output = result[0] print(first_output.keys()) ``` ### Predicted metadata Each output's `metadata` field contains the predicted values for that sample: ```python theme={null} for i, output in enumerate(result): print(f"Sample {i}: {output['metadata']}") # Access specific predictions for first sample first_sample = result[0]["metadata"] print(first_sample.get("cell_type_ontology_id")) print(first_sample.get("tissue_ontology_id")) print(first_sample.get("disease_ontology_id")) ``` ### Classifier probabilities For categorical metadata fields, the model returns probability distributions over all possible values. These are useful for understanding prediction confidence: ```python theme={null} first_output = result[0] cell_type_probs = first_output["classifier_probs"]["cell_type"] sorted_probs = sorted(cell_type_probs.items(), key=lambda x: x[1], reverse=True) print("Top predicted cell types:", sorted_probs[:5]) ``` ### Latent representations The model also returns latent vectors that capture biological, technical, and perturbation characteristics: ```python theme={null} first_output = result[0] biological_latents = first_output["latents"]["biological"] technical_latents = first_output["latents"]["technical"] ``` ## Use cases ### Sample annotation Annotate unlabeled samples with predicted metadata: ```python theme={null} import pandas as pd unlabeled_counts = pd.read_csv("unlabeled_samples.csv", index_col=0) query = pysynthbio.get_example_query(model_id="gem-1-bulk_predict-metadata")["example_query"] query["inputs"] = [ {"counts": unlabeled_counts.iloc[:, i].tolist()} for i in range(unlabeled_counts.shape[1]) ] result = pysynthbio.predict_query(query, model_id="gem-1-bulk_predict-metadata") annotations = pd.DataFrame([output["metadata"] for output in result]) annotations["sample_id"] = unlabeled_counts.columns.tolist() ``` ### Quality control Validate existing sample labels against predicted metadata: ```python theme={null} provided_labels = ["UBERON:0002107", "UBERON:0002107", "UBERON:0000955", "UBERON:0000955"] predicted_labels = [output["metadata"].get("tissue_ontology_id") for output in result] mismatches = [ i for i, (provided, predicted) in enumerate(zip(provided_labels, predicted_labels)) if provided != predicted ] if mismatches: print(f"Potential mislabeled samples: {mismatches}") ``` ### Batch characterization Understand batch-specific technical characteristics: ```python theme={null} import numpy as np batch_labels = ["batch1", "batch1", "batch2", "batch2"] technical_latents = [output["latents"]["technical"] for output in result] for batch in set(batch_labels): batch_indices = [i for i, batch_name in enumerate(batch_labels) if batch_name == batch] batch_mean = np.mean([technical_latents[i][0] for i in batch_indices]) print(f"{batch} technical latent mean: {batch_mean}") ``` ## Important notes ### Counts vector length The counts vector for each sample must match the model's expected number of genes. If the length does not match, the API returns a validation error. Use `get_example_query()` to see the expected structure. ### Gene order Ensure your counts are in the same gene order expected by the model. The gene order should match what the baseline model expects. You can retrieve this from any prediction result's `gene_order` field. ### Non-negative counts All count values must be non-negative integers. Floats that are whole numbers, such as `10.0`, are accepted, but negative values cause validation errors. # Reference conditioning Source: https://docs.synthesize.bio/pysynthbio/models/reference-conditioning Generate expression data conditioned on a real reference sample. ## Overview Reference conditioning models generate expression data conditioned on a real reference sample. This lets you anchor to an existing expression profile while applying perturbations or modifications. This is useful when you want to: * Simulate the effect of a perturbation on a specific sample * Generate expression profiles that preserve the biological and technical characteristics of a reference * Create synthetic treated versus control pairs ## Available models * **`gem-1-bulk_reference-conditioning`**: Bulk RNA-seq reference conditioning model * **`gem-1-sc_reference-conditioning`**: Single-cell RNA-seq reference conditioning model These endpoints may require 1 to 2 minutes of startup time if they have been scaled down. Plan accordingly for interactive use. ```python theme={null} import pysynthbio ``` ## How it works Reference conditioning encodes the biological and technical characteristics from a real expression sample, then generates new expression data that: 1. Preserves the biological and technical latent space of the reference 2. Applies any perturbation metadata you specify 3. Returns synthetic expression that reflects the perturbation effect on that specific sample ## Creating a query Reference conditioning queries require different inputs than baseline models: ```python theme={null} example_query = pysynthbio.get_example_query(model_id="gem-1-bulk_reference-conditioning")["example_query"] print(example_query) ``` The query structure includes: 1. **`inputs`**: A list where each input contains: * **`counts`**: The reference expression counts * **`metadata`**: Perturbation-only metadata * **`num_samples`**: How many samples to generate 2. **`conditioning`**: Which latent spaces to condition on, typically `["biological", "technical"]` 3. **`sampling_strategy`**: `"mean estimation"` or `"sample generation"` ### Perturbation-only metadata Unlike baseline models, reference conditioning queries only accept perturbation metadata fields: * `perturbation_ontology_id` * `perturbation_type` * `perturbation_time` * `perturbation_dose` All other biological and technical metadata is inferred from the reference expression. ## Example: simulating a drug treatment A complete example simulating a drug treatment effect on a reference sample: ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk_reference-conditioning")["example_query"] # Replace with your actual reference counts. # The counts list must match the model's expected gene order and length. query["inputs"][0]["counts"] = your_reference_counts # Specify the perturbation query["inputs"][0]["metadata"] = { "perturbation_ontology_id": "CHEMBL25", # Aspirin (ChEMBL ID) "perturbation_type": "compound", "perturbation_time": "24 hours", "perturbation_dose": "10 um", } query["inputs"][0]["num_samples"] = 3 query["sampling_strategy"] = "mean estimation" result = pysynthbio.predict_query(query, model_id="gem-1-bulk_reference-conditioning") ``` ## Example: CRISPR knockout simulation Simulate the effect of knocking out a specific gene: ```python theme={null} query = pysynthbio.get_example_query(model_id="gem-1-bulk_reference-conditioning")["example_query"] # Your reference sample counts query["inputs"][0]["counts"] = control_sample_counts # CRISPR knockout of TP53 query["inputs"][0]["metadata"] = { "perturbation_ontology_id": "ENSG00000141510", # TP53 Ensembl ID "perturbation_type": "crispr", } query["inputs"][0]["num_samples"] = 5 result = pysynthbio.predict_query(query, model_id="gem-1-bulk_reference-conditioning") ``` ## Query parameters ### `conditioning` (list, optional) Controls which latent spaces are conditioned on the reference. Default is `["biological", "technical"]`. When both are conditioned, the model preserves both biological identity and technical characteristics from the reference sample. ### `sampling_strategy` (str, required) Controls the type of prediction: * **`"sample generation"`**: Generates realistic-looking synthetic data with measurement error. **Bulk only** * **`"mean estimation"`**: Provides stable mean estimates. **Bulk and single-cell** ```python theme={null} query["sampling_strategy"] = "mean estimation" ``` ### `fixed_total_count` (bool, optional) Controls whether to preserve the reference's library size: * **`False`** (default): The output's total count is taken from the reference expression sum * **`True`**: Forces the model to use the `total_count` parameter value or default instead of the reference's library size ```python theme={null} # Preserve reference library size (default) query["fixed_total_count"] = False # Or force a specific library size query["fixed_total_count"] = True query["total_count"] = 10_000_000 ``` ### `total_count` (int, optional) Library size used when converting predicted log CPM back to raw counts. Only effective when `fixed_total_count = True`. * Default: 10,000,000 for bulk; 10,000 for single-cell ### `deterministic_latents` (bool, optional) If `True`, the model uses the mean of each latent distribution instead of sampling. This produces deterministic, reproducible outputs. * Default: `False` ```python theme={null} query["deterministic_latents"] = True ``` ### `seed` (int, optional) Random seed for reproducibility. ```python theme={null} query["seed"] = 42 ``` ## Valid perturbation metadata | Field | Description / format | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `perturbation_ontology_id` | Ensembl gene ID, [ChEBI ID](https://www.ebi.ac.uk/chebi/), [ChEMBL ID](https://www.ebi.ac.uk/chembl/), or [NCBI Taxonomy ID](https://www.ncbi.nlm.nih.gov/taxonomy) | | `perturbation_type` | One of `"coculture"`, `"compound"`, `"control"`, `"crispr"`, `"genetic"`, `"infection"`, `"other"`, `"overexpression"`, `"peptide or biologic"`, `"shrna"`, `"sirna"` | | `perturbation_time` | Time since perturbation as a number and unit separated by a space, such as `"24 hours"` | | `perturbation_dose` | Dose as a number and unit separated by a space, such as `"10 um"` or `"1 mg/kg"` | ## Working with results The result structure is similar to baseline models: ```python theme={null} metadata = result["metadata"] expression = result["expression"] print(expression.shape) print(metadata.head()) ``` ### Differential expression When conditioning on both biological and technical latents, you can directly compare the generated expression to your reference to identify perturbation effects: ```python theme={null} import numpy as np # Your reference (input) counts reference_cpm = your_reference_counts / np.sum(your_reference_counts) * 1e6 # Generated (perturbed) counts generated_counts = expression.iloc[0].values generated_cpm = generated_counts / np.sum(generated_counts) * 1e6 # Log fold change log2fc = np.log2(generated_cpm + 1) - np.log2(reference_cpm + 1) # Identify top changed genes gene_names = expression.columns top_indices = np.argsort(log2fc)[-20:] print("Top upregulated genes:", gene_names[top_indices].tolist()) ``` ## Important notes ### Counts vector length The reference counts vector must match the model's expected number of genes. If the length does not match, the API returns a validation error. Use `get_example_query()` to see the expected structure and ensure your counts vector has the correct length. ### Gene order Ensure your reference counts are in the same gene order expected by the model. The response includes a `gene_order` field that specifies the expected order. # Self-hosted models Source: https://docs.synthesize.bio/pysynthbio/self-hosted Run Synthesize Bio models in your own environment via synchronous Apache Arrow streaming. Partners who run Synthesize Bio models inside their own environment (for example, on a GPU host in their own cloud account) can use the same `pysynthbio` client against a self-hosted model container instead of the hosted API at `app.synthesize.bio`. Self-hosting is a model deployment option available through a Synthesize Bio partnership. Reach out to [partnerships@synthesize.bio](mailto:partnerships@synthesize.bio) for more information. ## How it differs from the hosted path The hosted path is asynchronous: it starts a query, polls for completion, and downloads results. A self-hosted container instead returns predictions **synchronously** as an [Apache Arrow](https://arrow.apache.org/) IPC stream. `pysynthbio` decodes that stream into exactly the same data frames you get from the hosted path (`expression`, `metadata`, and `latents`), so downstream code does not change. Key differences: * **No polling and no download URL** — a single request returns the data. `return_download_url=True` is not supported in self-hosted mode. * **Requires the optional `pyarrow` package** — install it with the `self_hosted` extra: `pip install "pysynthbio[self_hosted]"`. * **No API key required** — a key is only sent when `SYNTHESIZE_API_KEY` is set (use this if your container runs with authentication enabled). ## Enabling self-hosted mode Set `self_hosted=True` on a call, or enable it for the whole session with the `SYNTHESIZE_SELF_HOSTED` environment variable (truthy values: `1`, `true`, `yes`, `on`). ```python theme={null} import os os.environ["SYNTHESIZE_SELF_HOSTED"] = "1" ``` ## Pointing each model at its container Self-hosted deployments typically run one container per model. Set a per-model base URL once and you never have to pass `api_base_url` on individual calls. The variable name is `SYNTHESIZE_API_BASE_URL__`, where `` is the upper-cased model id with non-alphanumeric characters replaced by underscores (for example, `gem-1-bulk` becomes `SYNTHESIZE_API_BASE_URL__GEM_1_BULK`). ```python theme={null} import os import pysynthbio os.environ["SYNTHESIZE_API_BASE_URL__GEM_1_BULK"] = "https://gem-1-bulk.internal.example" os.environ["SYNTHESIZE_API_BASE_URL__GEM_1_SC"] = "https://gem-1-sc.internal.example" query = pysynthbio.get_example_query("gem-1-bulk", self_hosted=True)["example_query"] result = pysynthbio.predict_query(query, model_id="gem-1-bulk", self_hosted=True) expression = result["expression"] metadata = result["metadata"] ``` Variant slugs backed by the same container (for example, `gem-1-bulk_reference-conditioning` and `gem-1-bulk_predict-metadata`) resolve to the same per-model variable as their base model. ### Resolution precedence The base URL is resolved in this order: 1. An explicit `api_base_url` argument passed to the call. 2. The per-model variable `SYNTHESIZE_API_BASE_URL__`. 3. The global `SYNTHESIZE_API_BASE_URL`. 4. The production default (`https://app.synthesize.bio`). You can always override the environment by passing `api_base_url` directly: ```python theme={null} result = pysynthbio.predict_query( query, model_id="gem-1-bulk", api_base_url="https://gem-1-bulk.internal.example", self_hosted=True, ) ``` ## Authentication (optional) Self-hosted containers may run without authentication. If yours requires a key, set `SYNTHESIZE_API_KEY` and the client attaches it as a bearer token: ```python theme={null} import os os.environ["SYNTHESIZE_API_KEY"] = "your-container-api-key" ``` ## Raw responses Pass `raw_response=True` to receive the raw Apache Arrow IPC stream bytes instead of the transformed data frames. Decode them yourself with `pyarrow`: ```python theme={null} import io import pyarrow as pa raw = pysynthbio.predict_query( query, model_id="gem-1-bulk", self_hosted=True, raw_response=True, ) table = pa.ipc.open_stream(io.BytesIO(raw)).read_all() ``` # Available metadata Source: https://docs.synthesize.bio/rsynthbio/available-metadata Browse and download the metadata vocabularies that each Synthesize Bio model accepts. ## Overview Every model on Synthesize Bio accepts specific metadata fields as inputs—things like cell type, tissue, disease state, and perturbation details. The valid values for each field (e.g. ontology IDs, cell line names) are defined by the model's vocabulary. You can browse and download the vocabulary for any model you have access to at: **[app.synthesize.bio/docs/vocab](https://app.synthesize.bio/docs/vocab)** Select a model from the dropdown to see all available fields, and use the download links to get the full list of valid values for each field as JSON. # Getting started Source: https://docs.synthesize.bio/rsynthbio/getting-started Authenticate, list models, and make your first prediction with rsynthbio. `rsynthbio` is an R package that provides a convenient interface to the [Synthesize Bio](https://www.synthesize.bio/) API, allowing users to generate realistic gene expression data based on specified biological conditions. This package enables researchers to easily access AI-generated transcriptomic data for various modalities including bulk RNA-seq and single-cell RNA-seq. To generate datasets without code, use our [web platform](https://app.synthesize.bio/datasets/). ## Authentication Before using the Synthesize Bio API, you need to set up your API token. The package provides a secure way to handle authentication: ```r theme={null} # Securely prompt for and store your API token # The token will not be visible in the console set_synthesize_token() # You can also store the token in your system keyring for persistence # across R sessions (requires the 'keyring' package) set_synthesize_token(use_keyring = TRUE) ``` Loading your API key for a session. ```r theme={null} # In future sessions, load the stored token load_synthesize_token_from_keyring() # Check if a token is already set has_synthesize_token() ``` You can manually set the token, but don't commit it to version control! ```r theme={null} set_synthesize_token(token = "your-token-here") ``` You can obtain an API token by registering at [Synthesize Bio](https://app.synthesize.bio). ## Available Model Types Synthesize Bio provides several types of models for different use cases: ### Baseline Models Generate synthetic gene expression data from metadata alone. You describe the biological conditions (tissue type, disease state, perturbations, etc.) and the model generates realistic expression profiles. * **`gem-1-bulk`**: Bulk RNA-seq baseline model * **`gem-1-sc`**: Single-cell RNA-seq baseline model See the [Baseline Models](/rsynthbio/models/baseline) vignette for detailed usage. ### Reference Conditioning Models Generate expression data conditioned on a real reference sample. This allows you to "anchor" to an existing expression profile while applying perturbations or modifications. * **`gem-1-bulk_reference-conditioning`**: Bulk RNA-seq reference conditioning model * **`gem-1-sc_reference-conditioning`**: Single-cell RNA-seq reference conditioning model See the [Reference Conditioning](/rsynthbio/models/reference-conditioning) vignette for detailed usage. ### Metadata Prediction Models Infer metadata from observed expression data. Given a gene expression profile, predict the likely biological characteristics (cell type, tissue, disease state, etc.). * **`gem-1-bulk_predict-metadata`**: Bulk RNA-seq metadata prediction model * **`gem-1-sc_predict-metadata`**: Single-cell RNA-seq metadata prediction model See the [Metadata Prediction](/rsynthbio/models/metadata-prediction) vignette for detailed usage. Only baseline models are available to all users. You can check which models are available programmatically, use `list_models()`. Contact us at [support@synthesize.bio](mailto:support@synthesize.bio) if you have any questions. ### Listing Available Models You can check which models are available programmatically: ```r theme={null} # Check available models list_models() ``` ### Exploring Available Metadata Each model accepts a specific set of metadata fields with defined vocabularies (valid ontology IDs, cell lines, tissues, etc.). You can browse and download these vocabularies at [app.synthesize.bio/docs/vocab](https://app.synthesize.bio/docs/vocab). See the [Available Metadata](/rsynthbio/available-metadata) vignette for more details. ## Quick Start Here's a quick example using a baseline model: ```r theme={null} # Get an example query structure query <- get_example_query(model_id = "gem-1-bulk")$example_query # Submit the query and get results result <- predict_query(query, model_id = "gem-1-bulk") # Access the results metadata <- result$metadata expression <- result$expression ``` For more detailed examples and advanced usage, see the model-specific vignettes linked above. # R SDK Source: https://docs.synthesize.bio/rsynthbio/index rsynthbio — the official R client for the Synthesize Bio platform. `rsynthbio` is an R package that provides a convenient interface to the [Synthesize Bio](https://www.synthesize.bio/) API. It lets you generate realistic gene expression data for specified biological conditions, work with reference samples, and predict metadata from observed expression, all from R. If you'd prefer 1-click dataset generation and analysis, try the [web platform](https://app.synthesize.bio/datasets/). Install from CRAN, GitHub, or a local source build. Authenticate, list models, and make your first prediction. Generate synthetic expression from metadata alone. Anchor generation to a real reference sample. Infer biological metadata from observed expression. Generated from the package help pages in this repo. ## Quickstart ```r theme={null} library(rsynthbio) set_synthesize_token(use_keyring = TRUE) query <- get_example_query(model_id = "gem-1-bulk")$example_query result <- predict_query(query, model_id = "gem-1-bulk") metadata <- result$metadata expression <- result$expression ``` ## Source and support * [Source code](https://github.com/synthesizebio/rsynthbio) * [CRAN package page](https://cran.r-project.org/package=rsynthbio) * Email [support@synthesize.bio](mailto:support@synthesize.bio) # Installation Source: https://docs.synthesize.bio/rsynthbio/installation Install rsynthbio from CRAN, GitHub, or a local source build. ## Prerequisites To use `rsynthbio`, first create an account at [app.synthesize.bio](https://app.synthesize.bio/). ## From CRAN The recommended way to install: ```r theme={null} install.packages("rsynthbio") ``` ## Development version from GitHub For the latest unreleased changes: ```r theme={null} if (!("remotes" %in% installed.packages())) { install.packages("remotes") } remotes::install_github("synthesizebio/rsynthbio") ``` ## Verify the install ```r theme={null} library(rsynthbio) packageVersion("rsynthbio") ``` Authenticate and make your first prediction. # License Source: https://docs.synthesize.bio/rsynthbio/license rsynthbio is licensed under the MIT License. `rsynthbio` is licensed under the MIT License. ```text theme={null} YEAR: 2025 COPYRIGHT HOLDER: rsynthbio authors ``` # Baseline models Source: https://docs.synthesize.bio/rsynthbio/models/baseline Generate synthetic gene expression data from metadata alone. ## Overview Baseline models generate synthetic gene expression data from metadata alone. You describe the biological conditions—tissue type, disease state, perturbations, cell type, etc.—and the model generates realistic expression profiles matching those conditions. This is the most common use case: generating synthetic data for conditions where real data may be scarce or unavailable. ## Available Models * **`gem-1-bulk`**: Bulk RNA-seq baseline model * **`gem-1-sc`**: Single-cell RNA-seq baseline model ```r theme={null} library(rsynthbio) ``` ## Creating a Query The structure of the query required by the API is specific to each model. Use `get_example_query()` to get a correctly structured example for your chosen model. ```r theme={null} # Get the example query structure for a specific model example_query <- get_example_query(model_id = "gem-1-bulk")$example_query # Inspect the query structure str(example_query) ``` The query consists of: 1. **`sampling_strategy`**: The prediction mode that controls how expression data is generated: * **"sample generation"**: Generates realistic-looking synthetic data with measurement error (bulk only) * **"mean estimation"**: Provides stable mean estimates of expression levels (bulk and single-cell) 2. **`inputs`**: A list of biological conditions to generate data for Each input contains `metadata` (describing the biological sample) and `num_samples` (how many samples to generate). ## Making a Prediction Once your query is ready, send it to the API to generate gene expression data: ```r theme={null} # Create a query for the bulk model query <- get_example_query(model_id = "gem-1-bulk")$example_query # Submit and get results result <- predict_query(query, model_id = "gem-1-bulk") ``` The result is a list containing two data frames: `metadata` and `expression`. ### Single-Cell Example ```r theme={null} # Create a query for the single-cell model sc_query <- get_example_query(model_id = "gem-1-sc")$example_query # Submit and get results sc_result <- predict_query(sc_query, model_id = "gem-1-sc") ``` Single-cell models only support `"mean estimation"` mode. ## Query Parameters In addition to metadata, queries support several optional parameters that control the generation process. ### sampling\_strategy (character, required) Controls the type of prediction the model generates. This parameter is required in all queries. Available modes: * **"sample generation"**: The model generates realistic-looking synthetic data that captures measurement error. This mode is useful when you want data that mimics real experimental measurements. **(Bulk only)** * **"mean estimation"**: The model creates a distribution capturing biological heterogeneity consistent with the supplied metadata, then returns the mean of that distribution. This mode is useful when you want a stable estimate of expected expression levels. **(Bulk and single-cell)** ```r theme={null} # Bulk query with sample generation bulk_query <- get_example_query(model_id = "gem-1-bulk")$example_query bulk_query$sampling_strategy <- "sample generation" # Bulk query with mean estimation bulk_query_mean <- get_example_query(model_id = "gem-1-bulk")$example_query bulk_query_mean$sampling_strategy <- "mean estimation" # Single-cell query (must use mean estimation) sc_query <- get_example_query(model_id = "gem-1-sc")$example_query sc_query$sampling_strategy <- "mean estimation" # Required for single-cell ``` ### total\_count (integer, optional) Library size used when converting predicted log CPM back to raw counts. Higher values scale counts up proportionally. * Default: 10,000,000 for bulk; 10,000 for single-cell ```r theme={null} # Create a query and add custom total_count query <- get_example_query(model_id = "gem-1-bulk")$example_query query$total_count <- 5000000 ``` ### deterministic\_latents (logical, optional) If `TRUE`, the model uses the mean of each latent distribution (`p(z|metadata)`) instead of sampling. This removes randomness from latent sampling and produces deterministic outputs for the same inputs. * Default: `FALSE` (sampling is enabled) ```r theme={null} # Create a query and enable deterministic latents query <- get_example_query(model_id = "gem-1-bulk")$example_query query$deterministic_latents <- TRUE ``` ### seed (integer, optional) Random seed for reproducibility when using stochastic sampling. ```r theme={null} # Create a query with a specific seed query <- get_example_query(model_id = "gem-1-bulk")$example_query query$seed <- 42 ``` ### Combining Parameters You can combine multiple parameters in a single query: ```r theme={null} # Create a query and add multiple parameters query <- get_example_query(model_id = "gem-1-bulk")$example_query query$total_count <- 8000000 query$deterministic_latents <- TRUE query$sampling_strategy <- "mean estimation" results <- predict_query(query, model_id = "gem-1-bulk") ``` ## Valid Metadata Keys The input metadata is a list of lists. Here is the full list of valid metadata keys: ### Biological * `age_years` * `cell_line_ontology_id` * `cell_type_ontology_id` * `developmental_stage` * `disease_ontology_id` * `ethnicity` * `genotype` * `race` * `sample_type` ("cell line", "organoid", "other", "primary cells", "primary tissue", "xenograft") * `sex` ("male", "female") * `tissue_ontology_id` ### Perturbational * `perturbation_dose` (number and unit separated by a space, e.g., "10 um") * `perturbation_ontology_id` * `perturbation_time` (number and unit separated by a space, e.g., "24 hours") * `perturbation_type` ("coculture", "compound", "control", "crispr", "genetic", "infection", "other", "overexpression", "peptide or biologic", "shrna", "sirna") ### Technical * `study` (Bioproject ID) * `library_selection` (e.g., "cDNA", "polyA", "Oligo-dT" - see [https://ena-docs.readthedocs.io/en/latest/submit/reads/webin-cli.html#permitted-values-for-library-selection](https://ena-docs.readthedocs.io/en/latest/submit/reads/webin-cli.html#permitted-values-for-library-selection)) * `library_layout` ("PAIRED", "SINGLE") * `platform` ("illumina") ## Valid Metadata Values The following are the valid values or expected formats for selected metadata keys: | Metadata Field | Requirement / Example | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `cell_line_ontology_id` | Requires a [Cellosaurus ID](https://www.cellosaurus.org/). | | `cell_type_ontology_id` | Requires a [CL ID](https://www.ebi.ac.uk/ols4/ontologies/cl). | | `disease_ontology_id` | Requires a [MONDO ID](https://www.ebi.ac.uk/ols4/ontologies/mondo). | | `perturbation_ontology_id` | Must be a valid Ensembl gene ID (e.g., `ENSG00000156127`), [ChEBI ID](https://www.ebi.ac.uk/chebi/) (e.g., `CHEBI:16681`), [ChEMBL ID](https://www.ebi.ac.uk/chembl/) (e.g., `CHEMBL1234567`), or [NCBI Taxonomy ID](https://www.ncbi.nlm.nih.gov/taxonomy) (e.g., `9606`). | | `tissue_ontology_id` | Requires a [UBERON ID](https://www.ebi.ac.uk/ols4/ontologies/uberon). | We highly recommend using the [EMBL-EBI Ontology Lookup Service](https://www.ebi.ac.uk/ols4/) to find valid IDs for your metadata. Models have a limited acceptable range of metadata input values. If you provide a value that is not in the acceptable range, the API will return an error. ## Modifying Query Inputs You can customize the query inputs to fit your specific research needs: ```r theme={null} # Get a base query query <- get_example_query(model_id = "gem-1-bulk")$example_query # Adjust number of samples for the first input query$inputs[[1]]$num_samples <- 10 # Add a new condition query$inputs[[3]] <- list( metadata = list( sex = "male", sample_type = "primary tissue", tissue_ontology_id = "UBERON:0002371" ), num_samples = 5 ) ``` ## Working with Results ```r theme={null} # Access metadata and expression matrices metadata <- result$metadata expression <- result$expression # Check dimensions dim(expression) # View metadata sample head(metadata) ``` You may want to process the data in chunks or save it for later use: ```r theme={null} # Save results to RDS file saveRDS(result, "synthesize_results.rds") # Load previously saved results result <- readRDS("synthesize_results.rds") # Export as CSV write.csv(result$expression, "expression_matrix.csv") write.csv(result$metadata, "sample_metadata.csv") ``` # Metadata prediction Source: https://docs.synthesize.bio/rsynthbio/models/metadata-prediction Infer biological metadata from observed expression data. ## Overview Metadata prediction models **infer biological metadata from observed expression data**. Given a gene expression profile, the model predicts the likely biological characteristics such as cell type, tissue, disease state, and more. This is useful when you want to: * Annotate samples of unknown origin * Validate sample labels against expression patterns * Discover potential mislabeled or contaminated samples * Understand the biological characteristics captured in expression data ## Available Models * **`gem-1-bulk_predict-metadata`**: Bulk RNA-seq metadata prediction model * **`gem-1-sc_predict-metadata`**: Single-cell RNA-seq metadata prediction model These endpoints may require 1-2 minutes of startup time if they have been scaled down. Plan accordingly for interactive use. ```r theme={null} library(rsynthbio) ``` ## How It Works Metadata prediction encodes your expression data into the model's latent space and then uses classifiers to predict the most likely metadata values for each sample. The model returns: 1. **Classifier probabilities**: For each categorical metadata field, the probability distribution over possible values 2. **Predicted labels**: The most likely value for each metadata field 3. **Latent representations**: The biological, technical, and perturbation latent vectors ## Creating a Query Metadata prediction queries are simpler than other model types—you only need to provide expression counts: ```r theme={null} # Get the example query structure example_query <- get_example_query(model_id = "gem-1-bulk_predict-metadata")$example_query # Inspect the query structure str(example_query) ``` The query structure includes: 1. **`inputs`**: A list of count vectors, where each element is a named list with a `counts` field containing expression values 2. **`seed`** (optional): Random seed for reproducibility ## Example: Predicting Sample Metadata Here's a complete example predicting metadata for expression samples: ```r theme={null} # Start with example query structure query <- get_example_query(model_id = "gem-1-bulk_predict-metadata")$example_query # Replace with your actual expression counts # Each input should be a list with a counts vector query$inputs <- list( list(counts = sample1_counts), list(counts = sample2_counts), list(counts = sample3_counts) ) # Optional: set seed for reproducibility query$seed <- 42 # Submit the query result <- predict_query(query, model_id = "gem-1-bulk_predict-metadata") ``` ## Example: Single Sample Prediction For predicting metadata of a single sample: ```r theme={null} query <- get_example_query(model_id = "gem-1-bulk_predict-metadata")$example_query # Single sample query$inputs <- list( list(counts = my_sample_counts) ) result <- predict_query(query, model_id = "gem-1-bulk_predict-metadata") # Access the predictions print(result$outputs$metadata) ``` ## Query Parameters ### inputs (list, required) A list of expression count vectors. Each element should be a named list containing: * **`counts`**: A vector of non-negative integers representing gene expression counts ```r theme={null} query$inputs <- list( list(counts = c(0, 12, 5, 0, 33, 7, ...)), # Sample 1 list(counts = c(3, 0, 0, 7, 1, 0, ...)) # Sample 2 ) ``` ### seed (integer, optional) Random seed for reproducibility. ```r theme={null} query$seed <- 123 ``` ## Understanding the Results The results from metadata prediction include several components: ### Predicted Metadata The `metadata` data frame contains the predicted values for each sample: ```r theme={null} # View predicted metadata head(result$outputs$metadata) # Access specific predictions result$outputs$metadata$cell_type_ontology_id result$outputs$metadata$tissue_ontology_id result$outputs$metadata$disease_ontology_id ``` ### Classifier Probabilities For categorical metadata fields, the model returns probability distributions over all possible values. These are useful for understanding prediction confidence: ```r theme={null} # If probabilities are included in the output # Access cell type probabilities for first sample # The exact structure depends on the API response format # Example: viewing top predicted cell types cell_type_probs <- result$outputs$classifier_probs$cell_type[[1]] head(sort(cell_type_probs, decreasing = TRUE)) ``` ### Latent Representations The model also returns latent vectors that capture biological, technical, and perturbation characteristics: ```r theme={null} # Access latent representations (if returned) biological_latents <- result$outputs$latents$biological technical_latents <- result$outputs$latents$technical ``` ## Use Cases ### Sample Annotation Annotate unlabeled samples with predicted metadata: ```r theme={null} # Load your unlabeled samples unlabeled_counts <- read.csv("unlabeled_samples.csv", row.names = 1) # Create query query <- get_example_query(model_id = "gem-1-bulk_predict-metadata")$example_query query$inputs <- lapply(1:ncol(unlabeled_counts), function(i) { list(counts = unlabeled_counts[, i]) }) # Predict metadata result <- predict_query(query, model_id = "gem-1-bulk_predict-metadata") # Combine with sample IDs annotations <- result$outputs$metadata annotations$sample_id <- colnames(unlabeled_counts) ``` ### Quality Control Validate existing sample labels against predicted metadata: ```r theme={null} # Compare predicted vs. provided labels provided_labels <- c("UBERON:0002107", "UBERON:0002107", "UBERON:0000955", "UBERON:0000955") predicted_labels <- result$outputs$metadata$tissue_ontology_id # Identify potential mismatches mismatches <- which(provided_labels != predicted_labels) if (length(mismatches) > 0) { message("Potential mislabeled samples: ", paste(mismatches, collapse = ", ")) } ``` ## Important Notes ### Counts Vector Length The counts vector for each sample must match the model's expected number of genes. If the length doesn't match, the API will return a validation error. Use `get_example_query()` to see the expected structure. ### Gene Order Ensure your counts are in the same gene order expected by the model. The gene order should match what the baseline model expects—you can retrieve this from any prediction result's `gene_order` field. ### Non-Negative Counts All count values must be non-negative integers. Floats that are whole numbers (like `10.0`) are accepted, but negative values will cause validation errors. # Reference conditioning Source: https://docs.synthesize.bio/rsynthbio/models/reference-conditioning Generate expression data conditioned on a real reference sample. ## Overview Reference conditioning models generate expression data **conditioned on a real reference sample**. This allows you to "anchor" to an existing expression profile while applying perturbations or modifications. This is useful when you want to: * Simulate the effect of a perturbation on a specific sample * Generate expression profiles that preserve the biological and technical characteristics of a reference * Create synthetic "treated vs. control" pairs ## Available Models * **`gem-1-bulk_reference-conditioning`**: Bulk RNA-seq reference conditioning model * **`gem-1-sc_reference-conditioning`**: Single-cell RNA-seq reference conditioning model These endpoints may require 1-2 minutes of startup time if they have been scaled down. Plan accordingly for interactive use. ```r theme={null} library(rsynthbio) ``` ## How It Works Reference conditioning encodes the biological and technical characteristics from a real expression sample, then generates new expression data that: 1. Preserves the biological/technical latent space of the reference 2. Applies any perturbation metadata you specify 3. Returns synthetic expression that reflects the perturbation effect on that specific sample ## Creating a Query Reference conditioning queries require different inputs than baseline models: ```r theme={null} # Get the example query structure example_query <- get_example_query(model_id = "gem-1-bulk_reference-conditioning")$example_query # Inspect the query structure str(example_query) ``` The query structure includes: 1. **`inputs`**: A list where each input contains: * **`counts`**: The reference expression counts (a numeric vector) * **`metadata`**: Perturbation-only metadata (see below) * **`num_samples`**: How many samples to generate 2. **`conditioning`**: Which latent spaces to condition on (typically `["biological", "technical"]`) 3. **`sampling_strategy`**: `"mean estimation"` or `"sample generation"` ### Perturbation-Only Metadata Unlike baseline models, reference conditioning queries only accept perturbation metadata fields: * `perturbation_ontology_id` * `perturbation_type` * `perturbation_time` * `perturbation_dose` All other biological and technical metadata is inferred from the reference expression. ## Example: Simulating a Drug Treatment Here's a complete example simulating a drug treatment effect on a reference sample: ```r theme={null} # Start with example query structure query <- get_example_query(model_id = "gem-1-bulk_reference-conditioning")$example_query # Replace with your actual reference counts # The counts vector must match the model's expected gene order and length query$inputs[[1]]$counts <- your_reference_counts # Specify the perturbation query$inputs[[1]]$metadata <- list( perturbation_ontology_id = "CHEMBL25", # Aspirin (ChEMBL ID) perturbation_type = "compound", perturbation_time = "24 hours", perturbation_dose = "10 um" ) query$inputs[[1]]$num_samples <- 3 # Set the sampling strategy query$sampling_strategy <- "mean estimation" # Submit the query result <- predict_query(query, model_id = "gem-1-bulk_reference-conditioning") ``` ## Example: CRISPR Knockout Simulation Simulate the effect of knocking out a specific gene: ```r theme={null} query <- get_example_query(model_id = "gem-1-bulk_reference-conditioning")$example_query # Your reference sample counts query$inputs[[1]]$counts <- control_sample_counts # CRISPR knockout of TP53 query$inputs[[1]]$metadata <- list( perturbation_ontology_id = "ENSG00000141510", # TP53 Ensembl ID perturbation_type = "crispr" ) query$inputs[[1]]$num_samples <- 5 result <- predict_query(query, model_id = "gem-1-bulk_reference-conditioning") ``` ## Query Parameters ### conditioning (list, optional) Controls which latent spaces are conditioned on the reference. Default is `["biological", "technical"]`. When both are conditioned, the model preserves both biological identity and technical characteristics from the reference sample. ### sampling\_strategy (character, required) Controls the type of prediction: * **"sample generation"**: Generates realistic-looking synthetic data with measurement error. **(Bulk only)** * **"mean estimation"**: Provides stable mean estimates. **(Bulk and single-cell)** ```r theme={null} query$sampling_strategy <- "mean estimation" ``` ### fixed\_total\_count (logical, optional) Controls whether to preserve the reference's library size: * **`FALSE`** (default): The output's total count is taken from the reference expression (sum of its counts). Use this when you want the synthetic sample to preserve the reference's library size. * **`TRUE`**: Forces the model to use the `total_count` parameter value (or default) instead of the reference's library size. ```r theme={null} # Preserve reference library size (default) query$fixed_total_count <- FALSE # Or force a specific library size query$fixed_total_count <- TRUE query$total_count <- 10000000 ``` ### total\_count (integer, optional) Library size used when converting predicted log CPM back to raw counts. Only effective when `fixed_total_count = TRUE`. * Default: 10,000,000 for bulk; 10,000 for single-cell ### deterministic\_latents (logical, optional) If `TRUE`, the model uses the mean of each latent distribution (`p(z|metadata)` for perturbation, `q(z|x)` for conditioned components) instead of sampling. This produces deterministic, reproducible outputs. * Default: `FALSE` ```r theme={null} query$deterministic_latents <- TRUE ``` ### seed (integer, optional) Random seed for reproducibility. ```r theme={null} query$seed <- 42 ``` ## Valid Perturbation Metadata | Field | Description / Format | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `perturbation_ontology_id` | Ensembl gene ID (e.g., `ENSG00000141510`), [ChEBI ID](https://www.ebi.ac.uk/chebi/), [ChEMBL ID](https://www.ebi.ac.uk/chembl/), or [NCBI Taxonomy ID](https://www.ncbi.nlm.nih.gov/taxonomy) | | `perturbation_type` | One of: "coculture", "compound", "control", "crispr", "genetic", "infection", "other", "overexpression", "peptide or biologic", "shrna", "sirna" | | `perturbation_time` | Time since perturbation, as a number and unit separated by a space (e.g., "24 hours", "48 hours") | | `perturbation_dose` | Dose of perturbation, as a number and unit separated by a space (e.g., "10 um", "1 mg/kg") | ## Working with Results The result structure is similar to baseline models: ```r theme={null} # Access metadata and expression matrices metadata <- result$metadata expression <- result$expression # Compare to your reference dim(expression) head(metadata) ``` ### Differential Expression When conditioning on both biological and technical latents, you can directly compare the generated expression to your reference to identify perturbation effects: ```r theme={null} # Your reference (input) counts reference_cpm <- your_reference_counts / sum(your_reference_counts) * 1e6 # Generated (perturbed) counts generated_cpm <- expression[1, ] / sum(expression[1, ]) * 1e6 # Log fold change log2fc <- log2(generated_cpm + 1) - log2(reference_cpm + 1) # Identify top changed genes head(sort(log2fc, decreasing = TRUE), 20) ``` ## Important Notes ### Counts Vector Length The reference counts vector must match the model's expected number of genes. If the length doesn't match, the API will return a validation error. Use `get_example_query()` to see the expected structure and ensure your counts vector has the correct length. ### Gene Order Ensure your reference counts are in the same gene order expected by the model. The response includes a `gene_order` field that specifies the expected order. # Function reference Source: https://docs.synthesize.bio/rsynthbio/reference Generated reference pages for exported rsynthbio functions and constants. `rsynthbio` ships its function-level docs with the package itself. The pages below are generated from the package help files in `man/` so the shared docs site can mirror the current exported reference. ```r theme={null} ?predict_query ?set_synthesize_token help(package = "rsynthbio") ``` The full reference for the latest CRAN release, in one file. ## Predictions * [`predict_query`](/rsynthbio/reference/predict_query) — Predict Gene Expression. Sends a query to the Synthesize Bio API for prediction * [`get_example_query`](/rsynthbio/reference/get_example_query) — Get Example Query for Model. Retrieves an example query structure for a specific model. * [`list_models`](/rsynthbio/reference/list_models) — List Available Models. Returns a list of all models available in the Synthesize Bio API. ## Authentication * [`set_synthesize_token`](/rsynthbio/reference/set_synthesize_token) — Set Synthesize Bio API Token. Securely prompts for and stores the Synthesize Bio API token in the * [`load_synthesize_token_from_keyring`](/rsynthbio/reference/load_synthesize_token_from_keyring) — Load Synthesize Bio API Token from Keyring. Loads the previously stored Synthesize Bio API token from the system * [`has_synthesize_token`](/rsynthbio/reference/has_synthesize_token) — Check if Synthesize Bio API Token is Set. Checks whether a Synthesize Bio API token is currently set in the * [`clear_synthesize_token`](/rsynthbio/reference/clear_synthesize_token) — Clear Synthesize Bio API Token. Clears the Synthesize Bio API token from the environment for the ## Constants * [`API_BASE_URL`](/rsynthbio/reference/API_BASE_URL) — API Base URL. Base URL for the Synthesize Bio API * [`DEFAULT_TIMEOUT`](/rsynthbio/reference/DEFAULT_TIMEOUT) — Default Timeout. Default timeout (seconds) for outbound HTTP requests * [`DEFAULT_POLL_INTERVAL_SECONDS`](/rsynthbio/reference/DEFAULT_POLL_INTERVAL_SECONDS) — Default Poll Interval. Default polling interval (seconds) for async model queries * [`DEFAULT_POLL_TIMEOUT_SECONDS`](/rsynthbio/reference/DEFAULT_POLL_TIMEOUT_SECONDS) — Default Poll Timeout. Default maximum timeout (seconds) for async model queries # API_BASE_URL Source: https://docs.synthesize.bio/rsynthbio/reference/API_BASE_URL API Base URL. Base URL for the Synthesize Bio API ## Usage ```r theme={null} API_BASE_URL ``` ## Source Generated from [`R/utils.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/utils.R) and the package help files in `man/`. # DEFAULT_POLL_INTERVAL_SECONDS Source: https://docs.synthesize.bio/rsynthbio/reference/DEFAULT_POLL_INTERVAL_SECONDS Default Poll Interval. Default polling interval (seconds) for async model queries ## Usage ```r theme={null} DEFAULT_POLL_INTERVAL_SECONDS ``` ## Source Generated from [`R/utils.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/utils.R) and the package help files in `man/`. # DEFAULT_POLL_TIMEOUT_SECONDS Source: https://docs.synthesize.bio/rsynthbio/reference/DEFAULT_POLL_TIMEOUT_SECONDS Default Poll Timeout. Default maximum timeout (seconds) for async model queries ## Usage ```r theme={null} DEFAULT_POLL_TIMEOUT_SECONDS ``` ## Source Generated from [`R/utils.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/utils.R) and the package help files in `man/`. # DEFAULT_TIMEOUT Source: https://docs.synthesize.bio/rsynthbio/reference/DEFAULT_TIMEOUT Default Timeout. Default timeout (seconds) for outbound HTTP requests ## Usage ```r theme={null} DEFAULT_TIMEOUT ``` ## Source Generated from [`R/utils.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/utils.R) and the package help files in `man/`. # clear_synthesize_token Source: https://docs.synthesize.bio/rsynthbio/reference/clear_synthesize_token Clear Synthesize Bio API Token. Clears the Synthesize Bio API token from the environment for the current R session. This is useful for security purposes when you've finished working with the API or when switching between different accounts. ## Usage ```r theme={null} clear_synthesize_token(remove_from_keyring = FALSE) ``` ## Arguments * **`remove_from_keyring`**: Logical, whether to also remove the token from the system keyring if it's stored there. Defaults to FALSE. ## Returns Invisibly returns TRUE. ## Examples ```r theme={null} # Clear token from current session only clear_synthesize_token() # Clear token from both session and keyring clear_synthesize_token(remove_from_keyring = TRUE) ``` ## Source Generated from [`R/key-handlers.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/key-handlers.R) and the package help files in `man/`. # get_example_query Source: https://docs.synthesize.bio/rsynthbio/reference/get_example_query Get Example Query for Model. Retrieves an example query structure for a specific model. This provides a template that can be modified for your specific needs. ## Usage ```r theme={null} get_example_query(model_id, api_base_url = NULL, self_hosted = NULL) ``` ## Arguments * **`model_id`**: Character string specifying the model ID (e.g., "gem-1-bulk", "gem-1-sc"). * **`api_base_url`**: The base URL for the API server. When NULL (default), it is resolved from the `SYNTHESIZE_API_BASE_URL` environment variable, falling back to the production default (API\_BASE\_URL). Point this at a self-hosted model container to fetch its example query. * **`self_hosted`**: Logical; when TRUE, the request targets a self-hosted container and does not require an API key (one is only sent if set). When NULL (default), it is resolved from the `SYNTHESIZE_SELF_HOSTED` environment variable (truthy for 1/true/yes/on), defaulting to FALSE. ## Returns A list representing a valid query structure for the specified model. ## Examples ```r theme={null} # Get example query for bulk RNA-seq model query <- get_example_query(model_id = "gem-1-bulk")$example_query # Get example query for single-cell model query_sc <- get_example_query(model_id = "gem-1-sc")$example_query # Modify the query structure query$inputs[[1]]$num_samples <- 10 # Fetch from a self-hosted container (no API key required) query <- get_example_query( model_id = "gem-1-bulk", api_base_url = "https://gem-1-bulk.internal.partner.example", self_hosted = TRUE )$example_query ``` ## Source Generated from [`R/call_model_api.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/call_model_api.R) and the package help files in `man/`. # has_synthesize_token Source: https://docs.synthesize.bio/rsynthbio/reference/has_synthesize_token Check if Synthesize Bio API Token is Set. Checks whether a Synthesize Bio API token is currently set in the environment. Useful for conditional code that requires an API token. ## Usage ```r theme={null} has_synthesize_token() ``` ## Returns Logical, TRUE if token is set, FALSE otherwise. ## Examples ```r theme={null} # Check if token is set if (!has_synthesize_token()) # Prompt for token if not set set_synthesize_token() ``` ## Source Generated from [`R/key-handlers.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/key-handlers.R) and the package help files in `man/`. # list_models Source: https://docs.synthesize.bio/rsynthbio/reference/list_models List Available Models. Returns a list of all models available in the Synthesize Bio API. Each model has a unique ID that can be used with predict\_query() and get\_example\_query(). ## Usage ```r theme={null} list_models(api_base_url = NULL, self_hosted = NULL) ``` ## Arguments * **`api_base_url`**: The base URL for the API server. When NULL (default), it is resolved from the `SYNTHESIZE_API_BASE_URL` environment variable, falling back to the production default (API\_BASE\_URL). Point this at a self-hosted model container to list its models. * **`self_hosted`**: Logical; when TRUE, the request targets a self-hosted container and does not require an API key (one is only sent if set). When NULL (default), it is resolved from the `SYNTHESIZE_SELF_HOSTED` environment variable (truthy for 1/true/yes/on), defaulting to FALSE. ## Returns A list or data frame containing available models with their IDs and metadata. ## Examples ```r theme={null} # Get all available models models <- list_models() print(models) # List models from a self-hosted container (no API key required) models <- list_models( api_base_url = "https://gem-1-bulk.internal.partner.example", self_hosted = TRUE ) ``` ## Source Generated from [`R/call_model_api.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/call_model_api.R) and the package help files in `man/`. # load_synthesize_token_from_keyring Source: https://docs.synthesize.bio/rsynthbio/reference/load_synthesize_token_from_keyring Load Synthesize Bio API Token from Keyring. Loads the previously stored Synthesize Bio API token from the system keyring and sets it in the environment for the current session. ## Usage ```r theme={null} load_synthesize_token_from_keyring() ``` ## Returns Invisibly returns TRUE if successful, FALSE if token not found in keyring. ## Examples ```r theme={null} # Load token from keyring load_synthesize_token_from_keyring() ``` ## Source Generated from [`R/key-handlers.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/key-handlers.R) and the package help files in `man/`. # predict_query Source: https://docs.synthesize.bio/rsynthbio/reference/predict_query Predict Gene Expression. Sends a query to the Synthesize Bio API for prediction and retrieves gene expression samples. This function sends the query to the API and processes the response into usable data frames. ## Usage ```r theme={null} predict_query( query, model_id, api_base_url = NULL, poll_interval_seconds = DEFAULT_POLL_INTERVAL_SECONDS, poll_timeout_seconds = DEFAULT_POLL_TIMEOUT_SECONDS, return_download_url = FALSE, raw_response = FALSE, self_hosted = NULL, ... ) ``` ## Arguments * **`query`**: A list representing the query data to send to the API. Use `get_example_query()` to generate an example. The query supports additional optional fields: `total_count` (integer): Library size used when converting predicted log CPM back to raw counts. Higher values scale counts up proportionally. `deterministic_latents` (logical): If TRUE, the model uses the mean of each latent distribution instead of sampling, producing deterministic outputs for the same inputs. Useful for reproducibility. `seed` (integer): Random seed for reproducibility. * **`model_id`**: Character string specifying the model ID (e.g., "gem-1-bulk", "gem-1-sc"). Use `list_models()` to see available models. * **`api_base_url`**: The base URL for the API server. When NULL (default), it is resolved in order from the per-model environment variable `SYNTHESIZE_API_BASE_URL__` (e.g. `SYNTHESIZE_API_BASE_URL__GEM_1_BULK`), then the global `SYNTHESIZE_API_BASE_URL`, then the production default (API\_BASE\_URL). The per-model variable lets you point each self-hosted model at its own container once and omit `api_base_url` on every call. * **`poll_interval_seconds`**: Seconds between polling attempts of the status endpoint. Default is DEFAULT\_POLL\_INTERVAL\_SECONDS (2). * **`poll_timeout_seconds`**: Maximum total seconds to wait before timing out. Default is DEFAULT\_POLL\_TIMEOUT\_SECONDS (900 = 15 minutes). * **`return_download_url`**: Logical, if TRUE, returns a list containing the signed download URL instead of parsing into data frames. Default is FALSE. * **`raw_response`**: Logical, if TRUE, returns the raw (unformatted) response from the API without applying any output transformers. For the production path this is the parsed JSON; for `self_hosted = TRUE` it is the parsed Arrow `Table` together with its schema metadata. Default is FALSE. * **`self_hosted`**: Logical, if TRUE, sends a single synchronous request to a self-hosted model container that returns predictions as an Apache Arrow IPC stream (no polling, no download URL). Requires the optional `arrow` package and an `api_base_url` pointing at the container. Unlike the production path, no API key is required (one is only sent if configured). When NULL (default), it is resolved from the `SYNTHESIZE_SELF_HOSTED` environment variable (truthy for 1/true/yes/on), defaulting to FALSE. * **`...`**: Additional parameters to include in the query body. These are passed directly to the API and validated server-side. ## Returns A list. For the production path, if `return_download_url` is `FALSE` (default) the list contains `metadata` and `expression` data frames; if `TRUE` it contains `download_url` and empty data frames. For `self_hosted = TRUE`, the list contains the transformed data frames (`metadata`, `expression`, and `latents`; plus `classifier_probs` for metadata-prediction models) with `model_version` and `request_type` attached as attributes. ## Examples ```r theme={null} # Set your API key (in practice, use a more secure method) # To start using rsynthbio, first you need to have an account with synthesize.bio. # Go here to create one: https://app.synthesize.bio/ set_synthesize_token() # Get available models models <- list_models() # Create a query for a specific model query <- get_example_query(model_id = "gem-1-bulk")$example_query # Request raw counts result <- predict_query(query, model_id = "gem-1-bulk") # Access the results metadata <- result$metadata expression <- result$expression # Explore the top expressed genes in the first sample head(sort(expression[1, ], decreasing = TRUE)) # Use deterministic latents for reproducible results query$deterministic_latents <- TRUE result_det <- predict_query(query, model_id = "gem-1-bulk") # Specify a custom total count (library size) query$total_count <- 5000000 result_custom <- predict_query(query, model_id = "gem-1-bulk") # Self-hosted container returning a synchronous Apache Arrow IPC stream result_sh <- predict_query( query, model_id = "gem-1-bulk", api_base_url = "https://gem-1-bulk.internal.partner.example", self_hosted = TRUE ) ``` ## Source Generated from [`R/call_model_api.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/call_model_api.R) and the package help files in `man/`. # set_synthesize_token Source: https://docs.synthesize.bio/rsynthbio/reference/set_synthesize_token Set Synthesize Bio API Token. Securely prompts for and stores the Synthesize Bio API token in the environment. This function uses getPass to securely handle the token input without displaying it in the console. The token is stored in the SYNTHESIZE\_API\_KEY environment variable for the current R session. ## Usage ```r theme={null} set_synthesize_token(use_keyring = FALSE, token = NULL) ``` ## Arguments * **`use_keyring`**: Logical, whether to also store the token securely in the system keyring for future sessions. Defaults to FALSE. * **`token`**: Character, optional. If provided, uses this token instead of prompting. This parameter should only be used in non-interactive scripts. ## Returns Invisibly returns TRUE if successful. ## Examples ```r theme={null} # Interactive prompt for token set_synthesize_token() # Provide token directly (less secure, not recommended for interactive use) set_synthesize_token(token = "your-token-here") # Store in system keyring for future sessions set_synthesize_token(use_keyring = TRUE) ``` ## Source Generated from [`R/key-handlers.R`](https://github.com/synthesizebio/rsynthbio/blob/main/R/key-handlers.R) and the package help files in `man/`. # Self-hosted models Source: https://docs.synthesize.bio/rsynthbio/self-hosted Run Synthesize Bio models in your own environment via synchronous Apache Arrow streaming. Partners who run Synthesize Bio models inside their own environment (for example, on a GPU host in their own cloud account) can use the same `rsynthbio` client against a self-hosted model container instead of the hosted API at `app.synthesize.bio`. Self-hosted deployment is a model deployment option available within a Synthesize Bio partnership. To learn more or request access, contact [partnerships@synthesize.bio](mailto:partnerships@synthesize.bio). ## How it differs from the hosted path The hosted path is asynchronous: it starts a query, polls for completion, and downloads results. A self-hosted container instead returns predictions **synchronously** as an [Apache Arrow](https://arrow.apache.org/) IPC stream. `rsynthbio` decodes that stream into exactly the same data frames you get from the hosted path (`expression`, `metadata`, and `latents`), so downstream code does not change. Key differences: * **No polling and no download URL** — a single request returns the data. * **Requires the optional `arrow` package** — install it with `install.packages("arrow")`. * **No API key required** — a key is only sent when `SYNTHESIZE_API_KEY` is set (use this if your container runs with authentication enabled). ## Enabling self-hosted mode Set `self_hosted = TRUE` on a call, or enable it for the whole session with the `SYNTHESIZE_SELF_HOSTED` environment variable (truthy values: `1`, `true`, `yes`, `on`). ```r theme={null} library(rsynthbio) Sys.setenv(SYNTHESIZE_SELF_HOSTED = "1") ``` ## Pointing each model at its container Self-hosted deployments typically run one container per model. Set a per-model base URL once and you never have to pass `api_base_url` on individual calls. The variable name is `SYNTHESIZE_API_BASE_URL__`, where `` is the upper-cased model id with non-alphanumeric characters replaced by underscores (for example, `gem-1-bulk` becomes `SYNTHESIZE_API_BASE_URL__GEM_1_BULK`). ```r theme={null} Sys.setenv( SYNTHESIZE_API_BASE_URL__GEM_1_BULK = "https://gem-1-bulk.internal.example", SYNTHESIZE_API_BASE_URL__GEM_1_SC = "https://gem-1-sc.internal.example" ) query <- get_example_query("gem-1-bulk", self_hosted = TRUE)$example_query result <- predict_query(query, model_id = "gem-1-bulk", self_hosted = TRUE) expression <- result$expression metadata <- result$metadata ``` Variant slugs backed by the same container (for example, `gem-1-bulk_reference-conditioning` and `gem-1-bulk_predict-metadata`) resolve to the same per-model variable as their base model. ### Resolution precedence When `api_base_url` is `NULL`, the base URL is resolved in this order: 1. An explicit `api_base_url` argument passed to the call. 2. The per-model variable `SYNTHESIZE_API_BASE_URL__`. 3. The global `SYNTHESIZE_API_BASE_URL`. 4. The production default (`https://app.synthesize.bio`). You can always override the environment by passing `api_base_url` directly: ```r theme={null} result <- predict_query( query, model_id = "gem-1-bulk", api_base_url = "https://gem-1-bulk.internal.example", self_hosted = TRUE ) ``` ## Authentication (optional) Self-hosted containers may run without authentication. If yours requires a key, set `SYNTHESIZE_API_KEY` and the client attaches it as a bearer token: ```r theme={null} Sys.setenv(SYNTHESIZE_API_KEY = "your-container-api-key") ``` ## Raw responses Pass `raw_response = TRUE` to receive the parsed Arrow `Table` and its schema metadata (including `model_version`, `request_type`, and `gene_order`) instead of the transformed data frames: ```r theme={null} raw <- predict_query( query, model_id = "gem-1-bulk", self_hosted = TRUE, raw_response = TRUE ) raw$table # an arrow::Table raw$model_version ```