# SendGrid Operating Runbook
**Cold Bore Ballistics LLC — Confidential**
Last updated: 2026-06-06

> This document contains step-by-step procedures for day-to-day SendGrid operations. For account details, domain IDs, and API key IDs, see `SendGrid_Architecture_Reference.md`.

---

## Prerequisites

### Console Access
1. Go to `https://app.sendgrid.com`
2. Log in with the CBB SendGrid account credentials

### API Access
All API operations use the SendGrid API key. Set in your shell before running commands:
```bash
export SG_KEY="<api_key_value>"
```

---

## Procedure: Rotate the claude-code API Key

Use when the `claude-code` key is compromised or being rotated on schedule.

1. Create a new Full Access key first:
```bash
curl -s -X POST "https://api.sendgrid.com/v3/api_keys" \
  -H "Authorization: Bearer $SG_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "claude-code", "scopes": []}' 
```
> Empty `scopes` array = Full Access.

2. Copy the new key value — shown only once.
3. Update `SendGrid_Architecture_Reference.md` with the new key ID.
4. Delete the old key:
```bash
curl -s -X DELETE "https://api.sendgrid.com/v3/api_keys/<old_key_id>" \
  -H "Authorization: Bearer $NEW_SG_KEY"
```

---

## Procedure: Rotate the twilio-ivr API Key

Use when the `twilio-ivr` key is compromised or needs rotation.

1. Create a new restricted key:
```bash
curl -s -X POST "https://api.sendgrid.com/v3/api_keys" \
  -H "Authorization: Bearer $SG_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "twilio-ivr", "scopes": ["mail.send"]}'
```

2. Copy the new key value — shown only once.
3. Update the Twilio Function environment variable `SENDGRID_API_KEY` with the new value:
   - Console (ScopeDOPE subaccount) → Functions → Services → `ivr-voicemail-handler` → Environment Variables → update `SENDGRID_API_KEY` → Save → Deploy All
4. Update `SendGrid_Architecture_Reference.md` with the new key ID.
5. Delete the old key:
```bash
curl -s -X DELETE "https://api.sendgrid.com/v3/api_keys/<old_key_id>" \
  -H "Authorization: Bearer $SG_KEY"
```

---

## Procedure: Re-verify a Domain

Use if DNS records are changed or domain verification expires.

```bash
# coldboreballisticsllc.com
curl -s -X POST "https://api.sendgrid.com/v3/whitelabel/domains/31320832/validate" \
  -H "Authorization: Bearer $SG_KEY" | python3 -m json.tool

# scope-dope.com
curl -s -X POST "https://api.sendgrid.com/v3/whitelabel/domains/31320833/validate" \
  -H "Authorization: Bearer $SG_KEY" | python3 -m json.tool
```

Both should return `"valid": true` with all three sub-records valid. If any fail, check the DNS records in the Namecheap CBB account (`coldboreballistics` login) match the values in `SendGrid_Architecture_Reference.md`.

---

## Procedure: Add a New Authenticated Domain

Use when a new CBB domain needs to send email via SendGrid.

1. Create the domain authentication:
```bash
curl -s -X POST "https://api.sendgrid.com/v3/whitelabel/domains" \
  -H "Authorization: Bearer $SG_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "subdomain": "em",
    "default": false,
    "automatic_security": true
  }' | python3 -m json.tool
```

2. Note the three CNAME records returned (`mail_cname`, `dkim1`, `dkim2`).
3. Add the three CNAME records in Namecheap CBB account.
4. Validate:
```bash
curl -s -X POST "https://api.sendgrid.com/v3/whitelabel/domains/<id>/validate" \
  -H "Authorization: Bearer $SG_KEY" | python3 -m json.tool
```
5. Update `SendGrid_Architecture_Reference.md` — add domain to Authenticated Domains table and DNS Records section.

---

## Procedure: Check Bounce and Suppression Lists

```bash
# Bounces
curl -s "https://api.sendgrid.com/v3/suppression/bounces" \
  -H "Authorization: Bearer $SG_KEY" | python3 -m json.tool

# Spam reports
curl -s "https://api.sendgrid.com/v3/suppression/spam_reports" \
  -H "Authorization: Bearer $SG_KEY" | python3 -m json.tool

# Unsubscribes
curl -s "https://api.sendgrid.com/v3/suppression/unsubscribes" \
  -H "Authorization: Bearer $SG_KEY" | python3 -m json.tool
```

---

## Procedure: Send a Test Email

Use to verify the `twilio-ivr` key and domain authentication are working end-to-end.

```bash
curl -s -X POST "https://api.sendgrid.com/v3/mail/send" \
  -H "Authorization: Bearer <twilio-ivr-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "personalizations": [{"to": [{"email": "jason@coldboreballisticsllc.com"}]}],
    "from": {"email": "noreply@scope-dope.com", "name": "ScopeDOPE IVR"},
    "subject": "[Test] SendGrid delivery test",
    "content": [{"type": "text/plain", "value": "SendGrid delivery test from CBB IVR system."}],
    "headers": {
      "X-CBB-Called": "test",
      "X-CBB-Option": "test"
    }
  }'
```

A 202 response with no body indicates successful acceptance. Check `jason@coldboreballisticsllc.com` inbox for delivery.

---

## Document Control

| Field | Value |
|---|---|
| **Document owner** | `jschwefel@coldboreballisticsllc.com` |
| **Classification** | Confidential (03_-_Confidential/) |
| **Location** | `OneDrive/CBB_Corporate/03_-_Confidential/Infrastructure/SendGrid/SendGrid_Operating_Runbook.md` |
| **Cross-references** | `SendGrid_Architecture_Reference.md`; `SendGrid_Rebuild_Guide.md`; `SendGrid_Integration_Guide.md` |
| **Created** | 2026-06-06 |
| **Last updated** | 2026-06-06 |
| **Next full review due** | 2027-06-06 |

---

## Revision Control Block

| Rev | Date | Changed By | Reviewed By | Approved By | Summary |
|-----|------|------------|-------------|-------------|---------|
| 0.9 | 2026-06-06 | jschwefel | — | — | Initial release |
