Agent Automation Guide

This guide is written for an AI agent (or a human following agent-style steps) that needs to set up and manage a Buddo operator business entirely from the command line. No prior knowledge of Buddo is assumed. Follow the steps in order — each step verifies its own output before proceeding.

Self-contained: This guide alone is sufficient to go from a fresh machine to a live, revenue-generating deployment with active ad campaigns. You do not need to read other documentation first.

Overview & Architecture

The Buddo platform is a shared loyalty economy. Users earn and spend Buddo points across every operator app on the network. As an operator you:

buddo login # authenticate once │ ▼ buddo apps create # register OAuth app → get client_id │ ▼ buddo deploy # deploy container → get app URL │ ▼ buddo campaigns create # fund campaign → users start seeing ads │ ▼ buddo analytics spend # monitor spend and impressions │ ▼ buddo campaigns pause / resume # control campaign pacing │ ▼ buddo billing balance # check runway │ ▼ buddo deploy stop / destroy # wind down when done

Base URL: https://api.buddo.xyz
Portal: https://buddo.xyz
Docs: https://docs.buddocloud.com

1

Install the CLI

Download the buddo binary for your platform.

macOS (arm64 / Apple Silicon):

curl -L https://docs.buddocloud.com/cli/buddo-darwin-arm64 -o buddo
chmod +x buddo
sudo mv buddo /usr/local/bin/

macOS (amd64 / Intel):

curl -L https://docs.buddocloud.com/cli/buddo-darwin-amd64 -o buddo
chmod +x buddo
sudo mv buddo /usr/local/bin/

Linux (amd64):

curl -L https://docs.buddocloud.com/cli/buddo-linux-amd64 -o buddo
chmod +x buddo
sudo mv buddo /usr/local/bin/

Windows (PowerShell):

Invoke-WebRequest https://docs.buddocloud.com/cli/buddo-windows-amd64.exe -OutFile buddo.exe
# Move buddo.exe to a directory in your PATH

Verify installation:

buddo version
Expected: buddo version v2.0.0 (or higher). If this succeeds, proceed to Step 2.
2

Authenticate

Run buddo login. The CLI opens your default browser and completes an OAuth 2.0 PKCE flow. Your credentials are saved locally and automatically refreshed on each subsequent command.

buddo login

The browser will show the Buddo login page. Sign in with your Buddo account (or create one at buddo.xyz). After successful login the browser shows "Authentication successful" and the terminal prints:

Logged in as alice (alice@example.com)
Expected: a line starting with Logged in as. If you see this, proceed.

For CI/headless environments:

Obtain a JWT by calling POST /api/auth/login directly, then:

# Obtain JWT
JWT=$(curl -s -X POST https://api.buddo.xyz/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","password":"yourpassword"}' \
  | jq -r '.token')

# Authenticate CLI with the JWT
buddo login --token "$JWT"
Token lifetime: Browser-flow tokens expire based on the server's OAuth policy (typically 24 hours). The CLI refreshes tokens automatically using the stored refresh token. For long-running scripts, check for "Your session has expired" errors and re-authenticate.

Verify authentication status:

buddo status

This shows your operator app (if any) and current deployments, confirming that credentials are valid and the API is reachable.

3

Register an Operator App

An operator app is your identity on the platform. It holds a point balance (funded by you), tracks your users, and is the entity that owns your deployments and campaigns.

buddo apps create --name "My Business" \
  --scopes "profile:read,points:read,points:spend,deploy:manage,campaigns:manage,app:balance:read"

The CLI prints your client_id and (if applicable) your client_secret. Save both immediately:

App created successfully!
------------------------------------------------------------
  App Name:            My Business
  Client ID:           f47ac10b-58cc-4372-a567-0e02b2c3d479
  Client Secret:       s3cr3t...
  Scopes:              profile:read, points:read, ...
  Status:              approved
------------------------------------------------------------
Save your client secret now. It is displayed only once. Store it in a secrets manager or environment variable before closing the terminal.
Expected: Status: approved. The deploy:manage scope is auto-approved. If status is pending, contact the Buddo platform team.

Confirm registration:

buddo apps list --json | jq '.[].name'

Scope reference — choose what your app needs:

ScopeWhen to include
profile:readAlways — needed to identify users
points:readAlways — needed to show user balances
points:spendIf users pay with Buddo points in your app
points:transferIf your app transfers points between users (e.g., P2P games)
deploy:manageAlways — required to deploy containers
app:balance:readTo create campaigns (balance check is required)
campaigns:manageTo pause, resume, and view campaign analytics
4

Deploy Your App

Deploy a Docker container to the buddocloud platform. The container is assigned a *.apps.buddocloud.com subdomain with automatic TLS.

Option A — Using buddo.json (recommended):

Create buddo.json in your project directory:

{
  "app": {
    "name": "my-business"
  },
  "deploy": {
    "image": "myregistry/my-business:latest",
    "port": 3000,
    "env": {
      "NODE_ENV": "production",
      "BUDDO_CLIENT_ID": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "BUDDO_CLIENT_SECRET": "s3cr3t..."
    }
  }
}
buddo deploy

Option B — Inline flags (good for scripts):

buddo deploy \
  --name my-business \
  --image myregistry/my-business:latest \
  --port 3000

Confirm the prompt when shown:

Deploying "my-business" ...
  Image : myregistry/my-business:latest
  Port  : 3000

Proceed? [y/N] y

Deployment started!
  ID     : d8f3a1c2
  Status : running
  URL    : https://my-business.apps.buddocloud.com

Save the app ID — you will need it for stop/restart/destroy:

APP_ID="d8f3a1c2"
Expected: Status: running and a URL ending in .apps.buddocloud.com. Test the URL to confirm your app is live.

Check deployment status:

buddo status
# Or for JSON output suitable for scripting:
buddo status --json | jq '.deployed_apps[] | {name, status, url}'
Image registry: Your image must be accessible from the buddocloud infrastructure. Use a public registry (Docker Hub) or authenticate with Harbor at harbor.buddo.xyz:4443.
5

Create an Ad Campaign

Ad campaigns drive users to your app. You fund them with Buddo points; the platform distributes those points to users as impression rewards. The platform takes a 10% rake on the total budget you pay.

Before creating a campaign, ensure your app account has sufficient Buddo points. Check your balance:

buddo billing balance

Create a campaign:

buddo campaigns create \
  --name "Launch Campaign" \
  --budget 50000 \
  --surface banner \
  --payout-rate 10

The CLI shows a preview before creating:

Creating campaign:
  Name:                  Launch Campaign
  Surface:               banner
  Total payment:         50000 points
  Platform fee:          5000 points (10% rake)
  Campaign budget:       45000 points
  Payout rate:           10 points/impression

Campaign created successfully!
------------------------------------------------------------
  ID:                    550e8400-e29b-41d4-a716-446655440000
  Name:                  Launch Campaign
  Surface:               banner
  Status:                active
  Campaign budget:       45000 points
  Platform rake:         5000 points
  Total paid:            50000 points
  Payout rate:           10 points/impression
------------------------------------------------------------

Save the campaign ID:

CAMPAIGN_ID="550e8400-e29b-41d4-a716-446655440000"
Expected: Status: active. The campaign is now live and serving ads on the Buddo network.

Surface type guidance:

SurfaceBest forNotes
bannerBrand awareness, always-visible placementLowest cost per impression
videoHigh engagement, storytellingUsers watch a video to earn points
rewardedUser acquisition, high intentUser explicitly opts in; highest engagement

Budget sizing guidance:

  • At 10 pts/impression with a 10,000 pt budget (after rake): ~900 impressions
  • At 20 pts/impression with a 10,000 pt budget (after rake): ~450 impressions
  • Higher payout rates attract more users but burn budget faster
6

Monitor Performance

Monitor your campaigns and platform engagement with the analytics commands. Run these on a schedule (e.g., every hour) to track spend.

Spend breakdown across all campaigns:

buddo analytics spend

Spend for a specific campaign:

buddo analytics spend $CAMPAIGN_ID

Platform engagement (impressions & user counts):

buddo analytics impressions
buddo analytics clicks

Scripting: detect when a campaign is exhausted

# Returns 0 if campaign is active, 1 if exhausted or cancelled
buddo analytics spend $CAMPAIGN_ID --json | jq '
  .campaigns[0] |
  if .status == "active" then
    "active: spent \(.spent) of \(.budget)"
  else
    "inactive: \(.status)"
  end
'

Date-windowed spend check:

buddo analytics spend \
  --since 2026-06-01 \
  --until 2026-06-30 \
  --json | jq '.totals'
Analytics API note: The impressions and clicks commands return operator-level 30-day aggregate totals from GET /api/operator/analytics. Per-campaign impression and click counts are not yet exposed as separate fields — use analytics spend for per-campaign data.
7

Manage Lifecycle

Control your deployments and campaigns at any point using lifecycle commands. All commands are idempotent and safe to call from scripts.

Campaign lifecycle

# Pause a campaign (stops serving ads, budget preserved)
buddo campaigns pause $CAMPAIGN_ID

# Resume a paused campaign
buddo campaigns resume $CAMPAIGN_ID

# Cancel a campaign (unspent budget refunded; 10% rake is non-refundable)
buddo campaigns cancel $CAMPAIGN_ID

# List all campaigns with current status
buddo campaigns list

Deployment lifecycle

# Stop a running deployment (container terminated, record preserved)
buddo deploy stop $APP_ID

# Restart a deployment (start a stopped container, or cycle a running one)
buddo deploy restart $APP_ID

# Permanently destroy a deployment (irreversible)
buddo deploy destroy $APP_ID

# Check current status of all deployments
buddo status

State machine — campaigns:

active ──pause──► paused ──resume──► active active ──cancel──► cancelled (unspent budget refunded) paused ──cancel──► cancelled (unspent budget refunded) active ──(budget exhausted)──► completed (automatic)

State machine — deployments:

running ──stop────► stopped stopped ──restart──► running running ──restart──► running (cycles container) running ──destroy──► (removed permanently) stopped ──destroy──► (removed permanently)

Scripting: automated campaign rotation

Example shell script that pauses campaigns when spend reaches 80% of budget:

#!/bin/bash
# Monitor spend and pause near-exhausted campaigns

CAMPAIGNS=$(buddo campaigns list --json | jq -r '.campaigns[].id')

for CAMPAIGN_ID in $CAMPAIGNS; do
  DATA=$(buddo analytics spend "$CAMPAIGN_ID" --json)
  BUDGET=$(echo "$DATA" | jq '.campaigns[0].budget')
  SPENT=$(echo "$DATA" | jq '.campaigns[0].spent')
  STATUS=$(echo "$DATA" | jq -r '.campaigns[0].status')

  if [ "$STATUS" = "active" ] && [ "$BUDGET" -gt 0 ]; then
    PCT=$(echo "scale=0; $SPENT * 100 / $BUDGET" | bc)
    echo "Campaign $CAMPAIGN_ID: ${PCT}% spent"

    if [ "$PCT" -ge 80 ]; then
      echo "  → Pausing (80% threshold reached)"
      buddo campaigns pause "$CAMPAIGN_ID" --json
    fi
  fi
done
8

Check Billing Health

Run a billing health check regularly to ensure your app account has sufficient runway. If balance runs out, active deployments may be stopped automatically.

Check current balance and runway:

buddo billing balance
  Balance      : 950,000 pts
  Daily burn   : 1,666 pts/day (estimated from last 30 transactions)
  Runway       : 570 days

Parse runway for alerting:

RUNWAY=$(buddo billing balance --json | jq -r '.runway_days')
echo "Runway: $RUNWAY days"

# Alert if under 30 days
if [ "$RUNWAY" != "unlimited" ] && [ "$RUNWAY" -lt 30 ] 2>/dev/null; then
  echo "WARNING: less than 30 days runway — top up your app account"
fi

Runway values:

ValueMeaningAction
"unlimited"No spending detected in last 30 transactionsNo action needed
"overdue"Balance is negativeTop up immediately — deployments may be stopped
"<N>"Estimated days of runway at current burn rateTop up if N < 30

View full transaction history:

buddo billing history --limit 50

Per-app billing status (check for billing-failed):

buddo billing apps --json | jq '.[] | select(.billing_status == "billing-failed") | .name'
Healthy billing state: Balance above zero, no apps with billing-failed status, runway above 30 days.

Automation Patterns

Full end-to-end setup script

This script performs the complete operator setup sequence. Suitable for use in CI pipelines or agent workflows that need to bootstrap a new business from scratch.

#!/bin/bash
set -euo pipefail

# 1. Authenticate (assumes token is available in CI)
buddo login --token "$BUDDO_JWT"

# 2. Register operator app
APP_DATA=$(buddo apps create \
  --name "My Business" \
  --scopes "profile:read,points:read,points:spend,deploy:manage,campaigns:manage,app:balance:read" \
  --json)

CLIENT_ID=$(echo "$APP_DATA" | jq -r '.client_id')
echo "Registered app: $CLIENT_ID"

# 3. Deploy application
DEPLOY_DATA=$(buddo deploy \
  --name my-business \
  --image myregistry/my-business:latest \
  --port 3000 \
  --json)  # Note: deploy does not currently support --json; check status after

APP_URL=$(buddo status --json | jq -r '.deployed_apps[0].url')
echo "App live at: $APP_URL"

# 4. Create launch campaign
CAMPAIGN_DATA=$(buddo campaigns create \
  --name "Launch Campaign" \
  --budget 50000 \
  --surface banner \
  --payout-rate 10 \
  --json)

CAMPAIGN_ID=$(echo "$CAMPAIGN_DATA" | jq -r '.id')
echo "Campaign live: $CAMPAIGN_ID"

# 5. Verify billing health
buddo billing balance

echo "Setup complete."

Daily health check script

#!/bin/bash
# Run daily — check deployments, campaigns, and billing

echo "=== Deployment Status ==="
buddo status --json | jq '.deployed_apps[] | "\(.name): \(.status)"'

echo ""
echo "=== Campaign Status ==="
buddo campaigns list --json | jq '.campaigns[] | "\(.name): \(.status) — spent \(.spent)/\(.budget)"'

echo ""
echo "=== Billing ==="
buddo billing balance --json | jq '"Balance: \(.balance_points) pts | Runway: \(.runway_days) days"'

echo ""
echo "=== Billing-Failed Apps ==="
buddo billing apps --json | jq '.[] | select(.billing_status == "billing-failed") | .name'

JSON output for all commands

Every command supports --json for machine-readable output. Use this flag in scripts rather than parsing human-readable text:

# Good — parse JSON
buddo billing balance --json | jq '.balance_points'

# Fragile — don't parse human-readable output
buddo billing balance | grep "Balance" | awk '{print $3}'

Troubleshooting

ErrorCauseFix
Your session has expired. Run 'buddo login' to re-authenticate. Access token expired; refresh token also expired or missing Run buddo login or buddo login --token $JWT
could not start local server on port 34567 Another process is bound to port 34567 Kill the conflicting process: lsof -ti:34567 | xargs kill (macOS/Linux)
Error: Insufficient Buddo points in your app account. App account balance too low for the requested campaign budget Top up via the Buddo portal or request points from an admin
Error: Campaign is not active — only active campaigns can be paused. Tried to pause a campaign that is already paused, completed, or cancelled Check status: buddo campaigns list --json | jq '.campaigns[] | select(.id=="$ID") | .status'
Error: Campaign is not paused — only paused campaigns can be resumed. Tried to resume a campaign that is not paused Check status as above
Not available yet: ... (exit code 2) The API endpoint is not yet live on this server version This is expected for some deploy API endpoints in early access. The exit code is 2 (not 1) so scripts can distinguish from hard errors.
Error: --name is required Required flag was not passed to campaigns create Pass all required flags: --name, --budget, --surface
App shows billing-failed in buddo billing apps App was automatically stopped due to insufficient balance Top up balance, then run buddo deploy restart $APP_ID
Deploy status shows app not running after buddo deploy Container failed health check or image pull failed Check logs: buddo deploy logs $APP_ID
Token exchange failed: invalid_client CLI OAuth app not registered on this server Contact the Buddo platform team with client_id ae82729e-c708-448c-8361-cde45318a5be

Getting help

# Help for any command
buddo --help
buddo campaigns --help
buddo deploy --help
buddo billing --help
buddo analytics --help
API reference: Every CLI operation maps to a REST API call. If the CLI is unavailable, the same operations can be performed via curl against https://api.buddo.xyz. See the Operator Onboarding Guide for the full curl equivalents.