API Overview
Launch published workflows from your own systems with a single POST, then poll or receive a webhook when the run finishes.
Every Published workflow is a REST endpoint. The RamAIn API lets your backend, scheduler, or internal tools launch workflows and agents with structured inputs, track the run as it executes, and fetch the structured result, including any files the run produced.
Base URL: https://api.ramain.ai/api/v1
No code required?
If you'd rather launch workflows without writing any code, use schedules and email triggers instead. Same runs, no API key needed.
Authentication
Requests are authenticated with a workspace API key, passed as a Bearer token:
Authorization: Bearer rmn_live_xJ4...
Create keys under Resources → API keys. Each key gets a name and a set of scopes:

Keys are shown once
The full key (
rmn_live_…) is displayed only at creation time. RamAIn stores just a hash, so copy the key immediately and keep it server-side. You can revoke a key at any time from the same page.
The async model
Workflow runs take seconds to minutes, so the API is asynchronous. Launching a
run returns immediately with 202 Accepted and everything you need to follow
it.
Step 1
Submit. POST /automations/{workflowId}/runs with your workflow's
inputs. The response includes a run_id plus ready-made status_url,
result_url, and events_url.
Step 2
Wait. Poll status_url until the run reaches completed or failed,
or pass a callback_url when you launch and receive a webhook the moment
the run finishes.
Step 3
Fetch. GET result_url for the structured output fields and any
files, each with a signed downloadUrl.
Quickstart
The same three calls (launch, poll, fetch result) in your language of choice.
The examples launch a workflow that takes a single order_number input.
Tab: curl
# 1. Launch a run
curl -X POST https://api.ramain.ai/api/v1/automations/wf_audit_zoho/runs \
-H "Authorization: Bearer rmn_live_xJ4..." \
-H "Content-Type: application/json" \
-d '{
"inputs": { "order_number": "JODL-2041" },
"callback_url": "https://example.com/hooks/ramain"
}'
# 2. Poll the status (repeat until status is completed or failed)
curl https://api.ramain.ai/api/v1/runs/run_9f3ka72 \
-H "Authorization: Bearer rmn_live_xJ4..."
# 3. Fetch the result
curl https://api.ramain.ai/api/v1/runs/run_9f3ka72/result \
-H "Authorization: Bearer rmn_live_xJ4..."
Tab: Python
import time
import requests
BASE = "https://api.ramain.ai/api/v1"
HEADERS = {"Authorization": "Bearer rmn_live_xJ4..."}
# 1. Launch a run
launch = requests.post(
f"{BASE}/automations/wf_audit_zoho/runs",
headers=HEADERS,
json={
"inputs": {"order_number": "JODL-2041"},
"callback_url": "https://example.com/hooks/ramain",
},
)
launch.raise_for_status()
run = launch.json()
# 2. Poll the status until the run is terminal
while True:
status = requests.get(run["status_url"], headers=HEADERS).json()
if status["status"] in ("completed", "failed", "dead_letter"):
break
time.sleep(3)
# 3. Fetch the result
result = requests.get(run["result_url"], headers=HEADERS).json()
print(result["outputs"])
Tab: Node.js
const BASE = "https://api.ramain.ai/api/v1";
const HEADERS = {
Authorization: "Bearer rmn_live_xJ4...",
"Content-Type": "application/json",
};
// 1. Launch a run
const launch = await fetch(`${BASE}/automations/wf_audit_zoho/runs`, {
method: "POST",
headers: HEADERS,
body: JSON.stringify({
inputs: { order_number: "JODL-2041" },
callback_url: "https://example.com/hooks/ramain",
}),
});
const run = await launch.json();
// 2. Poll the status until the run is terminal
let status;
do {
await new Promise((r) => setTimeout(r, 3000));
status = await (await fetch(run.status_url, { headers: HEADERS })).json();
} while (!["completed", "failed", "dead_letter"].includes(status.status));
// 3. Fetch the result
const result = await (await fetch(run.result_url, { headers: HEADERS })).json();
console.log(result.outputs);
The launch response tells you where the run is and where to follow it:
{
"run_id": "run_9f3ka72",
"workflow_id": "wf_audit_zoho",
"status": "pending",
"created_at": "2026-07-21T10:30:00Z",
"status_url": "https://api.ramain.ai/api/v1/runs/run_9f3ka72",
"result_url": "https://api.ramain.ai/api/v1/runs/run_9f3ka72/result",
"events_url": "https://api.ramain.ai/api/v1/runs/run_9f3ka72/events",
"queue": { "position": 0 }
}
Poll politely
A few seconds between polls is plenty; browser workflows rarely finish in under ten seconds, so start around 3 to 5 seconds and back off to 15 to 30 seconds for long-running workflows. If you want step-by-step progress for a UI, read
events_urlinstead of hammering the status endpoint. And if you can receive webhooks, passcallback_urland skip polling entirely.
Idempotency
Network calls fail, and retrying a launch blindly can start the same job
twice. Pass an idempotency_key that identifies the business operation, and
RamAIn will return the original run instead of creating a duplicate when the
same key arrives again:
curl -X POST https://api.ramain.ai/api/v1/automations/wf_audit_zoho/runs \
-H "Authorization: Bearer rmn_live_xJ4..." \
-H "Content-Type: application/json" \
-d '{
"inputs": { "order_number": "JODL-2041" },
"idempotency_key": "order-JODL-2041-create"
}'
A good key is derived from your own data (an order ID, an invoice number, a job ID in your queue), not a random value generated per request. That way a retry after a timeout hits the same key and you can never double-submit the order.
Inputs mirror the workflow
A workflow's API contract is its Input block. Add an input in the editor,
publish, and the API gains that parameter. There is no separate schema to
maintain. Inputs are validated on launch; unknown keys are rejected with
400 INVALID_INPUTS. Saved Passwords referenced by a
workflow are never part of the contract, so credentials stay inside the
workspace.
In-portal API docs
You don't have to write the request by hand. The portal generates live, per-workflow API documentation (endpoint, input table, JSON and curl snippets) under API Docs in the sidebar. It always reflects the latest published version.

Rate & queue behavior
Runs are queued per workspace. If the queue is full the API returns 429;
retry with backoff, and use the launch response's queue.position to see
where a run sits.
Next
Every endpoint, request and response shape, webhook payload, error codes, and run statuses.
Schedules, email triggers, and manual launches: the no-code alternatives.
Was this page helpful?