{
  "info": {
    "name": "Toolzplanet API — catalogue and wallet",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "# Toolzplanet developer API — beginner setup\n\n💳 Minimum wallet balance: $5 USD\nMaintain at least $5 in your Toolzplanet wallet to access and sync our API catalogues. This is usable wallet balance, not an additional activation fee. Exactly $5 qualifies.\n\n1. Sign in at https://toolzplanet.net and open Fund wallet. Keep at least $5 USD (500 USD cents) in your spendable wallet after verified funding. NGN display values and pending transfers do not count.\n2. Request access at https://toolzplanet.net/developers.php. Administrator approval and API launch availability are separate requirements. Funding does not bypass approval or a global pause.\n3. Once approved and the API is enabled, create a read-only key for catalogue syncing. Store it privately on your server as TOOLZPLANET_API_KEY. Purchase keys require separate approval.\n4. Call GET https://toolzplanet.net/developer-api.php?action=balance with Authorization: Bearer YOUR_API_KEY. The balance is returned in integer USD cents.\n5. Call GET ?action=catalogue&kind=product&page=1 or kind=sms, following next_page until null. Exactly 500 cents or above qualifies. Every catalogue page checks the current wallet, including requests made with existing keys.\n6. Quote an item before buying. Purchase rules, scopes, limits and wallet debits remain unchanged. Use a unique Idempotency-Key for each purchase and reuse it when retrying an uncertain purchase.\n\n## Below the catalogue minimum\n\nHTTP 403 returns a JSON error with code minimum_wallet_balance_required, currency USD, required_balance_cents 500, your current balance_cents, funding_url and funding_instructions. This requirement never deducts, reserves or charges $5.\n\nStop catalogue sync jobs when this error occurs. Sign in, open Fund wallet and top up until the authoritative balance is at least $5. After payment is verified and credited, retry the catalogue GET with the same existing key. No reactivation, replacement key or separate fee is needed.\n\nPurchases can reduce the wallet below $5; the next catalogue request will be blocked. Balance checks, me/account access, order history, delivery retrieval, refresh, and eligible cancellation/refund actions remain available below the threshold. Quotes and purchases retain their existing rules. Authentication, approval, rate limits and global availability still apply to every action.\n\n## Error example\n\n```json\n{\"success\":false,\"error\":{\"code\":\"minimum_wallet_balance_required\",\"message\":\"Maintain at least $5 USD in your usable Toolzplanet wallet to access and sync the catalogue. Fund your wallet and retry after funding is verified. This is not an activation fee.\",\"currency\":\"USD\",\"required_balance_cents\":500,\"balance_cents\":499,\"funding_url\":\"https://toolzplanet.net/index.php?page=funding\",\"funding_instructions\":\"Sign in to Toolzplanet, open Fund wallet, and top up to at least $5 USD. Wait for verified wallet credit, then retry the same catalogue GET request. Existing keys resume automatically.\"},\"request_id\":\"example\"}\n```\n\n## Connection checker\n\nThe public checker sends no API key and performs no purchase. It verifies endpoint availability only. A 401 means authentication is required; 503 api_paused means launch is paused. It cannot prove authenticated catalogue access or the $5 requirement. Use the server examples or Postman with your approved key for that test.\n\n## PHP and Node.js\n\nUse the copyable server examples on https://toolzplanet.net/developers.php#docs. Handle minimum_wallet_balance_required by pausing only catalogue sync and directing the customer to funding_url. Do not block their balance or existing order support actions. Do not retry catalogue continuously while the wallet is below the minimum.\n\n## Postman\n\nImport the collection at https://toolzplanet.net/developers.php?asset=postman. Set base_url to https://toolzplanet.net/developer-api.php and api_key to your approved read-only key. Keep the variable private and never export a collection containing a real key. Run Wallet balance first, then Catalogue. The catalogue test accepts success at >=500 cents or the documented HTTP 403 below 500. Top up through verified wallet funding and rerun Catalogue using the same key to confirm recovery. Use only an isolated test environment for below/exactly/above balance fixtures; never change a production wallet to run Postman tests.\n\n## Threshold test matrix\n\n| Authoritative balance | Catalogue result |\n| --- | --- |\n| 499 USD cents ($4.99) | HTTP 403 minimum_wallet_balance_required |\n| 500 USD cents ($5.00) | Allowed, subject to existing access controls |\n| 501 USD cents ($5.01) | Allowed, subject to existing access controls |\n| Below minimum → verified top-up to >=500 cents | Same key resumes catalogue access automatically |\n| Purchase leaves 499 cents | Catalogue pauses; existing order support remains available |\n\n\n## Approved product scope and TextPlus\n\nGET action=me reports approved_catalogue_scope. Existing supplier access is preserved by default. An admin can approve TextPlus-only or selected marketplace product IDs/exact categories. Restrictions apply to existing and new keys, catalogue, quotes and new purchases; existing order support stays available.\n\nTextPlus catalogue: GET ?action=catalogue&kind=textplus&page=1. TextPlus-only customers may omit kind. Follow next_page. IDs are strings like textplus:123; preserve this namespace. Quotes use GET ?action=quote&item_id=textplus:123. Stock counts unsold, non-retired inventory; pricing uses the existing TextPlus pricing function and approved listing consistency checks. No credentials or full phone numbers are exposed. TextPlus API purchasing remains disabled (textplus_purchase_disabled), including on purchase-enabled accounts.\n\n## Optional monitoring: beginner setup\n\n1. Open https://toolzplanet.net/api-integration.php while signed in. Register your integration name and a public HTTPS site you control.\n2. Optional endpoint: enter a health URL on that exact hostname and authorise checks. Return HTTP 200 JSON containing the displayed toolzplanet_monitor_token and status \"ok\". A normal homepage is insufficient. URLs cannot contain credentials, query strings, fragments or non-443 ports. Private/internal destinations and redirects are blocked. Checks use strict TLS, bounded public DNS validation, address pinning, six-second timeouts and a 16 KB response limit.\n3. Optional heartbeat: enable it, then send POST ?action=heartbeat with Authorization: Bearer YOUR_PRIVATE_KEY, Content-Type: application/json and {\"status\":\"ok\"} from your integration server every configured interval (initially 300 seconds). Send status \"degraded\" when your integration reports a problem. Heartbeats remain available below $5; normal authentication/rate rules still apply.\n4. View evidence and internal notices in your authenticated settings. Uncheck monitoring and save to withdraw consent. No external email, Telegram or WhatsApp notifications are sent.\n\n## Status meanings and limits\n\n- API activity: requests reaching Toolzplanet, with measured counts, HTTP outcomes and server processing latency. Online means recent requests; Inactive means no requests in 15 minutes, not downtime. Unknown means no retained attributed measurements. Low-wallet rejections are counted separately from technical failures.\n- Website/integration endpoint: fresh validated health endpoint evidence. Online is responsive, Degraded is slow or below the failure threshold, Suspected outage is consecutive failures after endpoint ownership was proven. Unknown covers missing ownership proof or stale monitoring. Not configured means no consent/setup.\n- Integration heartbeat: authenticated sender activity only. Missing first heartbeat is Unknown; stale heartbeats are Degraded or Suspected outage after configured missed intervals. This cannot independently prove website availability or successful imports.\n- Wallet/catalogue eligibility: authoritative usable USD balance >=500 cents qualifies, subject to authentication, approval and scope. Below it is a funding pause, not a server outage.\n\nDefault polling is five minutes with three failures before an outage incident. Admin can set 300–3600 seconds and 3–10 failures. One due endpoint is checked per existing scheduled-worker invocation; capacity or worker delays can make checks stale. A successful catalogue API response does not prove the customer imported it. No synthetic uptime scores are supplied.\n\nAdmin dashboard: https://toolzplanet.net/api-customers.php — restricted administrators only. Search/filter customers, inspect distinct evidence, key prefixes, approved scopes, real request windows (1h/24h/7d), purchase outcomes and deduplicated internal alert transitions. Customer balances show observation time; the wallet's last transaction time is not inferred.\n\nRetention: request/check metadata 30 days, internal alert history 90 days, dedicated monitoring audit 365 days. Active configuration/incidents remain until changed. Existing financial/order and central audit retention is unchanged. Keys, passwords, delivery contents and sensitive request bodies are never monitoring data.\n"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://toolzplanet.net/developer-api.php"
    },
    {
      "key": "api_key",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "Wallet balance — available below $5",
      "request": {
        "method": "GET",
        "url": "{{base_url}}?action=balance",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "description": "Catalogue only requires an authoritative wallet balance >=500 USD cents; existing authentication and permissions still apply."
      }
    },
    {
      "name": "Account — available below $5",
      "request": {
        "method": "GET",
        "url": "{{base_url}}?action=me",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "description": "Catalogue only requires an authoritative wallet balance >=500 USD cents; existing authentication and permissions still apply."
      }
    },
    {
      "name": "Catalogue — requires at least $5",
      "request": {
        "method": "GET",
        "url": "{{base_url}}?action=catalogue&kind=product&page=1",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "description": "Catalogue only requires an authoritative wallet balance >=500 USD cents; existing authentication and permissions still apply."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const d = pm.response.json();",
              "if (d.error && d.error.code === 'minimum_wallet_balance_required') {",
              "  pm.test('Catalogue minimum is documented', () => {",
              "    pm.response.to.have.status(403);",
              "    pm.expect(d.error.required_balance_cents).to.eql(500);",
              "    pm.expect(d.error.currency).to.eql('USD');",
              "    pm.expect(d.error.balance_cents).to.be.below(500);",
              "    pm.expect(d.error.funding_url).to.eql('https://toolzplanet.net/index.php?page=funding');",
              "  });",
              "} else if (pm.response.code === 200) {",
              "  pm.test('Catalogue returned', () => { pm.expect(d.success).to.eql(true); pm.expect(d.data.items).to.be.an('array'); });",
              "} else { pm.test('Existing access control response', () => { pm.expect([401,403,429,503]).to.include(pm.response.code); }); }"
            ]
          }
        }
      ]
    },
    {
      "name": "Existing orders — available below $5",
      "request": {
        "method": "GET",
        "url": "{{base_url}}?action=orders",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "description": "Catalogue only requires an authoritative wallet balance >=500 USD cents; existing authentication and permissions still apply."
      }
    },
    {
      "name": "TextPlus catalogue — explicitly approved scope only",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{api_key}}"
          }
        ],
        "url": "{{base_url}}?action=catalogue&kind=textplus&page=1",
        "description": "Read-only. $5 usable USD minimum. Preserve string IDs textplus:PRODUCT_ID. API purchasing remains disabled."
      }
    },
    {
      "name": "Heartbeat — opt in from authenticated account first",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Authorization",
            "value": "Bearer {{api_key}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{base_url}}?action=heartbeat",
        "body": {
          "mode": "raw",
          "raw": "{\"status\":\"ok\"}"
        },
        "description": "Enable heartbeat consent at /api-integration.php first. Send from your server at the configured interval; never export a real key. No purchase or wallet minimum applies."
      }
    }
  ]
}