Code Examples
Code Examples
Complete integration snippets for common use cases. All examples use the flw_test_… sandbox key — replace with your live key for production.
Trigger a Workflow
The most common integration: send data to Flow80 and trigger a workflow execution. Returns 202 Accepted with a run_id you can use to track progress.
json
1// Response: HTTP 202 Accepted2{3 "run_id": "run_yyyyyyyyyyyyyyyy",4 "flow_id": "wf_xxxxxxxxxxxxxxxx",5 "status": "queued",6 "queued_at": "2026-04-08T10:00:00Z"7}Full example — trigger a workflow
PHP
1<?php2// Trigger a Flow80 workflow via API3$api_key = getenv('FLOW80_API_KEY'); // flw_live_...4 5$payload = json_encode([6 'flow_id' => 'wf_xxxxxxxxxxxxxxxx',7 'trigger' => 'api',8 'payload' => [9 'order_id' => 'ORD-' . time(),10 'customer_email' => '[email protected]',11 'items' => [['sku' => 'WIDGET-A', 'qty' => 2]],12 ],13]);14 15$ch = curl_init("https://app.flow80.com/api/v1/flows/execute");16curl_setopt_array($ch, [17 CURLOPT_HTTPHEADER => [18 'Authorization: Bearer ' . $api_key,19 'Content-Type: application/json',20 ],21 CURLOPT_POST => true,22 CURLOPT_POSTFIELDS => $payload,23 CURLOPT_RETURNTRANSFER => true,24 CURLOPT_TIMEOUT => 30,25]);26$response = curl_exec($ch);27$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);28curl_close($ch);29 30$result = json_decode($response, true);31if ($http_code === 202) {32 echo "Workflow triggered! Run ID: " . $result['run_id'];33} else {34 echo "Error ($http_code): " . ($result['error'] ?? $response);35}PYTHON
1import os2import requests3import time4 5API_KEY = os.environ.get("FLOW80_API_KEY") # flw_live_...6 7payload = {8 "flow_id": "wf_xxxxxxxxxxxxxxxx",9 "trigger": "api",10 "payload": {11 "order_id": f"ORD-{int(time.time())}",12 "customer_email": "[email protected]",13 "items": [{"sku": "WIDGET-A", "qty": 2}],14 },15}16 17resp = requests.post(18 f"https://app.flow80.com/api/v1/flows/execute",19 headers={20 "Authorization": f"Bearer {API_KEY}",21 "Content-Type": "application/json",22 },23 json=payload,24 timeout=30,25)26 27if resp.status_code == 202:28 data = resp.json()29 print(f"Workflow triggered! Run ID: {data['run_id']}")30else:31 print(f"Error ({resp.status_code}): {resp.text}")NODE
1import os from 'os';2import crypto from 'crypto';3 4const API_KEY = process.env.FLOW80_API_KEY!; // flw_live_...5 6async function triggerFlow(flowId: string, payload: Record<string, unknown>) {7 const orderId = `ORD-${Date.now()}`;8 9 const response = await fetch(`https://app.flow80.com/api/v1/flows/execute`, {10 method: 'POST',11 headers: {12 'Authorization': `Bearer ${API_KEY}`,13 'Content-Type': 'application/json',14 },15 body: JSON.stringify({16 flow_id: flowId,17 trigger: 'api',18 payload: { order_id: orderId, ...payload },19 }),20 signal: AbortSignal.timeout(30_000),21 });22 23 if (!response.ok) {24 throw new Error(`API error ${response.status}: ${await response.text()}`);25 }26 27 const result = await response.json();28 console.log(`Workflow triggered! Run ID: ${result.run_id}`);29 return result;30}31 32triggerFlow('wf_xxxxxxxxxxxxxxxx', {33 customer_email: '[email protected]',34 items: [{ sku: 'WIDGET-A', qty: 2 }],35});RUBY
1require 'net/http'2require 'json'3require 'time'4 5API_KEY = ENV['FLOW80_API_KEY'] # flw_live_...6BASE_URL = 'https://app.flow80.com/api/v1'7 8payload = {9 flow_id: 'wf_xxxxxxxxxxxxxxxx',10 trigger: 'api',11 payload: {12 order_id: "ORD-#{Time.now.to_i}",13 customer_email: '[email protected]',14 items: [{ sku: 'WIDGET-A', qty: 2 }],15 },16}17 18uri = URI("#{BASE_URL}/flows/execute")19req = Net::HTTP::Post.new(uri)20req['Authorization'] = "Bearer #{API_KEY}"21req['Content-Type'] = 'application/json'22req.body = JSON.generate(payload)23 24Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, timeout: 30) do |http|25 res = http.request(req)26 if res.is_a?(Net::HTTPSuccess)27 data = JSON.parse(res.body)28 puts "Workflow triggered! Run ID: #{data['run_id']}"29 else30 puts "Error (#{res.code}): #{res.body}"31 end32endGO
1package main2 3import (4 "bytes"5 "encoding/json"6 "fmt"7 "net/http"8 "os"9 "strconv"10 "time"11)12 13func triggerFlow(flowID string, payload map[string]interface{}) error {14 apiKey := os.Getenv("FLOW80_API_KEY")15 body, _ := json.Marshal(map[string]interface{}{16 "flow_id": flowID,17 "trigger": "api",18 "payload": payload,19 })20 req, err := http.NewRequest("POST", "https://app.flow80.com/api/v1/flows/execute", bytes.NewBuffer(body))21 if err != nil {22 return err23 }24 req.Header.Set("Authorization", "Bearer "+apiKey)25 req.Header.Set("Content-Type", "application/json")26 req.Header.Set("User-Agent", "Flow80-Go/1.0")27 28 client := &http.Client{Timeout: 30 * time.Second}29 resp, err := client.Do(req)30 if err != nil {31 return err32 }33 defer resp.Body.Close()34 35 if resp.StatusCode != 202 {36 return fmt.Errorf("API error: %d", resp.StatusCode)37 }38 39 var result map[string]interface{}40 json.NewDecoder(resp.Body).Decode(&result)41 fmt.Println("Workflow triggered! Run ID:", result["run_id"])42 return nil43}44 45func main() {46 triggerFlow("wf_xxxxxxxxxxxxxxxx", map[string]interface{}{47 "order_id": fmt.Sprintf("ORD-%d", time.Now().Unix()),48 "customer_email": "[email protected]",49 "items": []map[string]int{{"sku": "WIDGET-A", "qty": 2}},50 })51}CURL
1curl -X POST "https://app.flow80.com/api/v1/flows/execute" \2 -H "Authorization: Bearer flw_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \3 -H "Content-Type: application/json" \4 -d '{5 "flow_id": "wf_xxxxxxxxxxxxxxxx",6 "trigger": "api",7 "payload": {8 "order_id": "ORD-12345",9 "customer_email": "[email protected]",10 "items": [{"sku": "WIDGET-A", "qty": 2}]11 }12 }'Poll Run Status
After triggering a workflow, poll GET /flows/runs/:id until the run reaches a terminal state. For production, consider using webhooks instead — they're far more efficient than polling.
Poll run status until terminal state
PHP
1<?php2// Poll a workflow run until completion (max 30 attempts, 2s interval)3$run_id = $result['run_id'] ?? null;4$attempt = 0;5$max_attempts = 30;6 7while ($attempt < $max_attempts) {8 $ch = curl_init("https://app.flow80.com/api/v1/flows/runs/{$run_id}");9 curl_setopt_array($ch, [10 CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $api_key],11 CURLOPT_RETURNTRANSFER => true,12 ]);13 $res = curl_exec($ch);14 $data = json_decode($res, true);15 curl_close($ch);16 17 $status = $data['status'] ?? 'unknown';18 echo "Status: $status\n";19 20 if (in_array($status, ['completed', 'failed', 'cancelled'])) {21 echo "Final status: $status\n";22 break;23 }24 25 sleep(2);26 $attempt++;27}PYTHON
1import requests2import time3 4run_id = result.get('run_id')5for attempt in range(30):6 resp = requests.get(7 f"https://app.flow80.com/api/v1/flows/runs/{run_id}",8 headers={"Authorization": f"Bearer {API_KEY}"},9 )10 data = resp.json()11 status = data.get('status', 'unknown')12 print(f"[{attempt+1}] Status: {status}")13 14 if status in ('completed', 'failed', 'cancelled'):15 print(f"Final: {status}")16 break17 time.sleep(2)NODE
1const runId = result.run_id;2const maxAttempts = 30;3for (let attempt = 0; attempt < maxAttempts; attempt++) {4 const resp = await fetch(`https://app.flow80.com/api/v1/flows/runs/${runId}`, {5 headers: { 'Authorization': `Bearer ${API_KEY}` },6 });7 const data = await resp.json();8 console.log(`[${attempt+1}] Status: ${data.status}`);9 if (['completed', 'failed', 'cancelled'].includes(data.status)) {10 console.log(`Final: ${data.status}`);11 break;12 }13 await new Promise(r => setTimeout(r, 2000));14}RUBY
1require 'net/http'2require 'json'3 4run_id = result['run_id']530.times do |attempt|6 uri = URI("#{BASE_URL}/flows/runs/#{run_id}")7 req = Net::HTTP::Get.new(uri)8 req['Authorization'] = "Bearer #{API_KEY}"9 res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }10 data = JSON.parse(res.body)11 status = data['status']12 puts "[#{attempt+1}] Status: #{status}"13 break if ['completed', 'failed', 'cancelled'].include?(status)14 sleep(2)15endGO
1// Poll run status (Go routine + channel)2go func() {3 for attempt := 0; attempt < 30; attempt++ {4 req, _ := http.NewRequest("GET", fmt.Sprintf("https://app.flow80.com/api/v1/flows/runs/%s", runID), nil)5 req.Header.Set("Authorization", "Bearer "+apiKey)6 resp, _ := client.Do(req)7 var data map[string]interface{}8 json.NewDecoder(resp.Body).Decode(&data)9 fmt.Printf("[%d] Status: %v\n", attempt+1, data["status"])10 if slices.Contains([]string{"completed", "failed", "cancelled"}, data["status"]) {11 break12 }13 time.Sleep(2 * time.Second)14 }15}()CURL
1# Polling requires a loop — use your language's HTTP client2# This example uses bash + jq:3RUN_ID="run_yyyyyyyyyyyyyyyy"4for i in $(seq 1 30); do5 STATUS=$(curl -s "https://app.flow80.com/api/v1/flows/runs/${RUN_ID}" \6 -H "Authorization: Bearer flw_test_..." | jq -r '.status')7 echo "[$i] Status: $STATUS"8 [[ "$STATUS" =~ completed|failed|cancelled ]] && break9 sleep 210doneMore Examples
Additional examples are available in each guide: