Quickstart
Trigger your first TurfAI workflow over HTTP, from webhook to result.
Trigger a workflow and read its result in four HTTP calls: create a webhook, trigger it, poll with the returned token, and read the output. You'll need a TurfAI account, a JWT (see Authentication), and the ID of a workflow (an "activity") to trigger.
Base URLs: staging is https://apisandbox.turfai.in/api, local development is
http://localhost:1338/api. All examples below use staging.
The flow
1. Create a webhook for your workflow
A webhook binds a public trigger URL to one workflow (activity). This call needs your JWT.
curl -X POST https://apisandbox.turfai.in/api/webhooks \
-H "Authorization: Bearer $TURFAI_JWT" \
-H "Content-Type: application/json" \
-d '{
"activity": 123,
"name": "Quickstart Webhook"
}'{
"success": true,
"data": {
"id": 1,
"name": "Quickstart Webhook",
"url": "https://apisandbox.turfai.in/api/webhooks/trigger/1",
"secret_key": "a1b2c3d4...64_char_hex...",
"active": true,
"trigger_count": 0
}
}Save the url and secret_key. The secret is shown in full only on create and
regenerate — store it like a password.
2. Trigger the workflow
The trigger endpoint is public — it authenticates with the X-Webhook-Secret header,
not your JWT. Any JSON body becomes the workflow's inputs.
curl -X POST https://apisandbox.turfai.in/api/webhooks/trigger/1 \
-H "X-Webhook-Secret: $WEBHOOK_SECRET" \
-H "Content-Type: application/json" \
-d '{
"candidate_name": "Jane Smith",
"email": "[email protected]",
"resume_file_id": "1ABC123xyz"
}'{
"success": true,
"execution_id": 456,
"message": "Workflow execution started",
"polling_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}You get back an execution_id and a short-lived polling_token (a JWT, ~1 hour) scoped to
polling this one execution.
To send files, use multipart/form-data instead of JSON. Each uploaded file is stored as
a document and injected into the workflow as inputs.<field>_file_url and
inputs.<field>_document_id. See Event-driven automation and
Build a chatbot.
3. Poll for the result
Use the polling_token as a Bearer token to check status. Poll every 2–5 seconds and stop
on a terminal status (completed or failed).
curl https://apisandbox.turfai.in/api/workflow-executions/456 \
-H "Authorization: Bearer $POLLING_TOKEN"{
"data": {
"id": 456,
"status": "completed",
"inputs": { "candidate_name": "Jane Smith" },
"outputs": {
"Classify resume-classify-1": { "type": "resume", "confidence": 0.95 },
"Extract fields-extract-1": { "name": "Jane Smith", "skills": ["Python", "ML"] }
},
"started_at": "2025-11-24T10:00:00.000Z",
"completed_at": "2025-11-24T10:00:45.000Z"
}
}Status values: queued (waiting), running (executing), completed (success), failed
(check the error field). A long-running workflow with a human step can also report
awaiting_user_input — see the HITL guide.
4. Read the output
The data.outputs object holds each node's output, keyed by "<node label>-<node id>". Pull the field you need with
JSONPath in your own code, or chain another task in the workflow that emails or POSTs the
result somewhere.
A complete poller
import os, time, requests
BASE = "https://apisandbox.turfai.in/api"
def trigger(payload):
r = requests.post(
os.environ["WEBHOOK_URL"], json=payload,
headers={"X-Webhook-Secret": os.environ["WEBHOOK_SECRET"]},
)
r.raise_for_status()
return r.json()
def poll(execution_id, token, attempts=30):
for _ in range(attempts):
r = requests.get(f"{BASE}/workflow-executions/{execution_id}",
headers={"Authorization": f"Bearer {token}"})
r.raise_for_status()
data = r.json()["data"]
if data["status"] == "completed":
return data["outputs"]
if data["status"] == "failed":
raise RuntimeError(data.get("error"))
time.sleep(2)
raise TimeoutError("polling timed out")
started = trigger({"candidate_name": "Jane Smith", "resume_file_id": "1ABC123xyz"})
print(poll(started["execution_id"], started["polling_token"]))Next steps
- Concepts — understand workflows, task types, agents, and RAG.
- Build a chatbot or an agent with tools.
- API reference — the full endpoint and task-type catalog.