How to Generate Weekly Headcount Reports by Deputy Location
Build a Spojit workflow that runs every week, counts your Deputy employees by location, has an Agent-mode Connector node summarize the staffing changes in plain language, archives the report in MongoDB, and emails it to leadership.
What This Integration Does
Operations and HR leaders rarely have a single, current view of who works where. Deputy holds the source of truth for employees and the locations they are assigned to, but turning that into a weekly "how many people per site, and what changed" summary usually means someone exporting spreadsheets by hand. This Spojit workflow does the counting for you: it pulls every employee and every location from Deputy, groups headcount by site, compares against last week's stored figures, and asks the agent to explain the movement in a few sentences a busy executive can read at a glance.
The workflow runs on a Schedule trigger (for example every Monday at 7am in your local timezone). On each run it reads the current employee and location lists from Deputy, computes per-location counts, loads the previous week's report from MongoDB, lets the agent write a short staffing-changes summary, inserts the new report as a document in MongoDB for history, and sends an email to leadership. Each run leaves one new report document behind, so re-running is safe: it appends another dated snapshot rather than overwriting, and the "what changed" comparison simply looks at the most recent prior document.
Prerequisites
- A Deputy connection added under Connections -> Add connection, authorized to read employees and locations.
- A MongoDB connection with write access to a database (this tutorial uses a
hrdatabase and aheadcount_reportscollection). - Leadership recipient email addresses. External addresses must be on your org allowlist under Settings -> General -> Email recipients.
- Credits available for one Agent mode summarization step per run (the rest of the workflow uses Direct mode and costs no AI credits).
Step 1: Add a Schedule trigger
Start a new workflow and set the Trigger type to Schedule. A Schedule trigger uses a 5-field Unix cron expression plus an IANA timezone. To run every Monday at 7am Sydney time, use:
0 7 * * 1
Australia/Sydney
The trigger output is {{ scheduledAt }}, which you can carry into the report as the "generated at" timestamp. A single trigger can hold multiple schedules if you want, for example, both Monday and Thursday runs.
Step 2: Pull employees and locations from Deputy
Add two Connector nodes in Direct mode, both pointing at your Deputy connection. These are deterministic single-tool calls, so they cost no AI credits.
- First node: tool
list-locations. It takes no inputs and returns every company location. Map its output to a variable, for examplelocations. - Second node: tool
list-employees. It also takes no inputs and returns every employee record, each of which references the location it is assigned to. Map its output toemployees.
Run these in sequence (or wrap them in a Parallel node if you prefer them concurrent). You now have {{ locations }} and {{ employees }} available downstream.
Step 3: Count headcount per location with a Transform node
Add a Transform node to reshape the raw Deputy data into a clean per-location tally. Group the {{ employees }} list by each employee's assigned location field and join it against {{ locations }} so every site is named, including sites with zero staff. Produce a compact array and store it as headcount:
{
"generatedAt": "{{ scheduledAt }}",
"locations": [
{ "locationId": 12, "locationName": "Sydney CBD", "employeeCount": 18 },
{ "locationId": 14, "locationName": "Parramatta", "employeeCount": 9 }
],
"totalEmployees": 27
}
If you would rather not hand-build the mapping, ask Miraxa: "Add a Transform node that groups {{ employees }} by location, joins location names from {{ locations }}, and outputs an array of locationName and employeeCount with a total." Miraxa knows the workflow you are editing and will scaffold the node for you to fine-tune in the properties panel.
Step 4: Load last week's report from MongoDB
Add a Connector node in Direct mode on your MongoDB connection using the find-documents tool. Query the headcount_reports collection in the hr database for the single most recent prior report, sorted newest first and limited to one document:
{
"database": "hr",
"collection": "headcount_reports",
"filter": {},
"sort": { "generatedAt": -1 },
"limit": 1
}
Store the result as previousReport. On the very first run this returns nothing, which is expected; the summary step below handles the "no prior data" case gracefully.
Step 5: Summarize staffing changes with Agent mode
Add a Connector node in Agent mode so the agent can reason over both snapshots and write the human-readable summary. In the prompt, hand it this week's tally and last week's report, and ask for a concise staffing-changes narrative:
This week's headcount by location: {{ headcount }}
Last week's report (may be empty on the first run): {{ previousReport }}
Write a 3-4 sentence summary for company leadership describing
how headcount changed per location since last week. Call out the
largest increases and decreases by name, note any location that
dropped to zero, and state the new total. If there is no prior
report, say this is the first baseline report.
Turn on a Response Schema to force clean JSON output so the email and the stored document stay structured. For example:
{
"type": "object",
"properties": {
"summary": { "type": "string" },
"totalEmployees": { "type": "number" },
"biggestChange": { "type": "string" }
},
"required": ["summary", "totalEmployees"]
}
Store the result as analysis. Agent mode costs AI credits; this is the only step in the workflow that does.
Step 6: Store the report in MongoDB
Add a Connector node in Direct mode on your MongoDB connection using the insert-documents tool. Write a single document into hr.headcount_reports that combines the tally, the timestamp, and the AI summary so future runs can compare against it:
{
"database": "hr",
"collection": "headcount_reports",
"documents": [
{
"generatedAt": "{{ scheduledAt }}",
"totalEmployees": "{{ analysis.totalEmployees }}",
"summary": "{{ analysis.summary }}",
"locations": "{{ headcount.locations }}"
}
]
}
Because each run inserts a fresh dated document rather than updating an existing one, your headcount_reports collection becomes a clean week-by-week history you can chart or query later.
Step 7: Email the report to leadership
Add a Send Email node, which sends from Spojit's built-in mail service with no connection required. Set Recipients to your leadership addresses (comma-separated), give it a dated Subject, and put the AI summary plus the per-location counts in the Body:
Subject: Weekly Headcount Report - {{ scheduledAt }}
Body:
{{ analysis.summary }}
Total employees: {{ analysis.totalEmployees }}
Headcount by location:
{{ headcount.locations }}
Set If sending fails to Fail the workflow so a delivery problem is visible in your execution history rather than passing silently. If you would rather send from your own domain, swap the Send Email node for a Connector node on the Resend or SMTP connector using its send-email tool.
Tips
- Keep the heavy reasoning in a single Agent mode step. The Deputy reads, the grouping, the MongoDB read/write, and the email are all deterministic and free of AI cost when run in Direct mode.
- Use the same field name (
generatedAt) for the timestamp in both the stored document and the MongoDB sort, so the "find last week's report" query in Step 4 always returns the true most recent snapshot. - If you want a per-location trend chart later, the dated documents in
headcount_reportsare already query-ready with the MongoDBaggregatetool. - Ask Miraxa "Why did my last run fail?" to investigate any failed execution directly from the page you are on.
Common Pitfalls
- Timezone drift. The cron expression is evaluated in the IANA timezone you set on the trigger, not in UTC. Set it explicitly (for example
Australia/Sydney) so "Monday 7am" means local Monday. - First-run empty comparison. On the first run the MongoDB
find-documentsquery returns nothing. Make sure your Agent mode prompt explicitly handles the empty{{ previousReport }}so it writes a baseline instead of erroring. - Unmapped locations. Employees with no assigned location in Deputy will not match any site when grouping. Add a catch-all bucket (for example "Unassigned") in your Transform so nobody is silently dropped from the total.
- External recipients blocked. The Send Email node only delivers to external addresses on your org allowlist. Add leadership addresses under Settings -> General -> Email recipients first.
Testing
Before turning the schedule on, validate the whole chain on a small scope. Temporarily replace the Schedule trigger with a Manual trigger and click Run so you control exactly when it fires. Confirm the Deputy list-employees and list-locations nodes return data, check the Transform output groups counts correctly, and verify that one document lands in hr.headcount_reports. Run it a second time to confirm the comparison against the prior week reads the right document and that the summary reflects the difference. Point the email at your own inbox first, then switch back to the Schedule trigger and add the real leadership recipients once you are happy with the output.