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.
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:
- Register an OAuth app to get a
client_idand credentials - Deploy a containerised app to buddocloud hosting
- Create ad campaigns — you fund them with points, the platform distributes those points to users as rewards for engagement
- Monitor analytics and billing to manage spend
Base URL: https://api.buddo.xyz
Portal: https://buddo.xyz
Docs: https://docs.buddocloud.com
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
buddo version v2.0.0 (or higher). If this succeeds, proceed to Step 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)
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"
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.
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
------------------------------------------------------------
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:
| Scope | When to include |
|---|---|
profile:read | Always — needed to identify users |
points:read | Always — needed to show user balances |
points:spend | If users pay with Buddo points in your app |
points:transfer | If your app transfers points between users (e.g., P2P games) |
deploy:manage | Always — required to deploy containers |
app:balance:read | To create campaigns (balance check is required) |
campaigns:manage | To pause, resume, and view campaign analytics |
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"
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}'
harbor.buddo.xyz:4443.
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"
Status: active. The campaign is now live and
serving ads on the Buddo network.
Surface type guidance:
| Surface | Best for | Notes |
|---|---|---|
banner | Brand awareness, always-visible placement | Lowest cost per impression |
video | High engagement, storytelling | Users watch a video to earn points |
rewarded | User acquisition, high intent | User 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
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'
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.
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:
State machine — deployments:
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
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:
| Value | Meaning | Action |
|---|---|---|
"unlimited" | No spending detected in last 30 transactions | No action needed |
"overdue" | Balance is negative | Top up immediately — deployments may be stopped |
"<N>" | Estimated days of runway at current burn rate | Top 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'
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
| Error | Cause | Fix |
|---|---|---|
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
curl against https://api.buddo.xyz.
See the Operator Onboarding Guide
for the full curl equivalents.