Compute

Run governed outbound work for your organization — prepared, parameterized HTTP calls and one-off generic requests — bounded by a layered egress allow-list and Vault credential indirection, so secrets are resolved server-side and never exposed to the caller.

What ships today

Compute v0 ships the HTTP Collections family and the standalone compute.http.request capability. The Functions family (managed serverless handlers) and a Browser family are coming soon — their zones and permissions are declared for forward-compatibility, but the endpoints respond 501 for now. Everything in this guide other than HTTP Collections and generic HTTP is preview.

Key Concepts

Compute is the platform's executor: it makes outbound calls on behalf of members, agents, automations, and apps, under the same zones, connections, and Vault model the rest of Ergon uses. It is organized as a family of capabilities that share one outbound-call engine and one set of guardrails.

The Compute Family

Two things are live today. HTTP Collections are prepared, parameterized calls — think Postman, but governed by the platform. The standalone compute.http.request is the “let this agent just call an API” primitive — a one-off call gated by the org-border compute:http:request capability. The Functions family (serverless handlers on AWS Lambda) and a Browser family are coming soon.

One Engine, One Set of Guardrails

Whether a call comes from a collection request or a generic HTTP request, it runs through the same engine: render the final target, check it against the layered egress allow-list, resolve any Vault credential server-side, apply it, make the call, and write an invocation row recording status, timing, egress records, and which credential references were resolved (references only — never values).

Reactions and scheduling are not a Compute concern. Compute is the executor; the central Automations service decides cadence and triggers. An automation step becomes “invoke a Compute request” or “invoke compute.http.request.”

HTTP Collections

A collection is a federated zone that holds shared configuration plus a set of requests. Collections live inside collection folders, which are organizational containers — creating a folder mints its zone, and so does creating a collection inside it.

A Collection Holds Config; Requests Are the Leaves

The collection is the unit of shared config: a base_url, variables referenced as {{vars.*}}, default_headers, an auth_strategy, and the Vault credential references its requests may use. Each request is a governed leaf — one prepared call with a method, a path appended to the base URL, headers, query, body, and a params_schema for caller-filled inputs. You grant on the collection to cover all of its requests, or on a single request to scope to one call.

Collections are not typed by API style — REST and GraphQL both compile to a single outbound HTTP call, so the style lives on the request's kind (rest or graphql). This lets one logical integration mix both under one base URL and one credential.

# 1 — Create a collection inside a folder
curl -X POST https://platform.ergondata.ai/api/v1/compute/collection-folders/{folder_id}/collections \
  -H "Authorization: Bearer {token}" \
  -H "X-Company-Id: {company_id}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Stripe",
    "base_url": "https://api.stripe.com",
    "auth_strategy": {
      "kind": "bearer",
      "credential_ref": {"namespace": "payments", "credential": "stripe_secret_key"}
    },
    "credential_refs": [{"namespace": "payments", "credential": "stripe_secret_key"}]
  }'

# 2 — Add a request (a leaf) with a non-secret param
curl -X POST https://platform.ergondata.ai/api/v1/compute/collections/{collection_id}/requests \
  -H "Authorization: Bearer {token}" \
  -H "X-Company-Id: {company_id}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Get invoice",
    "method": "GET",
    "path": "/v1/invoices/{{params.invoice_id}}",
    "params_schema": {
      "type": "object",
      "required": ["invoice_id"],
      "properties": {"invoice_id": {"type": "string"}}
    },
    "expose_as_tool": true
  }'

Set expose_as_tool on a request to register it in IAM's tool registry. Its params_schema becomes the tool's args_schema, so agents and automations know exactly which parameters to pass.

Invoking a Request

To run a request, POST to its /invoke endpoint with a params object. These are non-secret, invoke-time inputs — distinct from the collection's static {{vars.*}} and from Vault secrets. Params are treated as untrusted caller input: they are validated against the request's params_schema, rendered into the path, query, headers, or body as {{params.*}}, and can never override the auth slots or escape the host pinned by the collection's base URL.

curl -X POST https://platform.ergondata.ai/api/v1/compute/collections/{collection_id}/requests/{request_id}/invoke \
  -H "Authorization: Bearer {token}" \
  -H "X-Company-Id: {company_id}" \
  -H "Content-Type: application/json" \
  -d '{"params": {"invoice_id": "in_1MqABCdef"}}'

Every invoke produces an invocation row you can read back from the Invocations endpoints — with status, timing, egress records, and the credential references that were resolved (references only). For a one-off call that is not part of a collection, use the standalone POST /http/request instead, gated by the org-border compute:http:request capability.

Egress Model

Every outbound call — collection request or generic HTTP — is bounded by a layered egress allow-list. A target is allowed only if every applicable layer permits the final rendered URL, checked against its resolved IP so a permitted hostname that resolves into a private range is still refused.

  • Platform floor (always on). A hardcoded, non-configurable layer that denies private (10/8, 172.16/12, 192.168/16), loopback, link-local, and reserved ranges — including the cloud metadata endpoint 169.254.169.254. It protects platform internals from SSRF, has no setting, and no endpoint.
  • Company allow-list (deny by default). One policy per organization, disabled / allow-none out of the box. An administrator must enable it and define the hostname allow-list (specific hosts/suffixes, or ["*"] for all public hosts, still subject to the floor). This is the superset every principal draws from.
  • Per-principal subset (optional). When the compute:http:request capability is toggled on an agent or automation, that consumer may carry its own allow-list — a subset of the company policy, never a superset. If absent, the principal inherits the company allow-list as-is.
# Enable company egress and set the allow-list (admin)
curl -X PUT https://platform.ergondata.ai/api/v1/compute/egress/company-policy \
  -H "Authorization: Bearer {token}" \
  -H "X-Company-Id: {company_id}" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true, "allow_hosts": ["api.stripe.com", "*.example.com"]}'

# Restrict a specific agent to a subset of the company list
curl -X PUT https://platform.ergondata.ai/api/v1/compute/egress/principal-policies/{principal_id} \
  -H "Authorization: Bearer {token}" \
  -H "X-Company-Id: {company_id}" \
  -H "Content-Type: application/json" \
  -d '{"principal_type": "agent", "allow_hosts": ["api.stripe.com"]}'

The per-principal list is intersected with the company policy at save time — entries the company list would not permit are silently dropped, so a per-principal policy can only ever narrow the company allow-list.

Credentials & Vault

Compute never stores secret values. A collection declares credential_refs as a list of {namespace, credential} pointers into Vault — references only. The secret is resolved at execution time and redacted from logs, invocation output, and audit.

Credential Indirection

A collection has its own IAM principal (minted lazily on first connect to Vault). To use a credential, the collection connects to the Vault namespace and is granted vault:credentials:use on it. At invoke time, Compute resolves the credential as the collection's principal, applies it to the call, and redacts it. The triggering caller — an agent holding only compute:collections:requests:invoke — holds no vault:*, never connects to Vault, and never sees the secret. This is the recommended shape for use-without-seeing.

Standalone calls have no indirection

The generic compute.http.request has no collection principal to resolve a secret on your behalf. So if a standalone call references a Vault credential, the calling principal itself must hold vault:credentials:use. Resolution is still server-side and redacted — the caller is authorized for the secret but never handles its bytes.

Sharing a collection with another principal uses the platform's unified access model: grant on the collection zone, or let a consumer raise a connection request that the zone admin approves. For the full lifecycle — principals, grants, connection requests, and runtime enforcement — see the Permissions guide.

Ready to start building? Head to the Compute API Reference for the complete list of endpoints, request parameters, and response schemas.