{
  "info": {
    "name": "ByteVerse Partner API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Set api_key to a bv_test_ key to use the sandbox."
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.byteverseafrica.com/v1"
    },
    {
      "key": "api_key",
      "value": "bv_test_REPLACE_ME"
    },
    {
      "key": "campaign_id",
      "value": ""
    },
    {
      "key": "endpoint_id",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "Account",
      "item": [
        {
          "name": "Retrieve the current key",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/me",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "me"
              ]
            },
            "description": "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."
          }
        }
      ]
    },
    {
      "name": "Catalog",
      "item": [
        {
          "name": "List Growth Action types",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/task_types",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "task_types"
              ]
            },
            "description": "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."
          }
        },
        {
          "name": "Get a price quote",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/quotes",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "quotes"
              ]
            },
            "description": "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.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"task_type\": \"instagram-follow\",\n  \"budget\": 5000\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Campaigns",
      "item": [
        {
          "name": "Create a campaign",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns"
              ]
            },
            "description": "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.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Sallah Weekend Ankara Sale\",\n  \"task_type\": \"instagram-follow\",\n  \"budget\": 5000,\n  \"destination_url\": \"https://instagram.com/arewathreads\",\n  \"targeting\": {\n    \"locations\": [\n      \"Lagos\",\n      \"Kano\"\n    ],\n    \"gender\": \"all\"\n  },\n  \"external_reference\": \"order_10482\",\n  \"metadata\": {\n    \"order_id\": \"10482\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List campaigns",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns"
              ]
            },
            "description": "Returns your campaigns, newest first."
          }
        },
        {
          "name": "Retrieve a campaign",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns/{{campaign_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns",
                "{{campaign_id}}"
              ]
            },
            "description": "Returns one campaign with live progress and budget figures."
          }
        },
        {
          "name": "Pause a campaign",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns/{{campaign_id}}/pause",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns",
                "{{campaign_id}}",
                "pause"
              ]
            },
            "description": "Temporarily stops new people from taking the Growth Action. Only active campaigns can be paused. Budget stays reserved."
          }
        },
        {
          "name": "Resume a campaign",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns/{{campaign_id}}/resume",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns",
                "{{campaign_id}}",
                "resume"
              ]
            },
            "description": "Re-opens a paused campaign. Only paused campaigns can be resumed."
          }
        },
        {
          "name": "Cancel a campaign",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns/{{campaign_id}}/cancel",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns",
                "{{campaign_id}}",
                "cancel"
              ]
            },
            "description": "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."
          }
        }
      ]
    },
    {
      "name": "Performance",
      "item": [
        {
          "name": "Campaign performance",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns/{{campaign_id}}/performance",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns",
                "{{campaign_id}}",
                "performance"
              ]
            },
            "description": "Verified results, spend and a daily breakdown for one campaign. Only actions that ByteVerse has verified count as verified_actions and are billed."
          }
        },
        {
          "name": "Performance summary",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/performance/summary",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "performance",
                "summary"
              ]
            },
            "description": "Totals across all campaigns created in a date range (Africa/Lagos dates)."
          }
        }
      ]
    },
    {
      "name": "Submissions",
      "item": [
        {
          "name": "List submissions",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/campaigns/cmp_8f3a1c9d2b7e4f60a5d1/submissions?status=approved&limit=20&starting_after=",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "campaigns",
                "cmp_8f3a1c9d2b7e4f60a5d1",
                "submissions"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "approved",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "20",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "disabled": true
                }
              ]
            },
            "description": "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."
          }
        },
        {
          "name": "Submission evidence",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/submissions/sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13/evidence",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "submissions",
                "sub_3f9a1c0e7b2d4e58a6c1d9b04e7f2a13",
                "evidence"
              ]
            },
            "description": "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. Proof can be removed after review, in which case this returns 404 not_found."
          }
        }
      ]
    },
    {
      "name": "Wallet",
      "item": [
        {
          "name": "Retrieve wallet balance",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/wallet",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "wallet"
              ]
            },
            "description": "Your prepaid balance for the current environment. Test wallets start with 5,000,000 NGN of play money."
          }
        },
        {
          "name": "List wallet transactions",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/wallet/transactions",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "wallet",
                "transactions"
              ]
            },
            "description": "Every credit, debit and refund, newest first."
          }
        }
      ]
    },
    {
      "name": "Webhooks",
      "item": [
        {
          "name": "Create a webhook endpoint",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints"
              ]
            },
            "description": "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.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://api.arewathreads.ng/webhooks/byteverse\",\n  \"events\": [\n    \"campaign.activated\",\n    \"campaign.progress\",\n    \"campaign.completed\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List webhook endpoints",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints"
              ]
            },
            "description": "Your endpoints for the current environment (secrets are never shown)."
          }
        },
        {
          "name": "Retrieve a webhook endpoint",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints/{{endpoint_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints",
                "{{endpoint_id}}"
              ]
            },
            "description": "One endpoint and its health (consecutive_failures)."
          }
        },
        {
          "name": "Update a webhook endpoint",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints/{{endpoint_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints",
                "{{endpoint_id}}"
              ]
            },
            "description": "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).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Delete a webhook endpoint",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints/{{endpoint_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints",
                "{{endpoint_id}}"
              ]
            },
            "description": "Permanently removes the endpoint and its delivery history."
          }
        },
        {
          "name": "Rotate a signing secret",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints/{{endpoint_id}}/rotate_secret",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints",
                "{{endpoint_id}}",
                "rotate_secret"
              ]
            },
            "description": "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."
          }
        },
        {
          "name": "Send a test event",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints/{{endpoint_id}}/test",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints",
                "{{endpoint_id}}",
                "test"
              ]
            },
            "description": "Queues a webhook.test event to this endpoint so you can verify reachability and signature checking. Delivery is asynchronous; check the deliveries list."
          }
        },
        {
          "name": "List delivery attempts",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/webhook_endpoints/{{endpoint_id}}/deliveries",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "webhook_endpoints",
                "{{endpoint_id}}",
                "deliveries"
              ]
            },
            "description": "Recent deliveries to an endpoint with status, attempt count, last HTTP status and error. Use it to debug failures."
          }
        }
      ]
    },
    {
      "name": "Events",
      "item": [
        {
          "name": "List events",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/events",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "events"
              ]
            },
            "description": "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."
          }
        },
        {
          "name": "Retrieve an event",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/events/evt_5b2e9a41c7d84f03a6b1e2c9",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "events",
                "evt_5b2e9a41c7d84f03a6b1e2c9"
              ]
            },
            "description": "One event exactly as it was delivered to webhooks."
          }
        }
      ]
    },
    {
      "name": "Sandbox",
      "item": [
        {
          "name": "Simulate campaign progress",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/sandbox/campaigns/{{campaign_id}}/simulate",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "sandbox",
                "campaigns",
                "{{campaign_id}}",
                "simulate"
              ]
            },
            "description": "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.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"event\": \"progress\",\n  \"actions\": 20\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Utility",
      "item": [
        {
          "name": "Health check",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/health",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "health"
              ]
            },
            "description": "Unauthenticated liveness check. Returns {\"status\":\"ok\"}.",
            "auth": {
              "type": "noauth"
            }
          }
        }
      ]
    }
  ]
}