Triage & Label an Inbox
This cookbook builds an inbox triage agent: a script that classifies every unread message, labels it, and files it — starring hot leads, snoozing things to follow up later, and bulk-archiving noise. It's the "decide before you act" companion to the auto-reply agent.
What you'll build
For each unread message, the agent:
Classifies it (lead / support / noise) with an LLM.
Applies a label and stars hot leads.
Snoozes "follow up later" mail to resurface on a schedule.
Bulk-archives everything classified as noise in one call.
Prerequisites
A connected mailbox and a token.
Python 3 with
requests.The labels you'll use, created once:
curl -X POST "https://spideriq.ai/api/v1/mail/labels" \
-H "Authorization: Bearer $SPIDERIQ_TOKEN" -H "Content-Type: application/json" \
-d '{"name":"lead","color":"#E11D48"}'This cookbook classifies with SpiderGate, SpiderIQ's OpenAI-compatible LLM gateway, so you stay on one platform and one token. Any LLM works — swap the classify() body for your provider of choice.
The script
import os, json, requests
BASE = "https://spideriq.ai/api/v1"
TOKEN = os.environ["SPIDERIQ_TOKEN"]
HEAD = {"Authorization": f"Bearer {TOKEN}"}
MAILBOX = os.environ["MAILBOX"]
def get(path, **params):
return requests.get(f"{BASE}{path}", headers=HEAD, params=params).json()
def post(path, body):
return requests.post(f"{BASE}{path}", headers=HEAD, json=body).json()
def patch(path, body):
return requests.patch(f"{BASE}{path}", headers=HEAD, json=body).json()
def classify(subject, body):
# SpiderGate chat completion — returns one of: lead | support | noise
r = requests.post("https://spideriq.ai/api/gate/v1/chat/completions",
headers=HEAD, json={
"model": "spideriq/classification",
"messages": [{"role": "user", "content":
f"Classify this email as exactly one word — lead, support, or noise.\n\n"
f"Subject: {subject}\n\n{body}"}],
}).json()
return r["choices"][0]["message"]["content"].strip().lower()
inbox = get("/mail/inbox", email=MAILBOX, unread_only="true", limit=50)
to_archive = []
for msg in inbox.get("messages", []):
mid = msg["id"]
full = get(f"/mail/messages/{mid}")
kind = classify(full.get("subject", ""), full.get("body_text", ""))
if kind == "lead":
patch(f"/mail/messages/{mid}", {"labels": ["lead"], "is_starred": True,
"notes": "Auto-triaged: hot lead"})
elif kind == "support":
patch(f"/mail/messages/{mid}", {"labels": ["support"]})
post(f"/mail/messages/{mid}/snooze", {"snoozed_until": "2026-06-09T09:00:00Z"})
else: # noise
to_archive.append(mid)
# 4. One bulk call archives all the noise
if to_archive:
post("/mail/messages/bulk", {"message_ids": to_archive, "action": "archive"})
print(f"triaged {len(inbox.get('messages', []))}, archived {len(to_archive)}")Run it
python triage.py
# triaged 23, archived 9Open the dashboard inbox and the leads are starred and labeled, support is filed and snoozed for Monday, and the noise is gone — all in one pass.
Make it sharper
Search instead of scanning all unread. Use
/mail/searchto triage only mail matching a query or sender.Persist the rules as a view. Save a view like
label:lead + starredso the team sees the triaged result instantly.Hand off to the reply agent. Pipe the
lead-labeled messages into the auto-reply agent for a first-touch response.
Tip: Bulk actions take up to 100 message ids per call — collect ids in a loop and archive/label them in one request instead of one PATCH per message. It's the fastest way for an agent to clear a backlog.
Next steps
Auto-Reply Agent — respond to the leads you just found.
Send Personalized Email — reach out at scale, one-to-one.