{"openapi":"3.1.0","info":{"title":"Phi — Protein Design API","description":"Phi is a biomodal computation platform for protein design. Submit structure-prediction and sequence-design jobs, track their status, and retrieve scored results — all via a single REST API.\n\n## Authentication\nAll endpoints require an API key supplied as `Authorization: Bearer <key>` or a Clerk session token. Organisation ID is derived automatically from Clerk tokens; static-key callers must include `X-Organization-ID`.\n\n## Quick links\n- `POST /v1/phi/jobs` — submit a job\n- `GET  /v1/phi/jobs/{job_id}/status` — poll status\n- `GET  /v1/phi/jobs/{job_id}/scores` — download scored results\n","version":"1.0.0"},"servers":[{"url":"https://api.dyno-agents.app","description":"Production"},{"url":"http://localhost:8000","description":"Local development"}],"paths":{"/v1/phi/auth/me":{"get":{"tags":["auth"],"summary":"Get Current User Profile","description":"Return the Clerk-verified user profile and primary org ID.\n\n``org_id`` is sourced in priority order:\n  1. Directly from the verified token claims (``org_id`` claim in session JWTs\n     and ``ak_…`` keys scoped to an org).  This is the common path now that\n     Clerk \"Membership required\" is enabled.\n  2. Fetched from the Clerk membership API when the token has no ``org_id``\n     claim (older sessions / tokens issued without an active org context).\n  3. Returns a 422 if no org can be determined for a Clerk-authed caller, so\n     the client receives a clear error instead of a silent \"default-org\" that\n     would be rejected downstream.\n\nStatic API-key callers receive a stub profile; ``org_id`` comes from the\n``X-Organization-ID`` header or falls back to ``\"default-org\"``.","operationId":"get_current_user_profile_v1_phi_auth_me_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/auth/me/quota":{"get":{"tags":["auth"],"summary":"Get My Quota","description":"Return the authenticated user's quota limits and current usage.\n\nAvailable to any user with a valid Clerk JWT or ``ak_`` key — no admin\nprivilege required.  Use this to drive quota banners and progress bars in\nthe frontend.","operationId":"get_my_quota_v1_phi_auth_me_quota_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserQuotaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/files/upload-url":{"post":{"tags":["files"],"summary":"Create Upload Url","description":"Generate a short-lived signed GCS URL so the browser or CLI can PUT a file\ndirectly to cloud storage without routing through the API server.\n\nClient workflow:\n  1. POST /v1/phi/files/upload-url → receive upload_url + gcs_uri\n  2. PUT upload_url with raw file bytes (no auth header needed)\n  3. Pass gcs_uri as params.fasta_gcs_uri or params.pdb_gcs_uri in job submission","operationId":"create_upload_url_v1_phi_files_upload_url_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadUrlRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/files/upload":{"post":{"tags":["files"],"summary":"Upload File Direct","description":"Upload a file directly through the API server (proxy to GCS).\n\nUse this instead of ``POST /upload-url`` when a direct client→GCS PUT is\nblocked by VPC Service Controls or firewall rules.\n\nClient workflow:\n  1. POST /v1/phi/files/upload (multipart/form-data, field ``file``)\n  2. Pass the returned ``gcs_uri`` as ``params.fasta_gcs_uri`` or\n     ``params.pdb_gcs_uri`` in job submission — identical to the signed-URL flow.","operationId":"upload_file_direct_v1_phi_files_upload_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_file_direct_v1_phi_files_upload_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/ingest_sessions/":{"post":{"tags":["ingest"],"summary":"Create Ingest Session","description":"Create a new ingest session for a batch of files.\n\nReturns a session ID and a GCS prefix where files should be uploaded\nusing the signed URLs returned by POST /ingest_sessions/{id}/upload_urls.","operationId":"create_ingest_session_v1_phi_ingest_sessions__post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/ingest_sessions/{session_id}/upload_urls":{"post":{"tags":["ingest"],"summary":"Get Upload Urls","description":"Return signed GCS PUT URLs for a batch of filenames (max 50 per request).\n\nThe client should PUT each file directly to its signed URL.\nMultiple calls are supported for large batches.","operationId":"get_upload_urls_v1_phi_ingest_sessions__session_id__upload_urls_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadUrlsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadUrlsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/ingest_sessions/{session_id}/upload/{filename}":{"post":{"tags":["ingest"],"summary":"Upload File To Session","description":"Upload a single file to an ingest session through the API server (proxy to GCS).\n\nUse this instead of ``POST /upload_urls`` + client-side PUT when a direct\nclient→GCS PUT is blocked by VPC Service Controls or firewall rules.\n\nClient workflow:\n  1. POST /v1/phi/ingest_sessions/ → session_id\n  2. POST /v1/phi/ingest_sessions/{id}/upload/{filename} for each file\n  3. POST /v1/phi/ingest_sessions/{id}/finalize\n  4. Poll GET /v1/phi/ingest_sessions/{id} until status == READY","operationId":"upload_file_to_session_v1_phi_ingest_sessions__session_id__upload__filename__post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_file_to_session_v1_phi_ingest_sessions__session_id__upload__filename__post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectFileUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/ingest_sessions/{session_id}/finalize":{"post":{"tags":["ingest"],"summary":"Finalize Ingest Session","description":"Trigger the asynchronous ingest pipeline for a completed upload session.\n\nThe pipeline will:\n  1. List all objects under the session's GCS prefix\n  2. Compute checksums and deduplicate\n  3. Create a Dataset record and link DatasetFile rows\n  4. Update the session status to READY\n\nPoll GET /ingest_sessions/{id} to track progress.","operationId":"finalize_ingest_session_v1_phi_ingest_sessions__session_id__finalize_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Finalize Ingest Session V1 Phi Ingest Sessions  Session Id  Finalize Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/ingest_sessions/{session_id}":{"get":{"tags":["ingest"],"summary":"Get Ingest Session","description":"Poll ingest session status.","operationId":"get_ingest_session_v1_phi_ingest_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestSessionStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/datasets/":{"get":{"tags":["datasets"],"summary":"List Datasets","description":"List datasets owned by the current organization.","operationId":"list_datasets_v1_phi_datasets__get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Page Size"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/datasets/{dataset_id}":{"get":{"tags":["datasets"],"summary":"Get Dataset","description":"Return dataset metadata and a sample of its file artifacts.","operationId":"get_dataset_v1_phi_datasets__dataset_id__get","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["datasets"],"summary":"Update Dataset","description":"Rename a dataset. Returns the full updated dataset object.","operationId":"update_dataset_v1_phi_datasets__dataset_id__patch","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchDatasetRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/datasets/{dataset_id}/jobs":{"get":{"tags":["datasets"],"summary":"List Dataset Jobs","description":"List all jobs that were run against this dataset, newest first.","operationId":"list_dataset_jobs_v1_phi_datasets__dataset_id__jobs_get","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Page Size"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetJobsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/datasets/{dataset_id}/scores":{"get":{"tags":["datasets"],"summary":"Get Dataset Scores","description":"Return a signed download URL for the most recent scores.csv for this dataset.","operationId":"get_dataset_scores_v1_phi_datasets__dataset_id__scores_get","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Expires In"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetScoresResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/datasets/{dataset_id}/research-notes":{"post":{"tags":["research-notes"],"summary":"Append to dataset research notes","description":"Append markdown content to the dataset's cumulative research notes file in GCS.\n\nThe notes file lives at ``research/{dataset_id}/notes.md``. If it does not exist\nyet it is created. If it does, the new content is appended after a separator.","operationId":"append_research_notes_v1_phi_datasets__dataset_id__research_notes_post","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendNotesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchNotesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["research-notes"],"summary":"Get dataset research notes","description":"Retrieve the accumulated research notes for a dataset.\n\nReturns the full markdown content inline plus a signed GCS URL for direct\ndownload. Returns ``exists: false`` (with no content) if no notes have been\nsaved for this dataset yet.","operationId":"get_research_notes_v1_phi_datasets__dataset_id__research_notes_get","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"string","title":"Dataset Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchNotesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/plan/public":{"post":{"tags":["workflows"],"summary":"Plan Workflow Public","description":"Generate a workflow plan from a natural language prompt — no authentication required.\n\nIdentical to POST /plan but:\n- Requires no API key or session token\n- ``execute_immediately`` and ``auto_publish`` are always ignored (planning only)\n- The resulting spec is **not saved** to the database; no ``workflow_id`` is returned\n\nIntended for public demos, embedded widgets, and unauthenticated frontend previews.","operationId":"plan_workflow_public_v1_phi_workflows_plan_public_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanWorkflowRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Plan Workflow Public V1 Phi Workflows Plan Public Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/plan":{"post":{"tags":["workflows"],"summary":"Plan Workflow","description":"Generate workflow plan from natural language prompt.\n\nThis is the primary endpoint for AI-powered workflow planning.\nTakes a natural language description and generates a validated WorkflowSpec.\n\nArgs:\n    request: Planning request with prompt and options\n    org_id: Organization ID from header\n    user_id: User ID from header\n    openai_api_key: OpenAI API key from dependency\n\nReturns:\n    workflow_id: ID of created workflow\n    spec: Full WorkflowSpec JSON\n    status: draft or published\n    validation_errors: Any validation issues\n    run_id: If execute_immediately=true, the run ID\n\nRaises:\n    HTTPException: If planning fails or validation errors occur","operationId":"plan_workflow_v1_phi_workflows_plan_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Plan Workflow V1 Phi Workflows Plan Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/plan/execute":{"post":{"tags":["workflows"],"summary":"Plan And Execute With Protocol","description":"Plan and execute workflow from protocol with user adjustments (frontend contract).\n\nThis endpoint:\n1. Loads the selected protocol template\n2. Substitutes protocolAdjustments into template variables\n3. Uses agent to adapt template to user's specific query\n4. Executes the workflow if executeImmediately=true\n\nArgs:\n    request: PlanExecuteRequest with protocol ID and adjustments\n    org_id: Organization ID from header\n    user_id: User ID from header\n    openai_api_key: OpenAI API key from dependency\n\nReturns:\n    workflow_id: ID of created workflow\n    spec: Full WorkflowSpec JSON\n    status: published\n    run_id: The execution run ID (if executeImmediately=true)\n\nRaises:\n    HTTPException: If protocol not found or planning fails","operationId":"plan_and_execute_with_protocol_v1_phi_workflows_plan_execute_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanExecuteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Plan And Execute With Protocol V1 Phi Workflows Plan Execute Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/":{"post":{"tags":["workflows"],"summary":"Create Workflow","description":"Create new workflow from planner output.\n\nValidates and saves the workflow to database as a draft.\n\nBy default, returns existing workflow if identical spec already exists.\nSet force_new=true query parameter to create a copy anyway.\n\nArgs:\n    request: Workflow creation request\n    org_id: Organization ID (from header)\n    user_id: User ID (from header)\n    force_new: If true, always create new workflow even if duplicate exists\n\nReturns:\n    workflow_id: ID of workflow (new or existing)\n    is_new: Whether a new workflow was created\n    message: Description of what happened","operationId":"create_workflow_v1_phi_workflows__post","parameters":[{"name":"force_new","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force New"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Workflow V1 Phi Workflows  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["workflows"],"summary":"List Workflows","description":"List workflows for organization.\n\nArgs:\n    org_id: Organization ID from header\n    status: Optional status filter (draft/published/archived)\n    limit: Maximum workflows to return (default: 100)\n    offset: Pagination offset (default: 0)\n    include_runs: Include recent execution runs (default: False for list endpoint)\n    runs_limit: Maximum number of runs per workflow (default: 10, max: 50)\n    db: Database session\n\nReturns:\n    List of workflows with optional runs arrays","operationId":"list_workflows_v1_phi_workflows__get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"include_runs","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Runs"}},{"name":"runs_limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Runs Limit"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Workflows V1 Phi Workflows  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/{workflow_id}":{"get":{"tags":["workflows"],"summary":"Get Workflow","description":"Get workflow by ID.\n\nArgs:\n    workflow_id: Workflow ID\n    org_id: Organization ID from header\n    include_runs: Include recent execution runs (default: True)\n    runs_limit: Maximum number of runs to return (default: 10, max: 50)\n    db: Database session\n\nReturns:\n    Workflow details with optional runs array","operationId":"get_workflow_v1_phi_workflows__workflow_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"include_runs","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Runs"}},{"name":"runs_limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Runs Limit"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Workflow V1 Phi Workflows  Workflow Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["workflows"],"summary":"Update Workflow","description":"Update workflow (creates new version).","operationId":"update_workflow_v1_phi_workflows__workflow_id__put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Workflow V1 Phi Workflows  Workflow Id  Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/{workflow_id}/publish":{"post":{"tags":["workflows"],"summary":"Publish Workflow","description":"Publish workflow (make it executable).","operationId":"publish_workflow_v1_phi_workflows__workflow_id__publish_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Publish Workflow V1 Phi Workflows  Workflow Id  Publish Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/{workflow_id}/versions":{"get":{"tags":["workflows"],"summary":"Get Workflow Versions","description":"Get all versions of workflow.","operationId":"get_workflow_versions_v1_phi_workflows__workflow_id__versions_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Workflow Versions V1 Phi Workflows  Workflow Id  Versions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/{workflow_id}/execute":{"post":{"tags":["workflows"],"summary":"Execute Workflow","description":"Execute a published workflow.","operationId":"execute_workflow_v1_phi_workflows__workflow_id__execute_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Execute Workflow V1 Phi Workflows  Workflow Id  Execute Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/workflows/{workflow_id}/runs/{run_id}/status":{"get":{"tags":["workflows"],"summary":"Get Workflow Run Status","description":"Get real-time workflow execution status.\n\nQueries the running Temporal workflow for current state including\nnode-level progress, artifacts produced, and execution metrics.\n\nArgs:\n    workflow_id: Workflow ID\n    run_id: Temporal run ID\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    WorkflowStatusResponse with real-time state\n\nRaises:\n    HTTPException: If workflow not found or query fails","operationId":"get_workflow_run_status_v1_phi_workflows__workflow_id__runs__run_id__status_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Workflow Run Status V1 Phi Workflows  Workflow Id  Runs  Run Id  Status Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/agents/":{"post":{"tags":["agents"],"summary":"Create Agent","description":"Create new agent.","operationId":"create_agent_v1_phi_agents__post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAgentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Agent V1 Phi Agents  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["agents"],"summary":"List Agents","description":"List agents for organization.","operationId":"list_agents_v1_phi_agents__get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Agents V1 Phi Agents  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/agents/{agent_id}":{"get":{"tags":["agents"],"summary":"Get Agent","description":"Get agent by ID.","operationId":"get_agent_v1_phi_agents__agent_id__get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Agent V1 Phi Agents  Agent Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["agents"],"summary":"Update Agent","description":"Update agent configuration and/or tools.","operationId":"update_agent_v1_phi_agents__agent_id__put","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAgentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Agent V1 Phi Agents  Agent Id  Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/agents/{agent_id}/tools":{"post":{"tags":["agents"],"summary":"Update Agent Tools","description":"Update which tools are enabled for agent.","operationId":"update_agent_tools_v1_phi_agents__agent_id__tools_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Tool Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Agent Tools V1 Phi Agents  Agent Id  Tools Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/projects":{"post":{"tags":["assets"],"summary":"Create Project","description":"Create a new project.\n\nArgs:\n    request: Project creation request\n    auth: Verified auth context (org_id maps to team_id, user_id maps to owner_id)\n    db: Database session\n\nReturns:\n    Created project details","operationId":"create_project_v1_phi_projects_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Project V1 Phi Projects Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["assets"],"summary":"List Projects","description":"List projects for team.\n\nArgs:\n    auth: Verified auth context\n    status: Status filter (active/archived)\n    db: Database session\n\nReturns:\n    List of projects","operationId":"list_projects_v1_phi_projects_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"active","title":"Status"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Projects V1 Phi Projects Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/projects/{project_id}":{"get":{"tags":["assets"],"summary":"Get Project","description":"Get project details.\n\nArgs:\n    project_id: Project ID\n    auth: Verified auth context\n    db: Database session\n\nReturns:\n    Project details","operationId":"get_project_v1_phi_projects__project_id__get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Project V1 Phi Projects  Project Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/projects/{project_id}/asset-groups":{"get":{"tags":["assets"],"summary":"List Asset Groups","description":"List asset groups for a project.\n\nArgs:\n    project_id: Project ID\n    auth: Verified auth context\n    db: Database session\n\nReturns:\n    List of asset groups","operationId":"list_asset_groups_v1_phi_projects__project_id__asset_groups_get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Asset Groups V1 Phi Projects  Project Id  Asset Groups Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/asset-groups/{asset_group_id}/assets":{"get":{"tags":["assets"],"summary":"List Assets","description":"List assets in an asset group with optional filtering and sorting.\n\nArgs:\n    asset_group_id: Asset group ID\n    team_id: Team ID from header\n    asset_type: Optional filter by asset type (sequence, structure, etc.)\n    filter_key: Metadata key to filter on (e.g., \"plddt\", \"rmsd\", \"score\")\n    filter_op: Comparison operator (eq, ne, gt, gte, lt, lte, contains)\n    filter_value: Value to compare against\n    sort_by: Metadata key to sort by (e.g., \"plddt\", \"rmsd\")\n    sort_order: Sort order (\"asc\" or \"desc\", default \"asc\")\n    db: Database session\n\nReturns:\n    List of filtered/sorted assets\n\nExamples:\n    ?filter_key=plddt&filter_op=gte&filter_value=90  # pLDDT >= 90\n    ?filter_key=rmsd&filter_op=lt&filter_value=2.0   # RMSD < 2.0\n    ?sort_by=plddt&sort_order=desc                   # Sort by pLDDT descending","operationId":"list_assets_v1_phi_asset_groups__asset_group_id__assets_get","parameters":[{"name":"asset_group_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Group Id"}},{"name":"asset_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset Type"}},{"name":"filter_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filter Key"}},{"name":"filter_op","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filter Op"}},{"name":"filter_value","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filter Value"}},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort By"}},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","default":"asc","title":"Sort Order"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Assets V1 Phi Asset Groups  Asset Group Id  Assets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/assets/{asset_id}":{"get":{"tags":["assets"],"summary":"Get Asset","description":"Get asset details.\n\nArgs:\n    asset_id: Asset ID\n    auth: Verified auth context\n    db: Database session\n\nReturns:\n    Asset details","operationId":"get_asset_v1_phi_assets__asset_id__get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Asset V1 Phi Assets  Asset Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/runs/{run_id}/assets":{"get":{"tags":["assets"],"summary":"Get Run Assets","description":"Get asset group and assets for a specific run.\n\nArgs:\n    run_id: Run ID\n    auth: Verified auth context\n    db: Database session\n\nReturns:\n    Asset group with assets","operationId":"get_run_assets_v1_phi_runs__run_id__assets_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Run Assets V1 Phi Runs  Run Id  Assets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/tools/":{"get":{"tags":["tools"],"summary":"List Tools","description":"List all available system tools.","operationId":"list_tools_v1_phi_tools__get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Tools V1 Phi Tools  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/tools/{tool_id}":{"get":{"tags":["tools"],"summary":"Get Tool","description":"Get tool details including parameter schema.","operationId":"get_tool_v1_phi_tools__tool_id__get","parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Tool V1 Phi Tools  Tool Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/tools/categories/":{"get":{"tags":["tools"],"summary":"List Categories","description":"List all tool categories.","operationId":"list_categories_v1_phi_tools_categories__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Categories V1 Phi Tools Categories  Get"}}}}}}},"/v1/phi/protocols":{"get":{"tags":["protocols"],"summary":"List Protocols","description":"List protocols for organization.\n\nArgs:\n    org_id: Organization ID from header\n    visibility: Filter by visibility (private/team/org)\n    tags: Comma-separated tags to filter by\n    starred: Filter by starred status (true/false/null for all)\n    limit: Max results\n    offset: Pagination offset\n    db: Database session\n\nReturns:\n    List of protocols with reputation","operationId":"list_protocols_v1_phi_protocols_get","parameters":[{"name":"visibility","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility"}},{"name":"tags","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"}},{"name":"starred","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Starred"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Protocols V1 Phi Protocols Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["protocols"],"summary":"Create Protocol","description":"Create new protocol.\n\nArgs:\n    request: Protocol creation request\n    org_id: Organization ID from header\n    user_id: User ID from header\n    db: Database session\n\nReturns:\n    Created protocol","operationId":"create_protocol_v1_phi_protocols_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProtocolRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/protocols/{protocol_id}":{"get":{"tags":["protocols"],"summary":"Get Protocol","description":"Get protocol by ID.\n\nArgs:\n    protocol_id: Protocol ID\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Protocol details","operationId":"get_protocol_v1_phi_protocols__protocol_id__get","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["protocols"],"summary":"Update Protocol","description":"Update protocol metadata.\n\nArgs:\n    protocol_id: Protocol ID\n    request: Update request\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Updated protocol","operationId":"update_protocol_v1_phi_protocols__protocol_id__put","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProtocolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["protocols"],"summary":"Delete Protocol","description":"Delete a protocol.\n\nDeletes the protocol and cascades to:\n- ProtocolExecution records (CASCADE)\n- ProtocolReputation records (CASCADE)\n\nSets NULL on:\n- Workflow.source_workflow_id (SET NULL)\n- Protocol.parent_protocol_id (SET NULL)\n\nArgs:\n    protocol_id: Protocol ID\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Success response\n\nRaises:\n    HTTPException: If protocol not found or deletion fails","operationId":"delete_protocol_v1_phi_protocols__protocol_id__delete","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Protocol V1 Phi Protocols  Protocol Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/protocols/validate":{"post":{"tags":["protocols"],"summary":"Validate Protocol Template","description":"Validate a protocol template without persisting.\n\nReturns validation errors and warnings. Useful for UI to validate before submit.","operationId":"validate_protocol_template_v1_phi_protocols_validate_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateProtocolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Validate Protocol Template V1 Phi Protocols Validate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/protocols/{protocol_id}/fork":{"post":{"tags":["protocols"],"summary":"Fork Protocol","description":"Fork protocol to create variant.\n\nArgs:\n    protocol_id: Protocol to fork\n    request: Fork request\n    org_id: Organization ID from header\n    user_id: User ID from header\n    db: Database session\n\nReturns:\n    Forked protocol","operationId":"fork_protocol_v1_phi_protocols__protocol_id__fork_post","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForkProtocolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/protocols/{protocol_id}/executions":{"get":{"tags":["protocols"],"summary":"Get Protocol Executions","description":"Get execution history for protocol.\n\nArgs:\n    protocol_id: Protocol ID\n    org_id: Organization ID from header\n    limit: Max results\n    offset: Pagination offset\n    db: Database session\n\nReturns:\n    List of protocol executions","operationId":"get_protocol_executions_v1_phi_protocols__protocol_id__executions_get","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Protocol Executions V1 Phi Protocols  Protocol Id  Executions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/protocols/recommend":{"post":{"tags":["protocols"],"summary":"Recommend Protocols","description":"Recommend protocols based on user intent.\n\nExtracts intent from prompt, searches for matching protocols,\nand ranks by performance metrics.\n\nArgs:\n    request: Recommendation request with prompt\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Recommended protocols with match scores and rationale","operationId":"recommend_protocols_v1_phi_protocols_recommend_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendProtocolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Recommend Protocols V1 Phi Protocols Recommend Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/protocols/{protocol_id}/star":{"post":{"tags":["protocols"],"summary":"Star Protocol","description":"Star a protocol for the organization.\n\nArgs:\n    protocol_id: Protocol ID\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Success response with updated starred status","operationId":"star_protocol_v1_phi_protocols__protocol_id__star_post","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Star Protocol V1 Phi Protocols  Protocol Id  Star Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["protocols"],"summary":"Unstar Protocol","description":"Unstar a protocol for the organization.\n\nArgs:\n    protocol_id: Protocol ID\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Success response with updated starred status","operationId":"unstar_protocol_v1_phi_protocols__protocol_id__star_delete","parameters":[{"name":"protocol_id","in":"path","required":true,"schema":{"type":"string","title":"Protocol Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Unstar Protocol V1 Phi Protocols  Protocol Id  Star Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/admin/seed-test-data":{"post":{"tags":["admin"],"summary":"Seed Test Data","description":"Seed test organization and user for development/staging.\n\n⚠️  DEV/STAGING ONLY: This endpoint should be disabled in production.\n\nCreates:\n- Organization: test-org\n- User: test-user (test@example.com)\n\nReturns:\n    Status and counts of created entities","operationId":"seed_test_data_v1_phi_admin_seed_test_data_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Seed Test Data V1 Phi Admin Seed Test Data Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/admin/quotas":{"get":{"tags":["admin"],"summary":"List Quotas","description":"List all configured job quotas with current usage counts.","operationId":"list_quotas_v1_phi_admin_quotas_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuotaResponse"},"title":"Response List Quotas V1 Phi Admin Quotas Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/admin/quotas/{scope}/{scope_id}":{"put":{"tags":["admin"],"summary":"Set Quota","description":"Create or update job quota limits for an org or user.\n\n- **scope**: `org` to cap all jobs in an organisation, `user` to cap a single user.\n- **scope_id**: the `org_id` or `user_id` to apply the limit to.\n- **max_total_jobs**: lifetime cap (-1 = unlimited).\n- **max_concurrent_jobs**: max active jobs at one time (-1 = unlimited).","operationId":"set_quota_v1_phi_admin_quotas__scope___scope_id__put","parameters":[{"name":"scope","in":"path","required":true,"schema":{"enum":["org","user"],"type":"string","title":"Scope"}},{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","title":"Scope Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete Quota","description":"Remove quota limits for an org or user, restoring them to the default (100 jobs for users).","operationId":"delete_quota_v1_phi_admin_quotas__scope___scope_id__delete","parameters":[{"name":"scope","in":"path","required":true,"schema":{"enum":["org","user"],"type":"string","title":"Scope"}},{"name":"scope_id","in":"path","required":true,"schema":{"type":"string","title":"Scope Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/admin/quotas/user/{user_id}/reset":{"post":{"tags":["admin"],"summary":"Reset User Quota","description":"Reset a user's job usage counter.\n\nSets ``reset_at`` to the current time so only jobs submitted *after* this\ncall count toward their limit.  The user effectively gets a fresh 100-job\nallowance (or whatever ``max_total_jobs`` is set to on their row).\n\nCreates the quota row with the default limit if it does not exist yet.","operationId":"reset_user_quota_v1_phi_admin_quotas_user__user_id__reset_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/admin/quotas/user/{user_id}/usage":{"get":{"tags":["admin"],"summary":"Get User Quota Usage","description":"Return current quota limits and usage for a specific user.\n\nWorks even when no explicit quota row exists — reports the default limit.","operationId":"get_user_quota_usage_v1_phi_admin_quotas_user__user_id__usage_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/tutorial":{"get":{"tags":["tutorial"],"summary":"Get Tutorial","description":"Return signed download URLs for the PDL-1 tutorial files.\n\nAlso idempotently pre-creates a tutorial Dataset in the caller's org so\nthat ``phi filter --dataset-id <id>`` works without a prior ``phi upload``.\n\nFiles are hosted at ``gs://<bucket>/tutorial/pdl1/`` and must be seeded\nonce with ``uv run python scripts/seed_tutorial_files.py``.","operationId":"get_tutorial_v1_phi_tutorial_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TutorialResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/":{"get":{"tags":["jobs"],"summary":"List Jobs","description":"List all jobs for an organization with pagination and filtering.\n\nArgs:\n    org_id: Organization ID from header\n    user_id: Optional user ID filter from header\n    page: Page number (1-indexed)\n    page_size: Number of results per page (max 100)\n    status: Optional status filter (pending, running, completed, failed, cancelled)\n    job_type: Optional job type filter (esmfold, alphafold, proteinmpnn, etc.)\n    dataset_id: Optional dataset ID filter\n    db: Database session\n\nReturns:\n    JobListResponse with paginated job list","operationId":"list_jobs_v1_phi_jobs__get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Page Size"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"job_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Type"}},{"name":"dataset_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["jobs"],"summary":"Submit Job","description":"Submit a biomodal job for execution.\n\nThis endpoint submits a single biomodal tool execution (e.g., ESMFold, ProteinMPNN)\nas a Temporal workflow. The job runs asynchronously and status can be polled via\nthe status endpoint.\n\nArgs:\n    request: Job submission request with type and parameters\n    org_id: Organization ID from header\n    user_id: User ID from header\n    db: Database session\n\nReturns:\n    JobSubmitResponse with job_id and run_id\n\nRaises:\n    HTTPException: If validation fails or submission errors occur","operationId":"submit_job_v1_phi_jobs__post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobSubmitRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/{job_id}/status":{"get":{"tags":["jobs"],"summary":"Get Job Status","description":"Get job execution status.\n\nQueries both the database and Temporal for the most up-to-date status information.\n\nArgs:\n    job_id: Job ID (UUID)\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    JobStatusResponse with current status and progress\n\nRaises:\n    HTTPException: If job not found or query fails","operationId":"get_job_status_v1_phi_jobs__job_id__status_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"include_assets","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Assets"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/{job_id}/logs/stream":{"get":{"tags":["jobs"],"summary":"Stream Job Logs","description":"Stream job logs via Server-Sent Events (SSE).\n\nThis endpoint provides real-time log streaming for a running job.\nLogs are aggregated from Temporal workflow events and GCS log files.\n\nThe stream continues until the job completes or the client disconnects.\n\nArgs:\n    job_id: Job ID (UUID)\n    org_id: Organization ID from header\n    request: FastAPI request object (for disconnect detection)\n    db: Database session\n\nReturns:\n    StreamingResponse with text/event-stream content\n\nRaises:\n    HTTPException: If job not found or access denied\n\nExample:\n    # Using curl\n    curl -N -H \"X-Organization-ID: org123\"             http://api.example.com/v1/phi/jobs/{job_id}/logs/stream\n\n    # Using EventSource in JavaScript\n    const eventSource = new EventSource(\n        `/v1/phi/jobs/${jobId}/logs/stream`,\n        { headers: { 'X-Organization-ID': orgId } }\n    );\n    eventSource.onmessage = (event) => {\n        const log = JSON.parse(event.data);\n        console.log(log.message);\n    };","operationId":"stream_job_logs_v1_phi_jobs__job_id__logs_stream_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/batch":{"post":{"tags":["jobs"],"summary":"Submit Batch Jobs","description":"Submit multiple biomodal jobs in a batch.\n\nThis endpoint allows submitting multiple jobs at once, with partial failure handling.\nEach job is submitted independently, and failures don't prevent other jobs from being submitted.\n\nArgs:\n    requests: List of job submission requests\n    org_id: Organization ID from header\n    user_id: User ID from header\n    db: Database session\n\nReturns:\n    BatchJobSubmitResponse with batch_id and per-job results\n\nExample:\n    ```json\n    {\n      \"requests\": [\n        {\n          \"job_type\": \"esmfold\",\n          \"params\": {\"fasta_str\": \">seq1\\nMKVLWAAS\"}\n        },\n        {\n          \"job_type\": \"alphafold\",\n          \"params\": {\"fasta_str\": \">seq2\\nGKVFWAAS\"}\n        }\n      ]\n    }\n    ```","operationId":"submit_batch_jobs_v1_phi_jobs_batch_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JobSubmitRequest"},"maxItems":50,"title":"Requests"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchJobSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/{job_id}":{"delete":{"tags":["jobs"],"summary":"Cancel Job","description":"Cancel a running job.\n\nAttempts to cancel a job by terminating its Temporal workflow.\nJobs that have already completed cannot be cancelled.\n\nArgs:\n    job_id: Job ID (UUID)\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    JobCancelResponse with cancellation status\n\nRaises:\n    HTTPException: If job not found, access denied, or cancellation fails","operationId":"cancel_job_v1_phi_jobs__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCancelResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/{job_id}/assets/create":{"post":{"tags":["jobs"],"summary":"Manually Create Assets","description":"Manually trigger asset creation for a completed job.\n\nUse this endpoint if automatic asset creation failed during job completion.\nThis is a fallback mechanism for debugging and recovery.\n\nArgs:\n    job_id: Job ID\n    org_id: Organization ID from header\n    db: Database session\n\nReturns:\n    Asset creation result with asset_group_id and assets_url\n\nRaises:\n    HTTPException: If job not found, not completed, or asset creation fails","operationId":"manually_create_assets_v1_phi_jobs__job_id__assets_create_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Manually Create Assets V1 Phi Jobs  Job Id  Assets Create Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/jobs/{job_id}/scores":{"get":{"tags":["jobs"],"summary":"Get Job Scores","description":"Return a signed download URL for the scores.csv produced by a design_pipeline job.","operationId":"get_job_scores_v1_phi_jobs__job_id__scores_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Expires In"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"},{"name":"X-User-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-User-Id"}},{"name":"X-Organization-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Organization-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoresDownloadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","description":"Health check endpoint with Modal authentication status.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Health Get"}}}}}}},"/runs":{"post":{"summary":"Create Run","description":"Submit a design workflow to Temporal (async execution).\n\nReturns immediately with a run_id. Check status with GET /runs/{run_id}.","operationId":"create_run_runs_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Create Run Runs Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/runs/{run_id}":{"get":{"summary":"Get Run Status","description":"Get workflow status from database.","operationId":"get_run_status_runs__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Run Status Runs  Run Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Cancel Run","description":"Cancel a running workflow.","operationId":"cancel_run_runs__run_id__delete","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Cancel Run Runs  Run Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/runs/{run_id}/result":{"get":{"summary":"Get Run Result","description":"Get workflow result from database.\n\nReturns 404 if run not found, 202 if still running, 500 if failed.","operationId":"get_run_result_runs__run_id__result_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DesignResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/runs/{run_id}/results":{"get":{"summary":"Get Workflow Results","description":"Get complete workflow execution results with all details.\n\nReturns comprehensive workflow results including:\n- Full workflow state (node-by-node status)\n- All artifacts with GCS URIs\n- Execution metrics (pLDDT, RMSD, alignment scores, etc.)\n- Node-level execution details\n\nArgs:\n    run_id: The workflow run ID\n    include_artifacts: Include artifact file list (default: true)\n    db: Database session\n\nReturns:\n    Complete workflow results with final_state, artifacts, metrics\n\nRaises:\n    404: Run not found\n    202: Run still in progress (check back later)\n    500: Run failed","operationId":"get_workflow_results_v1_phi_runs__run_id__results_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"include_artifacts","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Artifacts"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Workflow Results V1 Phi Runs  Run Id  Results Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/runs/{run_id}/artifacts":{"get":{"summary":"List Run Artifacts","description":"List all artifacts for a specific run.\n\nReturns:\n    ArtifactListResponse with all artifacts and summary statistics","operationId":"list_run_artifacts_runs__run_id__artifacts_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artifacts/{artifact_id}":{"get":{"summary":"Get Artifact","description":"Get details for a specific artifact.\n\nReturns:\n    ArtifactResponse with artifact metadata","operationId":"get_artifact_artifacts__artifact_id__get","parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artifacts/{artifact_id}/download":{"get":{"summary":"Get Artifact Download Url","description":"Generate a signed HTTPS download URL for an artifact.\n\nThe signed URL allows the caller to download the file directly from GCS\nwithout any GCP credentials.  The URL expires after `expires_in` seconds\n(default 1 hour).\n\nAuthentication is required: provide a valid x-api-key header (Clerk API key\nor the static API_SECRET_KEY for local dev).\n\nArgs:\n    artifact_id: Artifact ID\n    expires_in: URL expiry time in seconds (default: 3600 = 1 hour)\n\nReturns:\n    DownloadURLResponse with signed HTTPS download URL","operationId":"get_artifact_download_url_artifacts__artifact_id__download_get","parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Expires In"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadURLResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/phi/artifacts/{artifact_id}/download":{"get":{"summary":"Get Artifact Download Url","description":"Generate a signed HTTPS download URL for an artifact.\n\nThe signed URL allows the caller to download the file directly from GCS\nwithout any GCP credentials.  The URL expires after `expires_in` seconds\n(default 1 hour).\n\nAuthentication is required: provide a valid x-api-key header (Clerk API key\nor the static API_SECRET_KEY for local dev).\n\nArgs:\n    artifact_id: Artifact ID\n    expires_in: URL expiry time in seconds (default: 3600 = 1 hour)\n\nReturns:\n    DownloadURLResponse with signed HTTPS download URL","operationId":"get_artifact_download_url_v1_phi_artifacts__artifact_id__download_get","parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Expires In"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key for authentication","title":"X-Api-Key"},"description":"API key for authentication"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadURLResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AgentConfig":{"properties":{"name":{"type":"string","title":"Name","description":"Agent name (e.g., 'proteinmpnn-designer')"},"instructions":{"type":"string","title":"Instructions","description":"System prompt/instructions for the agent. Should be general-purpose, not prescriptive."},"model":{"type":"string","title":"Model","description":"LLM model to use","default":"gpt-4o"},"temperature":{"type":"number","title":"Temperature","description":"Temperature for LLM responses","default":0.1},"tool_choice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Choice","description":"Tool choice strategy: 'auto', 'required', 'none', or None for default behavior"},"tools":{"items":{},"type":"array","title":"Tools","description":"List of FunctionTools this agent can use"}},"type":"object","required":["name","instructions"],"title":"AgentConfig","description":"Configuration for an AI agent."},"AppendNotesRequest":{"properties":{"content":{"type":"string","title":"Content","description":"Markdown content to append to the dataset's research notes"}},"type":"object","required":["content"],"title":"AppendNotesRequest"},"ArtifactListResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"artifacts":{"items":{"$ref":"#/components/schemas/ArtifactResponse"},"type":"array","title":"Artifacts"},"total_count":{"type":"integer","title":"Total Count"},"total_size_bytes":{"type":"integer","title":"Total Size Bytes"}},"type":"object","required":["run_id","artifacts","total_count","total_size_bytes"],"title":"ArtifactListResponse","description":"Response model for list of artifacts."},"ArtifactResponse":{"properties":{"artifact_id":{"type":"string","title":"Artifact Id"},"run_id":{"type":"string","title":"Run Id"},"artifact_type":{"type":"string","title":"Artifact Type"},"filename":{"type":"string","title":"Filename"},"storage_path":{"type":"string","title":"Storage Path"},"size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size Bytes"},"mime_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime Type"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["artifact_id","run_id","artifact_type","filename","storage_path","size_bytes","mime_type","created_at","metadata"],"title":"ArtifactResponse","description":"Response model for artifact details."},"BatchJobSubmitResponse":{"properties":{"job_ids":{"items":{"type":"string"},"type":"array","title":"Job Ids"},"total_count":{"type":"integer","title":"Total Count"}},"type":"object","required":["job_ids","total_count"],"title":"BatchJobSubmitResponse","description":"Response for batch job submission."},"Body_upload_file_direct_v1_phi_files_upload_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"File to upload"},"content_type":{"type":"string","title":"Content Type","description":"MIME type of the file","default":"application/octet-stream"}},"type":"object","required":["file"],"title":"Body_upload_file_direct_v1_phi_files_upload_post"},"Body_upload_file_to_session_v1_phi_ingest_sessions__session_id__upload__filename__post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"File to upload"}},"type":"object","required":["file"],"title":"Body_upload_file_to_session_v1_phi_ingest_sessions__session_id__upload__filename__post"},"CreateAgentRequest":{"properties":{"config":{"$ref":"#/components/schemas/AgentConfig","description":"Agent configuration"},"name":{"type":"string","title":"Name","description":"Agent name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description"},"tool_ids":{"items":{"type":"string"},"type":"array","title":"Tool Ids","description":"Enabled tool IDs"}},"type":"object","required":["config","name"],"title":"CreateAgentRequest","description":"Request to create agent."},"CreateProjectRequest":{"properties":{"name":{"type":"string","title":"Name","description":"Project name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description"}},"type":"object","required":["name"],"title":"CreateProjectRequest","description":"Request to create a new project."},"CreateProtocolRequest":{"properties":{"name":{"type":"string","title":"Name","description":"Protocol name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Protocol description"},"intent_signature":{"additionalProperties":true,"type":"object","title":"Intent Signature","description":"Structured intent"},"protocol_template":{"additionalProperties":true,"type":"object","title":"Protocol Template","description":"Parameterized workflow template"},"source_workflow_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Workflow Id","description":"Source workflow ID"},"visibility":{"type":"string","title":"Visibility","description":"Visibility level","default":"private"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags","description":"Tags for search"}},"type":"object","required":["name","intent_signature","protocol_template"],"title":"CreateProtocolRequest","description":"Request to create protocol."},"CreateSessionRequest":{"properties":{"expected_files":{"type":"integer","minimum":1.0,"title":"Expected Files","description":"Total number of files to upload"},"file_type":{"type":"string","title":"File Type","description":"File type hint for validation (pdb, fasta, etc.)","default":"pdb"},"run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id","description":"Optional client-provided label for this batch"}},"type":"object","required":["expected_files"],"title":"CreateSessionRequest"},"CreateSessionResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"upload_prefix":{"type":"string","title":"Upload Prefix","description":"GCS prefix where files should be uploaded"},"status":{"type":"string","title":"Status"}},"type":"object","required":["session_id","upload_prefix","status"],"title":"CreateSessionResponse"},"CreateWorkflowRequest":{"properties":{"spec":{"$ref":"#/components/schemas/WorkflowSpec","description":"Workflow specification"},"name":{"type":"string","title":"Name","description":"Workflow name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description"}},"type":"object","required":["spec","name"],"title":"CreateWorkflowRequest","description":"Request to create workflow from spec."},"DatasetFileSummary":{"properties":{"filename":{"type":"string","title":"Filename"},"size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size Bytes"},"checksum":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checksum"}},"type":"object","required":["filename"],"title":"DatasetFileSummary"},"DatasetJobSummary":{"properties":{"job_id":{"type":"string","title":"Job Id"},"job_type":{"type":"string","title":"Job Type"},"status":{"type":"string","title":"Status"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"scores_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scores Url"}},"type":"object","required":["job_id","job_type","status"],"title":"DatasetJobSummary"},"DatasetJobsResponse":{"properties":{"dataset_id":{"type":"string","title":"Dataset Id"},"jobs":{"items":{"$ref":"#/components/schemas/DatasetJobSummary"},"type":"array","title":"Jobs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"}},"type":"object","required":["dataset_id","jobs","total_count","page","page_size"],"title":"DatasetJobsResponse"},"DatasetListResponse":{"properties":{"datasets":{"items":{"$ref":"#/components/schemas/DatasetResponse"},"type":"array","title":"Datasets"},"total_count":{"type":"integer","title":"Total Count"}},"type":"object","required":["datasets","total_count"],"title":"DatasetListResponse"},"DatasetResponse":{"properties":{"dataset_id":{"type":"string","title":"Dataset Id"},"org_id":{"type":"string","title":"Org Id"},"user_id":{"type":"string","title":"User Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"file_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Type"},"artifact_count":{"type":"integer","title":"Artifact Count"},"status":{"type":"string","title":"Status"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"sample_files":{"items":{"$ref":"#/components/schemas/DatasetFileSummary"},"type":"array","title":"Sample Files"}},"type":"object","required":["dataset_id","org_id","user_id","artifact_count","status"],"title":"DatasetResponse"},"DatasetScoresResponse":{"properties":{"dataset_id":{"type":"string","title":"Dataset Id"},"job_id":{"type":"string","title":"Job Id"},"download_url":{"type":"string","title":"Download Url"},"filename":{"type":"string","title":"Filename"},"expires_in":{"type":"integer","title":"Expires In"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["dataset_id","job_id","download_url","filename","expires_in"],"title":"DatasetScoresResponse"},"DesignRequest":{"properties":{"message":{"type":"string","maxLength":10000,"minLength":1,"title":"Message","description":"User's design request"},"context":{"additionalProperties":true,"type":"object","title":"Context","description":"Optional context"}},"type":"object","required":["message"],"title":"DesignRequest","description":"Request to design protein."},"DesignResponse":{"properties":{"message":{"type":"string","title":"Message"},"tool_calls":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Tool Calls"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["message","tool_calls","results","metadata"],"title":"DesignResponse","description":"Response from design agent."},"DirectFileUploadResponse":{"properties":{"file":{"type":"string","title":"File","description":"Filename as stored in GCS"},"gcs_uri":{"type":"string","title":"Gcs Uri","description":"Full GCS URI of the uploaded file"},"size_bytes":{"type":"integer","title":"Size Bytes","description":"Number of bytes written"}},"type":"object","required":["file","gcs_uri","size_bytes"],"title":"DirectFileUploadResponse","description":"Response for POST /v1/phi/ingest_sessions/{id}/upload/{filename}."},"DirectUploadResponse":{"properties":{"gcs_uri":{"type":"string","title":"Gcs Uri","description":"GCS URI of the uploaded object (use as job param)"}},"type":"object","required":["gcs_uri"],"title":"DirectUploadResponse","description":"Response for POST /v1/phi/files/upload."},"DownloadURLResponse":{"properties":{"artifact_id":{"type":"string","title":"Artifact Id"},"filename":{"type":"string","title":"Filename"},"download_url":{"type":"string","title":"Download Url"},"expires_in":{"type":"integer","title":"Expires In","description":"URL expiry time in seconds","default":3600}},"type":"object","required":["artifact_id","filename","download_url"],"title":"DownloadURLResponse","description":"Response model for download URL."},"EdgeSpec":{"properties":{"src":{"type":"string","title":"Src"},"dst":{"type":"string","title":"Dst"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"}},"additionalProperties":false,"type":"object","required":["src","dst"],"title":"EdgeSpec","description":"Specification for a workflow edge (dependency).\n\nAn edge defines the flow between nodes. It can include an optional\ncondition that must be satisfied for execution to continue."},"ExecuteWorkflowRequest":{"properties":{"inputs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Inputs","description":"Optional workflow inputs"}},"type":"object","title":"ExecuteWorkflowRequest","description":"Request to execute workflow."},"FileUploadUrl":{"properties":{"file":{"type":"string","title":"File"},"url":{"type":"string","title":"Url"}},"type":"object","required":["file","url"],"title":"FileUploadUrl"},"ForkProtocolRequest":{"properties":{"new_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Name","description":"Name for forked protocol"}},"type":"object","title":"ForkProtocolRequest","description":"Request to fork protocol."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IngestSessionStatusResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"status":{"type":"string","title":"Status"},"expected_files":{"type":"integer","title":"Expected Files"},"uploaded_files":{"type":"integer","title":"Uploaded Files"},"dataset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id"},"artifact_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Artifact Count"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["session_id","status","expected_files","uploaded_files"],"title":"IngestSessionStatusResponse"},"JobCancelResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"status":{"type":"string","title":"Status"},"message":{"type":"string","title":"Message"}},"type":"object","required":["job_id","status","message"],"title":"JobCancelResponse","description":"Response for job cancellation."},"JobListResponse":{"properties":{"jobs":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Jobs"},"total_count":{"type":"integer","title":"Total Count"},"total_pending":{"type":"integer","title":"Total Pending"},"total_running":{"type":"integer","title":"Total Running"},"total_completed":{"type":"integer","title":"Total Completed"},"total_failed":{"type":"integer","title":"Total Failed"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["jobs","total_count","total_pending","total_running","total_completed","total_failed"],"title":"JobListResponse","description":"Response for list of jobs."},"JobProgress":{"properties":{"current_step":{"type":"string","title":"Current Step","description":"Current execution step (e.g., 'folding sequence 5/10')"},"percent_complete":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Percent Complete","description":"Progress percentage"},"eta_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eta Seconds","description":"Estimated time to completion in seconds"}},"type":"object","required":["current_step","percent_complete"],"title":"JobProgress","description":"Job execution progress information."},"JobStatus":{"type":"string","enum":["pending","running","completed","failed","cancelled"],"title":"JobStatus","description":"Job execution status."},"JobStatusResponse":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Database job ID"},"run_id":{"type":"string","title":"Run Id","description":"Temporal workflow run ID"},"status":{"$ref":"#/components/schemas/JobStatus","description":"Current job status"},"progress":{"anyOf":[{"$ref":"#/components/schemas/JobProgress"},{"type":"null"}],"description":"Progress information (if job is running)"},"output_files":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Output Files","description":"Output files (available when job completes)"},"outputs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Outputs","description":"Inline text/structured outputs (e.g. report_md, citations for research jobs)"},"assets_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assets Url","description":"URL to fetch assets for this job (e.g., /assets/runs/{run_id}/assets)"},"asset_count":{"type":"integer","title":"Asset Count","description":"Number of assets created for this job","default":0},"asset_group":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Asset Group","description":"Asset group (included when include_assets=true)"},"assets":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Assets","description":"Assets created for this job (included when include_assets=true)"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message (if job failed)"},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Job creation timestamp"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At","description":"Job start timestamp"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At","description":"Job completion timestamp"}},"type":"object","required":["job_id","run_id","status","created_at"],"title":"JobStatusResponse","description":"Response with job status information."},"JobSubmitRequest":{"properties":{"job_type":{"$ref":"#/components/schemas/JobType","description":"Type of biomodal job to execute"},"params":{"additionalProperties":true,"type":"object","title":"Params","description":"Tool-specific parameters (validated against Modal function signature)"},"input_files":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Input Files","description":"Input files as artifact_name -> GCS URI mapping"},"run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id","description":"Optional custom run_id (generated if not provided)"},"priority":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Priority","description":"Job priority (0=lowest, 10=highest)","default":0},"context":{"additionalProperties":true,"type":"object","title":"Context","description":"Additional context (e.g., project_id for asset creation)"},"dataset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id","description":"Dataset ID to run the job against (batch mode). Mutually exclusive with inline fasta_str / pdb_content in params."}},"type":"object","required":["job_type"],"title":"JobSubmitRequest","description":"Request to submit a biomodal job."},"JobSubmitResponse":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Database job ID (UUID)"},"run_id":{"type":"string","title":"Run Id","description":"Temporal workflow run ID"},"status":{"type":"string","title":"Status","description":"Initial job status (typically 'submitted' or 'pending')"},"estimated_duration":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Duration","description":"Estimated execution time in seconds (if available)"},"message":{"type":"string","title":"Message","description":"Human-readable status message"}},"type":"object","required":["job_id","run_id","status","message"],"title":"JobSubmitResponse","description":"Response from job submission."},"JobType":{"type":"string","enum":["esmfold","proteinmpnn","alphafold","rfdiffusion","ligandmpnn","chai1","boltz","align_structures","tm_score","af2rank","rso","bindcraft","rf3","rfdiffusion3","boltzgen","esm2","openfold3","research","design_pipeline","filter_pipeline"],"title":"JobType","description":"Available biomodal job types."},"NodeSpec":{"properties":{"id":{"type":"string","title":"Id"},"op":{"type":"string","title":"Op"},"params":{"title":"Params"},"retry_policy":{"title":"Retry Policy"},"map_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Map Config"}},"additionalProperties":false,"type":"object","required":["id","op"],"title":"NodeSpec","description":"Specification for a single workflow node.\n\nA node represents a single operation (tool execution) in the workflow.\nIt includes the operation name, parameters, and optional retry policy.\n\nSpecial node type: op=\"map\" for parallel execution over collections.\n\nNote: params uses Any type to avoid strict schema validation issues\nwith dict[str, Any] in OpenAI Agents SDK."},"PatchDatasetRequest":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"PatchDatasetRequest"},"PlanExecuteRequest":{"properties":{"query":{"type":"string","minLength":1,"title":"Query","description":"User's natural language query"},"planContext":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plancontext","description":"Full plan text for additional context"},"protocolId":{"type":"string","title":"Protocolid","description":"Protocol ID to use as template"},"protocolAdjustments":{"additionalProperties":true,"type":"object","title":"Protocoladjustments","description":"User adjustments to protocol template variables (e.g., generate_n, top_n, temperature)"},"targetPdbId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Targetpdbid","description":"Explicit PDB ID for target structure (merged into protocol params; do not set with target_gcs_uri)"},"targetChain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Targetchain","description":"Chain ID for target structure (merged into protocol params)"},"targetGcsUri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Targetgcsuri","description":"GCS URI of existing target structure (upload or previous run); do not set with target_pdb_id"},"executeImmediately":{"type":"boolean","title":"Executeimmediately","description":"Execute without human review (automatically publishes first)","default":true},"context":{"additionalProperties":true,"type":"object","title":"Context","description":"Additional context for the run (e.g., project_id, team_id)"}},"type":"object","required":["query","protocolId"],"title":"PlanExecuteRequest","description":"Request to plan and execute workflow from protocol (frontend contract)."},"PlanWorkflowRequest":{"properties":{"prompt":{"type":"string","minLength":1,"title":"Prompt","description":"Natural language workflow description"},"protocol_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protocol Id","description":"Optional protocol ID to use as planning guidance"},"disable_auto_recommendations":{"type":"boolean","title":"Disable Auto Recommendations","description":"Disable automatic protocol recommendations (for de novo workflows)","default":false},"auto_publish":{"type":"boolean","title":"Auto Publish","description":"Auto-publish after creation","default":false},"execute_immediately":{"type":"boolean","title":"Execute Immediately","description":"Execute without human review (automatically publishes first)","default":false}},"type":"object","required":["prompt"],"title":"PlanWorkflowRequest","description":"Request to plan workflow from natural language prompt."},"ProtocolResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"intent_signature":{"additionalProperties":true,"type":"object","title":"Intent Signature"},"protocol_template":{"additionalProperties":true,"type":"object","title":"Protocol Template"},"source_workflow_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Workflow Id"},"parent_protocol_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Protocol Id"},"version":{"type":"integer","title":"Version"},"visibility":{"type":"string","title":"Visibility"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"is_starred":{"type":"boolean","title":"Is Starred"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","name","description","intent_signature","protocol_template","source_workflow_id","parent_protocol_id","version","visibility","tags","is_starred","created_at","updated_at"],"title":"ProtocolResponse","description":"Protocol response model."},"QuotaRequest":{"properties":{"max_total_jobs":{"type":"integer","title":"Max Total Jobs","description":"Lifetime job cap for this scope. -1 means unlimited.","default":-1},"max_concurrent_jobs":{"type":"integer","title":"Max Concurrent Jobs","description":"Maximum simultaneously active (pending/running) jobs. -1 means unlimited.","default":-1}},"type":"object","title":"QuotaRequest"},"QuotaResponse":{"properties":{"scope":{"type":"string","title":"Scope"},"scope_id":{"type":"string","title":"Scope Id"},"max_total_jobs":{"type":"integer","title":"Max Total Jobs"},"max_concurrent_jobs":{"type":"integer","title":"Max Concurrent Jobs"},"reset_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reset At"},"current_total_jobs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Total Jobs"},"current_concurrent_jobs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Concurrent Jobs"}},"type":"object","required":["scope","scope_id","max_total_jobs","max_concurrent_jobs"],"title":"QuotaResponse"},"RecommendProtocolRequest":{"properties":{"user_prompt":{"type":"string","title":"User Prompt","description":"User's workflow request"},"force_refresh":{"type":"boolean","title":"Force Refresh","description":"If true, bypass intent cache and re-extract (for 'Regenerate recommendations' button)","default":false},"filters":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Filters","description":"Optional filters (target_type, allowed_tools)"}},"type":"object","required":["user_prompt"],"title":"RecommendProtocolRequest","description":"Request for protocol recommendations."},"ResearchNotesResponse":{"properties":{"dataset_id":{"type":"string","title":"Dataset Id"},"exists":{"type":"boolean","title":"Exists"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content","description":"Full notes content (markdown)"},"gcs_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gcs Url","description":"Signed download URL (24 h TTL)"}},"type":"object","required":["dataset_id","exists"],"title":"ResearchNotesResponse"},"ScoresDownloadResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"artifact_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Id"},"download_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Download Url"},"filename":{"type":"string","title":"Filename"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["job_id","artifact_id","download_url","filename","expires_in"],"title":"ScoresDownloadResponse"},"TutorialFile":{"properties":{"filename":{"type":"string","title":"Filename"},"url":{"type":"string","title":"Url"},"gcs_uri":{"type":"string","title":"Gcs Uri"}},"type":"object","required":["filename","url","gcs_uri"],"title":"TutorialFile"},"TutorialResponse":{"properties":{"files":{"items":{"$ref":"#/components/schemas/TutorialFile"},"type":"array","title":"Files"},"dataset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id"},"message":{"type":"string","title":"Message","default":"Download the files below, then run: phi filter --dataset-id <dataset_id>"}},"type":"object","required":["files"],"title":"TutorialResponse"},"UpdateAgentRequest":{"properties":{"config":{"anyOf":[{"$ref":"#/components/schemas/AgentConfig"},{"type":"null"}],"description":"Updated agent configuration"},"tool_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tool Ids","description":"Updated tool IDs"}},"type":"object","title":"UpdateAgentRequest","description":"Request to update agent."},"UpdateProtocolRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Protocol name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Protocol description"},"intent_signature":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Intent Signature","description":"Structured intent"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags","description":"Tags for search"}},"type":"object","title":"UpdateProtocolRequest","description":"Request to update protocol."},"UpdateWorkflowRequest":{"properties":{"spec":{"$ref":"#/components/schemas/WorkflowSpec","description":"Updated workflow specification"},"change_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Change Summary","description":"Description of changes"}},"type":"object","required":["spec"],"title":"UpdateWorkflowRequest","description":"Request to update workflow."},"UploadUrlRequest":{"properties":{"filename":{"type":"string","title":"Filename","description":"Name of the file to upload (e.g. pdl1_binders.fasta)"},"content_type":{"type":"string","title":"Content Type","description":"MIME type of the file being uploaded","default":"application/octet-stream"},"size_bytes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Size Bytes","description":"File size in bytes (optional; used for validation only)"}},"type":"object","required":["filename"],"title":"UploadUrlRequest","description":"Request body for POST /v1/phi/files/upload-url."},"UploadUrlResponse":{"properties":{"upload_url":{"type":"string","title":"Upload Url","description":"Signed PUT URL to upload the file directly to GCS"},"gcs_uri":{"type":"string","title":"Gcs Uri","description":"GCS URI of the uploaded object (use as job param)"},"expires_in":{"type":"integer","title":"Expires In","description":"Seconds until the upload URL expires"}},"type":"object","required":["upload_url","gcs_uri","expires_in"],"title":"UploadUrlResponse","description":"Response for POST /v1/phi/files/upload-url."},"UploadUrlsRequest":{"properties":{"files":{"items":{"type":"string"},"type":"array","maxItems":50,"minItems":1,"title":"Files","description":"List of filenames (max 50 per request)"}},"type":"object","required":["files"],"title":"UploadUrlsRequest"},"UploadUrlsResponse":{"properties":{"urls":{"items":{"$ref":"#/components/schemas/FileUploadUrl"},"type":"array","title":"Urls"}},"type":"object","required":["urls"],"title":"UploadUrlsResponse"},"UserProfileResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"org_id":{"type":"string","title":"Org Id"},"org_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Name"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["user_id","email","display_name","org_id","org_name","created_at"],"title":"UserProfileResponse","description":"User profile returned by GET /v1/phi/auth/me."},"UserQuotaResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"max_total_jobs":{"type":"integer","title":"Max Total Jobs"},"max_concurrent_jobs":{"type":"integer","title":"Max Concurrent Jobs"},"reset_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reset At"},"current_total_jobs":{"type":"integer","title":"Current Total Jobs"},"current_concurrent_jobs":{"type":"integer","title":"Current Concurrent Jobs"}},"type":"object","required":["user_id","max_total_jobs","max_concurrent_jobs","current_total_jobs","current_concurrent_jobs"],"title":"UserQuotaResponse","description":"Quota limits and live usage for the authenticated user."},"ValidateProtocolRequest":{"properties":{"protocol_template":{"additionalProperties":true,"type":"object","title":"Protocol Template","description":"Parameterized workflow template to validate"},"dry_run":{"type":"boolean","title":"Dry Run","description":"If true, instantiate with synthetic params and run workflow/preflight validation","default":true}},"type":"object","required":["protocol_template"],"title":"ValidateProtocolRequest","description":"Request to validate a protocol template without persisting."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WorkflowSpec":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"nodes":{"items":{"$ref":"#/components/schemas/NodeSpec"},"type":"array","title":"Nodes"},"edges":{"items":{"$ref":"#/components/schemas/EdgeSpec"},"type":"array","title":"Edges"},"version":{"type":"string","title":"Version","default":"1.0"},"expected_artifacts":{"items":{"type":"string"},"type":"array","title":"Expected Artifacts"},"initial_artifacts":{"additionalProperties":true,"type":"object","title":"Initial Artifacts"}},"additionalProperties":false,"type":"object","required":["name","nodes","edges"],"title":"WorkflowSpec","description":"Complete workflow specification.\n\nThis is the immutable \"plan\" for a workflow. It defines all nodes,\nedges, and expected outputs. Once validated, this spec is executed\nby the Temporal workflow executor."}}}}