{"auth":{"api_key":{"example":"X-API-Key: m27_your_key_here","header":"X-API-Key","how_to_get":"POST /api/v1/api-keys (needs JWT first), or generate at platform.marc27.com/dashboard/api-keys"},"description":"Two methods. API key for agents (simplest, never expires). JWT for browser sessions.","jwt":{"header":"Authorization: Bearer <token>","how_to_get":"POST /api/v1/auth/token (with Supabase JWT), or device flow via POST /api/v1/auth/device/start"}},"cli":{"auth":"export MARC27_API_KEY=m27_your_key","description":"PRISM CLI — fastest way for agents to interact.","install":"pip install prism-platform","quick_start":["prism query --platform --semantic 'your question' --json","prism query --platform 'Inconel 718' | grep MAT","prism agent  # prints full command guide"]},"description":"Infrastructure for materials science — knowledge graph, LLM, compute, and collaboration.","error_handling":{"description":"All endpoints return structured errors. Smart 404s suggest correct endpoints.","format":{"error":{"code":"string","message":"string"},"suggestions":[{"description":"...","method":"GET","path":"/api/v1/..."}]},"hint":"If you get a 404, read the suggestions array — it tells you the correct endpoint."},"graphql":{"description":"GraphQL — query multiple services in one request. Preferred over REST for complex queries.","endpoint":"POST /api/v1/graphql","mutations":{"cancelComputeJob":"mutation { cancelComputeJob(id: \"...\") }","submitComputeJob":"mutation { submitComputeJob(input: { image: \"marc27/lammps\", inputs: \"{}\", gpuType: \"A100-80GB\" }) { id status } }","submitIngestJob":"mutation { submitIngestJob(input: { corpusId: \"...\", sourceUrl: \"...\" }) { id status } }"},"queries":{"agentRun":"{ agentRun(id: \"...\") { state answer error } }","agentRuns":"{ agentRuns(limit: 10) { id question state createdAt } }","billingBalance":"{ billingBalance { credits dollarValue orgName } }","computeGpus":"{ computeGpus { gpuType provider pricePerHourUsd vramGb } }","corpora":"{ corpora { name slug kind entryCount } }","deployments":"{ deployments(status: \"running\", limit: 5) { id name status target gpuType costUsd endpointUrl } }","discourseSpecs":"{ discourseSpecs(limit: 5) { id slug name version } }","embeddingStats":"{ embeddingStats { count } }","entity":"{ entity(name: \"Titanium\") { name entityType props neighbors(limit: 5) { target { name entityType } relType count } } }","graphStats":"{ graphStats { nodes edges entityTypes } }","llmModels":"{ llmModels(provider: \"anthropic\", limit: 5) { modelId displayName inputPrice outputPrice contextWindow } }","marketplace":"{ marketplace(limit: 5) { name slug resourceType } }","me":"{ me { id displayName avatarUrl } }","nodes":"{ nodes(limit: 5) { id name status visibility lastSeen pricePerHour } }","paths":"{ paths(from: \"Nickel\", to: \"Creep Resistance\", maxHops: 3) }","provenance":"{ provenance(entityType: \"CHM\", entityId: \"Nickel\") }","recall":"{ recall(query: \"creep resistance\", limit: 3) { chunks { docId content similarity } facts } }","resource":"{ resource(slug: \"...\") { name description contentMarkdown citations stars author } }","search":"{ search(term: \"nickel\", limit: 5) { name entityType label props } }","semanticSearch":"{ semanticSearch(query: \"thermal protection ablative\", limit: 3) { docId content similarity } }"}},"platform":"MARC27","services":{"account":{"endpoint_count":6,"endpoints":[{"description":"Is cloud storage of your PRISM account data on, and since when","method":"GET","path":"/api/v1/account/storage/opt-in"},{"description":"Turn cloud storage of your PRISM account data on or off (default off; turning it off does not delete what is already stored)","example_body":"{\"enabled\":true}","method":"POST","path":"/api/v1/account/storage/opt-in"},{"description":"Upload one file of your PRISM account data (body = raw bytes, ?path=ontology/store.db)","method":"PUT","path":"/api/v1/account/storage/object"},{"description":"Download one file of your PRISM account data (?path=ontology/store.db)","method":"GET","path":"/api/v1/account/storage/object"},{"description":"List your stored PRISM account data (?path= narrows to a sub-path)","method":"GET","path":"/api/v1/account/storage/list"},{"description":"Delete one file of your PRISM account data","example_body":"{\"path\":\"ontology/store.db\"}","method":"POST","path":"/api/v1/account/storage/delete"}]},"agent":{"endpoint_count":1,"endpoints":[{"description":"Full endpoint and capability map","method":"GET","path":"/api/v1/agent/capabilities"}]},"agents":{"endpoint_count":6,"endpoints":[{"description":"Start a research agent run; returns immediately with a run id","example_body":"{\"question\":\"How does rhenium affect creep in nickel superalloys?\"}","method":"POST","path":"/api/v1/agents"},{"description":"List your agent runs, newest first","method":"GET","path":"/api/v1/agents"},{"description":"Get a run's state and, once finished, its answer","method":"GET","path":"/api/v1/agents/{id}"},{"description":"Stream run events as SSE; resume with ?after_seq=N","method":"GET","path":"/api/v1/agents/{id}/events"},{"description":"Stream the same run events over a WebSocket","method":"GET","path":"/api/v1/agents/{id}/ws"},{"description":"Cancel a running agent run","method":"POST","path":"/api/v1/agents/{id}/cancel"}]},"api-keys":{"endpoint_count":3,"endpoints":[{"description":"List API keys","method":"GET","path":"/api/v1/api-keys"},{"description":"Create an API key","example_body":"{\"project_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"scopes\":[\"read\",\"write\"]}","method":"POST","path":"/api/v1/api-keys"},{"description":"Delete an API key","method":"DELETE","path":"/api/v1/api-keys/{id}"}]},"auth":{"endpoint_count":7,"endpoints":[{"description":"Exchange Supabase JWT for platform JWT","example_body":"{\"supabase_token\":\"...\"}","method":"POST","path":"/api/v1/auth/token"},{"description":"Refresh platform token","example_body":"{\"refresh_token\":\"m27r_...\"}","method":"POST","path":"/api/v1/auth/refresh"},{"description":"Revoke a refresh token","example_body":"{\"refresh_token\":\"m27r_...\"}","method":"POST","path":"/api/v1/auth/logout"},{"description":"Start device flow login","example_body":"{\"client_id\":\"prism\"}","method":"POST","path":"/api/v1/auth/device/start"},{"description":"Poll device flow authorization status","example_body":"{\"device_code\":\"...\"}","method":"POST","path":"/api/v1/auth/device/poll"},{"description":"Approve a device flow code","example_body":"{\"user_code\":\"ABCD-EFGH\",\"supabase_token\":\"eyJhbGciOi...\"}","method":"POST","path":"/api/v1/auth/device/approve"},{"description":"Deny a device flow code","example_body":"{\"user_code\":\"ABCD-EFGH\",\"supabase_token\":\"eyJhbGciOi...\"}","method":"POST","path":"/api/v1/auth/device/deny"}]},"billing":{"endpoint_count":9,"endpoints":[{"description":"Get the balance of the org billed for a project (omit project_id for the legacy fallback)","method":"GET","path":"/api/v1/billing/balance?project_id={project_id}"},{"description":"Usage breakdown by service/model","method":"GET","path":"/api/v1/billing/usage?period=monthly"},{"description":"Paginated transaction ledger","method":"GET","path":"/api/v1/billing/history?page=1&per_page=50"},{"description":"Current credit pricing table (public)","method":"GET","path":"/api/v1/billing/prices"},{"description":"Available credit packages for purchase","method":"GET","path":"/api/v1/billing/packages"},{"description":"Create checkout for the org that owns a project","example_body":"{\"package\":\"starter\",\"project_id\":\"00000000-0000-0000-0000-000000000000\"}","method":"POST","path":"/api/v1/billing/topup"},{"description":"Your org's monthly spend caps and spend to date","method":"GET","path":"/api/v1/billing/allowances"},{"description":"Set a per-org monthly spend cap (org admin)","example_body":"{\"org_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"category\":\"compute\",\"monthly_credits\":50000}","method":"PUT","path":"/api/v1/billing/allowances"},{"description":"Start checkout for the hosted-node subscription","method":"POST","path":"/api/v1/billing/subscribe"}]},"chat":{"endpoint_count":1,"endpoints":[{"description":"Chat grounded in the knowledge corpus","example_body":"{\"message\":\"Which superalloys resist creep above 1000 C?\"}","method":"POST","path":"/api/v1/chat"}]},"compute":{"endpoint_count":14,"endpoints":[{"description":"List available GPUs + pricing","method":"GET","path":"/api/v1/compute/gpus"},{"description":"List compute providers","method":"GET","path":"/api/v1/compute/providers"},{"description":"Submit a compute job","example_body":"{\"image\":\"my-model\",\"gpu_type\":\"A100-80GB\",\"inputs\":{}}","method":"POST","path":"/api/v1/compute/submit"},{"description":"Estimate job cost","example_body":"{\"image\":\"my-model\",\"gpu_type\":\"A100-80GB\",\"inputs\":{}}","method":"POST","path":"/api/v1/compute/estimate"},{"description":"Get job status","method":"GET","path":"/api/v1/compute/{job_id}"},{"description":"Get job logs","method":"GET","path":"/api/v1/compute/{job_id}/logs"},{"description":"Cancel a job","method":"POST","path":"/api/v1/compute/{job_id}/cancel"},{"description":"List model deployments","method":"GET","path":"/api/v1/compute/deployments"},{"description":"Create a model deployment","example_body":"{\"name\":\"my-model\",\"image\":\"repo/image:tag\",\"target\":\"prism_node\"}","method":"POST","path":"/api/v1/compute/deployments"},{"description":"Get model deployment details","method":"GET","path":"/api/v1/compute/deployments/{id}"},{"description":"Stop a model deployment","method":"DELETE","path":"/api/v1/compute/deployments/{id}"},{"description":"Run a deployment health check","method":"GET","path":"/api/v1/compute/deployments/{id}/health"},{"description":"Forward an inference request to the deployment (any method)","method":"ANY","path":"/api/v1/compute/deployments/{id}/invoke"},{"description":"Sub-path passthrough, e.g. .../invoke/v1/chat/completions","method":"ANY","path":"/api/v1/compute/deployments/{id}/invoke/{*path}"}]},"conversations":{"endpoint_count":5,"endpoints":[{"description":"Get a conversation","method":"GET","path":"/api/v1/conversations/{id}"},{"description":"Update a conversation's title or metrics","example_body":"{\"title\":\"Alloy screening v2\"}","method":"PATCH","path":"/api/v1/conversations/{id}"},{"description":"Delete a conversation","method":"DELETE","path":"/api/v1/conversations/{id}"},{"description":"Append messages to a conversation","example_body":"{\"messages\":[{\"id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"ordinal\":0,\"role\":\"user\",\"content\":\"...\"}]}","method":"POST","path":"/api/v1/conversations/{id}/messages"},{"description":"List a conversation's messages","method":"GET","path":"/api/v1/conversations/{id}/messages"}]},"data":{"endpoint_count":1,"endpoints":[{"description":"Query Materials Project through platform credentials","example_body":"{\"formula\":\"Ni3Al\",\"properties\":[\"formation_energy_per_atom\"]}","method":"POST","path":"/api/v1/data/materials-project"}]},"discourse":{"endpoint_count":6,"endpoints":[{"description":"List discourse specs","method":"GET","path":"/api/v1/discourse/specs"},{"description":"Create a discourse spec","example_body":"{\"slug\":\"my-discourse\",\"yaml\":\"...\"}","method":"POST","path":"/api/v1/discourse/specs"},{"description":"Get discourse spec","method":"GET","path":"/api/v1/discourse/specs/{id}"},{"description":"Run a discourse instance","example_body":"{\"inputs\":{}}","method":"POST","path":"/api/v1/discourse/run/{spec_id}"},{"description":"Get discourse instance","method":"GET","path":"/api/v1/discourse/{instance_id}"},{"description":"List discourse turns","method":"GET","path":"/api/v1/discourse/{instance_id}/turns"}]},"events":{"endpoint_count":1,"endpoints":[{"description":"Server-Sent Events tail of the platform event stream","method":"GET","path":"/api/v1/events/subscribe"}]},"federation":{"endpoint_count":1,"endpoints":[{"description":"The platform's Ed25519 public key, readable without a credential","method":"GET","path":"/api/v1/federation/platform-pubkey"}]},"graphql":{"endpoint_count":2,"endpoints":[{"description":"GraphQL query","example_body":"{\"query\":\"{ graphStats { nodes edges } }\"}","method":"POST","path":"/api/v1/graphql"},{"description":"GraphQL endpoint guide","method":"GET","path":"/api/v1/graphql"}]},"health":{"endpoint_count":3,"endpoints":[{"description":"Liveness check","method":"GET","path":"/health"},{"description":"Readiness check","method":"GET","path":"/health/ready"},{"description":"Prometheus-style metrics","method":"GET","path":"/health/metrics"}]},"install":{"endpoint_count":1,"endpoints":[{"description":"What a fresh install can do, read anonymously","method":"GET","path":"/api/v1/install/manifest"}]},"invites":{"endpoint_count":1,"endpoints":[{"description":"Accept an invite token","example_body":"{\"token\":\"...\"}","method":"POST","path":"/api/v1/invites/accept"}]},"jobs":{"endpoint_count":4,"endpoints":[{"description":"Submit a queue-backed platform job","example_body":"{\"job_type\":\"simulation\",\"project_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"payload\":{}}","method":"POST","path":"/api/v1/jobs"},{"description":"Get platform job details","method":"GET","path":"/api/v1/jobs/{id}"},{"description":"Cancel a platform job","method":"POST","path":"/api/v1/jobs/{id}/cancel"},{"description":"Stream platform job events","method":"GET","path":"/api/v1/jobs/{id}/events"}]},"knowledge":{"endpoint_count":24,"endpoints":[{"description":"Graph node/edge counts","method":"GET","path":"/api/v1/knowledge/graph/stats"},{"description":"Fulltext entity search","method":"GET","path":"/api/v1/knowledge/graph/search?q=titanium&limit=5"},{"description":"Entity + neighbors","method":"GET","path":"/api/v1/knowledge/graph/entity/{entity_name}"},{"description":"Find paths between graph entities","method":"GET","path":"/api/v1/knowledge/graph/paths"},{"description":"Seed graph data","example_body":"{\"source_url\":\"...\"}","method":"POST","path":"/api/v1/knowledge/graph/seed"},{"description":"Ingest graph entities and relationships","example_body":"{\"entities\":[],\"relationships\":[]}","method":"POST","path":"/api/v1/knowledge/graph/ingest"},{"description":"Admin: drop + re-create vector indexes at the configured dimension","method":"POST","path":"/api/v1/knowledge/admin/reconcile-vector-schema"},{"description":"Admin: backfill assertion embeddings","method":"POST","path":"/api/v1/knowledge/admin/embed-graph"},{"description":"Semantic vector search","example_body":"{\"query\":\"creep resistant superalloy\",\"limit\":5}","method":"POST","path":"/api/v1/knowledge/search"},{"description":"Embed text into vector store","example_body":"{\"doc_id\":\"my-doc\",\"content\":\"...\"}","method":"POST","path":"/api/v1/knowledge/embed"},{"description":"Bulk embed documents into vector store","example_body":"{\"documents\":[]}","method":"POST","path":"/api/v1/knowledge/embed/bulk"},{"description":"Embedding store statistics","method":"GET","path":"/api/v1/knowledge/embeddings/stats"},{"description":"List all corpora","method":"GET","path":"/api/v1/knowledge/catalog"},{"description":"Get corpus details","method":"GET","path":"/api/v1/knowledge/catalog/{slug}"},{"description":"Submit an ingest job","example_body":"{\"corpus_id\":\"...\",\"source_url\":\"...\"}","method":"POST","path":"/api/v1/knowledge/ingest-job"},{"description":"Get ingest job status","method":"GET","path":"/api/v1/knowledge/ingest-job/{job_id}"},{"description":"List ingest jobs","method":"GET","path":"/api/v1/knowledge/ingest-jobs"},{"description":"RLM research query (SSE stream)","example_body":"{\"question\":\"...\",\"depth\":1}","method":"POST","path":"/api/v1/knowledge/research/query"},{"description":"Run a web-backed research search","example_body":"{\"query\":\"...\"}","method":"POST","path":"/api/v1/knowledge/research/web-search"},{"description":"Knowledge service tool list","method":"GET","path":"/api/v1/knowledge/capabilities"},{"description":"Recall the passages and facts relevant to a question","method":"POST","path":"/api/v1/knowledge/recall"},{"description":"Ingest a document end to end, streaming progress","method":"POST","path":"/api/v1/knowledge/ingest/holistic/stream"},{"description":"Upload a document for end-to-end ingestion","method":"POST","path":"/api/v1/knowledge/ingest/holistic/upload"},{"description":"Web search for research (alias of /research/web-search)","method":"POST","path":"/api/v1/knowledge/research/search-web"}]},"marketplace":{"endpoint_count":20,"endpoints":[{"description":"List marketplace resources","method":"GET","path":"/api/v1/marketplace?status=approved"},{"description":"Same as above (alias)","method":"GET","path":"/api/v1/marketplace/resources"},{"description":"Search resources","method":"GET","path":"/api/v1/marketplace/search?q=titanium"},{"description":"Publish a resource","example_body":"{\"resource_type\":\"model\",\"name\":\"...\",\"slug\":\"...\"}","method":"POST","path":"/api/v1/marketplace"},{"description":"Get marketplace resource","method":"GET","path":"/api/v1/marketplace/{slug}"},{"description":"Update marketplace resource","example_body":"{\"description\":\"Updated description\"}","method":"PATCH","path":"/api/v1/marketplace/{slug}"},{"description":"Delete marketplace resource","method":"DELETE","path":"/api/v1/marketplace/{slug}"},{"description":"Submit marketplace resource for review","method":"POST","path":"/api/v1/marketplace/{slug}/submit"},{"description":"Upload and validate raw YAML for a draft ontology package","example_body":"ontology_id: my-ontology\\nversion: 1.0.0\\nclasses: []","method":"POST","path":"/api/v1/marketplace/{slug}/ontology"},{"description":"Purchase an approved ontology package and select it for a project","example_body":"{\"project_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}","method":"POST","path":"/api/v1/marketplace/{slug}/purchase"},{"description":"List marketplace resource versions","method":"GET","path":"/api/v1/marketplace/{slug}/versions"},{"description":"Create marketplace resource version","example_body":"{\"version\":\"1.0.0\"}","method":"POST","path":"/api/v1/marketplace/{slug}/versions"},{"description":"Record marketplace resource download","method":"POST","path":"/api/v1/marketplace/{slug}/download"},{"description":"Grant project access to a resource","example_body":"{\"project_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"resource_id\":\"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}","method":"POST","path":"/api/v1/marketplace/grants"},{"description":"Revoke project access to a resource","method":"DELETE","path":"/api/v1/marketplace/grants/{project_id}/{resource_id}"},{"description":"Resolve one entitled, coverage-validated licensed source (CALPHAD TDB, property dataset, instrument data) for the caller's project; refuses with the named gap instead of substituting","example_body":"{\"source_type\":\"thermodynamic_database\",\"required_coverage\":{\"elements\":[\"Mo\",\"Nb\"],\"systems\":[[\"Mo\",\"Nb\"]],\"property_domains\":[]}}","method":"POST","path":"/api/v1/marketplace/licensed-sources/resolve"},{"description":"Get a marketplace resource (alias)","method":"GET","path":"/api/v1/marketplace/resources/{slug}"},{"description":"Time-limited download URL for a resource artifact (alias)","method":"GET","path":"/api/v1/marketplace/resources/{slug}/install"},{"description":"Time-limited download URL for a resource artifact","method":"GET","path":"/api/v1/marketplace/{slug}/install"},{"description":"Semantic search over published resources","example_body":"{\"query\":\"creep-resistant superalloy dataset\",\"types\":[],\"limit\":5}","method":"POST","path":"/api/v1/marketplace/find"}]},"mird":{"endpoint_count":1,"endpoints":[{"description":"Conductor: pick and orchestrate models for a task","method":"POST","path":"/api/v1/mird"}]},"nodes":{"endpoint_count":11,"endpoints":[{"description":"List registered nodes","method":"GET","path":"/api/v1/nodes"},{"description":"List currently connected nodes","method":"GET","path":"/api/v1/nodes/live"},{"description":"Connect compute node WebSocket","method":"GET","path":"/api/v1/nodes/connect"},{"description":"Register a node (REST)","example_body":"{\"name\":\"my-node\",\"capabilities\":{}}","method":"POST","path":"/api/v1/nodes/register"},{"description":"Get node details","method":"GET","path":"/api/v1/nodes/{node_id}"},{"description":"Deregister a node","method":"DELETE","path":"/api/v1/nodes/{id}"},{"description":"Node heartbeat","method":"POST","path":"/api/v1/nodes/{node_id}/heartbeat"},{"description":"Get node E2EE public key","method":"GET","path":"/api/v1/nodes/{node_id}/public-key"},{"description":"E2EE key exchange","example_body":"{\"public_key\":\"base64...\"}","method":"POST","path":"/api/v1/nodes/{node_id}/exchange-key"},{"description":"Bring a compute node into a project in one call","example_body":"{\"name\":\"lab-a100\",\"target\":\"own-hardware\"}","method":"POST","path":"/api/v1/nodes/spin-up"},{"description":"Invoke a tool hosted on a remote node","example_body":"{\"args\":{}}","method":"POST","path":"/api/v1/nodes/{node_id}/tools/{tool}/invoke"}]},"orgs":{"endpoint_count":9,"endpoints":[{"description":"List organizations","method":"GET","path":"/api/v1/orgs"},{"description":"Create an organization","example_body":"{\"name\":\"My Lab\",\"slug\":\"my-lab\"}","method":"POST","path":"/api/v1/orgs"},{"description":"Get organization details","method":"GET","path":"/api/v1/orgs/{id}"},{"description":"Update an organization","example_body":"{\"name\":\"New Lab Name\"}","method":"PATCH","path":"/api/v1/orgs/{id}"},{"description":"Delete an organization","method":"DELETE","path":"/api/v1/orgs/{id}"},{"description":"List organization members","method":"GET","path":"/api/v1/orgs/{id}/members"},{"description":"Add an organization member","example_body":"{\"user_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"role\":\"member\"}","method":"POST","path":"/api/v1/orgs/{id}/members"},{"description":"Update an organization member role","example_body":"{\"role\":\"admin\"}","method":"PATCH","path":"/api/v1/orgs/{id}/members/{user_id}"},{"description":"Remove an organization member","method":"DELETE","path":"/api/v1/orgs/{id}/members/{user_id}"}]},"policy":{"endpoint_count":1,"endpoints":[{"description":"Check if an action is allowed (RBAC + data classification). The classification is read from the resource's provenance, not from this body; without a resolvable resource_id the request is refused.","example_body":"{\"action\":\"read_data\",\"resource\":{\"resource_type\":\"corpus\",\"resource_id\":\"ntrs:19650021522\"}}","method":"POST","path":"/api/v1/policy/evaluate"}]},"projects":{"endpoint_count":34,"endpoints":[{"description":"List all user's projects","method":"GET","path":"/api/v1/projects"},{"description":"Create a project","example_body":"{\"name\":\"My Project\",\"slug\":\"my-project\",\"org_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}","method":"POST","path":"/api/v1/projects"},{"description":"Get project details","method":"GET","path":"/api/v1/projects/{id}"},{"description":"Update a project","example_body":"{\"name\":\"New Project Name\"}","method":"PATCH","path":"/api/v1/projects/{id}"},{"description":"Delete a project","method":"DELETE","path":"/api/v1/projects/{id}"},{"description":"List jobs for a project","method":"GET","path":"/api/v1/projects/{id}/jobs"},{"description":"List project members","method":"GET","path":"/api/v1/projects/{project_id}/collab/members"},{"description":"Add a project member","example_body":"{\"user_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"role\":\"contributor\"}","method":"POST","path":"/api/v1/projects/{project_id}/collab/members"},{"description":"Update a project member role","example_body":"{\"role\":\"admin\"}","method":"PUT","path":"/api/v1/projects/{project_id}/collab/members/{user_id}"},{"description":"Remove a project member","method":"DELETE","path":"/api/v1/projects/{project_id}/collab/members/{user_id}"},{"description":"Create a project invite","example_body":"{\"email\":\"scientist@example.com\",\"role\":\"viewer\"}","method":"POST","path":"/api/v1/projects/{project_id}/collab/invite"},{"description":"List project invites","method":"GET","path":"/api/v1/projects/{project_id}/collab/invites"},{"description":"List project activity","method":"GET","path":"/api/v1/projects/{project_id}/collab/activity"},{"description":"Activate a corpus for a project","example_body":"{\"corpus_slug\":\"materials-project\"}","method":"POST","path":"/api/v1/projects/{project_id}/knowledge/activate"},{"description":"List project corpus activations","method":"GET","path":"/api/v1/projects/{project_id}/knowledge/activations"},{"description":"Deactivate a project corpus activation","method":"DELETE","path":"/api/v1/projects/{project_id}/knowledge/activations/{activation_id}"},{"description":"List LLM models","method":"GET","path":"/api/v1/projects/{project_id}/llm/models"},{"description":"LLM completion (SSE stream)","example_body":"{\"model\":\"claude-sonnet-4\",\"messages\":[{\"role\":\"user\",\"content\":\"...\"}]}","method":"POST","path":"/api/v1/projects/{project_id}/llm/stream"},{"description":"List LLM key hints for a project","method":"GET","path":"/api/v1/projects/{project_id}/llm-keys"},{"description":"Store an encrypted LLM API key","example_body":"{\"provider\":\"openai\",\"key\":\"sk-...\"}","method":"POST","path":"/api/v1/projects/{project_id}/llm-keys"},{"description":"Delete an LLM API key","method":"DELETE","path":"/api/v1/projects/{project_id}/llm-keys/{provider}"},{"description":"Rotate an encrypted LLM API key","example_body":"{\"key\":\"sk-...\"}","method":"POST","path":"/api/v1/projects/{project_id}/llm-keys/{provider}/rotate"},{"description":"List MCP service instances","method":"GET","path":"/api/v1/projects/{project_id}/mcp-services"},{"description":"Get MCP service instance details","method":"GET","path":"/api/v1/projects/{project_id}/mcp-services/{instance_id}"},{"description":"Proxy a request to an MCP service","example_body":"{\"path\":\"/tools/list\",\"body\":{}}","method":"POST","path":"/api/v1/projects/{project_id}/mcp-services/{instance_id}/proxy"},{"description":"Scale an MCP service instance","example_body":"{\"replicas\":1}","method":"POST","path":"/api/v1/projects/{project_id}/mcp-services/{instance_id}/scale"},{"description":"Create a conversation in a project","example_body":"{\"id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"title\":\"Alloy screening\",\"metrics_json\":{}}","method":"POST","path":"/api/v1/projects/{project_id}/conversations"},{"description":"List a project's conversations","method":"GET","path":"/api/v1/projects/{project_id}/conversations"},{"description":"Set the project's model auto-routing posture","example_body":"{\"enabled\":true}","method":"PUT","path":"/api/v1/projects/{id}/auto-route"},{"description":"List the project's data-class labels","method":"GET","path":"/api/v1/projects/{project_id}/data-access/classes"},{"description":"List data-class grants (project admin)","method":"GET","path":"/api/v1/projects/{project_id}/data-access/grants"},{"description":"Grant a subject access to a data class (project admin)","example_body":"{\"subject_type\":\"user\",\"subject_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"data_class\":\"restricted\",\"access\":\"read\"}","method":"POST","path":"/api/v1/projects/{project_id}/data-access/grants"},{"description":"Revoke a subject's data-class grant (project admin)","example_body":"{\"subject_type\":\"user\",\"subject_id\":\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\"data_class\":\"restricted\"}","method":"DELETE","path":"/api/v1/projects/{project_id}/data-access/grants"},{"description":"Your effective data access in this project","method":"GET","path":"/api/v1/projects/{project_id}/data-access/me"}]},"research":{"endpoint_count":1,"endpoints":[{"description":"Run research synchronously and return one answer document","example_body":"{\"question\":\"Which superalloys resist creep above 1000 C?\"}","method":"POST","path":"/api/v1/research"}]},"root":{"endpoint_count":1,"endpoints":[{"description":"API documentation (this page)","method":"GET","path":"/"}]},"support":{"endpoint_count":4,"endpoints":[{"description":"List support tickets","method":"GET","path":"/api/v1/support/tickets"},{"description":"Create a ticket","example_body":"{\"description\":\"...\",\"type\":\"bug_report\"}","method":"POST","path":"/api/v1/support/tickets"},{"description":"Get support ticket","method":"GET","path":"/api/v1/support/tickets/{ticket_id}"},{"description":"Update support ticket","example_body":"{\"status\":\"resolved\"}","method":"PATCH","path":"/api/v1/support/tickets/{ticket_id}"}]},"usage":{"endpoint_count":5,"endpoints":[{"description":"Get usage metrics","method":"GET","path":"/api/v1/usage/user"},{"description":"Get current usage metrics","method":"GET","path":"/api/v1/usage/me"},{"description":"Get project usage","method":"GET","path":"/api/v1/usage/projects/{project_id}"},{"description":"List project usage ledger entries","method":"GET","path":"/api/v1/usage/projects/{project_id}/entries"},{"description":"Total cost of a single run","method":"GET","path":"/api/v1/usage/runs/{run_id}"}]},"users":{"endpoint_count":2,"endpoints":[{"description":"Get current user profile","method":"GET","path":"/api/v1/users/me"},{"description":"Update profile","example_body":"{\"display_name\":\"Dr. Smith\",\"orcid_id\":\"0000-0001\"}","method":"PATCH","path":"/api/v1/users/me"}]},"workflows":{"endpoint_count":6,"endpoints":[{"description":"List workflow instances","method":"GET","path":"/api/v1/workflows"},{"description":"Start a workflow","example_body":"{\"spec\":\"my-workflow\",\"inputs\":{}}","method":"POST","path":"/api/v1/workflows"},{"description":"List workflow specs","method":"GET","path":"/api/v1/workflows/specs"},{"description":"Register a workflow spec","example_body":"{\"spec_yaml\":\"...\",\"access\":\"public\"}","method":"POST","path":"/api/v1/workflows/specs"},{"description":"Get workflow instance","method":"GET","path":"/api/v1/workflows/{id}"},{"description":"Cancel workflow instance","method":"POST","path":"/api/v1/workflows/{id}/cancel"}]}},"total_endpoints":191,"version":"0.1.0"}