INTEGRATIONS

REST API

Call Converge engines and read or write projects over HTTPS with an API key. Base URL, endpoints, errors, rate limits and the OpenAPI spec.

Last edited

Overview

The REST API runs every Converge engine function on the server and lets your own programs list, read and save projects. It is versioned under /v1, takes JSON in and returns JSON. You authenticate with a personal API key, which acts as the member who created it: same company, same permissions, same licence seats.

The engine functions are the same ones you call from scripts, with the same inputs and outputs.

Base URL

The API is served from the same address as the app:

text
https://<your-app-host>/v1

Integrations > REST API in the app shows the exact base URL for your deployment, and every snippet there uses it.

OpenAPI spec

An OpenAPI 3.1 description is public (no key needed):

text
https://<your-app-host>/v1/openapi.json

It is generated from the same engine catalogue and key scopes the server runs on, so it lists every engine function with its JSON Schema input and an example. The OpenAPI 3.1 button on Integrations > REST API opens it.

Authentication

  1. Create a key on Integrations > API keys.
  2. Keep it in an environment variable, CONVERGE_API_KEY.
  3. Send it on every request:
http
Authorization: Bearer cvg_...

A key is cvg_ followed by 43 characters. A request with a bearer header never falls back to a browser session cookie. Each endpoint needs a scope on the key; see the table below and API keys.

Endpoints

Method and path Scope What it does
GET /v1/me any valid key The member, company, plan and licences behind the key.
GET /v1/engine/functions any valid key Every engine function: name, module, title, description, input schema, example.
GET /v1/engine/functions/{name} any valid key One function's details.
POST /v1/engine/functions/{name} engine:run Runs the function. The body is its input.
GET /v1/projects projects:read The company's saved projects.
GET /v1/projects/{id} projects:read One project with its data.
PUT /v1/projects/{id} projects:write Creates or replaces a project.
DELETE /v1/projects/{id} projects:write Deletes a project.
GET /v1/projects/{id}/versions projects:read The project's saved versions.
POST /v1/projects/{id}/versions projects:write Saves a named version.
POST /v1/mcp any valid key; each tool checks its own The MCP server.

Every other endpoint (team, seats, AI, key management, roles, sign-off, admin) refuses API keys with 403. You sign in to the app for those.

Run an engine function

http
POST /v1/engine/functions/econ.metrics
Authorization: Bearer cvg_...
Content-Type: application/json

{ "cashFlows": [-1000, 300, 400, 500], "discountRates": [0.1], "discounting": "start-period" }

The answer has this shape:

text
{ "name": "econ.metrics", "module": "econ", "result": { "npv": [...], "irr": ..., "paybackYears": ..., ... }, "ms": <server time> }

name and module identify the call, result is the function output, and ms is the server time in milliseconds. Running a function also needs the member's permission to run scripts. An empty body is read as {}. The body limit is 4 MB.

Units are field units by default: psia, degF, STB/d, Mscf/d, scf/STB, ft, in, md, cp, days. Add "units": "metric" at the top level of the body to send and receive bara, degC, m, sm3/d and sm3/sm3. Unknown input keys are refused with the list of valid keys.

The list from GET /v1/engine/functions also includes project fluid-model tools named eos.model.*: the AI Engineer's compositional tools, run read-only on a saved project's fluid models. They need projectId in the body and a key with both engine:run and projects:read.

Save a project

http
PUT /v1/projects/{id}
Content-Type: application/json

{ "name": "Field A", "data": { ... } }
  • id: 1 to 64 letters, digits, _ or -.
  • name: 1 to 200 characters.
  • data: the project data, at most 1.5 MB as JSON.

The answer is { "project": ... } with 201 when the project is new and 200 when it replaced an existing one. Creating needs the member's create-project permission and editing needs the edit permission. The company's plan limit on the number of projects applies (402). The demo project and approved reporting versions are never saved. Deleting needs the delete-project permission, and a project that holds an approved reporting version cannot be deleted (409).

POST /v1/projects/{id}/versions takes { "label": "..." } (1 to 200 characters) and returns { "version": ... } with 201.

Seats

API access is the licensable Integrations module. Every key request holds the member's Integrations seat, and an engine call also holds the seat of the function's module (for example Well performance for well.nodal), exactly as if the member had opened the module in the app. The member and their scripts share one seat per module. Black-oil PVT needs no seat.

There is no heartbeat: each call refreshes the seat, and it is released 3 minutes after the last call. If every seat is taken, the answer is 409 no_seat with details.holders naming who holds them and since when.

Rate limits

Limit Value
Requests per key 120 per minute, REST and MCP together
Failed key attempts 20 per minute per client address
Engine busy 429 with Retry-After: 30

A 429 answer carries a Retry-After header in seconds, and retryAfter in the body. Engine calls run on the server with a time limit; a calculation that runs past it returns 422 engine_error with details.timeout: true.

Errors

Every error has the same shape:

json
{ "error": { "code": "validation_failed", "message": "...", "details": { "fields": { "fluid.api": "..." } } } }
HTTP Code When
400 validation_failed Invalid input or JSON. details.fields names each field.
401 unauthenticated Missing, malformed, unknown, revoked or expired key.
402 plan_limit No licence for the module, no API access on the plan, or the project limit.
403 forbidden The key lacks the scope, the member lacks the permission, the endpoint refuses keys, or the account is disabled.
403 email_not_verified The member has not verified their email.
403 tenant_suspended The company account is suspended.
404 not_found Unknown endpoint, function or project.
409 no_seat Every seat of the module is in use.
409 conflict For example, deleting a project with approved reporting versions.
422 engine_error The calculation ran but could not produce a result for this input (out of range, no solution, time limit).
429 rate_limited Too many requests.
500 internal An error on the server.

Snippets

Integrations > REST API > Snippets generates a ready-to-run call for any function in curl, Python or JavaScript, using that function's documented example input. The key is always read from CONVERGE_API_KEY, never written into the snippet.

bash
curl -sS -X POST "https://<your-app-host>/v1/engine/functions/pvt.gasProperties" \
  -H "Authorization: Bearer $CONVERGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"psia":3000,"TF":200,"gasSG":0.7}'
python
import os
import requests  # pip install requests

resp = requests.get(
    "https://<your-app-host>/v1/projects",
    headers={"Authorization": f"Bearer {os.environ['CONVERGE_API_KEY']}"},
    timeout=30,
)
resp.raise_for_status()
for p in resp.json()["projects"]:
    print(p["id"], p["name"], p["updatedAt"])