Compose safe, copy/paste-ready voluum-cli commands from user intent using public API workflows.
voluum-cli is community-supported software released under the MIT License. It is not an official Voluum product and is not endorsed or supported by Voluum. It uses publicly documented Voluum APIs.
voluum commands.summary, breakdown, query, schema, raw) with correct flags.# Access key login (preferred — longer-lived than email/password sessions)
# --accessId and --accessKeyId are aliases; both are accepted
voluum auth login --accessId '<ACCESS_ID>' --accessKey '<ACCESS_KEY>'
# Email/password login
voluum auth login --email [email protected] --password '<PASSWORD>'
# Check current token
voluum auth whoami
Set env vars in ~/.zshrc or ~/.bashrc to avoid re-logging in:
export VOLUUM_BASE_URL=https://api.voluum.com
export VOLUUM_TOKEN=<your-token>
All create and update commands accept JSON via one of:
--data '<json>' — inline JSON string--file <path> — path to a JSON file (preferred for complex payloads)These flags are mutually exclusive; exactly one is required.
# Inline JSON
voluum offers create --data '{"name":"My Offer","url":"https://example.com/offer"}'
# From file
voluum offers create --file ./offer.json
# Update always requires --id
voluum offers update --id '<ID>' --file ./updated-offer.json
voluum campaigns list
voluum campaigns get --id '<CAMPAIGN_ID>'
voluum campaigns create --data '{"name":"My Campaign"}'
voluum campaigns create --file ./campaign.json
voluum campaigns update --id '<CAMPAIGN_ID>' --data '{"name":"Updated Name"}'
voluum campaigns update --id '<CAMPAIGN_ID>' --file ./campaign.json
voluum campaigns delete --id '<CAMPAIGN_ID>'
voluum offers list
voluum offers get --id '<OFFER_ID>'
voluum offers create --data '{"name":"My Offer","url":"https://example.com"}'
voluum offers create --file ./offer.json
voluum offers update --id '<OFFER_ID>' --data '{"name":"Updated Offer"}'
voluum offers update --id '<OFFER_ID>' --file ./offer.json
voluum offers delete --id '<OFFER_ID>'
voluum landers list
voluum landers get --id '<LANDER_ID>'
voluum landers create --data '{"name":"My Lander","url":"https://example.com/lp"}'
voluum landers create --file ./lander.json
voluum landers update --id '<LANDER_ID>' --data '{"name":"Updated Lander"}'
voluum landers update --id '<LANDER_ID>' --file ./lander.json
voluum landers delete --id '<LANDER_ID>'
voluum flows list
voluum flows get --id '<FLOW_ID>'
voluum flows create --data '{"name":"My Flow"}'
voluum flows create --file ./flow.json
voluum flows update --id '<FLOW_ID>' --data '{"name":"Updated Flow"}'
voluum flows update --id '<FLOW_ID>' --file ./flow.json
voluum flows delete --id '<FLOW_ID>'
voluum traffic-sources list
voluum traffic-sources get --id '<TRAFFIC_SOURCE_ID>'
voluum traffic-sources create --data '{"name":"My Traffic Source"}'
voluum traffic-sources create --file ./traffic-source.json
voluum traffic-sources update --id '<TRAFFIC_SOURCE_ID>' --data '{"name":"Updated Source"}'
voluum traffic-sources update --id '<TRAFFIC_SOURCE_ID>' --file ./traffic-source.json
voluum traffic-sources delete --id '<TRAFFIC_SOURCE_ID>'
voluum affiliate-networks list
voluum affiliate-networks get --id '<NETWORK_ID>'
voluum affiliate-networks create --data '{"name":"My Network"}'
voluum affiliate-networks create --file ./network.json
voluum affiliate-networks update --id '<NETWORK_ID>' --data '{"name":"Updated Network"}'
voluum affiliate-networks update --id '<NETWORK_ID>' --file ./network.json
voluum affiliate-networks delete --id '<NETWORK_ID>'
voluum tracker-domains list
voluum tracker-domains get --id '<TRACKER_DOMAIN_ID>'
voluum tracker-domains create --data '{"domain":"track.example.com"}'
voluum tracker-domains create --file ./domain.json
voluum tracker-domains update --id '<TRACKER_DOMAIN_ID>' --data '{"domain":"new.example.com"}'
voluum tracker-domains update --id '<TRACKER_DOMAIN_ID>' --file ./domain.json
voluum tracker-domains delete --id '<TRACKER_DOMAIN_ID>'
The Voluum API uses two separate params for sorting. The combined sort=field:direction
syntax does NOT work and returns a 400 error.
Correct:
sort=revenue direction=desc
sort=visits direction=asc
sort=conversions direction=desc
Wrong (will 400):
sort=revenue:desc ← invalid
--query vs --query-json--query parses comma-separated key=value pairs: good for simple params--query-json accepts a JSON object: required when a value contains commas (e.g. columns=a,b,c)--query-json wins on duplicate keysExample combining both:
voluum reports query \
--query "from=2026-02-01T00:00:00.000Z,to=2026-02-18T00:00:00.000Z,groupBy=campaignId,limit=20" \
--query-json '{"sort":"revenue","direction":"desc","columns":"campaignId,campaignName,revenue,conversions,cr,epc"}'
--out <file> to capture full output: stdout is capped at ~24k chars.columnMappings and internal metadata fields.# 7-day campaign summary
voluum reports summary \
--from 2026-02-12T00:00:00.000Z \
--to 2026-02-19T00:00:00.000Z \
--groupBy campaign
# Top 20 campaigns by revenue
voluum reports query \
--query-json '{
"from": "2026-02-12T00:00:00.000Z",
"to": "2026-02-19T00:00:00.000Z",
"groupBy": "campaignId",
"limit": 20,
"sort": "revenue",
"direction": "desc",
"columns": "campaignId,campaignName,revenue,conversions,cr,epc,ap"
}'
# Top 20 offers by revenue
voluum reports query \
--query-json '{
"from": "2026-02-12T00:00:00.000Z",
"to": "2026-02-19T00:00:00.000Z",
"groupBy": "offerId",
"limit": 20,
"sort": "revenue",
"direction": "desc",
"columns": "offerId,offerName,revenue,conversions,cr,epc,ap"
}'
# Save large results to file
voluum reports query \
--query-json '{"from":"...","to":"...","groupBy":"campaignId","limit":200,"sort":"revenue","direction":"desc"}' \
--out /tmp/campaigns.json
# Traffic source distribution
voluum reports breakdown --by traffic-source \
--from 2026-02-12T00:00:00.000Z \
--to 2026-02-19T00:00:00.000Z \
--limit 50
# Offer breakdown for a specific campaign
voluum reports breakdown --by offer-by-campaign \
--campaignId '<CAMPAIGN_ID>' \
--from 2026-02-12T00:00:00.000Z \
--to 2026-02-19T00:00:00.000Z
# Lander performance
voluum reports breakdown --by lander \
--from 2026-02-12T00:00:00.000Z \
--to 2026-02-19T00:00:00.000Z \
--limit 20
# Flow breakdown
voluum reports breakdown --by flow \
--from 2026-02-12T00:00:00.000Z \
--to 2026-02-19T00:00:00.000Z
# List all groupable columns for a report
voluum reports schema \
--query "from=2026-02-01T00:00:00.000Z,to=2026-02-18T00:00:00.000Z,groupBy=campaignId" \
--groupable
# Find money columns with search
voluum reports schema \
--query "from=2026-02-01T00:00:00.000Z,to=2026-02-18T00:00:00.000Z,groupBy=campaignId" \
--type money --search revenue
# Full param catalog
voluum reports schema \
--query "from=2026-02-01T00:00:00.000Z,to=2026-02-18T00:00:00.000Z,groupBy=campaignId" \
--with-query-params
voluum reports raw \
--from 2026-02-12T00:00:00.000Z \
--to 2026-02-19T00:00:00.000Z \
--limit 50
| groupBy value | What it groups by |
|---|---|
campaignId | Individual campaigns |
offerId | Individual offers |
trafficSourceId | Traffic sources |
flowId | Flows |
landerId | Landers |
Note: country is not a valid groupBy for /report. Use /report/conversions or
check voluum reports schema --groupable for valid groupBy fields per endpoint.
revenue, visits, conversions, clicks, cr, epc, ap, profit, roi, cv
Always pair with direction=asc or direction=desc.
voluum api get /campaign --query status=active,limit=50
voluum api get /traffic-source
| Error | Cause | Fix |
|---|---|---|
401 | Token expired or missing | voluum auth login or set VOLUUM_TOKEN |
400 INVALID_QUERY | Bad groupBy, invalid column, or wrong sort syntax | Check --groupable schema; use sort=field + direction=asc|desc separately |
400 PARAMETER_MISSING | Missing required param (e.g. groupBy for schema) | Add the missing param |
429 / 5xx | Rate limit or server error | Smaller date range, lower limit, or wait and retry |
trafficSourceId=<id> in the query are accepted but may be silently ignored
by some report endpoints — verify by checking if totalRows changes.columns=... param is accepted but Voluum returns all fields anyway; it's cosmetic.--json for compact JSON or --pretty for pretty-printed JSON.--json is required when piping to jq or other JSON tools.--out <file> always writes full output regardless of format.