Skip to navigation

Using output steps

Output steps turn a flow’s results into something that leaves the flow: a rendered document, a stored file, an email, an analytics event, or a message streamed to the client. This page shows how to configure Render Template, Generate PDF, Store Asset, Send Email, Send Event, and Send Stream of Data.

Before you begin

Open a flow in the Flow editor. To add any of these steps, click the + control where you want the step, then select the step in the step picker. Render Template, Store Asset, and Generate PDF are in the Context group. Send Email and Send Event are in the Actions group. Send Stream of Data is in the Replies group.

Each step except Send Stream of Data writes its result to the Output variable that you set. Later steps read it with {{name}}. For the variable syntax, see Flow variables and templates.

Render a document with Render Template

Render Template renders a Liquid template into HTML, email HTML, markdown, plain text, or a PDF. Use it when a document has loops, conditions, or filters that plain {{name}} substitution can’t express.

To configure the step, follow these steps:

  1. In Output format, choose HTML, HTML Email, Markdown, PDF, or Plain Text.
  2. On the Code tab, enter the Liquid template.
  3. Optional: On the Sample Data tab, add a scenario with example JSON. The Preview tab renders the template with that data. Sample data is used only for the preview.
  4. In Output variable, enter a name. The default is rendered_output.

By default, the template can read every flow variable by name. To limit the template to specific values, open Advanced, click Add input, and map a name to an expression such as {{lookupCustomer.result}}. When you define inputs, the template sees only those names. An expression that is a single {{reference}} keeps its original type, so the template can loop over an array or read an object’s fields.

The following template renders an order summary from a flow variable named order. Liquid doesn’t escape values on its own, so the template adds the escape filter to text that a customer typed:

<h1>Order {{ order.id }}</h1>
<ul>
{% for item in order.items %}
<li>{{ item.name | escape }}: {{ item.price }}</li>
{% endfor %}
</ul>

To reuse a block of markup, open Advanced, click Add partial, name it, and include it with {% include 'header' %}. Partials can include other partials up to 8 levels deep. A template can also read a managed secret with {{secret:NAME}}.

The output depends on the format:

  • HTML, HTML Email, Markdown, and Plain Text write the rendered text to the output variable.
  • PDF writes an object with contentType, bytes (the PDF as a base64 string), and byteLength. To get a shareable URL instead, use Generate PDF, or pass {{rendered_output.bytes}} to Store Asset.

For a PDF, Advanced also shows PDF options: Paper size (A4 or Letter) and Orientation. To show the rendered output in a Persona chat, select Emit as Persona artifact (chat surfaces).

A template can be at most 256 KB, and the data that it reads can be at most 1 MB.

Create a PDF file with Generate PDF

Generate PDF renders HTML or markdown as a PDF, stores the file, and returns a URL.

To configure the step, follow these steps:

  1. Choose the HTML or Markdown tab.
  2. In HTML body or Markdown body, enter the content. You can use flow variables, such as {{rendered_output}} from a Render Template step.
  3. Optional: In Filename, enter a name such as invoice-{{order.id}}.pdf. Without a filename, Runtype names the file document- followed by a timestamp.
  4. In Visibility, choose Public or Private (signed URL). For what each option returns, see Choose a visibility.
  5. Optional: Open PDF Options to set the Page format (A4 or Letter), Landscape orientation, and Margins. Margins take CSS sizes, such as 10mm or 0.5in.
  6. In Output variable, enter a name. The default is pdf_asset.

The output variable holds an object with assetId, url, contentType, sizeBytes, visibility, and expiresIn. Reference the link as {{pdf_asset.url}}.

If the body references a field that doesn’t exist on a variable that does, such as {{order.totl}} when order exists, the step fails instead of printing the placeholder text into the PDF.

Save a file with Store Asset

Store Asset saves a file and returns a URL. Use it to keep a copy of a file from another site, or to store bytes that an earlier step produced.

To configure the step, follow these steps:

  1. Choose the source:
    • To copy a file from the web, choose From URL and enter the Source URL.
    • To store bytes from an earlier step, choose Inline content, enter the base64 data in Base64 content, and set the Content type, such as application/pdf. Without a content type, Runtype stores the file as application/octet-stream.
  2. Optional: In Filename, enter the name that browsers use when they download the file.
  3. In Visibility, choose Public or Private (signed URL).
  4. In Output variable, enter a name. The default is asset_result.

The output variable holds the same fields as Generate PDF, plus originalUrl for a file copied from a URL. A file can be at most 25 MB.

Choose a visibility

Store Asset and Generate PDF offer the same two options:

  • Public: the URL doesn’t expire. Anyone with the URL can open the file.
  • Private (signed URL): the URL is signed and expires after 1 hour. expiresIn holds the lifetime in seconds.

Use Private (signed URL) for files that contain customer data, and send the link soon after the step runs.

Send an email with Send Email

Send Email sends an email to one or more recipients.

To configure the step, follow these steps:

  1. In Send email to, enter one or more addresses separated by commas. You can use variables, such as {{customer.email}}.
  2. Optional: In from, enter a sender address. For the rules, see Choose a sender.
  3. In subject, enter the subject line.
  4. In HTML, enter the email body.
  5. Optional: Open Advanced to add a Plain text body (fallback), reply to, cc, and bcc addresses, and attachments.
  6. In Output variable, enter a name. The default is email_result.

When the email is sent, the output variable holds id, from, to, subject, status (sent), and timestamp.

If the subject or body references a field that doesn’t exist on a variable that does, the step fails instead of sending the placeholder text.

Choose a sender

Leave from blank to send from the platform-managed sender. The address is built from the flow’s ID, and the step shows it under the field.

To send from your own address, add a Resend API key in Settings > Integrations, then enter the address in from. The address must be on a domain that you verified in Resend. It can’t use the platform-managed sender’s domain.

Add attachments

To add an attachment, open Advanced, click Add Attachment, and fill in Filename and Content (Text or Base64). Runtype detects whether the content is base64. Text content, such as CSV data, is encoded for you.

To attach a variable, enter only the reference, such as {{csv_data}}. The attachment content supports a single top-level variable that holds a string. A nested path such as {{invoice.bytes}} produces an empty attachment, and text around a reference is sent as written.

To attach a PDF from Render Template, copy its bytes into a top-level variable first:

  1. Add a Set Variable step after Render Template.
  2. Set the variable name to invoice_pdf_bytes and the value to {{rendered_output.bytes}}.
  3. In the Send Email attachment, set Content (Text or Base64) to {{invoice_pdf_bytes}} and Filename to invoice.pdf.

To send a link instead of an attachment, use Generate PDF and put {{pdf_asset.url}} in the email body.

Track an event with Send Event

Send Event sends an analytics event to PostHog. It needs your PostHog Project API Key in Settings > Integrations. For setup, plan requirements, and the PostHog region that events go to, see PostHog integration.

To configure the step, follow these steps:

  1. In Send event, enter the event name, such as invoice_sent.
  2. Leave the provider set to PostHog.
  3. Optional: Under Event Properties, click Add Property and enter a name and value for each property. Values can use variables and are sent as strings.
  4. In Output variable, enter a name. The default is event_result.

PostHog records the event with the ID of the Runtype user who ran the flow as its distinct_id. When PostHog accepts the event, the output variable holds { "status": "sent" }.

Stream a message with Send Stream of Data

Send Stream of Data sends a message to the client while the flow is still running. Use it to show progress, such as “Generating your invoice”, before a slow step finishes.

In Stream message to client, enter the message. You can use variables, such as Invoice sent to {{customer.email}}. The step has no Output variable field in the editor. The message is stored in the message variable. To use another name, set outputVariable in the flow definition.

Define the steps in code

The following flow definition steps render an invoice, store it as a private PDF, email the link, and record an event. Each object goes in the flow’s steps array:

[
{
"type": "send-stream",
"name": "Announce",
"config": { "message": "Preparing invoice {{order.id}}" }
},
{
"type": "template",
"name": "Render invoice",
"config": {
"template": "<h1>Invoice {{ order.id }}</h1>{% for item in order.items %}<p>{{ item.name }}</p>{% endfor %}",
"outputFormat": "html",
"outputVariable": "invoice_html"
}
},
{
"type": "generate-pdf",
"name": "Create PDF",
"config": {
"html": "{{invoice_html}}",
"filename": "invoice-{{order.id}}.pdf",
"visibility": "private",
"pdfOptions": { "format": "Letter" },
"outputVariable": "invoice_pdf",
"errorHandling": { "onError": "fail" }
}
},
{
"type": "send-email",
"name": "Email customer",
"config": {
"to": "{{order.email}}",
"subject": "Your invoice {{order.id}}",
"html": "<p>Download your invoice: <a href=\"{{invoice_pdf.url}}\">invoice</a></p>",
"outputVariable": "email_result",
"errorHandling": { "onError": "fail" }
}
},
{
"type": "send-event",
"name": "Track invoice",
"config": {
"provider": "posthog",
"eventName": "invoice_sent",
"properties": { "orderId": "{{order.id}}" },
"outputVariable": "event_result"
}
}
]

Replace order with the name of the flow input or step output that holds the order. Render Template uses "type": "template". Generate PDF accepts markdown in place of html, and Store Asset takes url or content, but never both. For how to create and update flows from code, see Manage flows as code.

Handle errors

What happens when an output step fails depends on its error handling mode:

  • Stop on error: the run ends with an error. Send Email, Send Event, Store Asset, and Generate PDF start in this mode when you add them in the Flow editor.
  • Continue on error: the flow keeps going. Send Email, Send Event, Store Asset, and Generate PDF write the step’s default value to the output variable. With no default value, the output is { "status": "failed", "error": "..." }. Send Stream of Data writes its default value, or null. A failed Render Template step doesn’t set its output variable.
  • Use fallbacks: Runtype retries the step. Add one Retry per attempt.

A step in a flow definition that has no errorHandling field continues on error. To stop the flow when an email or event fails, set "errorHandling": { "onError": "fail" }. For how error handling works across step types, see Error handling.

Troubleshoot output steps

These errors are the most common:

  • A custom email provider key is required for custom sender addresses: from has an address, but you haven’t added a Resend API key. Add the key in Settings > Integrations, or clear from.
  • Custom sender addresses cannot use the managed domain: from uses the platform-managed sender’s domain. Clear from to use the managed sender, or use your own domain.
  • Refusing to send an email containing the literal placeholder text or Refusing to render a PDF: a reference names a field that doesn’t exist. Check the spelling of the path in the run’s step output.
  • PostHog API key not configured: add your PostHog Project API Key in Settings > Integrations.
  • Template references undefined partial: an {% include %} tag names a partial that isn’t defined in Advanced.
  • Asset exceeds size limit: the file is larger than 25 MB.

For more diagnosis steps, see Flow execution failures.

Next steps

Continue with these guides: