Results
Read scientific outputs and save generated files.
A job result contains tool-specific structured data and a file manifest. Read job status before requesting results; a finished job can have full output, partial output, or no stored result.
Fetch results
GET /api/v1/results/{jobId} requires jobs:read and a job in the key's workspace.
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $PROTEINIQ_API_KEY" \
"https://proteiniq.io/api/v1/results/$JOB_ID" \
--output result.jsonSet JOB_ID to the ID returned by submission. Requests for a different workspace return not_found.
Result resource
The response has these fields:
object: Alwaysjob_result.job_idandtool: The source job and analysis.statusandcompleted_at: Execution outcome and completion time.results: Structured scientific output, whose shape depends on the tool.files: Available file metadata; entries may includename,key,content_type, andurl.data_source: Result storage format metadata. Interpret scientific output using the tool's output contract.
Read the tool detail to understand its output fields. An empty files array does not mean results is empty.
Result availability
The endpoint handles job states as follows:
PENDING,QUEUED,PROCESSING, orRETRY: Returns HTTP 409 withjob_not_completedandRetry-After: 5.COMPLETEDorBUDGET_EXCEEDED: Returns stored output when available; otherwise HTTP 404 withnot_found.FAILED: Returns results only when the job has stored output.TIMEOUTorCANCELLED: Returns HTTP 404 withnot_found.
A failed or budget-limited result is partial. Inspect its status, diagnostics, and files before deciding whether it is suitable for further analysis.
Wait at least the supplied Retry-After before retrying a 409 or rate-limit response. Do not repeatedly request a terminal job's unavailable result as though it were still running.
Download a file
The url field is a temporary signed download URL. Some file entries may have no URL; use only entries with one.
After saving a successful response to result.json, this Python example downloads the first available file:
import json
import urllib.request
from pathlib import Path
result = json.loads(Path("result.json").read_text(encoding="utf-8"))
file = next((item for item in result.get("files", []) if item.get("url")), None)
if file is None:
print("No downloadable files. Inspect result['results'] for structured output.")
else:
destination = Path("downloaded-result")
with urllib.request.urlopen(file["url"], timeout=60) as response:
with destination.open("wb") as output:
while chunk := response.read(1024 * 1024):
output.write(chunk)
print("Saved:", destination)The signed URL authorizes the download. Do not send your API key to it. Fetch the result again if the URL expires, and treat signed URLs as private while they remain valid.
The quickstart saves all downloadable files into a directory for the job. Downloading results to your own storage creates a copy you control; saving a job artifact in ProteinIQ's file library does not protect it from source job deletion.