# PredictStructure API Reference This document describes the network API that the BV-BRC web UI uses to submit and monitor PredictStructure jobs. Other BV-BRC services use the same envelope, so most of this generalizes — only the parameter object on the wire (the `values` payload) is service-specific. > **Scope.** This is the *AppService* JSON-RPC interface — the one the web form talks to when you click **Submit Job**. The public REST data API at `https://www.bv-brc.org/api/` (documented at ) is a different endpoint and is not covered here. ## Endpoints The Web UI initializes three RPC endpoints (`public/js/p3/app/p3app.js`); for job submission only the first one matters. | Endpoint | Purpose | Configured in | |---|---|---| | `serviceAPI` | **AppService** — submit / query jobs (this doc) | `BV-BRC-Web` config | | `workspaceAPI` | Workspace file CRUD (the `ws://` URIs you'll see in payloads) | `BV-BRC-Web` config | | `dataAPI` | Public RDF / Solr data API | `BV-BRC-Web` config | The current production AppService endpoint is `https://www.bv-brc.org/services/AppService` (subject to change; the value used by the live UI is whatever `serviceAPI` was set to in the deployed `config.js`). ## Transport JSON-RPC 2.0 over HTTPS POST with one custom detail: the content type is the BV-BRC-specific MIME type `application/jsonrpc+json` (not plain `application/json`). ``` POST Content-Type: application/jsonrpc+json Authorization: X-Requested-With: false ``` Request body: ```json { "jsonrpc": "2.0", "id": 1, "method": "AppService.start_app2", "params": ["PredictStructure", { ...values... }, { ...start_params... }] } ``` Response on success: ```json { "jsonrpc": "2.0", "id": 1, "result": [ { "id": "", "app": { "id": "PredictStructure" }, ... } ] } ``` Response on failure: ```json { "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "...", "data": "..." } } ``` ## Authentication Every call requires a BV-BRC auth token in the `Authorization` header. Tokens are issued by the BV-BRC account service; the UI obtains one through the login flow and stores it in `window.App.authorizationToken`. For programmatic use, see the BV-BRC SDK or the `p3-login` / `p3-token` tools shipped with the BV-BRC CLI. ## Methods ### `AppService.start_app2` Submit a new PredictStructure job. ``` AppService.start_app2(app_id, values, start_params) → [task] ``` | Argument | Type | Description | |---|---|---| | `app_id` | string | Always `"PredictStructure"` | | `values` | object | Job parameters (see [Parameters](#parameters)) | | `start_params` | object | Submission metadata (see [Start parameters](#start-parameters)) | Returns a single-element array containing the task descriptor: ```json [ { "id": "a3f8c9d2-...", "parent_id": null, "app": { "id": "PredictStructure", "label": "Protein Structure Prediction" }, "workspace": "//.", "parameters": { ...echoed values... }, "user_id": "@BVBRC", "submit_time": "2026-05-21T19:30:00Z", "start_time": null, "completed_time": null, "status": "queued" } ] ``` ### `AppService.query_tasks` / `AppService.query_task_summary` Inspect job status. The Web UI calls `query_task_summary` on each page load for the **Completed Jobs** badge; the Jobs list view paginates via `query_tasks`. ``` AppService.query_task_summary([]) → [{ submitted, queued, in_progress, completed, failed, ... }] AppService.query_tasks([ids?]) → [tasks...] ``` ### `AppService.enumerate_apps` Lists all registered app specs the AppService knows about. Useful to confirm the deployed `PredictStructure.json` parameter set matches what your client expects. ### `AppService.kill_task` / `AppService.delete_task` Standard administrative endpoints; require ownership of the task. ## Parameters The `values` object mirrors the basic app spec in [`app_specs/PredictStructure.json`](https://github.com/CEPI-dxkb/PredictStructureApp/blob/main/app_specs/PredictStructure.json). Only `tool`, `output_path`, and `output_file` are required by the schema; the rest depend on what you're predicting. | Field | Type | Required | Description | |---|---|---|---| | `tool` | enum | yes | `auto` \| `boltz` \| `openfold` \| `chai` \| `alphafold` \| `esmfold` | | `input_file` | wsfile (`ws://...`) | conditional | Protein FASTA. Required unless DNA / RNA / ligand / SMILES / `text_input` is given | | `dna_file` | wsfile | no | DNA FASTA (Boltz / OpenFold / Chai only) | | `rna_file` | wsfile | no | RNA FASTA (Boltz / OpenFold / Chai only) | | `ligand` | array of string | no | CCD codes, each 1–3 alphanumeric chars (e.g. `["ATP", "NAG"]`) | | `smiles` | array of string | no | SMILES strings | | `text_input` | array of object | no | Inline sequences: `{ "sequence": "...", "type": "auto|protein|dna|rna" }`. Lets clients submit without a workspace file | | `msa_file` | wsfile | conditional | Pre-computed MSA (`.a3m`, `.sto`, `.pqt`). Required for Boltz / OpenFold / Chai unless `use_msa_server` is set; in that case BV-BRC computes the MSA with ColabFold | | `debug` | boolean | no | Verbose service-side logging (sets `P3_DEBUG=1`) | | `output_path` | folder (`ws://...`) | yes | Workspace folder where the job result directory will be created | | `output_file` | string | yes | Job result name; results land at `${output_path}/.${output_file}/` | Workspace files use the `ws://@BVBRC/` URI scheme. The service script resolves them via `p3-cp` before launching the underlying engine. ### Validation rules enforced by the service The Perl `App-PredictStructure.pl` rejects the submission *before* it reaches the queue if any of the following are violated: 1. At least one of `input_file`, `dna_file`, `rna_file`, `text_input`, `ligand`, or `smiles` is present. 2. Both `output_path` and `output_file` are present. 3. CCD ligand codes match `/^[A-Za-z0-9]{1,3}$/`. 4. SMILES strings are non-empty. 5. `text_input[i].type ∈ { auto, protein, dna, rna }`. 6. FASTA inputs start with `>` on the first non-blank line (peek of first 5 lines via `p3-cat | head`). 7. MSA inputs start with `>` (A3M) or `# STOCKHOLM` (Stockholm) on the first non-blank line. 8. Boltz YAML manifests (passed as `input_file` with `.yaml`/`.yml`) contain both `version:` and `sequences:` keys. A validation failure returns a JSON-RPC error with the human-readable reason in `error.message`. ### Tool-specific parameter compatibility Even though the schema accepts any combination, the Perl preflight will reject combinations that no engine can run: | Tool | DNA | RNA | Ligand | SMILES | MSA required | |---|:-:|:-:|:-:|:-:|:-:| | `boltz` | ✓ | ✓ | ✓ | ✓ | ✓ | | `openfold` | ✓ | ✓ | ✓ | ✓ | ✓ | | `chai` | ✓ | ✓ | ✓ | — | ✓ | | `alphafold` | — | — | — | — | (built locally) | | `esmfold` | — | — | — | — | — | | `auto` | (forwarded; selector decides) | | | | conditional | Submitting `{ "tool": "alphafold", "dna_file": "ws://..." }` returns: ``` error: AlphaFold 2 supports protein only; remove dna_file or change tool to boltz/openfold/chai. ``` ## Start parameters The `start_params` (3rd argument) is a small bag of UI/UX hints attached by the Web form. The schema is not formally specified; the keys you'll see in practice are: | Field | Type | Description | |---|---|---| | `parent_id` | string | Parent task ID when this submission is a "rerun" | | `workflow_id` | string | Identifier when launched as part of a multi-app workflow | | `comment` | string | Free-text job label shown in the Jobs list | Pass `{}` if you don't have anything to set. ## Job lifecycle ``` [client] [AppService] [worker] │ start_app2 PredictStructure ───▶ │ │ │ │── persist task, status=queued│ │ ◀──── task descriptor ───────────│ │ │ │ │ │ query_task_summary ◀── poll ───│ │ │ │ pick from queue ───────────▶│ │ │ run │ │ │ status=in_progress ◀──────│ │ │ │ │ │ preflight (resource estimate) │ │ validate inputs │ │ p3-cp ws:// → /tmp │ │ predict-structure ... │ │ protein_compare (report) │ │ p3-cp results → ws://output_path │ │ │ │ │ status=completed ◀──────│ │ query_tasks([id]) ────▶ │ │ │ ◀──── final task w/ paths ────────│ │ ``` Failures are surfaced as `status: failed` with `stderr` accessible via the workspace job directory. ## Preflight The Web UI does **not** call preflight directly — the AppService calls it internally before scheduling. Programmatic clients can invoke it via the same JSON-RPC method that the AppService uses, but the practical equivalent is the Python CLI: ```bash predict-structure preflight --tool boltz --msa /dev/null # → { "cpu": 8, "memory_gb": 64, "runtime_hours": 4, "gpu": true, "partition": "gpu2" } ``` The preflight result is what determines which node the job runs on. The defaults from `PredictStructure.json` are: ```json { "default_memory": "64G", "default_cpu": 8, "default_runtime": 14400 } ``` ## Example request — Boltz with MSA, single chain ```json { "jsonrpc": "2.0", "id": 42, "method": "AppService.start_app2", "params": [ "PredictStructure", { "tool": "boltz", "input_file": "ws://awilke@BVBRC/home/inputs/crambin.fasta", "msa_file": "ws://awilke@BVBRC/home/inputs/crambin.a3m", "output_path": "ws://awilke@BVBRC/home/jobs/", "output_file": "crambin-boltz-2026-05-21" }, {} ] } ``` ## Example request — protein–DNA complex (auto-select) ```json { "jsonrpc": "2.0", "id": 43, "method": "AppService.start_app2", "params": [ "PredictStructure", { "tool": "auto", "input_file": "ws://awilke@BVBRC/home/tf.fasta", "dna_file": "ws://awilke@BVBRC/home/operator.fasta", "msa_file": "ws://awilke@BVBRC/home/tf.a3m", "ligand": ["MG"], "output_path": "ws://awilke@BVBRC/home/jobs/", "output_file": "tf-dna-complex" }, { "comment": "DNA-binding TF + Mg2+" } ] } ``` ## Example request — protein–ligand with SMILES (Boltz only) ```json { "jsonrpc": "2.0", "id": 44, "method": "AppService.start_app2", "params": [ "PredictStructure", { "tool": "boltz", "input_file": "ws://awilke@BVBRC/home/kinase.fasta", "msa_file": "ws://awilke@BVBRC/home/kinase.a3m", "smiles": ["CC(=O)Oc1ccccc1C(=O)O"], "output_path": "ws://awilke@BVBRC/home/jobs/", "output_file": "kinase-aspirin" }, {} ] } ``` ## Example request — inline sequences with `text_input` ```json { "jsonrpc": "2.0", "id": 45, "method": "AppService.start_app2", "params": [ "PredictStructure", { "tool": "esmfold", "text_input": [ { "sequence": "MEEPQSDPSVEPPLSQETFSDLWKLLPENN...", "type": "protein" } ], "output_path": "ws://awilke@BVBRC/home/jobs/", "output_file": "p53-esmfold" }, {} ] } ``` ## Output On success, the workspace folder contains a job directory `${output_path}/.${output_file}/` with the canonical layout documented in the [Quick Reference](/quick_references/services/predict_structure_service#output-results). The task descriptor returned by `query_tasks` includes the absolute workspace path; the UI uses this to render the result page. ## Errors The server returns standard JSON-RPC 2.0 error objects: | `error.code` | Meaning | |---|---| | `-32600` | Invalid request envelope | | `-32601` | Method not found (typo in `method`) | | `-32602` | Invalid params (schema mismatch, e.g. ligand longer than 3 chars) | | `-32603` | Internal error | | `-32000` | Application error from `App-PredictStructure.pl` (validation, preflight, runtime); message contains the reason | | `-32001` | Not authorized (token invalid / expired) | ## Rate limiting and quotas AppService enforces per-user concurrency limits on running jobs and aggregate runtime quotas, configured per BV-BRC deployment. The current production caps are not exposed via the API; queued jobs in excess of the cap remain in `status: queued` until earlier ones finish. ## Client examples ### `curl` ```bash TOKEN="$(p3-token)" # or read from ~/.patric_token curl -sS https://www.bv-brc.org/services/AppService \ -H "Content-Type: application/jsonrpc+json" \ -H "Authorization: $TOKEN" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "AppService.start_app2", "params": ["PredictStructure", { "tool": "esmfold", "input_file": "ws://awilke@BVBRC/home/crambin.fasta", "output_path": "ws://awilke@BVBRC/home/jobs/", "output_file": "crambin-esm" }, {}] }' ``` ### Python (`requests`) ```python import os, requests TOKEN = open(os.path.expanduser("~/.patric_token")).read().strip() body = { "jsonrpc": "2.0", "id": 1, "method": "AppService.start_app2", "params": ["PredictStructure", { "tool": "boltz", "input_file": "ws://awilke@BVBRC/home/crambin.fasta", "msa_file": "ws://awilke@BVBRC/home/crambin.a3m", "output_path":"ws://awilke@BVBRC/home/jobs/", "output_file":"crambin-boltz", }, {}], } r = requests.post( "https://www.bv-brc.org/services/AppService", headers={ "Content-Type": "application/jsonrpc+json", "Authorization": TOKEN, }, json=body, timeout=120, ) r.raise_for_status() print(r.json()) ``` ### Python (BV-BRC SDK) ```python from Bio.KBase.AppService import Client # if installed c = Client("https://www.bv-brc.org/services/AppService", token=TOKEN) task = c.start_app2("PredictStructure", { "tool": "auto", "input_file": "ws://awilke@BVBRC/home/crambin.fasta", "msa_file": "ws://awilke@BVBRC/home/crambin.a3m", "output_path":"ws://awilke@BVBRC/home/jobs/", "output_file":"crambin-auto", }, {}) ``` ## See also - BV-BRC Data API (public REST, *not* this endpoint): - [Quick Reference](/quick_references/services/predict_structure_service) - [CLI Reference](/quick_references/services/predict_structure_cli) - Source: [CEPI-dxkb/PredictStructureApp](https://github.com/CEPI-dxkb/PredictStructureApp) (`service-scripts/App-PredictStructure.pl`, `app_specs/PredictStructure.json`) - UI widget: [BV-BRC/BV-BRC-Web](https://github.com/BV-BRC/BV-BRC-Web/blob/master/public/js/p3/widget/app/PredictStructure.js)