Dhanur AI
Docs menu· Tool run API

Tool run API

Live

Run your own tools from your own code with a project API key, and read the result in the same request.

The tool run API runs one of your own tools with the inputs you send, and answers when the run is finished. It uses the same project API keys as the run API for agents.

  • Only published tools run, always on their latest published version.
  • A key reaches only its own project's tools. A tool in another project, or another workspace, answers 404.
  • Every run is recorded. It shows on the tool's Run tab as an API run, with its inputs, each step's result and its rupee cost. Secrets and inputs marked Hide in run logs are masked there.
  • Platform limits still apply. If AI work is paused on the platform, or the daily spending limit is reached, runs are refused. A single run stops once it has spent ₹5.

Before you start

  1. Build and publish the tool. Its Run tab shows the endpoint and ready-to-use examples.
  2. An Owner or Admin creates an API key under Integrations, then API keys. Keep it on your server, never in a web page or a mobile app.

Run a tool

POST /v1/api/tools/{tool_id}/runs

Send the key as Authorization: Bearer dhk_… and the inputs as JSON, using the input keys from the builder:

curl -X POST "https://engine.dhanurai.com/v1/api/tools/ctl_.../runs" \
  -H "Authorization: Bearer $DHANUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"order_id": "A1234"}}'
const res = await fetch("https://engine.dhanurai.com/v1/api/tools/ctl_.../runs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.DHANUR_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ inputs: { order_id: "A1234" } }),
});
const run = await res.json();
import os
import httpx

run = httpx.post(
    "https://engine.dhanurai.com/v1/api/tools/ctl_.../runs",
    headers={"Authorization": f"Bearer {os.environ['DHANUR_API_KEY']}"},
    json={"inputs": {"order_id": "A1234"}},
    timeout=70,
).json()

The body has one field, inputs. Leave out optional inputs you don't have. Values are checked the same way as on the form: numbers can be sent as numbers or text, yes-or-no inputs as true or false, and JSON inputs as any JSON value.

The request waits for the run to finish, for up to 60 seconds. Set your client's timeout a little higher.

The answer

{
  "run_id": "trn_...",
  "tool_id": "ctl_...",
  "version": 3,
  "status": "done",
  "output": {"status": "shipped", "eta": "2026-09-20"},
  "error": null,
  "error_code": null,
  "steps": [
    {"id": "get_order", "name": "Get the order", "status": "ok", "duration_ms": 412},
    {"id": "summary", "name": "Write a status line", "status": "ok", "duration_ms": 950}
  ],
  "cost_inr": 0.0412,
  "duration_ms": 1391
}
Field Meaning
status done when the tool finished, failed when it stopped
output The tool's result: text or JSON, as set in its Output. null when the run failed.
error Why the run stopped, in plain words, such as "Step 1 (Get the order): The site answered with status 404."
error_code step (a step failed), cost_cap (the run's spending limit), time (the run took too long), paused or daily_cap (platform limits), internal (our error)
steps The steps that ran, in order, with their status and how long each took
cost_inr What the run cost in rupees (AI and connected-app use)

A tool can end early on purpose, when a Condition step stops it. That still counts as done, with the condition's result as output.

Secret values never appear in the answer, even if another service sends them back.

Status codes

Code When
200 The run finished. Check status: a run whose step failed also answers 200, with status: "failed".
401 The key is missing, wrong or revoked.
404 No tool with this id in the key's project.
409 The tool isn't published yet.
422 The inputs are wrong. detail lists every problem, such as "Fill in Order number."
429 Too many requests with this key (30 runs a minute). Wait for the seconds in Retry-After.
503 AI work is paused on the platform, or the daily spending limit was reached. The body has error_code paused or daily_cap. Try again later.
504 The run took longer than 60 seconds and was stopped.

Good practice

  • Retry with care. A tool that changes data may have made some changes before it failed. Check the run on the Run tab, or in your other system, before running it again.
  • One key per system, so you can revoke one without stopping the others.
  • Keep secrets in tool secrets. Your code only sends inputs; the tool adds keys for the services it calls. See Tool secrets.

Last updated 24 September 2026

Something unclear or wrong? Tell us