|
1 | 1 | --- |
2 | 2 | name: adaptyv |
3 | | -description: Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding assays, expression testing, thermostability measurements, enzyme activity assays, or protein sequence optimization. Also use for submitting experiments via API, tracking experiment status, downloading results, optimizing protein sequences for better expression using computational tools (NetSolP, SoluProt, SolubleMPNN, ESM), or managing protein design workflows with wet-lab validation. |
4 | | -license: Unknown |
5 | | -metadata: |
6 | | - skill-author: K-Dense Inc. |
| 3 | +author: "K-Dense, Inc." |
| 4 | +description: "How to use the Adaptyv Bio Foundry API and Python SDK for protein experiment design, submission, and results retrieval. Use this skill whenever the user mentions Adaptyv, Foundry API, protein binding assays, protein screening experiments, BLI/SPR assays, thermostability assays, or wants to submit protein sequences for experimental characterization. Also trigger when code imports `adaptyv`, `adaptyv_sdk`, or `FoundryClient`, or references `foundry-api-public.adaptyvbio.com`." |
7 | 5 | --- |
8 | 6 |
|
9 | | -# Adaptyv |
| 7 | +# Adaptyv Bio Foundry API |
10 | 8 |
|
11 | | -Adaptyv is a cloud laboratory platform that provides automated protein testing and validation services. Submit protein sequences via API or web interface and receive experimental results in approximately 21 days. |
| 9 | +Adaptyv Bio is a cloud lab that turns protein sequences into experimental data. Users submit amino acid sequences via API or UI; Adaptyv's automated lab runs assays (binding, thermostability, expression, fluorescence) and delivers results in ~21 days. |
12 | 10 |
|
13 | 11 | ## Quick Start |
14 | 12 |
|
15 | | -### Authentication Setup |
| 13 | +**Base URL:** `https://foundry-api-public.adaptyvbio.com/api/v1` |
16 | 14 |
|
17 | | -Adaptyv requires API authentication. Set up your credentials: |
| 15 | +**Authentication:** Bearer token in the `Authorization` header. Tokens are obtained from [foundry.adaptyvbio.com](https://foundry.adaptyvbio.com/) sidebar. |
18 | 16 |
|
19 | | -1. Contact support@adaptyvbio.com to request API access (platform is in alpha/beta) |
20 | | -2. Receive your API access token |
21 | | -3. Set environment variable: |
| 17 | +When writing code, always read the API key from the environment variable `ADAPTYV_API_KEY` or from a `.env` file — never hardcode tokens. Check for a `.env` file in the project root first; if one exists, use a library like `python-dotenv` to load it. |
22 | 18 |
|
23 | 19 | ```bash |
24 | | -export ADAPTYV_API_KEY="your_api_key_here" |
| 20 | +export FOUNDRY_API_TOKEN="abs0_..." |
| 21 | +curl https://foundry-api-public.adaptyvbio.com/api/v1/targets?limit=3 \ |
| 22 | + -H "Authorization: Bearer $FOUNDRY_API_TOKEN" |
25 | 23 | ``` |
26 | 24 |
|
27 | | -Or create a `.env` file: |
| 25 | +Every request except `GET /openapi.json` requires authentication. Store tokens in environment variables or `.env` files — never commit them to source control. |
28 | 26 |
|
| 27 | +## Python SDK |
| 28 | + |
| 29 | +Install: `uv add adaptyv-sdk` (falls back to `uv pip install adaptyv-sdk` if no `pyproject.toml` exists) |
| 30 | + |
| 31 | +**Environment variables** (set in shell or `.env` file): |
| 32 | +```bash |
| 33 | +ADAPTYV_API_KEY=your_api_key |
| 34 | +ADAPTYV_API_URL=https://foundry-api-public.adaptyvbio.com/api/v1 |
29 | 35 | ``` |
30 | | -ADAPTYV_API_KEY=your_api_key_here |
| 36 | + |
| 37 | +### Decorator Pattern |
| 38 | + |
| 39 | +```python |
| 40 | +from adaptyv import lab |
| 41 | + |
| 42 | +@lab.experiment(target="PD-L1", experiment_type="screening", method="bli") |
| 43 | +def design_binders(): |
| 44 | + return {"design_a": "MVKVGVNG...", "design_b": "MKVLVAG..."} |
| 45 | + |
| 46 | +result = design_binders() |
| 47 | +print(f"Experiment: {result.experiment_url}") |
31 | 48 | ``` |
32 | 49 |
|
33 | | -### Installation |
| 50 | +### Client Pattern |
34 | 51 |
|
35 | | -Install the required package using uv: |
| 52 | +```python |
| 53 | +from adaptyv import FoundryClient |
36 | 54 |
|
37 | | -```bash |
38 | | -uv pip install requests python-dotenv |
| 55 | +client = FoundryClient(api_key="...", base_url="https://foundry-api-public.adaptyvbio.com/api/v1") |
| 56 | + |
| 57 | +# Browse targets |
| 58 | +targets = client.targets.list(search="EGFR", selfservice_only=True) |
| 59 | + |
| 60 | +# Estimate cost |
| 61 | +estimate = client.experiments.cost_estimate({ |
| 62 | + "experiment_spec": { |
| 63 | + "experiment_type": "screening", |
| 64 | + "method": "bli", |
| 65 | + "target_id": "target-uuid", |
| 66 | + "sequences": {"seq1": "EVQLVESGGGLVQ..."}, |
| 67 | + "n_replicates": 3 |
| 68 | + } |
| 69 | +}) |
| 70 | + |
| 71 | +# Create and submit |
| 72 | +exp = client.experiments.create({...}) |
| 73 | +client.experiments.submit(exp.experiment_id) |
| 74 | + |
| 75 | +# Later: retrieve results |
| 76 | +results = client.experiments.get_results(exp.experiment_id) |
39 | 77 | ``` |
40 | 78 |
|
41 | | -### Basic Usage |
| 79 | +## Experiment Types |
42 | 80 |
|
43 | | -Submit protein sequences for testing: |
| 81 | +| Type | Method | Measures | Requires Target | |
| 82 | +|---|---|---|---| |
| 83 | +| `affinity` | `bli` or `spr` | KD, kon, koff kinetics | Yes | |
| 84 | +| `screening` | `bli` or `spr` | Yes/no binding | Yes | |
| 85 | +| `thermostability` | — | Melting temperature (Tm) | No | |
| 86 | +| `expression` | — | Expression yield | No | |
| 87 | +| `fluorescence` | — | Fluorescence intensity | No | |
44 | 88 |
|
45 | | -```python |
46 | | -import os |
47 | | -import requests |
48 | | -from dotenv import load_dotenv |
| 89 | +## Experiment Lifecycle |
49 | 90 |
|
50 | | -load_dotenv() |
| 91 | +``` |
| 92 | +Draft → WaitingForConfirmation → QuoteSent → WaitingForMaterials → InQueue → InProduction → DataAnalysis → InReview → Done |
| 93 | +``` |
51 | 94 |
|
52 | | -api_key = os.getenv("ADAPTYV_API_KEY") |
53 | | -base_url = "https://kq5jp7qj7wdqklhsxmovkzn4l40obksv.lambda-url.eu-central-1.on.aws" |
| 95 | +| Status | Who Acts | Description | |
| 96 | +|---|---|---| |
| 97 | +| `Draft` | You | Editable, no cost commitment | |
| 98 | +| `WaitingForConfirmation` | Adaptyv | Under review, quote being prepared | |
| 99 | +| `QuoteSent` | You | Review and confirm the quote | |
| 100 | +| `WaitingForMaterials` | Adaptyv | Gene fragments and target ordered | |
| 101 | +| `InQueue` | Adaptyv | Materials arrived, queued for lab | |
| 102 | +| `InProduction` | Adaptyv | Assay running | |
| 103 | +| `DataAnalysis` | Adaptyv | Raw data processing and QC | |
| 104 | +| `InReview` | Adaptyv | Final validation | |
| 105 | +| `Done` | You | Results available | |
| 106 | +| `Canceled` | Either | Experiment canceled | |
54 | 107 |
|
55 | | -headers = { |
56 | | - "Authorization": f"Bearer {api_key}", |
57 | | - "Content-Type": "application/json" |
58 | | -} |
| 108 | +The `results_status` field on an experiment tracks: `none`, `partial`, or `all`. |
59 | 109 |
|
60 | | -# Submit experiment |
61 | | -response = requests.post( |
62 | | - f"{base_url}/experiments", |
63 | | - headers=headers, |
64 | | - json={ |
65 | | - "sequences": ">protein1\nMKVLWALLGLLGAA...", |
66 | | - "experiment_type": "binding", |
67 | | - "webhook_url": "https://your-webhook.com/callback" |
| 110 | +## Common Workflows |
| 111 | + |
| 112 | +### 1. Submit a Binding Screen (Step by Step) |
| 113 | + |
| 114 | +```python |
| 115 | +# 1. Find a target |
| 116 | +targets = client.targets.list(search="EGFR", selfservice_only=True) |
| 117 | +target_id = targets.items[0].id |
| 118 | + |
| 119 | +# 2. Preview cost |
| 120 | +estimate = client.experiments.cost_estimate({ |
| 121 | + "experiment_spec": { |
| 122 | + "experiment_type": "screening", |
| 123 | + "method": "bli", |
| 124 | + "target_id": target_id, |
| 125 | + "sequences": {"seq1": "EVQLVESGGGLVQ...", "seq2": "MKVLVAG..."}, |
| 126 | + "n_replicates": 3 |
68 | 127 | } |
69 | | -) |
| 128 | +}) |
| 129 | + |
| 130 | +# 3. Create experiment (starts as Draft) |
| 131 | +exp = client.experiments.create({ |
| 132 | + "name": "EGFR binder screen batch 1", |
| 133 | + "experiment_spec": { |
| 134 | + "experiment_type": "screening", |
| 135 | + "method": "bli", |
| 136 | + "target_id": target_id, |
| 137 | + "sequences": {"seq1": "EVQLVESGGGLVQ...", "seq2": "MKVLVAG..."}, |
| 138 | + "n_replicates": 3 |
| 139 | + } |
| 140 | +}) |
| 141 | + |
| 142 | +# 4. Submit for review |
| 143 | +client.experiments.submit(exp.experiment_id) |
70 | 144 |
|
71 | | -experiment_id = response.json()["experiment_id"] |
| 145 | +# 5. Poll or use webhooks until Done |
| 146 | +# 6. Retrieve results |
| 147 | +results = client.experiments.get_results(exp.experiment_id) |
| 148 | +``` |
| 149 | + |
| 150 | +### 2. Automated Pipeline (Skip Draft + Auto-Accept Quote) |
| 151 | + |
| 152 | +```python |
| 153 | +exp = client.experiments.create({ |
| 154 | + "name": "Auto pipeline run", |
| 155 | + "experiment_spec": {...}, |
| 156 | + "skip_draft": True, |
| 157 | + "auto_accept_quote": True, |
| 158 | + "webhook_url": "https://my-server.com/webhook" |
| 159 | +}) |
| 160 | +# Webhook fires on each status transition; poll or wait for Done |
72 | 161 | ``` |
73 | 162 |
|
74 | | -## Available Experiment Types |
75 | | -Adaptyv supports multiple assay types: |
76 | | -- **Binding assays** - Test protein-target interactions using biolayer interferometry |
77 | | -- **Expression testing** - Measure protein expression levels |
78 | | -- **Thermostability** - Characterize protein thermal stability |
79 | | -- **Enzyme activity** - Assess enzymatic function |
| 163 | +### 3. Using Webhooks |
80 | 164 |
|
81 | | -See `reference/experiments.md` for detailed information on each experiment type and workflows. |
| 165 | +Pass `webhook_url` when creating an experiment. Adaptyv POSTs to that URL on every status transition with the experiment ID, previous status, and new status. |
82 | 166 |
|
83 | | -## Protein Sequence Optimization |
84 | | -Before submitting sequences, optimize them for better expression and stability: |
| 167 | +## Sequences |
85 | 168 |
|
86 | | -**Common issues to address:** |
87 | | -- Unpaired cysteines that create unwanted disulfides |
88 | | -- Excessive hydrophobic regions causing aggregation |
89 | | -- Poor solubility predictions |
| 169 | +- Simple format: `{"seq1": "EVQLVESGGGLVQPGGSLRLSCAAS"}` |
| 170 | +- Rich format: `{"seq1": {"aa_string": "EVQLVESGGGLVQ...", "control": false, "metadata": {"type": "scfv"}}}` |
| 171 | +- Multi-chain: use colon separator — `"MVLS:EVQL"` |
| 172 | +- Valid amino acids: A, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y (case-insensitive, stored uppercase) |
| 173 | +- Sequences can only be added to experiments in `Draft` status |
90 | 174 |
|
91 | | -**Recommended tools:** |
92 | | -- NetSolP / SoluProt - Initial solubility filtering |
93 | | -- SolubleMPNN - Sequence redesign for improved solubility |
94 | | -- ESM - Sequence likelihood scoring |
95 | | -- ipTM - Interface stability assessment |
96 | | -- pSAE - Hydrophobic exposure quantification |
| 175 | +## Filtering, Sorting, and Pagination |
97 | 176 |
|
98 | | -See `reference/protein_optimization.md` for detailed optimization workflows and tool usage. |
| 177 | +All list endpoints support pagination (`limit` 1-100, default 50; `offset`), search (free-text on name fields), and sorting. |
| 178 | + |
| 179 | +**Filtering** uses s-expression syntax via the `filter` query parameter: |
| 180 | +- Comparison: `eq(field,value)`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains(field,substring)` |
| 181 | +- Range/set: `between(field,lo,hi)`, `in(field,v1,v2,...)` |
| 182 | +- Logic: `and(expr1,expr2,...)`, `or(...)`, `not(expr)` |
| 183 | +- Null: `is_null(field)`, `is_not_null(field)` |
| 184 | +- JSONB: `at(field,key)` — e.g., `eq(at(metadata,score),42)` |
| 185 | +- Cast: `float()`, `int()`, `text()`, `timestamp()`, `date()` |
| 186 | + |
| 187 | +**Sorting** uses `asc(field)` or `desc(field)`, comma-separated (max 8): |
| 188 | +``` |
| 189 | +sort=desc(created_at),asc(name) |
| 190 | +``` |
| 191 | + |
| 192 | +**Example:** `filter=and(gte(created_at,2026-01-01),eq(status,done))` |
| 193 | + |
| 194 | +## Error Handling |
| 195 | + |
| 196 | +All errors return: |
| 197 | +```json |
| 198 | +{ |
| 199 | + "error": "Human-readable description", |
| 200 | + "request_id": "req_019462a4-b1c2-7def-8901-23456789abcd" |
| 201 | +} |
| 202 | +``` |
| 203 | +The `request_id` is also in the `x-request-id` response header — include it when contacting support. |
99 | 204 |
|
100 | | -## API Reference |
101 | | -For complete API documentation including all endpoints, request/response formats, and authentication details, see `reference/api_reference.md`. |
| 205 | +## Token Management |
102 | 206 |
|
103 | | -## Examples |
104 | | -For concrete code examples covering common use cases (experiment submission, status tracking, result retrieval, batch processing), see `reference/examples.md`. |
| 207 | +Tokens use Biscuit-based cryptographic attenuation. You can create restricted tokens scoped by organization, resource type, actions (read/create/update), and expiry via `POST /tokens/attenuate`. Revoking a token (`POST /tokens/revoke`) revokes it and all its descendants. |
105 | 208 |
|
106 | | -## Important Notes |
107 | | -- Platform is currently in alpha/beta phase with features subject to change |
108 | | -- Not all platform features are available via API yet |
109 | | -- Results typically delivered in ~21 days |
110 | | -- Contact support@adaptyvbio.com for access requests or questions |
111 | | -- Suitable for high-throughput AI-driven protein design workflows |
| 209 | +## Detailed API Reference |
112 | 210 |
|
| 211 | +For the full list of all 32 endpoints with request/response schemas, read `references/api-endpoints.md`. |
0 commit comments