|
| 1 | +# Outreach SOP |
| 2 | + |
| 3 | +This is the canonical operating procedure for Proof cold outreach. |
| 4 | + |
| 5 | +## Purpose |
| 6 | + |
| 7 | +Use the admin outreach pipeline to: |
| 8 | +- load targets into D1 |
| 9 | +- review pending targets |
| 10 | +- send a controlled batch through the Worker |
| 11 | +- inspect batch stats/status before and after sends |
| 12 | + |
| 13 | +This keeps contact lists out of git and makes outreach auditable through the existing admin API. |
| 14 | + |
| 15 | +## Rules |
| 16 | + |
| 17 | +- Never commit contact lists or email addresses to the repository. |
| 18 | +- Use `Authorization: Bearer $ADMIN_TOKEN` for admin API calls. |
| 19 | +- Run `GET /api/admin/status` before sending any batch. |
| 20 | +- If `ok=false`, stop and fix critical health checks first. |
| 21 | +- If `has_warnings=true`, review the warning checks before deciding to proceed. |
| 22 | +- Prefer small batches and verify results before sending more. |
| 23 | + |
| 24 | +## Endpoints |
| 25 | + |
| 26 | +- `GET /api/admin/status` |
| 27 | +- `POST /api/admin/outreach/targets` |
| 28 | +- `GET /api/admin/outreach/targets` |
| 29 | +- `GET /api/admin/outreach/stats` |
| 30 | +- `POST /api/admin/outreach/send` |
| 31 | + |
| 32 | +Base URL: |
| 33 | + |
| 34 | +```bash |
| 35 | +export PROOF_API_BASE="https://api.socialproof.dev" |
| 36 | +``` |
| 37 | + |
| 38 | +## 1) Check admin status |
| 39 | + |
| 40 | +```bash |
| 41 | +curl -s "$PROOF_API_BASE/api/admin/status" \ |
| 42 | + -H "Authorization: Bearer $ADMIN_TOKEN" | jq |
| 43 | +``` |
| 44 | + |
| 45 | +Interpretation: |
| 46 | +- `ok=true` means critical systems are healthy |
| 47 | +- `has_warnings=true` means optional integrations have issues; read `checks.*.error` |
| 48 | + |
| 49 | +## 2) Load targets into D1 |
| 50 | + |
| 51 | +Prepare a local JSON file that is **not committed**: |
| 52 | + |
| 53 | +```json |
| 54 | +{ |
| 55 | + "targets": [ |
| 56 | + { |
| 57 | + "email": "owner@example.com", |
| 58 | + "name": "Sam", |
| 59 | + "business_name": "Sam's Plumbing", |
| 60 | + "vertical": "plumber", |
| 61 | + "variant": "v1" |
| 62 | + } |
| 63 | + ] |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +Upload: |
| 68 | + |
| 69 | +```bash |
| 70 | +curl -s "$PROOF_API_BASE/api/admin/outreach/targets" \ |
| 71 | + -H "Authorization: Bearer $ADMIN_TOKEN" \ |
| 72 | + -H "Content-Type: application/json" \ |
| 73 | + --data @targets.json | jq |
| 74 | +``` |
| 75 | + |
| 76 | +## 3) Review pending targets |
| 77 | + |
| 78 | +```bash |
| 79 | +curl -s "$PROOF_API_BASE/api/admin/outreach/targets" \ |
| 80 | + -H "Authorization: Bearer $ADMIN_TOKEN" | jq |
| 81 | +``` |
| 82 | + |
| 83 | +## 4) Check outreach stats |
| 84 | + |
| 85 | +```bash |
| 86 | +curl -s "$PROOF_API_BASE/api/admin/outreach/stats" \ |
| 87 | + -H "Authorization: Bearer $ADMIN_TOKEN" | jq |
| 88 | +``` |
| 89 | + |
| 90 | +Use this to confirm current pending/sent/error counts before sending. |
| 91 | + |
| 92 | +## 5) Send a small batch |
| 93 | + |
| 94 | +```bash |
| 95 | +curl -s "$PROOF_API_BASE/api/admin/outreach/send" \ |
| 96 | + -X POST \ |
| 97 | + -H "Authorization: Bearer $ADMIN_TOKEN" \ |
| 98 | + -H "Content-Type: application/json" \ |
| 99 | + -d '{"limit":10}' | jq |
| 100 | +``` |
| 101 | + |
| 102 | +Suggested practice: |
| 103 | +- start with `limit: 5` or `10` |
| 104 | +- inspect stats/results |
| 105 | +- only then send the next batch |
| 106 | + |
| 107 | +## 6) Verify outcome |
| 108 | + |
| 109 | +Re-run stats after the batch: |
| 110 | + |
| 111 | +```bash |
| 112 | +curl -s "$PROOF_API_BASE/api/admin/outreach/stats" \ |
| 113 | + -H "Authorization: Bearer $ADMIN_TOKEN" | jq |
| 114 | +``` |
| 115 | + |
| 116 | +Also inspect provider-side results if relevant. |
| 117 | + |
| 118 | +## Failure handling |
| 119 | + |
| 120 | +- 401: wrong or missing `ADMIN_TOKEN` |
| 121 | +- `ok=false` on `/api/admin/status`: do not send; fix critical integration failures first |
| 122 | +- send errors in outreach results: pause, inspect the error text, and avoid retry loops |
| 123 | + |
| 124 | +## Notes for agents |
| 125 | + |
| 126 | +- Old custom admin headers are obsolete. |
| 127 | +- The canonical admin contract is Bearer auth plus `/api/admin/*` routes. |
| 128 | +- The D1-backed outreach pipeline is preferred over ad hoc one-off send scripts. |
0 commit comments