HVAC seasonal promo: 12 neighborhood versions in one Format bulk run

A heating and cooling company can queue a furnace-tune-up promo for 12 neighborhoods in one bulk run: concurrency, per-item input, and a spend cap per run.

4 min readSume
All posts

An HVAC company can queue a seasonal promo for 12 neighborhoods in one request by posting a list of items to a Format's bulk-runs endpoint. Sume accepts up to 100 items per queue, runs them with the concurrency you set, and returns a queue you poll. Each item is an ordinary Format run with its own sandbox and receipt.

The Format you call is your choice. Read the catalog with GET /v1/formats/sume/{slug} to see whether a Sume Format fits a local-service promo; if none does, call your own saved Format that holds the promo's look and wording.

Why bulk runs fit a local trade

A local company's ad is the same offer with a different place name: "furnace tune-up in Maple Heights", then the next street. Doing twelve of them by hand is an afternoon; the point of a queue is to leave it overnight. Sume's docs describe a bulk request as a server-side queue of ordinary Format runs, so you do not drive the fan-out from your laptop.

It is also the right place to put a cap, because twelve runs is twelve chances to overspend.

The request

Post to /v1/formats/{handle}/{slug}/bulk-runs with a concurrency number and an items array. Each item has its own instruction, input and generation_spend_cap_usd; the cap is the ceiling for that run, up to $500. Your key needs the formats:write scope, and service-account keys cannot create Format runs or bulk queues.

Use an Idempotency-Key on the create so a retry after a timeout does not make a second queue.

curl -sS -X POST "https://api.sume.com/v1/formats/yourhandle/furnace-promo/bulk-runs" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: furnace-promo-oct-w2" \
  -d '{
    "concurrency": 3,
    "items": [
      { "instruction": "Maple Heights", "generation_spend_cap_usd": 5, "input": { "neighborhood": "Maple Heights", "offer": "Furnace tune-up" } },
      { "instruction": "Oak Park", "generation_spend_cap_usd": 5, "input": { "neighborhood": "Oak Park", "offer": "Furnace tune-up" } },
      { "instruction": "Riverside", "generation_spend_cap_usd": 5, "input": { "neighborhood": "Riverside", "offer": "Furnace tune-up" } }
    ]
  }'

Poll the queue and handle failures

Poll GET /v1/format-run-queues/{queue_id} with a key that carries formats:read, and read each child run at GET /v1/format-runs/{run_id}. The API has no public list-queues or cancel-queue endpoint; to stop one child, call the cancel route for that run.

Check every output before it goes out. A promo that names the wrong neighborhood, or invents a discount, is worse than none. Keep the offer text in input as an exact string so the Format does not rephrase it.

Bulk-run facts (Sume docs, read 2026-10-07)
ItemValueNote
Items per queueUp to 10012 is well inside
Create scopeformats:writeNot available to service-account keys
Poll scopeformats:readGET /v1/format-run-queues/{queue_id}
Each itemOne ordinary Format runOwn sandbox, own receipt
CancelPer child run onlyNo public cancel-queue endpoint

What it does not do

A bulk run produces files. It does not buy ads, target a postal code or publish. If your offer has an expiry date or a license number that must appear, put it in the input and check it in the output.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume