# Swag Pending Approvals

> Check Swag.com referral-program campaigns for orders pending approval. Runs referral fraud checks on each pending order and includes approve/deny recommendations. Shows redeemed orders awaiting shipment approval with name, email, tier, and location, and posts a Slack summary to a configured channel. Use when the user asks for "pending swag approvals", "swag orders to approve", "referral program approvals", or "check swag".

- Skill: `warpdotdev/swag-pending-approvals` (Agent Skill)
- Install (CLI): `npx skillmds@latest add warpdotdev/swag-pending-approvals`
- Raw SKILL.md: https://api.skillmd.com/api/skills/warpdotdev/swag-pending-approvals/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: warpdotdev (https://skillmd.com/u/warpdotdev)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/warpdotdev/swag-pending-approvals

---


# Swag Pending Approvals

Check your Referral Program campaigns on Swag.com for orders in "received" status
— the recipient has redeemed their giveaway link and submitted shipping info, but
the order hasn't been approved yet.

## Prerequisites

- `SWAG_API_KEY` — Swag.com API key (HTTP Basic Auth username).
- `BUZZ_SLACK_TOKEN` — Slack bot token (only for sending).
- `APPROVALS_CHANNEL_ID` — Slack channel to post the summary to.

## API reference

<https://api-docs.swag.com/> — Swag Pro API v2. Auth is HTTP Basic with the API
key as username, no password. Base URL: `https://api.swag.com/v2/`.

## Configuring campaigns

List your Referral Program campaign IDs and their tier labels in a local config
or environment variable (do not commit real campaign IDs). Example shape:

```python
REFERRAL_CAMPAIGNS = {
    # campaign_id: "tier label"
    111111: "5 Tier",
    222222: "10 Tier",
    # ...
}
```

Dashboard URL pattern: `https://pro.swag.com/account/campaign/overview.php?storeid=<campaign_id>`

## Workflow

### Step 1: Fetch pending orders

Query each campaign for orders with status `received`, using the `campaign_id`
filter to avoid paging through all orders.

```python
import json, os, urllib.request, ssl, base64

SWAG_API_KEY = os.environ["SWAG_API_KEY"]
auth = base64.b64encode(f"{SWAG_API_KEY}:".encode()).decode()
ctx = ssl.create_default_context()

# Load REFERRAL_CAMPAIGNS from your local/private config.

received = []
for cid, tier in REFERRAL_CAMPAIGNS.items():
    offset = 0
    while True:
        url = f"https://api.swag.com/v2/orders?campaign_id={cid}&offset={offset}&limit=100"
        req = urllib.request.Request(url, headers={"Authorization": f"Basic {auth}"})
        resp = urllib.request.urlopen(req, context=ctx)
        data = json.loads(resp.read())
        orders = data.get("data", data) if isinstance(data, dict) else data
        if not orders:
            break
        for o in orders:
            if o.get("status") == "received":
                ship = o.get("ship_to", {}) or {}
                received.append({
                    "id": o["id"],
                    "tier": tier,
                    "campaign_id": cid,
                    "name": ship.get("name", "?"),
                    "email": ship.get("email", "?"),
                    "city": ship.get("city", "?"),
                    "state": ship.get("state", ""),
                    "country": ship.get("country", "?"),
                    "redeemed": o.get("updated_at", "?"),
                })
        if len(orders) < 100:
            break
        offset += 100

received.sort(key=lambda r: r["redeemed"], reverse=True)
```

### Step 1.5: Run referral fraud checks

Run the `referral-fraud-check` skill for every unique email in the pending list.
Read that skill for the workflow — it spawns a cloud agent, queries your
warehouse, and returns verdicts. Pass all emails in a single batch, then map each
verdict (APPROVE / DENY / INVESTIGATE) back to the corresponding order(s).

Also run these quick local heuristics and surface them as additional context:

- **Internal/team member**: email domain matches `$MAINTAINER_DOMAIN` — likely
  legitimate.
- **Name/email mismatch**: no overlap between the shipping name and the email
  local part.
- **Shared corporate domain**: multiple orders sharing the same non-common email
  domain (exclude gmail/yahoo/outlook/hotmail/icloud/proton).
- **Same email, multiple tiers**: the same email across multiple campaign tiers —
  a strong fraud signal.
- **High-tier scrutiny**: flag the highest tiers for extra review.

The fraud-check verdict takes precedence over local heuristics, but show both.

### Step 2: Format Slack message

Build a Slack mrkdwn message. Use `updated_at` as the redeemed date. Include a
dashboard link for each tier that has pending orders. If you maintain a referral
inspector dashboard, add its link via `$REFERRAL_INSPECTOR_URL` with the email as
a query parameter.

```
🎁 *Swag Pending Approvals — <date>*
<count> orders awaiting approval across Referral Program campaigns

*<tier> Tier* — <https://pro.swag.com/account/campaign/overview.php?storeid=<id>|Approve in dashboard>
• [APPROVE | DENY | INVESTIGATE] <name> · <email> · <city>, <country> · Redeemed <date>
  <1-2 sentence explanation of the recommendation>
  <local heuristic flags>
```

If zero orders are pending:
```
🎁 *Swag Pending Approvals — <date>*
✅ No orders pending approval — all clear!
```

### Step 3: Send to Slack (optional)

Only proceed if the user explicitly asks to send (or when running scheduled).

1. Check `$BUZZ_SLACK_TOKEN` exists.
2. Post to the user-provided channel, else `$APPROVALS_CHANNEL_ID`.

```python
import json, os, urllib.request

TOKEN = os.environ["BUZZ_SLACK_TOKEN"]
channel = channel_id or os.environ["APPROVALS_CHANNEL_ID"]

payload = json.dumps({
    "channel": channel,
    "text": formatted_summary,
    "unfurl_links": False,
    "unfurl_media": False,
}).encode()
req = urllib.request.Request(
    "https://slack.com/api/chat.postMessage",
    data=payload,
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json",
    },
)
with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read())
assert result["ok"], f"chat.postMessage failed: {result}"
```

## Scheduled Mode

When running on a schedule:

1. Always send the Slack message — no confirmation needed.
2. Post to `$APPROVALS_CHANNEL_ID` unless a different channel is configured.
3. `SWAG_API_KEY` and `BUZZ_SLACK_TOKEN` must be set.

Scheduled prompt: `"Check for pending swag approvals and send the report."`

## Edge Cases

- **SWAG_API_KEY not set**: stop and tell the user to set it.
- **API rate limit**: the Swag API is limited (~1,000 requests/hour).
- **Duplicate recipients**: flag the same email across multiple orders/tiers — a
  strong fraud signal.
- **Zero pending orders**: still send the message — a clean queue is good news.

## Constraints

- Do NOT hardcode or log the Swag API key, Slack token, campaign IDs, or PII.
- Use `updated_at` as the redeemed date, not `created_at`.

