From a919f40abf32f4f5d38d83ca96993eae1c65097b Mon Sep 17 00:00:00 2001 From: Will Strinz Date: Thu, 22 Oct 2026 09:41:19 -0500 Subject: [PATCH] [GG-1952] Document workflow email content endpoint Co-Authored-By: Claude Opus 5.5 --- source/includes/rest/_workflows.md | 203 ++++++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 1 deletion(-) diff --git a/source/includes/rest/_workflows.md b/source/includes/rest/_workflows.md index 70030c15eac..f2beb878d46 100644 --- a/source/includes/rest/_workflows.md +++ b/source/includes/rest/_workflows.md @@ -305,6 +305,7 @@ const body = await response.json(); "properties": { "automation_email_id": "957660884" }, "incomplete": false, "actions_required": [], + "email": { "id": "957660884", "subject": "Welcome, {{ subscriber.first_name }}!" }, "derived": { "type_name": "Send an email to a person", "summary": "Send \"Welcome!\"", @@ -435,7 +436,7 @@ branch still has an id. action - id, type, action_type, provider_id, status, properties, incomplete, actions_required + id, type, action_type, provider_id, status, properties, incomplete, actions_required, email (send_email only) type_name, summary, email_title @@ -497,6 +498,13 @@ Some configuration is never published. A `drip/http_post` action responds with a credentials; only `derived.type_name` survives. Raw segmentation criteria, provider credentials, and editor layout data are not published on any node. +A `send_email` action whose email exists also carries an `email` object with the email's `id` and +`subject`. `email.id` is the email's public id: pass it to +[Fetch a workflow email](#fetch-a-workflow-email) for the preheader and full HTML and text bodies. +Use `email.id` rather than `properties.automation_email_id`, which is published as stored and may +hold a legacy id that endpoint does not accept. The subject is as stored, with any Liquid tags +verbatim, and is null or empty on a draft whose subject has not been written. + ### Derived text Human-readable text lives in a `derived` object, separate from `properties`. Everything in @@ -575,6 +583,199 @@ an `ETag`, and a change confined to a withheld field does not invalidate one. None. +## Fetch a workflow email + +Returns one email a workflow sends: its subject, preheader, and full HTML and text bodies, along +with its name, builder type, and sender. It is read-only. + +The email is identified by its public id, the `email.id` a `send_email` action carries in +[Fetch a workflow's details](#fetch-a-workflow-39-s-details). An email is returned only through a +workflow with a `send_email` step that names it. + +> To fetch a workflow email: + +```shell +curl "https://api.getdrip.com/v2/YOUR_ACCOUNT_ID/workflows/WORKFLOW_ID/emails/WORKFLOW_EMAIL_ID" \ + -H 'User-Agent: Your App Name (www.yourapp.com)' \ + -u YOUR_API_KEY: +``` + +```ruby +require "net/http" +require "json" + +uri = URI("https://api.getdrip.com/v2/YOUR_ACCOUNT_ID/workflows/WORKFLOW_ID/emails/WORKFLOW_EMAIL_ID") + +request = Net::HTTP::Get.new(uri) +request.basic_auth("YOUR_API_KEY", "") +request["User-Agent"] = "Your App Name (www.yourapp.com)" + +response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| + http.request(request) +end + +puts response.body +``` + +```javascript +const response = await fetch( + "https://api.getdrip.com/v2/YOUR_ACCOUNT_ID/workflows/WORKFLOW_ID/emails/WORKFLOW_EMAIL_ID", + { + headers: { + "User-Agent": "Your App Name (www.yourapp.com)", + "Authorization": "Basic " + Buffer.from("YOUR_API_KEY:").toString("base64") + } + } +); + +const body = await response.json(); +``` + +> The response looks like this: + +```json +# The emails property is an array of one email object. +{ + "links": { + "emails.account": "https://api.getdrip.com/v2/accounts/{emails.account}", + "emails.workflow": "https://api.getdrip.com/v2/{emails.account}/workflows/{emails.workflow}" + }, + "emails": [ + { + "id": "957660884", + "href": "https://api.getdrip.com/v2/9999999/workflows/12345/emails/957660884", + "node_id": "4e5f6a7b", + "email_id": 4455661, + "name": "Welcome!", + "builder_type": "text", + "from_name": "John Doe", + "from_email": "john@acme.com", + "reply_to": "support@acme.com", + "subject": "Welcome, {{ subscriber.first_name }}!", + "preheader": "Here's how to get started", + "html_body": "

Hi {{ subscriber.first_name }},

{% if subscriber.tags contains 'vip' %}

Thanks for being a VIP.

{% endif %}", + "text_body": "Hi {{ subscriber.first_name }},", + "created_at": "2026-01-04T17:22:03Z", + "updated_at": "2026-07-28T14:02:11Z", + "links": { + "account": "9999999", + "workflow": "12345" + } + } + ] +} +``` + +**Properties** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescription
idThe email's public id. The same value as email.id on the send_email action that sends it.
hrefThe url designated for retrieving the email via the REST API.
node_idThe id of the send_email node in Fetch a workflow's details that sends the email.
email_idThe value the Metrics endpoint returns as email_id for this email, so it joins the email to its performance. Not the id this endpoint takes; use id.
nameThe name assigned to the email.
builder_typeThe editor the email was built with, whether text or visual (the Visual Email Builder).
from_nameThe From name set on the email. May be null.
from_emailThe From email address set on the email. May be null.
reply_toThe Reply-To address set on the email. May be null.
subjectThe subject line.
preheaderThe preheader text.
html_bodyThe HTML body. For a Visual Email Builder email, this is the full generated HTML; for other emails, it is the body only, without the account's email template or footer.
text_bodyThe plain text body.
created_atA timestamp representing when the email record was first created.
updated_atA timestamp representing when the email record was last updated.
linksAn object containing the ids of the account and the workflow.
+ +Content is returned as stored, as it is for Single-Email Campaigns: Liquid tags such as +`{{ subscriber.first_name }}` and `{% if %}` blocks appear verbatim and are not rendered for any +subscriber. `subject`, `preheader`, and the bodies may be null or empty when not yet written, as on +a draft email. + +New fields may be added at any time. Ignore fields you do not recognize. + +### Not found + +> If no `send_email` step in the workflow names the email, responds with a `404 Not Found`: + +```json +{ + "errors": [{ + "code": "not_found_error", + "message": "This workflow has no send-email step for that email id. Use the `email.id` of a send_email action from get_workflow_details: the email's public id." + }] +} +``` + +The same 404 is returned for the id of a Single-Email Campaign, of an Email Series Campaign email, +or of an email sent by a rule or a form, or an old id from `properties.automation_email_id`: only +the public id in `email.id` is accepted. A workflow that does not exist or is archived responds with +the standard `404 Not Found` described in [Errors](#errors). + +### HTTP Endpoint + +`GET /v2/:account_id/workflows/:workflow_id/emails/:workflow_email_id` + +### Arguments + +None. + ## Activate a workflow > To activate a workflow: