Skip to content

Client Onboarding Workflow

Fresh

Source: bible/campaigns.md (The full workflow), BIBLE.md (Phase 12 client-manager)

From a new client to running campaigns end-to-end.

Lifecycle

flowchart TD
  CC[1. Create client] --> KA[2. Define keywords + areas]
  KA --> BL[3. Baseline rank scan]
  BL --> GG[4. Initial geogrid scan]
  GG --> AS[5. Assign accounts]
  AS --> PW[6. Verify warmup state]
  PW --> CR[7. Create campaigns]
  CR --> SC[8. Schedule]
  SC --> RP[9. Set up reporting]
  RP --> M[10. Monitor + adjust]

1. Create client

bash
curl -X POST http://localhost:4700/clients \
  -H "Content-Type: application/json" \
  -d '{
    "id": "journey-junk",
    "name": "Journey Junk Removal",
    "domain": "journeyjunkremoval.com",
    "primaryCity": "Dallas, TX",
    "keywords": [
      "junk removal dallas",
      "junk hauling dallas",
      "furniture removal dallas"
    ]
  }'

2. Define keywords + service areas

Each keyword + city pair is a target. List them in the client record.

3. Baseline rank scan

bash
curl -X POST http://localhost:4700/ranks/batch \
  -H "Content-Type: application/json" \
  -d '{
    "checks": [
      { "keyword": "junk removal dallas", "domain": "journeyjunkremoval.com" },
      { "keyword": "junk hauling dallas", "domain": "journeyjunkremoval.com" }
    ],
    "state": "TX"
  }'

Record starting positions.

4. Initial geogrid scan

bash
curl -X POST http://localhost:4700/geogrid/scan \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "junk removal",
    "domain": "journeyjunkremoval.com",
    "center": { "lat": 32.7767, "lng": -96.7970 },
    "radiusMiles": 15,
    "gridSize": 7
  }'

This is the "before" picture.

5. Assign accounts

bash
curl http://localhost:4700/accounts/by-client/journey-junk

If no accounts assigned yet:

bash
# Pull warm accounts from the general pool
curl -X POST http://localhost:4700/clients/journey-junk/assign-accounts \
  -H "Content-Type: application/json" \
  -d '{ "count": 20, "filter": { "phase": 3 } }'

6. Verify warmup state

bash
curl http://localhost:4700/accounts/army-status

Confirm at least 10-20 accounts at phase 2+ for the client.

7. Create campaigns

CTR for each money keyword:

bash
# Create the campaign config file
cat > campaigns/jj-dallas-junk-removal.json <<'EOF'
{
  "name": "JJ Dallas Junk Removal CTR",
  "plugin": "ctr-engine",
  "pluginExport": "runCTR",
  "accountSource": "store",
  "accountFilter": { "clientId": "journey-junk", "status": "active" },
  "concurrency": 3,
  "scheduleEverySec": 900,
  "maxRunsPerAccount": 30,
  "jobConfig": {
    "keyword": "junk removal dallas",
    "targetDomain": "journeyjunkremoval.com",
    "city": "Dallas",
    "state": "TX",
    "dwellTime": "medium"
  }
}
EOF

8. Schedule

bash
node cli.mjs schedule create \
  --campaign "jj-dallas-junk-removal" \
  --clicks-per-day 30 \
  --start-hour 8 \
  --end-hour 20 \
  --strategy "natural"

# Daily rank tracking
curl -X POST http://localhost:4700/schedules \
  -H "Content-Type: application/json" \
  -d '{
    "jobType": "rank-check",
    "runsPerDay": 1,
    "startHour": 6,
    "jobConfig": {
      "keyword": "junk removal dallas",
      "domain": "journeyjunkremoval.com",
      "state": "TX"
    }
  }'

9. Set up reporting

bash
# Configure alert notifications
curl -X POST http://localhost:4700/notifications/channels/rank-changes \
  -H "Content-Type: application/json" \
  -d '{ "webhook": "https://discord.com/api/webhooks/..." }'

# Generate initial baseline report
curl -X POST http://localhost:4700/reports/generate \
  -H "Content-Type: application/json" \
  -d '{ "clientId": "journey-junk", "period": "today", "format": "html" }'

10. Monitor + adjust

Weekly: review rank trends, geogrid scans, campaign success rates.

Monthly: generate the client report.

bash
curl -X POST http://localhost:4700/reports/generate \
  -H "Content-Type: application/json" \
  -d '{ "clientId": "journey-junk", "period": "last-30-days", "format": "html" }'