How to Email an Investor-Style Monthly Business Summary with AI and Knowledge Context

Build a Spojit workflow that runs on the first of each month, pulls headline numbers from MySQL and Stripe in parallel, grounds them against a Knowledge collection of prior reports and targets, and uses an AI agent to draft an investor-style narrative that lands in leadership inboxes.

What This Integration Does

Every month someone on your team copies the same numbers out of a database and a payments dashboard, pastes them into a deck or email, and writes a paragraph or two explaining what changed. This workflow does all of that on a schedule. It reads operational metrics from your MySQL reporting database, reads revenue and subscription activity from Stripe, computes the month-over-month deltas with the math connector, and then asks the intelligent layer of your automation to write a tight, board-ready summary. Because the draft is grounded in a persistent Knowledge collection of your previous monthly summaries and stated targets, the narrative stays consistent in tone and actually references how this month compares to plan rather than describing the numbers in isolation.

A Schedule trigger fires the run once a month in your chosen timezone. Two data branches run concurrently inside a Parallel node so the database and Stripe reads do not wait on each other. The combined figures are queried against a workspace-scoped Knowledge collection (the same collection you have been embedding prior reports into) to retrieve relevant context, and a Connector node in Agent mode turns the figures plus that context into prose. The final draft is sent with a Send Email node. The run is read-only against your systems, leaves no state behind except the email it sends, and is safe to re-run for the same month: re-running simply regenerates and re-sends the summary.

Prerequisites

Step 1: Start the workflow on a monthly Schedule

Add a Trigger node and set its type to Schedule. A Schedule trigger uses a 5-field Unix cron expression plus an IANA timezone. To run at 07:00 on the first day of every month in Sydney, set the cron to 0 7 1 * * and the timezone to Australia/Sydney. The trigger output is { scheduledAt }, an ISO timestamp you can reference downstream as {{ scheduledAt }}.

You will usually want to summarize the month that just ended, not the one starting now. Add a Connector node on the date connector in Direct mode using start-of and subtract to compute the first and last day of the previous month from {{ scheduledAt }}, and store them as {{ period.start }} and {{ period.end }}. These two values become the boundaries for every data query below.

Step 2: Gather MySQL and Stripe numbers in parallel

Add a Parallel node so the database read and the payments read run at the same time. Give it two branches.

In the first branch, add a Connector node on the mysql connector in Direct mode and pick the execute-query tool. Write a parameterized query that returns the headline operational metrics for the period, for example:

SELECT
  COUNT(DISTINCT order_id)        AS order_count,
  COUNT(DISTINCT customer_id)     AS active_customers,
  SUM(line_total)                 AS gross_sales
FROM orders
WHERE created_at >= '{{ period.start }}'
  AND created_at <  '{{ period.end }}';

Store the result as {{ db_metrics }}. In the second branch, add a Connector node on the stripe connector in Direct mode and call list-charges scoped to the same period to capture settled revenue, plus list-subscriptions to capture active subscription counts and list-invoices if you bill on invoices. Store these as {{ stripe_charges }}, {{ stripe_subscriptions }}, and {{ stripe_invoices }}. Both branches complete before the workflow continues past the Parallel node.

Step 3: Compute the headline figures and deltas with math

Add one or more Connector nodes on the math connector in Direct mode to turn raw rows into clean, presentable numbers. Use sum to total the Stripe charge amounts into a single revenue figure, average for average order value, and percentage to express month-over-month change once you have last month's number (which you will retrieve as context in the next step). Use currency to format money values and round to tidy ratios.

For example, to compute net new revenue growth versus the prior month, pass this month's revenue and last month's revenue into percentage and store the result as {{ growth.revenuePct }}. Collect the finished figures into a single object with a Transform node so the agent receives one tidy payload:

{
  "period": "{{ period.start }} to {{ period.end }}",
  "grossSales": "{{ db_metrics.rows.0.gross_sales }}",
  "stripeRevenue": "{{ revenue.total }}",
  "activeCustomers": "{{ db_metrics.rows.0.active_customers }}",
  "activeSubscriptions": "{{ stripe_subscriptions.count }}",
  "avgOrderValue": "{{ aov.value }}",
  "revenueGrowthPct": "{{ growth.revenuePct }}"
}

Store this combined object as {{ figures }}.

Step 4: Retrieve context from your Knowledge collection

Add a Knowledge node set to Query mode. Choose your persistent collection (for example monthly-reports) in the Collection dropdown so the query reads from the long-lived archive of prior summaries and targets, not a transient one. Set the Prompt to retrieve the comparison material the narrative needs, for example:

Summarize last month's reported revenue, active customer count, and the
stated revenue target for {{ period.start }}. Note any commitments or
risks called out in the most recent monthly summary.

Leave Result Count at the default of 5 so the node pulls the most relevant passages, pick a synthesis Model, and set the Output Variable to {{ context }}. Use the same embedding model the collection was created with; you do not change that here, it is fixed at collection creation. The retrieved context gives the agent grounding for "compared to plan" and "versus last month" statements instead of inventing them.

Step 5: Draft the investor-style narrative with an AI agent

Add a Connector node and switch it to Agent mode. Agent mode lets the intelligent layer of your automation reason over the inputs and produce a polished narrative. In the prompt, hand it both the computed figures and the retrieved context, and tell it the audience and tone:

You are drafting a monthly business update for the board and leadership.
Write a concise, investor-style narrative (4 to 6 short paragraphs) in a
measured, factual tone. Lead with the headline result, then explain the
drivers, then call out one risk and one priority for next month.

This month's figures:
{{ figures }}

Context from prior reports and targets:
{{ context }}

Do not invent numbers. Use only the figures and context provided.

To keep the output predictable for the email body, attach a Response Schema so the agent returns structured fields such as headline, body, and subjectLine rather than free text. Store the agent result as {{ summary }}. Agent mode consumes AI credits, so this is the only AI step in the workflow; everything before it is deterministic.

Step 6: Email the summary to leadership

Add a Send Email node, which sends through Spojit's built-in mail service with no separate connection. Set Recipients to your allowlisted leadership addresses (comma-separated), set Subject to a templated line such as Monthly Business Summary - {{ period.start }} or {{ summary.subjectLine }}, and set Body to {{ summary.body }}. Set If sending fails to Fail the workflow so a delivery problem surfaces in your execution history rather than passing silently. Only upstream variables resolve in the body, which is exactly what you need here. If you would rather send from your own domain instead of the built-in service, swap this node for a Connector node on the resend or smtp connector using send-email.

Tips

  • Keep the entire data layer in Direct mode and reserve Agent mode for the single drafting step. This keeps AI cost to one call per month and makes the numbers reproducible.
  • Feed the math results through the agent rather than asking the agent to do arithmetic. The math connector is exact; an agent should describe numbers, not calculate them.
  • After each run, embed the finished summary back into the same Knowledge collection (a small Embed-mode Knowledge node at the end) so next month's query has the latest report as context. Use the same embedding model the collection was created with.
  • Ask Miraxa, the intelligent layer across your automation, to scaffold the skeleton for you with a prompt like "Build a monthly Schedule workflow with a Parallel node that runs a MySQL execute-query and a Stripe list-charges, then a Knowledge Query node, then an Agent-mode Connector node, then a Send Email node," and fine-tune the fields in the properties panel afterward.

Common Pitfalls

  • Timezone drift at month boundaries. The Schedule trigger uses the timezone you set, so always derive {{ period.start }} and {{ period.end }} from {{ scheduledAt }} using the date connector rather than hard-coding dates. A run at midnight in one zone can land in the wrong month in another.
  • Querying a transient collection by mistake. For context across months you must select your persistent collection in the Query node. A Transient collection only exists for the single run and holds nothing from prior months.
  • Recipients not on the allowlist. The Send Email node only delivers to external addresses listed under Settings -> General -> Email recipients. Add every leadership address before turning the schedule on.
  • Stripe and MySQL date ranges that disagree. Use the exact same {{ period.start }} and {{ period.end }} boundaries in both branches, and confirm the inclusive/exclusive edges match so revenue and order counts cover the same window.

Testing

Before scheduling it monthly, validate the logic on a small scope. Temporarily set the period dates to a recent, known month and run the workflow with the Run button from the designer (you can add a Manual trigger alongside the Schedule during testing). Open the run in your execution history and confirm each step: the Parallel branches both returned data, the math figures look right against a manual check, the Knowledge Query returned relevant passages from your prior reports, and the agent draft references real numbers without inventing any. Send the first email to yourself only by setting Recipients to your own allowlisted address, review the narrative end to end, then widen the recipients and enable the schedule.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.