{"id":"adaptyv","name":"adaptyv","summary":"Adaptyv Bio Foundry APIとPython SDKを使ってタンパク質実験の設計、提出、結果取得を行う方法。","body":"# Adaptyv Bio Foundry API\n\nAdaptyv 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.\n\n**Official docs:** [docs.adaptyvbio.com/api-reference](https://docs.adaptyvbio.com/api-reference) · [llms.txt index](https://docs.adaptyvbio.com/llms.txt) · [OpenAPI spec](https://foundry-api-public.adaptyvbio.com/api/v1/openapi.json)\n\n## Quick Start\n\n**Base URL:** `https://foundry-api-public.adaptyvbio.com/api/v1`\n\n**Authentication:** Bearer token in the `Authorization` header. Tokens are obtained from [foundry.adaptyvbio.com](https://foundry.adaptyvbio.com/) sidebar.\n\nWhen 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.\n\nThe [official API docs](https://docs.adaptyvbio.com/api-reference/api-introduction) use `FOUNDRY_API_TOKEN` in curl examples; that is the same bearer token — prefer `ADAPTYV_API_KEY` in Python and new shell scripts for consistency with the SDK.\n\n```bash\nexport ADAPTYV_API_KEY=\"abs0_...\"\ncurl https://foundry-api-public.adaptyvbio.com/api/v1/targets?limit=3 \\\n  -H \"Authorization: Bearer $ADAPTYV_API_KEY\"\n```\n\nEvery request except `GET /openapi.json` requires authentication. Store tokens in environment variables or `.env` files — never commit them to source control.\n\n## Python SDK\n\n**Version note:** `adaptyv-sdk` **0.1.0** (beta) is not yet on PyPI — install from GitHub:\n\n```bash\nuv pip install \"git+https://github.com/adaptyvbio/adaptyv-sdk.git\"\n```\n\nIn a project with `pyproject.toml`:\n\n```bash\nuv add \"adaptyv-sdk @ git+https://github.com/adaptyvbio/adaptyv-sdk.git\"\n```\n\n**Environment variables** (set in shell or `.env` file):\n\n```bash\nADAPTYV_API_KEY=your_api_key\nADAPTYV_API_URL=https://foundry-api-public.adaptyvbio.com/api/v1\nADAPTYV_ORGANIZATION_ID=your_org_id  # optional\n```\n\nThe `@lab.experiment` decorator and `FoundryClient` both read `ADAPTYV_API_KEY` and `ADAPTYV_API_URL` from the environment when not passed explicitly.\n\n### Decorator Pattern\n\n```python\nfrom adaptyv import lab\n\n@lab.experiment(target=\"PD-L1\", experiment_type=\"screening\", method=\"bli\")\ndef design_binders():\n    return {\"design_a\": \"MVKVGVNG...\", \"design_b\": \"MKVLVAG...\"}\n\nresult = design_binders()\nprint(f\"Experiment: {result.experiment_url}\")\n```\n\n### Client Pattern\n\n```python\nimport os\nfrom adaptyv import FoundryClient\n\nclient = FoundryClient(\n    api_key=os.environ[\"ADAPTYV_API_KEY\"],\n    base_url=os.environ.get(\n        \"ADAPTYV_API_URL\",\n        \"https://foundry-api-public.adaptyvbio.com/api/v1\",\n    ),\n)\n\n# Browse targets\ntargets = client.targets.list(search=\"EGFR\", selfservice_only=True)\n\n# Estimate cost\nestimate = client.experiments.cost_estimate({\n    \"experiment_spec\": {\n        \"experiment_type\": \"screening\",\n        \"method\": \"bli\",\n        \"target_id\": \"target-uuid\",\n        \"sequences\": {\"seq1\": \"EVQLVESGGGLVQ...\"},\n        \"n_replicates\": 3\n    }\n})\n\n# Create and submit\nexp = client.experiments.create({...})\nclient.experiments.submit(exp.experiment_id)\n\n# Later: retrieve results\nresults = client.experiments.get_results(exp.experiment_id)\n```\n\n## Experiment Types\n\n| Type | Method | Measures | Requires Target |\n|---|---|---|---|\n| `affinity` | `bli` or `spr` | KD, kon, koff kinetics | Yes |\n| `screening` | `bli` or `spr` | Yes/no binding | Yes |\n| `thermostability` | — | Melting temperature (Tm) | No |\n| `expression` | — | Expression yield | No |\n| `fluorescence` | — | Fluorescence intensity | No |\n\n## Experiment Lifecycle\n\n```\nDraft → WaitingForConfirmation → QuoteSent → WaitingForMaterials → InQueue → InProduction → DataAnalysis → InReview → Done\n```\n\n| Status | Who Acts | Description |\n|---|---|---|\n| `Draft` | You | Editable, no cost commitment |\n| `WaitingForConfirmation` | Adaptyv | Under review, quote being prepared |\n| `QuoteSent` | You | Review and confirm the quote |\n| `WaitingForMaterials` | Adaptyv | Gene fragments and target ordered |\n| `InQueue` | Adaptyv | Materials arrived, queued for lab |\n| `InProduction` | Adaptyv | Assay running |\n| `DataAnalysis` | Adaptyv | Raw data processing and QC |\n| `InReview` | Adaptyv | Final validation |\n| `Done` | You | Results available |\n| `Canceled` | Either | Experiment canceled |\n\nThe `results_status` field on an experiment tracks: `none`, `partial`, or `all`.\n\n## Common Workflows\n\n### 1. Submit a Binding Screen (Step by Step)\n\n```python\n# 1. Find a target\ntargets = client.targets.list(search=\"EGFR\", selfservice_only=True)\ntarget_id = targets.items[0].id\n\n# 2. Preview cost\nestimate = client.experiments.cost_estimate({\n    \"experiment_spec\": {\n        \"experiment_type\": \"screening\",\n        \"method\": \"bli\",\n        \"target_id\": target_id,\n        \"sequences\": {\"seq1\": \"EVQLVESGGGLVQ...\", \"seq2\": \"MKVLVAG...\"},\n        \"n_replicates\": 3\n    }\n})\n\n# 3. Create experiment (starts as Draft)\nexp = client.experiments.create({\n    \"name\": \"EGFR binder screen batch 1\",\n    \"experiment_spec\": {\n        \"experiment_type\": \"screening\",\n        \"method\": \"bli\",\n        \"target_id\": target_id,\n        \"sequences\": {\"seq1\": \"EVQLVESGGGLVQ...\", \"seq2\": \"MKVLVAG...\"},\n        \"n_replicates\": 3\n    }\n})\n\n# 4. Submit for review\nclient.experiments.submit(exp.experiment_id)\n\n# 5. Poll or use webhooks until Done\n# 6. Retrieve results\nresults = client.experiments.get_results(exp.experiment_id)\n```\n\n### 2. Automated Pipeline (Skip Draft + Auto-Accept Quote)\n\n```python\nexp = client.experiments.create({\n    \"name\": \"Auto pipeline run\",\n    \"experiment_spec\": {...},\n    \"skip_draft\": True,\n    \"auto_accept_quote\": True,\n    \"webhook_url\": \"https://my-server.com/webhook\"\n})\n# Webhook fires on each status transition; poll or wait for Done\n```\n\n### 3. Using Webhooks\n\nPass `webhook_url` when creating an experiment. Adaptyv POSTs to that URL on every status transition with the experiment ID, previous status, and new status.\n\n## Sequences\n\n- Simple format: `{\"seq1\": \"EVQLVESGGGLVQPGGSLRLSCAAS\"}`\n- Rich format: `{\"seq1\": {\"aa_string\": \"EVQLVESGGGLVQ...\", \"control\": false, \"metadata\": {\"type\": \"scfv\"}}}`\n- Multi-chain: use colon separator — `\"MVLS:EVQL\"`\n- 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)\n- Sequences can only be added to experiments in `Draft` status\n\n## Filtering, Sorting, and Pagination\n\nAll list endpoints support pagination (`limit` 1-100, default 50; `offset`), search (free-text on name fields), and sorting.\n\n**Filtering** uses s-expression syntax via the `filter` query parameter:\n- Comparison: `eq(field,value)`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains(field,substring)`\n- Range/set: `between(field,lo,hi)`, `in(field,v1,v2,...)`\n- Logic: `and(expr1,expr2,...)`, `or(...)`, `not(expr)`\n- Null: `is_null(field)`, `is_not_null(field)`\n- JSONB: `at(field,key)` — e.g., `eq(at(metadata,score),42)`\n- Cast: `float()`, `int()`, `text()`, `timestamp()`, `date()`\n\n**Sorting** uses `asc(field)` or `desc(field)`, comma-separated (max 8):\n```\nsort=desc(created_at),asc(name)\n```\n\n**Example:** `filter=and(gte(created_at,2026-01-01),eq(status,done))`\n\n## Error Handling\n\nAll errors return:\n```json\n{\n  \"error\": \"Human-readable description\",\n  \"request_id\": \"req_019462a4-b1c2-7def-8901-23456789abcd\"\n}\n```\nThe `request_id` is also in the `x-request-id` response header — include it when contacting support.\n\n## Token Management\n\nTokens 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.\n\n## Detailed API Reference\n\nFor the full list of all 32 endpoints with request/response schemas, read `references/api-endpoints.md`.","author":"@K-Dense-AI","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/K-Dense-AI/scientific-agent-skills/tree/main/skills/adaptyv","license":"MIT","category":"writing","lang":"en","tokens":2258,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/api-endpoints.md","size":20101,"sha256":"d731e8a88c7227d1e30ac06d0fe8f44fbf21381d78fff9b33413cc47db8e8c28"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["docs.adaptyvbio.com","foundry-api-public.adaptyvbio.com","foundry.adaptyvbio.com","my-server.com"]}}