Quickstart
Trigger your first TurfAI workflow over HTTP, from webhook to result.
This walkthrough takes you from nothing to a workflow 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": "jane@example.com",
"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 the event-driven and
chatbot guides.
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" },
"results": {
"classification": { "type": "resume", "confidence": 0.95 },
"extraction": { "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 results object is keyed by what each node produced. 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["results"]
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.