Public API · v1

Logs API

Integrate log catalog browsing, wallet-backed purchases, and order history into your server-side workflow using one account API key.

POST https://popesocials.com/api/v1/orders
{
  "product_id": 42,
  "quantity": 1,
  "recipient": "customer@example.com"
}

Base URL

Production endpoint

All paths in this guide are relative to the current API base URL. Protected endpoints require bearer authentication.

https://popesocials.com/api/v1
Formatapplication/json
AuthBearer API key
Versionv1

Breaking changes ship as a new version rather than modifying existing responses; additive fields may appear in v1 at any time, so integrations should ignore unrecognized fields.

Security

Authentication

Bearer API Key

Generate your API key from API access. Copy it immediately — it is shown only once. Generating a new key revokes the previous one.

Required headers

Headers
Accept: application/json
Authorization: Bearer mapi_your_key_id.your_secret

401 response

JSON
{
  "success": false,
  "status": 401,
  "message": "Unauthenticated. Please provide a valid bearer token.",
  "code": "UNAUTHENTICATED"
}

Scopes

Keys are issued with one or more scopes. A request fails with 403 if the key's scopes don't cover the endpoint.

ScopeGrants
catalog:readMarketplace products, categories, providers
wallet:readWallet balance
orders:writeCreate marketplace orders
orders:readList and look up marketplace orders
sms:readRead SMS balance, country, and service lists
sms:writeCreate, cancel, and renew SMS rentals
smm:readRead SMM services, pricing, and orders
smm:writeCreate SMM orders

Reference

Rate limits

Each key is limited per rolling minute. Every response includes headers describing current usage.

HeaderDescription
X-RateLimit-LimitRequests allowed per window
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-ResetUnix timestamp when the window resets
X-Request-IdUnique ID for this request, useful when contacting support

Exceeding the limit returns 429 Too Many Requests. Back off using the X-RateLimit-Reset value. List endpoints are cursor-paginated — pass limit and cursor as query parameters, and read next_cursor from the response to fetch the next page.

Reference

Idempotency

Send a unique Idempotency-Key header on POST /orders, POST /sms/rentals, and POST /smm/orders to safely retry a request without creating a duplicate. Reusing a key with an identical payload returns the original result; reusing it with a different payload returns 409. Keys are remembered for 24 hours.

GET

/products

Search and filter marketplace products. Requires bearer authentication.

Query parameters

ParamTypeDescription
qstringOptional. Free-text search on product name.
category_idintegerOptional. Filter by category.
provider_idintegerOptional. Filter by provider.
limitintegerOptional. Page size, default 20, max 100.
cursorstringOptional. Pagination cursor from a previous response.

Request example

curl -X GET "https://popesocials.com/api/v1/products?category_id=3&limit=20" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"
const response = await fetch('https://popesocials.com/api/v1/products?category_id=3&limit=20', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY_HERE'
  }
});
const data = await response.json();
import requests

url = 'https://popesocials.com/api/v1/products?category_id=3&limit=20'
headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY_HERE'
}

response = requests.get(url, headers=headers)
print(response.json())
<?php

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://popesocials.com/api/v1/products?category_id=3&limit=20',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Authorization: Bearer YOUR_API_KEY_HERE',
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);

200 response

JSON
{
  "data": [
    {
      "id": 42,
      "title": "Premium Digital Account",
      "description": "Verified marketplace listing with fast fulfillment.",
      "category_id": 3,
      "provider": "marketplace-partner",
      "provider_category": "accounts",
      "provider_product_id": "MKP-PRM-42",
      "currency": "NGN",
      "price_cents": 35000,
      "market_price_cents": 38500,
      "stock_value": 12,
      "is_out_of_stock": false,
      "is_active": true
    }
  ],
  "next_cursor": null,
  "has_more": false
}
GET

/categories

List product categories and counts. Requires bearer authentication.

Request example

cURL
curl -X GET "https://popesocials.com/api/v1/categories" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"

200 response

JSON
{
  "data": [
    { "id": 3, "name": "Digital Accounts", "product_count": 18 },
    { "id": 4, "name": "Premium Listings", "product_count": 6 }
  ]
}
GET

/providers

List active marketplace providers. Requires bearer authentication.

Request example

cURL
curl -X GET "https://popesocials.com/api/v1/providers" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"

200 response

JSON
{
  "data": [
    { "id": 7, "name": "Global Marketplace Network", "active": true },
    { "id": 8, "name": "Partner Fulfillment Hub", "active": true }
  ]
}
GET

/wallet

Returns the authenticated user's wallet balance. Requires the wallet:read scope.

Request example

curl -X GET "https://popesocials.com/api/v1/wallet" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"
const response = await fetch('https://popesocials.com/api/v1/wallet', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY_HERE'
  }
});
const data = await response.json();
console.log(data);
import requests

url = 'https://popesocials.com/api/v1/wallet'
headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY_HERE'
}

response = requests.get(url, headers=headers)
print(response.json())
<?php

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://popesocials.com/api/v1/wallet',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Authorization: Bearer YOUR_API_KEY_HERE',
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);
curl_close($ch);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://popesocials.com/api/v1/wallet"))
    .header("Accept", "application/json")
    .header("Authorization", "Bearer YOUR_API_KEY_HERE")
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

200 response

JSON
{
  "success": true,
  "data": {
    "balance": "12450.00",
    "currency": "NGN",
    "updated_at": "2026-07-07T09:14:02Z"
  }
}
POST

/orders

Creates an order, deducts the wallet balance, and returns the order details. The server calculates price and wallet deduction — do not send price from your integration. Use a unique idempotency_key for every checkout attempt.

Body parameters

ParamTypeDescription
product_idintegerRequired. Product to order.
quantityintegerRequired. Number of units, minimum 1.
recipientstringDepends on product. Delivery target, such as an account handle, email, or reference ID.
metadataobjectOptional. Arbitrary key/value pairs echoed back on the order and in webhooks.

Request example

curl -X POST "https://popesocials.com/api/v1/orders" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: partner-order-123" \
  -d '{"product_id":42,"quantity":1,"recipient":"customer@example.com"}'
const response = await fetch('https://popesocials.com/api/v1/orders', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY_HERE',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'partner-order-123'
  },
  body: JSON.stringify({
    product_id: 42,
    quantity: 1,
    recipient: 'customer@example.com'
  })
});
const data = await response.json();
import requests

url = 'https://popesocials.com/api/v1/orders'
headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY_HERE',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'partner-order-123'
}
payload = {
    'product_id': 42,
    'quantity': 1,
    'recipient': 'customer@example.com'
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())
<?php

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://popesocials.com/api/v1/orders',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Authorization: Bearer YOUR_API_KEY_HERE',
        'Content-Type: application/json',
        'Idempotency-Key: partner-order-123',
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => json_encode([
        'product_id' => 42,
        'quantity' => 1,
        'recipient' => 'customer@example.com',
    ]),
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
HttpClient client = HttpClient.newHttpClient();
String payload = """
{
    "product_id": 42,
    "quantity": 1,
    "recipient": "customer@example.com"
}
""";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://popesocials.com/api/v1/orders"))
    .header("Accept", "application/json")
    .header("Authorization", "Bearer YOUR_API_KEY_HERE")
    .header("Content-Type", "application/json")
    .header("Idempotency-Key", "partner-order-123")
    .method("POST", HttpRequest.BodyPublishers.ofString(payload))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

201 response

JSON
{
  "id": "ord_8n2k1p",
  "status": "pending",
  "product_id": 42,
  "quantity": 1,
  "amount": "350.00",
  "currency": "NGN",
  "created_at": "2026-07-07T09:15:41Z"
}
GET

/orders

List recent orders for the API key. Requires the orders:read scope.

Query parameters

ParamTypeDescription
statusstringOptional. Filter by pending, completed, or failed.
limitintegerOptional. Page size, default 20, max 100.
cursorstringOptional. Pagination cursor from a previous response.

Request example

cURL
curl -X GET "https://popesocials.com/api/v1/orders?status=completed" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"

200 response

JSON
{
  "data": [
    {
      "id": "ord_8n2k1p",
      "status": "completed",
      "product_id": 42,
      "quantity": 1,
      "amount": "350.00",
      "created_at": "2026-07-07T09:15:41Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
GET

/sms/balance

Check the SMS balance for the API key owner. Provider routing is handled internally. Requires the sms:read scope.

Request example

cURL
curl -X GET "https://popesocials.com/api/v1/sms/balance" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"

200 response

JSON
{
  "data": {
    "balance": 12.5,
    "currency": null,
    "last_checked": "2026-07-08T02:15:00Z"
  }
}
GET

/sms/providers

List available SMS provider options. Routing remains internal.

GET

/sms/countries

List available countries for SMS renting. Requires the sms:read scope.

GET

/sms/services

List available SMS services. Requires the sms:read scope.

POST

/sms/rentals

Request a new SMS rental. Send an Idempotency-Key header to safely retry the request. Requires the sms:write scope.

Body parameters

ParamTypeDescription
servicestringRequired. Service code from /sms/services.
countrystringRequired. Country code from /sms/countries.
operatorstringOptional. Carrier or operator code, when the provider supports it.

Request example

cURL
curl -X POST "https://popesocials.com/api/v1/sms/rentals" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sms-rental-0001" \
  -d '{"service":"whatsapp","country":"ng"}'
GET

/sms/rentals

List SMS rentals created by the current API key.

GET

/smm/wallet

Check the wallet balance for the API key owner.

GET

/smm/services

List SMM services. Provider routing is internal.

GET

/smm/pricing

List SMM service pricing and limits.

POST

/smm/orders

Create an SMM order. Send an Idempotency-Key header to avoid duplicate charges on retry. Requires the smm:write scope.

Body parameters

ParamTypeDescription
service_idstringRequired. Service id from /smm/services.
linkstringRequired. Target URL or profile link.
quantityintegerOptional. Order quantity, default 1.

Request example

cURL
curl -X POST "https://popesocials.com/api/v1/smm/orders" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: smm-order-0001" \
  -d '{"service_id":"ig-followers-1","link":"https://instagram.com/example","quantity":100}'
GET

/smm/orders

List SMM orders created by the current API key.

Events

Webhooks

Configure a webhook URL to receive events as an order changes state. Each delivery is a POST with a JSON body, retried with backoff for up to 24 hours if your endpoint doesn't return a 2xx.

EventFired when
order.pendingAn order is created and awaiting processing
order.completedAn order is successfully fulfilled
order.failedAn order could not be fulfilled

Payload

JSON
{
  "event": "order.completed",
  "data": {
    "id": "ord_8n2k1p",
    "status": "completed",
    "amount": "350.00"
  },
  "created_at": "2026-07-07T09:16:03Z"
}

Security

Verifying signatures

Every webhook request includes an X-Signature header: an HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret. Recompute it and compare using a constant-time check before trusting the payload.

PHP
$expected = hash_hmac('sha256', $rawBody, $webhookSecret);

if (!hash_equals($expected, $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
    http_response_code(400);
    exit;
}

Reference

Legacy endpoint

The older /api/service/* route stays available for compatibility during migration, but it is deprecated and will not receive new features. New integrations should build on /api/v1.

Reference

Error responses

Errors return a JSON body with a stable code and a human-readable message.

Error format

JSON
{
  "success": false,
  "status": 402,
  "message": "Wallet balance is too low to complete this order.",
  "code": "INSUFFICIENT_BALANCE"
}
UNAUTHENTICATEDThe bearer token is missing, invalid, or revoked.
VALIDATION_FAILEDOne or more request fields are missing or invalid.
PRODUCT_NOT_FOUNDThe product does not exist or is unavailable.
INSUFFICIENT_BALANCEThe wallet balance cannot cover the purchase.
OUT_OF_STOCKThere isn't enough stock in the selected category.
IDEMPOTENCY_KEY_REUSEDThe idempotency key was used for a different request.
RATE_LIMITEDToo many requests were sent in the current window.
SERVER_ERRORAn unexpected error occurred — safe to retry.

Reference

Changelog

  • 2026-06-02Added metadata to order creation and webhook payloads.
  • 2026-03-18Introduced cursor-based pagination on all list endpoints.
  • 2026-01-09Initial release of /api/v1.
Message support Support icon Join Group Group icon