ByteVerseDevelopers
Get API keys

Reference

API reference

Base URL https://api.byteverseafrica.com/v1. All requests need Authorization: Bearer <key> unless noted. Examples run unchanged against the sandbox with a bv_test_ key. Download the OpenAPI spec or the Postman collection.

Account

GET/v1/me

Retrieve the current key

Returns the partner account, environment (live or test), scopes and rate limit of the API key you used. A good first call to confirm your key works.

no scope needed

Example request

curl "https://api.byteverseafrica.com/v1/me" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/me", {
  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/me",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/me");
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);

Response

200 OK
{
  "object": "partner",
  "id": "7d1c3b52-9e04-4a6f-b1d8-52c0e7a93f16",
  "name": "Arewa Threads Ltd",
  "environment": "test",
  "key": {
    "id": "b3f0a7c4-61d2-4e8b-9a35-0c7e41d8f259",
    "scopes": [
      "catalog:read",
      "campaigns:read",
      "campaigns:write",
      "performance:read",
      "wallet:read",
      "webhooks:manage",
      "submissions:read",
      "evidence:read"
    ]
  },
  "rate_limit_per_minute": 60
}

Catalog

GET/v1/task_types

List Growth Action types

The catalog of actions you can buy, with the price ByteVerse charges per verified action and the minimum budget for each. Prices are in NGN and can change, so read them here instead of hard-coding.

scope: catalog:read

Example request

curl "https://api.byteverseafrica.com/v1/task_types" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/task_types", {
  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/task_types",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/task_types");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "like-only",
      "label": "Like Only",
      "price_per_action": 30,
      "min_budget": 1000,
      "currency": "NGN"
    },
    {
      "id": "instagram-follow",
      "label": "Instagram Follow",
      "price_per_action": 70,
      "min_budget": 1400,
      "currency": "NGN"
    },
    {
      "id": "google-maps-review",
      "label": "Google Maps Review",
      "price_per_action": 270,
      "min_budget": 5400,
      "currency": "NGN"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
POST/v1/quotes

Get a price quote

Calculates the exact cost of a campaign before you create it: service fee, total to be charged from your wallet and how many verified actions the budget buys. Nothing is charged.

scope: catalog:read

Request body

FieldTypeDescription
task_typerequiredstringA Growth Action type id.
budgetrequiredintegerBudget in whole naira.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/quotes" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "task_type": "instagram-follow",
    "budget": 5000
  }'
const res = await fetch("https://api.byteverseafrica.com/v1/quotes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "task_type": "instagram-follow",
    "budget": 5000
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/quotes",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    json={
        "task_type": "instagram-follow",
        "budget": 5000,
    },
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/quotes");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY"), "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode([
    "task_type" => "instagram-follow",
    "budget" => 5000,
  ]),
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "object": "quote",
  "currency": "NGN",
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "price_per_action": 70,
  "budget": 5000,
  "service_fee": 250,
  "total_charge": 5250,
  "estimated_actions": 71,
  "min_budget": 1400
}

Campaigns

POST/v1/campaigns

Create a campaign

Creates a campaign and charges the total (budget + 5% service fee) from your wallet in one atomic step. The campaign starts as in_review; once ByteVerse approves it, it becomes active and you receive a campaign.activated event.

scope: campaigns:writeIdempotency-Key required

Idempotency-Key is required. If your request times out, retry with the same key and body: you get the original result and are never charged twice.

Request body

FieldTypeDescription
namerequiredstringDisplay name of the brand or campaign (2-120 characters). Shown to people who see the Growth Action.
task_typerequiredstringWhat people should do. Must be an id from GET /v1/task_types, e.g. instagram-follow.
budgetrequiredintegerAmount in whole naira that is spent on verified actions. Minimum depends on the Growth Action type (see min_budget in the catalog).
destination_urlrequiredstringThe link people are sent to (your profile, post, page or app). Must be http(s).
captionstringText people are asked to post or use (up to 2,000 characters).
media_urlstringhttps URL of an image or video asset to accompany the Growth Action.
targeting.locationsstring[]Nigerian state names, FCT, or ["All Nigeria"] (default). "All Nigeria" cannot be mixed with states.
targeting.genderstringall (default), male or female.
contact_emailstringContact for this campaign. Defaults to your partner account email.
whatsapp_numberstringOptional WhatsApp contact (7-15 digits, optional leading +).
external_referencestringYour own id for this campaign (max 128 chars). Must be unique per environment, and you can look campaigns up by it.
metadataobjectUp to 20 key/value pairs (4,000 characters total) returned on every read. Never put secrets here.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name": "Sallah Weekend Ankara Sale",
    "task_type": "instagram-follow",
    "budget": 5000,
    "destination_url": "https://instagram.com/arewathreads",
    "targeting": {
      "locations": [
        "Lagos",
        "Kano"
      ],
      "gender": "all"
    },
    "external_reference": "order_10482",
    "metadata": {
      "order_id": "10482"
    }
  }'
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Sallah Weekend Ankara Sale",
    "task_type": "instagram-follow",
    "budget": 5000,
    "destination_url": "https://instagram.com/arewathreads",
    "targeting": {
      "locations": [
        "Lagos",
        "Kano"
      ],
      "gender": "all"
    },
    "external_reference": "order_10482",
    "metadata": {
      "order_id": "10482"
    }
  }),
});
const data = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
        "name": "Sallah Weekend Ankara Sale",
        "task_type": "instagram-follow",
        "budget": 5000,
        "destination_url": "https://instagram.com/arewathreads",
        "targeting": {
            "locations": ["Lagos", "Kano"],
            "gender": "all",
        },
        "external_reference": "order_10482",
        "metadata": {
            "order_id": "10482",
        },
    },
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY"), "Content-Type: application/json", "Idempotency-Key: " . bin2hex(random_bytes(16))],
  CURLOPT_POSTFIELDS => json_encode([
    "name" => "Sallah Weekend Ankara Sale",
    "task_type" => "instagram-follow",
    "budget" => 5000,
    "destination_url" => "https://instagram.com/arewathreads",
    "targeting" => [
      "locations" => ["Lagos", "Kano"],
      "gender" => "all",
    ],
    "external_reference" => "order_10482",
    "metadata" => [
      "order_id" => "10482",
    ],
  ]),
]);
$data = json_decode(curl_exec($ch), true);

Response

201 Created
{
  "id": "cmp_8f3a1c9d2b7e4f60a5d1",
  "object": "campaign",
  "environment": "live",
  "status": "in_review",
  "name": "Sallah Weekend Ankara Sale",
  "external_reference": "order_10482",
  "metadata": {
    "order_id": "10482"
  },
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "destination_url": "https://instagram.com/arewathreads",
  "caption": null,
  "media_url": null,
  "targeting": {
    "locations": [
      "Lagos",
      "Kano"
    ],
    "gender": "all"
  },
  "price_per_action": 70,
  "budget": {
    "currency": "NGN",
    "amount": 5000,
    "service_fee": 250,
    "total_charged": 5250,
    "spent": 0,
    "remaining": 5000
  },
  "progress": {
    "target_actions": 71,
    "verified_actions": 0,
    "rejected_actions": 0,
    "pending_actions": 0,
    "completion_percent": 0
  },
  "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
  "created_at": "2026-10-22T09:14:03Z",
  "completed_at": null,
  "cancelled_at": null,
  "refund_amount": null
}
GET/v1/campaigns

List campaigns

Returns your campaigns, newest first.

scope: campaigns:read

Query parameters

FieldTypeDescription
statusstringFilter: in_review, active, paused, completed or cancelled.
external_referencestringReturn only the campaign with this reference.
limitinteger1-100, default 20.
starting_afterstringCursor from next_cursor of the previous page.

Example request

curl "https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10", {
  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?status=active&limit=10",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/campaigns?status=active&limit=10");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "cmp_8f3a1c9d2b7e4f60a5d1",
      "object": "campaign",
      "environment": "live",
      "status": "active",
      "name": "Sallah Weekend Ankara Sale",
      "external_reference": "order_10482",
      "metadata": {
        "order_id": "10482"
      },
      "task_type": "instagram-follow",
      "task_label": "Instagram Follow",
      "destination_url": "https://instagram.com/arewathreads",
      "caption": null,
      "media_url": null,
      "targeting": {
        "locations": [
          "Lagos",
          "Kano"
        ],
        "gender": "all"
      },
      "price_per_action": 70,
      "budget": {
        "currency": "NGN",
        "amount": 5000,
        "service_fee": 250,
        "total_charged": 5250,
        "spent": 2100,
        "remaining": 2900
      },
      "progress": {
        "target_actions": 71,
        "verified_actions": 30,
        "rejected_actions": 3,
        "pending_actions": 4,
        "completion_percent": 42.3
      },
      "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
      "created_at": "2026-10-22T09:14:03Z",
      "completed_at": null,
      "cancelled_at": null,
      "refund_amount": null
    }
  ],
  "has_more": false,
  "next_cursor": null
}
GET/v1/campaigns/{id}

Retrieve a campaign

Returns one campaign with live progress and budget figures.

scope: campaigns:read

Path parameters

NameDescription
idThe campaign id, e.g. cmp_8f3a1c9d2b7e4f60a5d1.

Example request

curl "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1", {
  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",
    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");
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);

Response

200 OK
{
  "id": "cmp_8f3a1c9d2b7e4f60a5d1",
  "object": "campaign",
  "environment": "live",
  "status": "active",
  "name": "Sallah Weekend Ankara Sale",
  "external_reference": "order_10482",
  "metadata": {
    "order_id": "10482"
  },
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "destination_url": "https://instagram.com/arewathreads",
  "caption": null,
  "media_url": null,
  "targeting": {
    "locations": [
      "Lagos",
      "Kano"
    ],
    "gender": "all"
  },
  "price_per_action": 70,
  "budget": {
    "currency": "NGN",
    "amount": 5000,
    "service_fee": 250,
    "total_charged": 5250,
    "spent": 2100,
    "remaining": 2900
  },
  "progress": {
    "target_actions": 71,
    "verified_actions": 30,
    "rejected_actions": 3,
    "pending_actions": 4,
    "completion_percent": 42.3
  },
  "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
  "created_at": "2026-10-22T09:14:03Z",
  "completed_at": null,
  "cancelled_at": null,
  "refund_amount": null
}
POST/v1/campaigns/{id}/pause

Pause a campaign

Temporarily stops new people from taking the Growth Action. Only active campaigns can be paused. Budget stays reserved.

scope: campaigns:writeIdempotency-Key supported

Path parameters

NameDescription
idThe campaign id.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/pause" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/pause", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
  },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/pause",
    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/pause");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "cmp_8f3a1c9d2b7e4f60a5d1",
  "object": "campaign",
  "environment": "live",
  "status": "paused",
  "name": "Sallah Weekend Ankara Sale",
  "external_reference": "order_10482",
  "metadata": {
    "order_id": "10482"
  },
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "destination_url": "https://instagram.com/arewathreads",
  "caption": null,
  "media_url": null,
  "targeting": {
    "locations": [
      "Lagos",
      "Kano"
    ],
    "gender": "all"
  },
  "price_per_action": 70,
  "budget": {
    "currency": "NGN",
    "amount": 5000,
    "service_fee": 250,
    "total_charged": 5250,
    "spent": 2100,
    "remaining": 2900
  },
  "progress": {
    "target_actions": 71,
    "verified_actions": 30,
    "rejected_actions": 3,
    "pending_actions": 4,
    "completion_percent": 42.3
  },
  "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
  "created_at": "2026-10-22T09:14:03Z",
  "completed_at": null,
  "cancelled_at": null,
  "refund_amount": null
}
POST/v1/campaigns/{id}/resume

Resume a campaign

Re-opens a paused campaign. Only paused campaigns can be resumed.

scope: campaigns:writeIdempotency-Key supported

Path parameters

NameDescription
idThe campaign id.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/resume" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/resume", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
  },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/resume",
    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/resume");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "cmp_8f3a1c9d2b7e4f60a5d1",
  "object": "campaign",
  "environment": "live",
  "status": "active",
  "name": "Sallah Weekend Ankara Sale",
  "external_reference": "order_10482",
  "metadata": {
    "order_id": "10482"
  },
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "destination_url": "https://instagram.com/arewathreads",
  "caption": null,
  "media_url": null,
  "targeting": {
    "locations": [
      "Lagos",
      "Kano"
    ],
    "gender": "all"
  },
  "price_per_action": 70,
  "budget": {
    "currency": "NGN",
    "amount": 5000,
    "service_fee": 250,
    "total_charged": 5250,
    "spent": 2100,
    "remaining": 2900
  },
  "progress": {
    "target_actions": 71,
    "verified_actions": 30,
    "rejected_actions": 3,
    "pending_actions": 4,
    "completion_percent": 42.3
  },
  "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
  "created_at": "2026-10-22T09:14:03Z",
  "completed_at": null,
  "cancelled_at": null,
  "refund_amount": null
}
POST/v1/campaigns/{id}/cancel

Cancel a campaign

Stops a campaign and refunds your wallet. If the campaign has not been approved yet (in_review) you get the full amount including the service fee. If it is running, you get back the unspent budget (slots not yet verified or awaiting review); the service fee is not refunded. Completed and already-cancelled campaigns cannot be cancelled.

scope: campaigns:writeIdempotency-Key supported

Path parameters

NameDescription
idThe campaign id.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/cancel" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/cancel", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
  },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/cancel",
    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/cancel");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "cmp_8f3a1c9d2b7e4f60a5d1",
  "object": "campaign",
  "environment": "live",
  "status": "cancelled",
  "name": "Sallah Weekend Ankara Sale",
  "external_reference": "order_10482",
  "metadata": {
    "order_id": "10482"
  },
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "destination_url": "https://instagram.com/arewathreads",
  "caption": null,
  "media_url": null,
  "targeting": {
    "locations": [
      "Lagos",
      "Kano"
    ],
    "gender": "all"
  },
  "price_per_action": 70,
  "budget": {
    "currency": "NGN",
    "amount": 5000,
    "service_fee": 250,
    "total_charged": 5250,
    "spent": 2100,
    "remaining": 2900
  },
  "progress": {
    "target_actions": 71,
    "verified_actions": 30,
    "rejected_actions": 3,
    "pending_actions": 4,
    "completion_percent": 42.3
  },
  "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
  "created_at": "2026-10-22T09:14:03Z",
  "completed_at": null,
  "cancelled_at": "2026-10-22T11:02:41Z",
  "refund_amount": 2030
}

Performance

GET/v1/campaigns/{id}/performance

Campaign performance

Verified results, spend and a daily breakdown for one campaign. Only actions that ByteVerse has verified count as verified_actions and are billed.

scope: performance:read

Path parameters

NameDescription
idThe campaign id.

Query parameters

FieldTypeDescription
daysintegerDays of daily history, 1-90, default 30.

Example request

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);

Response

200 OK
{
  "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"
}
GET/v1/performance/summary

Performance summary

Totals across all campaigns created in a date range (Africa/Lagos dates).

scope: performance:read

Query parameters

FieldTypeDescription
fromstringStart date YYYY-MM-DD. Default: 30 days ago.
tostringEnd date YYYY-MM-DD. Default: today.

Example request

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);

Response

200 OK
{
  "object": "performance_summary",
  "environment": "live",
  "from": "2026-09-22",
  "to": "2026-10-22",
  "campaigns": {
    "total": 12,
    "by_status": {
      "in_review": 1,
      "active": 4,
      "paused": 0,
      "completed": 6,
      "cancelled": 1
    }
  },
  "actions": {
    "target": 2410,
    "verified": 1822,
    "rejected": 140,
    "pending": 31,
    "completion_percent": 75.6
  },
  "spend": {
    "currency": "NGN",
    "budget": 95000,
    "spent": 71230,
    "cost_per_verified_action": 39.1
  },
  "generated_at": "2026-10-22T14:00:00Z"
}

Submissions

GET/v1/campaigns/{id}/submissions

List submissions

A paged, anonymous list of the submissions on one campaign: id, action type, status, timing and whether proof is available. It never includes usernames, emails, avatars or any other identity field. Newest first.

scope: submissions:read

Path parameters

NameDescription
idThe campaign id.

Query parameters

FieldTypeDescription
statusstringFilter by pending, approved or rejected.
limitinteger1-100, default 20.
starting_afterstringCursor: pass the next_cursor from the previous page.

Example request

curl "https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/submissions?status=approved&limit=20" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/submissions?status=approved&limit=20", {
  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/submissions?status=approved&limit=20",
    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/submissions?status=approved&limit=20");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13",
      "object": "submission",
      "campaign_id": "cmp_8f3a1c9d2b7e4f60a5d1",
      "action_type": "instagram-follow",
      "status": "approved",
      "submitted_at": "2026-10-22T09:41:07Z",
      "verified_at": "2026-10-22T09:52:30Z",
      "evidence_available": true,
      "evidence_count": 2,
      "scanned_views": 412
    },
    {
      "id": "sub_a71d5e2c9b034f18b6e0c3d7f5a29e41",
      "object": "submission",
      "campaign_id": "cmp_8f3a1c9d2b7e4f60a5d1",
      "action_type": "instagram-follow",
      "status": "pending",
      "submitted_at": "2026-10-22T09:12:44Z",
      "verified_at": null,
      "evidence_available": true,
      "evidence_count": 1,
      "scanned_views": null
    }
  ],
  "has_more": true,
  "next_cursor": "WyIyMDI2LTEwLTIyVDA5OjEyOjQ0WiIsInN1Yl9hNzFkNWUyYzliMDM0ZjE4YjZlMGMzZDdmNWEyOWU0MSJd"
}

scanned_views is null until a submission is approved and scanned. evidence_available is false when a submission has no proof or the proof has been removed.

GET/v1/submissions/{id}/evidence

Submission evidence

Links to the proof screenshots for one submission (up to 5). Only the partner that owns the campaign can fetch them. Treat the links as sensitive: fetch what you need, do not publish them and do not store them long term.

scope: evidence:read

Path parameters

NameDescription
idThe submission id, starting sub_.

Example request

curl "https://api.byteverseafrica.com/v1/submissions/sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13/evidence" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/submissions/sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13/evidence", {
  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/submissions/sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13/evidence",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/submissions/sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13/evidence");
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);

Response

200 OK
{
  "submission_id": "sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13",
  "campaign_id": "cmp_8f3a1c9d2b7e4f60a5d1",
  "sandbox": false,
  "urls": [
    "https://example-storage.byteverseafrica.com/proofs/3f9a1c0e/1.jpg",
    "https://example-storage.byteverseafrica.com/proofs/3f9a1c0e/2.jpg"
  ],
  "count": 2
}

Proof can be removed after review. When it has been, this returns 404 not_found and evidence_available is false on the list. In the sandbox, urls is an empty list.

Wallet

GET/v1/wallet

Retrieve wallet balance

Your prepaid balance for the current environment. Test wallets start with 5,000,000 NGN of play money.

scope: wallet:read

Example request

curl "https://api.byteverseafrica.com/v1/wallet" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/wallet", {
  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/wallet",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/wallet");
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);

Response

200 OK
{
  "object": "wallet",
  "environment": "live",
  "currency": "NGN",
  "balance": 48950,
  "updated_at": "2026-10-22T09:14:03Z"
}
GET/v1/wallet/transactions

List wallet transactions

Every credit, debit and refund, newest first.

scope: wallet:read

Query parameters

FieldTypeDescription
limitinteger1-100, default 20.
starting_afterstringCursor from the previous page.

Example request

curl "https://api.byteverseafrica.com/v1/wallet/transactions?limit=10" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/wallet/transactions?limit=10", {
  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/wallet/transactions?limit=10",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/wallet/transactions?limit=10");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "5e0c...",
      "object": "wallet_transaction",
      "type": "debit",
      "amount": 5250,
      "balance_after": 48950,
      "currency": "NGN",
      "reference": "campaign:cmp_8f3a1c9d2b7e4f60a5d1",
      "campaign_id": "cmp_8f3a1c9d2b7e4f60a5d1",
      "description": "Campaign: Sallah Weekend Ankara Sale",
      "created_at": "2026-10-22T09:14:03Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Webhooks

POST/v1/webhook_endpoints

Create a webhook endpoint

Registers an https URL that ByteVerse will call when events happen. The signing secret is returned only in this response and when you rotate it. Up to 5 endpoints per environment.

scope: webhooks:manage

Request body

FieldTypeDescription
urlrequiredstringPublic https URL (port 443 or 8443). Private, local and internal addresses are rejected.
eventsstring[]Event types to receive. Default ["*"] (all).
descriptionstringUp to 200 characters.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/webhook_endpoints" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.arewathreads.ng/webhooks/byteverse",
    "events": [
      "campaign.activated",
      "campaign.progress",
      "campaign.completed"
    ]
  }'
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "url": "https://api.arewathreads.ng/webhooks/byteverse",
    "events": [
      "campaign.activated",
      "campaign.progress",
      "campaign.completed"
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/webhook_endpoints",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    json={
        "url": "https://api.arewathreads.ng/webhooks/byteverse",
        "events": ["campaign.activated", "campaign.progress", "campaign.completed"],
    },
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY"), "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode([
    "url" => "https://api.arewathreads.ng/webhooks/byteverse",
    "events" => ["campaign.activated", "campaign.progress", "campaign.completed"],
  ]),
]);
$data = json_decode(curl_exec($ch), true);

Response

201 Created
{
  "id": "0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
  "object": "webhook_endpoint",
  "environment": "live",
  "url": "https://api.arewathreads.ng/webhooks/byteverse",
  "events": [
    "campaign.activated",
    "campaign.progress",
    "campaign.completed"
  ],
  "description": null,
  "status": "active",
  "consecutive_failures": 0,
  "created_at": "2026-10-22T09:20:00Z",
  "secret": "whsec_9f1c4e0b7a2d...redacted"
}
GET/v1/webhook_endpoints

List webhook endpoints

Your endpoints for the current environment (secrets are never shown).

scope: webhooks:manage

Example request

curl "https://api.byteverseafrica.com/v1/webhook_endpoints" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints", {
  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/webhook_endpoints",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
      "object": "webhook_endpoint",
      "environment": "live",
      "url": "https://api.arewathreads.ng/webhooks/byteverse",
      "events": [
        "*"
      ],
      "description": null,
      "status": "active",
      "consecutive_failures": 0,
      "created_at": "2026-10-22T09:20:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
GET/v1/webhook_endpoints/{id}

Retrieve a webhook endpoint

One endpoint and its health (consecutive_failures).

scope: webhooks:manage

Path parameters

NameDescription
idThe endpoint id (UUID).

Example request

curl "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11", {
  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/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11");
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);

Response

200 OK
{
  "id": "0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
  "object": "webhook_endpoint",
  "environment": "live",
  "url": "https://api.arewathreads.ng/webhooks/byteverse",
  "events": [
    "*"
  ],
  "description": null,
  "status": "active",
  "consecutive_failures": 0,
  "created_at": "2026-10-22T09:20:00Z"
}
POST/v1/webhook_endpoints/{id}

Update a webhook endpoint

Change which events an endpoint receives, or re-enable one that was automatically disabled after 50 consecutive failures (status: "active" also resets the failure counter).

scope: webhooks:manage

Path parameters

NameDescription
idThe endpoint id.

Request body

FieldTypeDescription
statusstringactive or disabled.
eventsstring[]Replacement list of event types.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "active"
  }'
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "status": "active"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    json={
        "status": "active",
    },
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY"), "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode([
    "status" => "active",
  ]),
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
  "object": "webhook_endpoint",
  "environment": "live",
  "url": "https://api.arewathreads.ng/webhooks/byteverse",
  "events": [
    "*"
  ],
  "description": null,
  "status": "active",
  "consecutive_failures": 0,
  "created_at": "2026-10-22T09:20:00Z"
}
DELETE/v1/webhook_endpoints/{id}

Delete a webhook endpoint

Permanently removes the endpoint and its delivery history.

scope: webhooks:manage

Path parameters

NameDescription
idThe endpoint id.

Example request

curl -X DELETE "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
  },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
  "object": "webhook_endpoint",
  "deleted": true
}
POST/v1/webhook_endpoints/{id}/rotate_secret

Rotate a signing secret

Issues a new signing secret immediately and returns it once. The old secret stops working straight away, so deploy the new one first if you can.

scope: webhooks:manage

Path parameters

NameDescription
idThe endpoint id.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/rotate_secret" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/rotate_secret", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
  },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/rotate_secret",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/rotate_secret");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11",
  "object": "webhook_endpoint",
  "status": "active",
  "secret": "whsec_new...redacted"
}
POST/v1/webhook_endpoints/{id}/test

Send a test event

Queues a webhook.test event to this endpoint so you can verify reachability and signature checking. Delivery is asynchronous; check the deliveries list.

scope: webhooks:manage

Path parameters

NameDescription
idThe endpoint id.

Example request

curl -X POST "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/test" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/test", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
  },
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/test",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/test");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);

Response

202 Accepted
{
  "object": "webhook_test",
  "event_id": "evt_5b2e9a41c7d84f03a6b1e2c9",
  "delivery_id": "9a7c...",
  "queued": true
}
GET/v1/webhook_endpoints/{id}/deliveries

List delivery attempts

Recent deliveries to an endpoint with status, attempt count, last HTTP status and error. Use it to debug failures.

scope: webhooks:manage

Path parameters

NameDescription
idThe endpoint id.

Query parameters

FieldTypeDescription
limitinteger1-100, default 20.

Example request

curl "https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/deliveries" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/deliveries", {
  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/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/deliveries",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/webhook_endpoints/0c9d6f0a-4b1e-4c0e-9c55-2f1f7a9d3e11/deliveries");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "9a7c...",
      "object": "webhook_delivery",
      "event_id": "evt_5b2e9a41c7d84f03a6b1e2c9",
      "event_type": "campaign.progress",
      "status": "delivered",
      "attempts": 1,
      "response_status": 200,
      "last_error": null,
      "next_attempt_at": null,
      "delivered_at": "2026-10-22T10:01:12Z",
      "created_at": "2026-10-22T10:01:10Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Events

GET/v1/events

List events

Everything that happened to your campaigns and wallet in the last 30 days. Use this to catch up if your webhook endpoint was down, or instead of webhooks if you prefer polling.

scope: webhooks:manage

Query parameters

FieldTypeDescription
typestringFilter by event type.
limitinteger1-100, default 20.
starting_afterstringCursor from the previous page.

Example request

curl "https://api.byteverseafrica.com/v1/events?type=campaign.progress&limit=10" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/events?type=campaign.progress&limit=10", {
  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/events?type=campaign.progress&limit=10",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/events?type=campaign.progress&limit=10");
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);

Response

200 OK
{
  "object": "list",
  "data": [
    {
      "id": "evt_5b2e9a41c7d84f03a6b1e2c9",
      "object": "event",
      "type": "campaign.progress",
      "created": 1792660800,
      "environment": "live",
      "data": {
        "object": {
          "id": "cmp_8f3a1c9d2b7e4f60a5d1",
          "object": "campaign",
          "environment": "live",
          "status": "active",
          "name": "Sallah Weekend Ankara Sale",
          "external_reference": "order_10482",
          "metadata": {
            "order_id": "10482"
          },
          "task_type": "instagram-follow",
          "task_label": "Instagram Follow",
          "destination_url": "https://instagram.com/arewathreads",
          "caption": null,
          "media_url": null,
          "targeting": {
            "locations": [
              "Lagos",
              "Kano"
            ],
            "gender": "all"
          },
          "price_per_action": 70,
          "budget": {
            "currency": "NGN",
            "amount": 5000,
            "service_fee": 250,
            "total_charged": 5250,
            "spent": 2100,
            "remaining": 2900
          },
          "progress": {
            "target_actions": 71,
            "verified_actions": 30,
            "rejected_actions": 3,
            "pending_actions": 4,
            "completion_percent": 42.3
          },
          "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
          "created_at": "2026-10-22T09:14:03Z",
          "completed_at": null,
          "cancelled_at": null,
          "refund_amount": null,
          "milestone": 25
        }
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}
GET/v1/events/{id}

Retrieve an event

One event exactly as it was delivered to webhooks.

scope: webhooks:manage

Path parameters

NameDescription
idThe event id, e.g. evt_5b2e9a41c7d84f03a6b1e2c9.

Example request

curl "https://api.byteverseafrica.com/v1/events/evt_5b2e9a41c7d84f03a6b1e2c9" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/events/evt_5b2e9a41c7d84f03a6b1e2c9", {
  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/events/evt_5b2e9a41c7d84f03a6b1e2c9",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/events/evt_5b2e9a41c7d84f03a6b1e2c9");
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);

Response

200 OK
{
  "id": "evt_5b2e9a41c7d84f03a6b1e2c9",
  "object": "event",
  "type": "campaign.progress",
  "created": 1792660800,
  "environment": "live",
  "data": {
    "object": {
      "id": "cmp_8f3a1c9d2b7e4f60a5d1",
      "object": "campaign",
      "environment": "live",
      "status": "active",
      "name": "Sallah Weekend Ankara Sale",
      "external_reference": "order_10482",
      "metadata": {
        "order_id": "10482"
      },
      "task_type": "instagram-follow",
      "task_label": "Instagram Follow",
      "destination_url": "https://instagram.com/arewathreads",
      "caption": null,
      "media_url": null,
      "targeting": {
        "locations": [
          "Lagos",
          "Kano"
        ],
        "gender": "all"
      },
      "price_per_action": 70,
      "budget": {
        "currency": "NGN",
        "amount": 5000,
        "service_fee": 250,
        "total_charged": 5250,
        "spent": 2100,
        "remaining": 2900
      },
      "progress": {
        "target_actions": 71,
        "verified_actions": 30,
        "rejected_actions": 3,
        "pending_actions": 4,
        "completion_percent": 42.3
      },
      "tracking_url": "https://business.byteverseafrica.com/campaign-dashboard.html?campaign_id=cmp_8f3a1c9d2b7e4f60a5d1",
      "created_at": "2026-10-22T09:14:03Z",
      "completed_at": null,
      "cancelled_at": null,
      "refund_amount": null,
      "milestone": 25
    }
  }
}

Sandbox

POST/v1/sandbox/campaigns/{id}/simulate

Simulate campaign progress

Test keys only. Moves a sandbox campaign through its lifecycle so you can build and test your integration without waiting for real people. Fires the same webhook events as production.

scope: campaigns:write

Path parameters

NameDescription
idA sandbox campaign id (starts with cmp_test_).

Request body

FieldTypeDescription
eventrequiredstringactivate (in_review to active), progress (add verified actions) or complete (finish the campaign).
actionsintegerFor progress: how many verified actions to add (1-100000, default 10).

Example request

curl -X POST "https://api.byteverseafrica.com/v1/sandbox/campaigns/cmp_test_4b7e91d0a2c85f13/simulate" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "progress",
    "actions": 20
  }'
const res = await fetch("https://api.byteverseafrica.com/v1/sandbox/campaigns/cmp_test_4b7e91d0a2c85f13/simulate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BYTEVERSE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "event": "progress",
    "actions": 20
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.byteverseafrica.com/v1/sandbox/campaigns/cmp_test_4b7e91d0a2c85f13/simulate",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    json={
        "event": "progress",
        "actions": 20,
    },
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/sandbox/campaigns/cmp_test_4b7e91d0a2c85f13/simulate");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BYTEVERSE_API_KEY"), "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode([
    "event" => "progress",
    "actions" => 20,
  ]),
]);
$data = json_decode(curl_exec($ch), true);

Response

200 OK
{
  "id": "cmp_test_4b7e91d0a2c85f13",
  "object": "campaign",
  "environment": "test",
  "status": "active",
  "name": "Sallah Weekend Ankara Sale",
  "external_reference": "order_10482",
  "metadata": {
    "order_id": "10482"
  },
  "task_type": "instagram-follow",
  "task_label": "Instagram Follow",
  "destination_url": "https://instagram.com/arewathreads",
  "caption": null,
  "media_url": null,
  "targeting": {
    "locations": [
      "Lagos",
      "Kano"
    ],
    "gender": "all"
  },
  "price_per_action": 70,
  "budget": {
    "currency": "NGN",
    "amount": 5000,
    "service_fee": 250,
    "total_charged": 5250,
    "spent": 2100,
    "remaining": 2900
  },
  "progress": {
    "target_actions": 71,
    "verified_actions": 30,
    "rejected_actions": 3,
    "pending_actions": 4,
    "completion_percent": 42.3
  },
  "tracking_url": null,
  "created_at": "2026-10-22T09:14:03Z",
  "completed_at": null,
  "cancelled_at": null,
  "refund_amount": null
}

Utility

GET/v1/health

Health check

Unauthenticated liveness check. Returns {"status":"ok"}.

no scope neededno authentication

Example request

curl "https://api.byteverseafrica.com/v1/health" \
  -H "Authorization: Bearer $BYTEVERSE_API_KEY"
const res = await fetch("https://api.byteverseafrica.com/v1/health", {
  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/health",
    headers={"Authorization": f"Bearer {os.environ['BYTEVERSE_API_KEY']}"},
    timeout=30,
)
data = res.json()
<?php
$ch = curl_init("https://api.byteverseafrica.com/v1/health");
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);

Response

200 OK
{
  "status": "ok",
  "time": "2026-10-22T09:00:00.000Z"
}