{"openapi":"3.1.0","info":{"title":"OpenHelm Public API","version":"1.0.0","description":"Drive OpenHelm Cloud from your own product, server-to-server. Author jobs (reusable task templates whose prompts carry {{placeholders}}), then run them with parameters and read back a structured, schema-shaped result asynchronously — with evidence (screenshot + matched text), a confidence level, and usage/cost. Task-execution failures return 200 with a structured failure_reason; HTTP 4xx/5xx is reserved for request, auth, and quota errors."},"servers":[{"url":"https://api.openhelm.ai/v1","description":"Production"}],"security":[{"apiKey":[]}],"paths":{"/projects":{"get":{"summary":"List projects","responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a project","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"}}}}}},"responses":{"201":{"description":"Created"}}}},"/projects/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Get a project","responses":{"200":{"description":"OK"}}},"patch":{"summary":"Update a project","responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete a project","responses":{"200":{"description":"OK"}}}},"/jobs":{"get":{"summary":"List jobs (task templates)","responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a job (task template)","description":"`prompt` may contain {{placeholder}} tokens filled by `inputs` at run time. `input_schema.required` (if set) is validated per run. `output_schema` declares the result shape.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project_id","name","prompt"],"properties":{"project_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"prompt":{"type":"string","example":"Check whether {{model_ref}} ({{finish}}) is in stock at {{supplier_url}}. Use the browser; screenshot the stock state."},"model":{"type":"string","enum":["haiku","sonnet","opus"],"default":"sonnet"},"input_schema":{"type":"object"},"output_schema":{"type":"object"}}}}}},"responses":{"201":{"description":"Created"}}}},"/jobs/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Get a job","responses":{"200":{"description":"OK"}}},"patch":{"summary":"Update a job","responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete a job","responses":{"200":{"description":"OK"}}}},"/jobs/{id}/runs":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Run a job with parameters (async)","description":"Returns 202 immediately; poll GET /runs/{id} or supply callback_url.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"inputs":{"type":"object","additionalProperties":true},"output_schema":{"type":"object","description":"Overrides the job's output_schema for this run."},"callback_url":{"type":"string","format":"uri","description":"HMAC-signed completion webhook target."},"idempotency_key":{"type":"string","description":"Replays return the original run."}}}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"task_id":{"type":"string"},"status":{"type":"string","enum":["queued"]},"poll_url":{"type":"string"},"billing":{"$ref":"#/components/schemas/BillingHint"}}}}}},"402":{"description":"Subscription/trial/quota gate"},"429":{"description":"Too many concurrent runs"}}}},"/runs":{"get":{"summary":"List recent API runs","parameters":[{"name":"job_id","in":"query","schema":{"type":"string"},"description":"Filter by template job id"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Run an inline prompt (async, no pre-created job)","description":"One-call run: pass a `prompt` (with optional {{placeholders}} filled by `inputs`) and an optional `output_schema`. Returns 202 immediately; poll GET /runs/{id} or supply callback_url. `project_id` is optional — omit it and the run executes in the org's auto-created \"API Runs\" project.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","example":"Research {{company}} and summarise its latest funding round, investors, and valuation."},"inputs":{"type":"object","additionalProperties":true},"output_schema":{"type":"object","description":"Declares the result shape."},"model":{"type":"string","enum":["haiku","sonnet","opus"],"default":"sonnet"},"project_id":{"type":"string","description":"Optional; defaults to the org's \"API Runs\" project."},"name":{"type":"string","description":"Optional label for the run."},"callback_url":{"type":"string","format":"uri","description":"HMAC-signed completion webhook target."},"idempotency_key":{"type":"string","description":"Replays return the original run."}}}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"task_id":{"type":"string"},"status":{"type":"string","enum":["queued"]},"poll_url":{"type":"string"},"billing":{"$ref":"#/components/schemas/BillingHint"}}}}}},"402":{"description":"Subscription/trial/quota gate"},"429":{"description":"Too many concurrent runs"}}}},"/runs/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Poll a task result","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskEnvelope"}}}}}}},"/runs/{id}/cancel":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"summary":"Cancel a running task","responses":{"200":{"description":"OK"}}}},"/emails":{"post":{"summary":"Send an email from the org's identity","description":"Sends transactionally from the org's address (orgname@relay.openhelm.ai). The caller owns approval (e.g. an operator-approved body). Sets a correlation Reply-To so a supplier's reply threads back via the email.received webhook. `metadata` is an opaque object echoed verbatim on that webhook.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to","subject"],"properties":{"to":{"type":"string","format":"email"},"subject":{"type":"string"},"body_markdown":{"type":"string"},"body_html":{"type":"string","description":"Pre-rendered HTML; takes precedence over body_markdown."},"text":{"type":"string"},"from_name":{"type":"string","description":"Display name before the address (defaults to the org's name)."},"metadata":{"type":"object","additionalProperties":true,"description":"Echoed on the reply webhook."}}}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"message_id":{"type":"string"},"from_address":{"type":"string"},"correlation_token":{"type":"string"}}}}}},"400":{"description":"Email not configured / invalid body"}}}},"/emails/identity":{"get":{"summary":"Get the org's email address + inbound callback","responses":{"200":{"description":"OK"}}},"post":{"summary":"Allocate the identity + set the inbound webhook callback","description":"Allocates the org's address on first call. Set `callback_url` (https) to receive email.received webhooks. Optionally set `username` to choose a friendly address (username@relay.openhelm.ai). Returns the webhook_secret used to HMAC-sign webhooks.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"callback_url":{"type":"string","format":"uri","description":"https endpoint for email.received webhooks."},"username":{"type":"string","description":"Friendly email handle, e.g. \"pilot-hotel-group\" (3–32, a–z/0–9/-, unique)."}}}}}},"responses":{"200":{"description":"OK"}}}},"/connections":{"get":{"summary":"List connections","description":"The credentials and tools your runs can use (Gmail, GitHub, MCP servers…) with their auth status. Secrets are never returned.","responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a connection (token or mcp)","description":"Provision a connection programmatically. `type: \"token\"` stores an API key/secret in encrypted storage; `type: \"mcp\"` registers a remote HTTP/SSE MCP server by URL with optional headers (values may use ${SECRET}). For OAuth/browser providers that need a human, use POST /connections/links instead. The `secret` is write-only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","type"],"properties":{"name":{"type":"string"},"type":{"type":"string","enum":["token","mcp"]},"secret":{"type":"string","description":"API key/token to store (token type, or to back ${SECRET} in mcp headers)."},"env_var_name":{"type":"string","description":"token type: the env var the secret is injected as (e.g. GITHUB_TOKEN)."},"url":{"type":"string","format":"uri","description":"mcp type: the remote MCP server URL."},"transport":{"type":"string","enum":["http","sse"],"default":"http"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"mcp type: request headers."},"project_id":{"type":"string","description":"Scope to one project; omit for all the account's runs."}}}}}},"responses":{"201":{"description":"Created"},"400":{"description":"Invalid type/body"}}}},"/connections/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"summary":"Get a connection","responses":{"200":{"description":"OK"}}},"patch":{"summary":"Update a connection (name, enabled, rotate secret)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"is_enabled":{"type":"boolean"},"secret":{"type":"string","description":"Rotates the stored secret."},"env_var_name":{"type":"string"}}}}}},"responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete a connection (and its secret)","responses":{"200":{"description":"OK"}}}},"/connections/links":{"post":{"summary":"Mint a hosted connect link for an OAuth/browser provider","description":"Returns a short-lived signed URL to the hosted connect flow for providers that need a browser (Google, Notion, LinkedIn…). Open it once to authorise, then poll GET /connections until the connection shows as authenticated.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["provider"],"properties":{"provider":{"type":"string","description":"e.g. 'google', 'github', 'notion'."},"name":{"type":"string","description":"Optional label for the resulting connection."},"project_id":{"type":"string","description":"Optionally scope to one project."}}}}}},"responses":{"201":{"description":"Link created"},"400":{"description":"Connect disabled / missing provider"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Authorization: Bearer oh_live_… (mint under Settings → API & Webhooks)."}},"schemas":{"TaskEnvelope":{"type":"object","description":"Shared by the poll endpoint and the completion webhook. Webhook body is { \"event\": \"run.completed\" | \"run.failed\", \"data\": <this> }.","properties":{"task_id":{"type":"string"},"status":{"type":"string","enum":["queued","running","succeeded","failed","cancelled"]},"result":{"type":["object","null"],"description":"Best-effort object conforming to the run's output_schema."},"confidence":{"type":["string","null"],"enum":["high","medium","low",null]},"evidence":{"type":["object","null"],"properties":{"screenshot_url":{"type":["string","null"],"description":"Signed URL, valid 7 days"},"matched_text":{"type":["string","null"]},"checked_at":{"type":"string","format":"date-time"}}},"failure_reason":{"type":["string","null"],"enum":["captcha","auth_required","site_down","timeout","ambiguous","not_found",null]},"usage":{"type":"object","properties":{"duration_ms":{"type":["integer","null"]},"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"cost_usd":{"type":"number"}}},"created_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"BillingHint":{"type":"object","description":"An up-front cost ESTIMATE returned with a started run. The billed figure is always usage.cost_usd on the completed TaskEnvelope; this is a planning hint only and varies with task complexity and tools used.","properties":{"model":{"type":"string","enum":["haiku","sonnet","opus"]},"credit_usd_rate":{"type":"number","description":"USD value of one OpenHelm credit (1 credit = $0.05)."},"estimated_cost_usd":{"type":"object","properties":{"low":{"type":"number"},"high":{"type":"number"}}},"estimated_credits":{"type":"object","properties":{"low":{"type":"integer"},"high":{"type":"integer"}}},"monthly_cap_usd":{"type":["number","null"],"description":"This API key's monthly spend cap, if set."},"note":{"type":"string"}}}}}}