Guides
Performance & reporting
Measure what you paid for. Every number is based on actions ByteVerse has verified, so you are never billed for unverified work.
The numbers
| Field | Meaning |
|---|---|
target_actions | How many verified actions the budget buys. |
verified_actions | Actions ByteVerse approved. These are what you pay for. |
rejected_actions | Submissions that failed verification. Not billed. |
pending_actions | Submitted and waiting for review. Counted against budget until decided. |
completion_percent | verified / target as a percentage (one decimal). |
spent / remaining | verified × price_per_action, and the budget left. |
cost_per_verified_action | Spend divided by verified actions. null until the first verified action. |
verified_views | Views confirmed by ByteVerse's checks on post-style Growth Actions. 0 when not applicable. |
One campaign
curl "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/performance?days=14" \
-H "Authorization: Bearer $BYTEVERSE_API_KEY"const res = await fetch("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/performance?days=14", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/performance?days=14",
headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
timeout=30,
)
data = res.json()<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/performance?days=14");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);{
"object": "campaign_performance",
"campaign_id": "cmp_8f3a1c9d2b7e4f60a5d1",
"environment": "live",
"status": "active",
"timezone": "Africa/Lagos",
"totals": {
"target_actions": 71,
"verified_actions": 30,
"rejected_actions": 3,
"pending_actions": 4,
"completion_percent": 42.3,
"verified_views": 0
},
"spend": {
"currency": "NGN",
"budget": 5000,
"spent": 2100,
"remaining": 2900,
"cost_per_verified_action": 70
},
"daily": [
{
"date": "2026-10-21",
"verified_actions": 18
},
{
"date": "2026-10-22",
"verified_actions": 12
}
],
"generated_at": "2026-10-22T14:00:00Z"
}The daily series is grouped by calendar day in Africa/Lagos time and only includes days with verified actions.
All campaigns
curl "https://api.byteverseafrica.com/v1/performance/summary?from=2026-10-01&to=2026-10-22" \
-H "Authorization: Bearer $BYTEVERSE_API_KEY"const res = await fetch("https://api.byteverseafrica.com/v1/performance/summary?from=2026-10-01&to=2026-10-22", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
},
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.byteverseafrica.com/v1/performance/summary?from=2026-10-01&to=2026-10-22",
headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
timeout=30,
)
data = res.json()<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/performance/summary?from=2026-10-01&to=2026-10-22");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);Returns totals across every campaign created in the range, split by status, so you can build an overview screen with a single call.
Behind the numbers
To see the individual submissions behind verified_actions, rejected_actions and pending_actions, use List submissions. It is anonymous and paged.
Polling or webhooks?
For dashboards, polling GET /v1/campaigns/{id} every minute or so is fine and well inside the rate limit. For automation ("email my customer when the campaign finishes"), use webhooks: you get campaign.progress at 25, 50, 75 and 100% and campaign.completed without asking.
Counts update as ByteVerse reviews submissions, so pending_actions will move into verified or rejected over time. Treat the numbers as live, not as a final invoice until the campaign is completed.
