How to Flag Below-Minimum Stock and Draft Replenishment POs to Suppliers via Email
Build a Spojit workflow that runs every morning, queries NetSuite for items below their reorder point with SuiteQL, drafts a replenishment purchase order per supplier with an Agent-mode Connector node, waits for a human to approve, then emails each draft PO to the right supplier.
What This Integration Does
Wholesale and manufacturing teams lose margin when fast-moving SKUs quietly drop below their reorder point and nobody notices until a customer order can't ship. This workflow closes that gap. Every weekday morning it asks NetSuite which inventory items have fallen below their minimum, groups the shortfalls by each item's preferred supplier, and produces a clean, supplier-by-supplier draft purchase order. A buyer reviews and approves the drafts in one place, and Spojit emails the approved PO to each supplier automatically. You keep the human judgement where it matters (which orders to actually place) and remove all the spreadsheet wrangling around it.
A Schedule trigger starts the run on a cron. A Connector node on the netsuite connector reads current stock vs. reorder point with run-suiteql. A second Connector node runs in Agent mode with a Response Schema so the agent returns structured, per-supplier draft POs rather than free text. A Condition node short-circuits the run when nothing is below minimum, a Human node pauses for buyer approval, and a Send Email step dispatches each draft. The workflow is read-and-notify: it does not write anything back to NetSuite, so a re-run the next day simply re-evaluates current stock and is safe to repeat. Each run leaves an execution-history entry and (if anything was below minimum) one approval record plus one email per supplier.
Prerequisites
- A NetSuite connection in Spojit with permission to run SuiteQL queries and read inventory items. See the NetSuite connector docs for setup.
- Reorder points (minimum quantities) and a preferred vendor set on your inventory items in NetSuite, so the query has something to compare against.
- An idea of which field on your items holds the preferred-supplier name or ID, so you can confirm the SuiteQL column names against your account's Analytics schema.
- Your suppliers' contact email addresses added to the org allowlist under Settings → General → Email recipients, since Send Email only sends to allowlisted external recipients.
- At least one approver (a user, role, or team) to act as the buyer on the Human node.
Step 1: Start on a daily Schedule trigger
Add a Trigger node and set its type to Schedule. Use a 5-field Unix cron expression and an IANA timezone so the run lands in your buyers' local morning. For 7am on weekdays in Sydney, set the cron to 0 7 * * 1-5 and the timezone to Australia/Sydney. The trigger output is simply {{ scheduledAt }}, which you can reference later if you want to date-stamp the email subject.
Step 2: Query NetSuite for below-minimum items with SuiteQL
Add a Connector node on the netsuite connector in Direct mode and pick the run-suiteql tool. This is deterministic and uses no AI credits. In the query field, select inventory items whose available quantity is below their reorder point, and return each item's preferred supplier so the next step can group on it. Confirm the exact column names for your account in the NetSuite Analytics Data Source Schema Browser, then use a query like:
SELECT
i.itemid AS sku,
i.displayname AS item_name,
i.reorderpoint AS reorder_point,
i.quantityavailable AS qty_available,
(i.reorderpoint - i.quantityavailable) AS shortfall,
v.entityid AS supplier,
v.email AS supplier_email
FROM item i
LEFT JOIN vendor v ON i.vendor = v.id
WHERE i.isinactive = 'F'
AND i.reorderpoint IS NOT NULL
AND i.quantityavailable < i.reorderpoint
ORDER BY supplier, shortfall DESC
FETCH FIRST 500 ROWS ONLY
Set limit if you expect many rows, and use offset only if you need to page beyond it. Name the node output something like shortfalls so later steps can read its result rows.
Step 3: Stop early when nothing is below minimum
Add a Condition node so the workflow does no work (and sends no emails) on days when stock is healthy. Branch on whether the query returned any rows, for example checking that the row count of {{ shortfalls }} is greater than 0. Wire the false output to the end of the workflow so the run finishes quietly, and continue building on the true output. This keeps your execution history clean and avoids waking a buyer with an empty approval.
Step 4: Draft per-supplier POs with an Agent-mode node using a Response Schema
Add a second Connector node and switch it to Agent mode so the agent can reason over the shortfall list and group it by preferred supplier. In the prompt, pass the rows from {{ shortfalls }} and ask it to produce one draft purchase order per supplier, each listing the SKU, item name, current quantity, reorder point, and a suggested order quantity that brings stock back above minimum. To get reliable, machine-readable output instead of prose, define a Response Schema on the node, for example:
{
"type": "object",
"properties": {
"purchaseOrders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"supplier": { "type": "string" },
"supplierEmail": { "type": "string" },
"lines": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sku": { "type": "string" },
"itemName": { "type": "string" },
"qtyAvailable": { "type": "number" },
"reorderPoint": { "type": "number" },
"orderQty": { "type": "number" }
},
"required": ["sku", "orderQty"]
}
},
"draftBody": { "type": "string" }
},
"required": ["supplier", "supplierEmail", "lines", "draftBody"]
}
}
},
"required": ["purchaseOrders"]
}
Name the output drafts. Each entry in {{ drafts.purchaseOrders }} now holds a supplier, their email, the line items, and a ready-to-send draftBody you can drop straight into an email.
Step 5: Pause for buyer approval
Add a Human node so a buyer signs off before any PO leaves the building. Set a clear Label (for example Approve replenishment POs) and a Message that summarises what is about to be sent, such as {{ drafts.purchaseOrders }} draft purchase orders are ready to email to suppliers. Add the buyer (a user, role, or team) to an Approval slot; approval completes when every slot is satisfied. Set a Timeout (minutes) if you want the run to stop when no one responds in time, turn on Email approvers to nudge them, and raise Urgency to High during peak season. Approvers act in the Approvals inbox at /approvals. If the request is rejected or times out, the run halts and no emails go out.
Step 6: Email each approved draft PO to its supplier
Add a Loop node in ForEach mode over {{ drafts.purchaseOrders }} so each supplier gets its own message. Inside the loop, add a Send Email node, which uses Spojit's built-in mail service and needs no connection. Set Recipients to {{ item.supplierEmail }}, give the Subject a dated label such as Replenishment PO - {{ item.supplier }} - {{ scheduledAt }}, and set the Body to {{ item.draftBody }}. Leave Reply-To as the workflow owner (your buyer) so supplier replies land with a real person, and set If sending fails to Continue anyway if you would rather email the remaining suppliers than halt on one bad address. Remember each supplier email must be on the org allowlist, and these messages count toward your monthly email allowance. To send from your own domain instead, swap Send Email for the resend or smtp connector.
Tips
- Keep the SuiteQL read in Direct mode and reserve Agent mode for the grouping and drafting step. That keeps AI cost on the one task that genuinely needs judgement.
- If your account stores suggested reorder quantities, return them in the query and instruct the agent to honour them rather than inventing an
orderQty, so drafts match your purchasing policy. - For large catalogs, raise the
limitonrun-suiteqland page withoffset, or tighten theWHEREclause to a specific item category so the daily run stays fast. - Scaffold the whole flow quickly by asking Miraxa: "Build a workflow on a daily Schedule trigger that runs a NetSuite run-suiteql query for below-minimum items, drafts POs per supplier in Agent mode with a Response Schema, adds a Human approval, then loops Send Email to each supplier." Then fine-tune each node in the properties panel.
Common Pitfalls
- Column names in SuiteQL vary by account and customisation. Validate every field (
reorderpoint,quantityavailable, the vendor join) against your NetSuite Analytics schema before trusting the results. - Forgetting to allowlist supplier addresses means Send Email silently can't deliver. Add each supplier under Settings → General → Email recipients first.
- Reject and timeout both halt the run; Spojit does not support an "on reject, do X" branch after a Human node. If a buyer wants to amend quantities, have them edit in NetSuite and let tomorrow's run pick up the new picture.
- Schedule triggers fire in the timezone you set, not the server's. Double-check the IANA zone so a "7am" run does not arrive overnight for your team.
- If the agent ever returns prose instead of JSON, confirm the Response Schema is actually attached to the Agent-mode node; without it, the downstream loop has nothing structured to read.
Testing
Before turning the schedule on, run the workflow manually and scope it small. Temporarily narrow the run-suiteql query to a single item category or add FETCH FIRST 5 ROWS ONLY so you only pull a handful of shortfalls. Point the supplier emails at your own allowlisted inbox instead of real suppliers, approve the request in the Approvals inbox, and confirm you receive one well-formatted draft per supplier. Check the execution-history entry to verify the query rows, the structured drafts output, and the per-supplier emails all look right, then restore the full query and real recipients and enable the Schedule trigger.