curl --request GET \
--url https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "68b1c0d4e7b91d003c45a1f2",
"app_id": "6820f3a4e7b91d003c45a1f2",
"name": "Email me new signups",
"status": "active",
"social_post": {
"platform": "linkedin",
"title": "Meet our new app",
"body": "Our new app is ready to try.",
"hashtags": [
"launch"
]
},
"file_key": "email-me-new-signups",
"description": "Sends an email whenever a User record is created.",
"status_reason": "consecutive_failures",
"current_version_id": "9f2c1a7b3e5d84f60c1b2a9e7d4f8c3b6a5e2d1f0c9b8a7e6d5c4b3a2f1e0d9c",
"trigger": {
"config": {
"cron_expression": "0 9 * * *",
"timezone": "UTC",
"trigger_type": "scheduled"
}
},
"app_type_context": {
"anchor_message_id": "68b1c0d4e7b91d003c45a1f2",
"conversation_id": "0195f2a1-4c3e-7b21-9f0d-2a5c8e1b4d77"
},
"last_run_at": "2026-08-25T09:12:44Z",
"last_run_status": "success",
"consecutive_failures": 0,
"total_runs": 48,
"successful_runs": 44,
"failed_runs": 3,
"created_date": "2026-07-02T11:04:00Z",
"updated_date": "2026-08-20T16:31:00Z",
"created_by": "you@example.com",
"definition": {
"do": [],
"document": {
"dsl": "1.0.0",
"name": "notify",
"version": "1.0.0"
}
}
}Get workflow
Returns the specified workflow, including the full definition it currently runs.
This is the only endpoint that returns definition.
curl --request GET \
--url https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/workflows/{workflow_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "68b1c0d4e7b91d003c45a1f2",
"app_id": "6820f3a4e7b91d003c45a1f2",
"name": "Email me new signups",
"status": "active",
"social_post": {
"platform": "linkedin",
"title": "Meet our new app",
"body": "Our new app is ready to try.",
"hashtags": [
"launch"
]
},
"file_key": "email-me-new-signups",
"description": "Sends an email whenever a User record is created.",
"status_reason": "consecutive_failures",
"current_version_id": "9f2c1a7b3e5d84f60c1b2a9e7d4f8c3b6a5e2d1f0c9b8a7e6d5c4b3a2f1e0d9c",
"trigger": {
"config": {
"cron_expression": "0 9 * * *",
"timezone": "UTC",
"trigger_type": "scheduled"
}
},
"app_type_context": {
"anchor_message_id": "68b1c0d4e7b91d003c45a1f2",
"conversation_id": "0195f2a1-4c3e-7b21-9f0d-2a5c8e1b4d77"
},
"last_run_at": "2026-08-25T09:12:44Z",
"last_run_status": "success",
"consecutive_failures": 0,
"total_runs": 48,
"successful_runs": 44,
"failed_runs": 3,
"created_date": "2026-07-02T11:04:00Z",
"updated_date": "2026-08-20T16:31:00Z",
"created_by": "you@example.com",
"definition": {
"do": [],
"document": {
"dsl": "1.0.0",
"name": "notify",
"version": "1.0.0"
}
}
}Authorizations
Personal access token, sent as Authorization: Bearer <token>.
Path Parameters
ID of the app whose workflows you want to work with.
ID of the workflow, as returned in id by List workflows.
Response
The workflow, including its current definition.
ID of the workflow.
"68b1c0d4e7b91d003c45a1f2"
ID of the app the workflow belongs to.
"6820f3a4e7b91d003c45a1f2"
Name of the workflow.
"Email me new signups"
Whether the workflow runs: active, inactive, or archived. See Workflow status for what each means and how it changes.
"active"
Current post content for a social publishing workflow, or null when no linked post is available.
Show child attributes
Show child attributes
Name of the workflow's file in the app's code. This is null on workflows saved before files were kept.
"email-me-new-signups"
What the workflow is for.
"Sends an email whenever a User record is created."
Why Base44 changed the workflow's status on its own, as one of consecutive_failures, end_condition_reached, migration_activation_failed, or workflows_not_available. This is null when you changed the status yourself. See Workflow status for what each code means.
"consecutive_failures"
Version the workflow runs today, as the SHA-256 hash of that definition. This is null until a definition is saved.
"9f2c1a7b3e5d84f60c1b2a9e7d4f8c3b6a5e2d1f0c9b8a7e6d5c4b3a2f1e0d9c"
What starts the workflow. The trigger sits under config, keyed by trigger_type.
{
"config": {
"cron_expression": "0 9 * * *",
"timezone": "UTC",
"trigger_type": "scheduled"
}
}
Caller-specific context captured when the workflow was created, such as the conversation that authored it. This API never sets it, so a workflow you create through it starts with null. Updating a workflow through this API doesn't clear an existing value either, so a workflow originally authored through the Base44 app editor or a superagent keeps its context here even after an API update.
{
"anchor_message_id": "68b1c0d4e7b91d003c45a1f2",
"conversation_id": "0195f2a1-4c3e-7b21-9f0d-2a5c8e1b4d77"
}
When the workflow last started running, as an ISO 8601 UTC timestamp. This is null before its first run.
"2026-08-25T09:12:44Z"
How the workflow's most recent run ended: success, failed, or cancelled. This is null before the first run. See Workflow status for how this compares to a run's own status.
"success"
Runs that have failed in a row. Resets on the next success.
0
Runs the workflow has started, ever.
48
Runs that finished successfully, ever.
44
Runs that ended in an error, ever.
3
When the workflow was created, as an ISO 8601 UTC timestamp.
"2026-07-02T11:04:00Z"
When the workflow was last changed, as an ISO 8601 UTC timestamp.
"2026-08-20T16:31:00Z"
Email of whoever created the workflow.
"you@example.com"
The steps the workflow runs, as a CNCF Serverless Workflow v1.0 document. This is null when no version has been saved yet. Only this endpoint returns it. List workflows leaves it out.
{
"do": [],
"document": {
"dsl": "1.0.0",
"name": "notify",
"version": "1.0.0"
}
}
Was this page helpful?