// webhook api

CEXPing Webhook API

Real-time token listing events delivered to your server milliseconds after detection. Plug into any trading bot or automation pipeline.

⚡ Sub-500ms Phantom Plan HMAC-SHA256
// 01

Introduction

CEXPing Webhooks push real-time event notifications to your server the instant a new token listing is detected. Unlike polling, webhooks are event-driven your server gets a POST request the moment something happens.

Phantom Plan only. Upgrade from your dashboard to enable webhook delivery.

How it works

01

Register your endpoint

Add a public HTTPS URL in your dashboard. CEXPing sends a verification ping to confirm it's reachable.

02

Event detected

CEXPing detects a new token listing on any monitored exchange within milliseconds.

03

Payload delivered

A signed JSON payload is POSTed exchange, pair, type, volume, AI score, and more.

04

You respond & act

Return HTTP 200. Your bot places orders, sends alerts, or triggers any workflow.


// 02

Quick Start

Get your first webhook running in under 5 minutes.

Step 1 Register endpoint

Dashboard → Settings → Webhooks → Add URL. CEXPing sends a verification ping to confirm reachability.

Step 2 Expose POST route

Express.js
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhook/cxp', (req, res) => {
  // ✅ Acknowledge FIRST
  res.status(200).json({ received: true });
  const { type, symbol, exchange } = req.body;
  if (type === 'new_listing')
    console.log(`🚀 ${symbol} on ${exchange}`);
});
app.listen(3000);

Step 3 Test with curl

bash
curl -X POST https://yourdomain.com/webhook/cxp \
  -H "Content-Type: application/json" \
  -H "X-CEXPing-Signature: sha256=<hash>" \
  -d '{"type":"new_listing","exchange":"Binance"}'

// 03

Authentication

Every request includes X-CEXPing-Signature header to verify it's genuinely from CEXPing.

formula
HMAC-SHA256(webhook_secret, raw_request_body)

Your webhook_secret is shown once when you register your endpoint. Store it securely.


// 04

Setup Endpoint

RequirementDetail
ProtocolHTTPS only
MethodMust accept POST
ResponseReturn 2xx within 10s
Content-Typeapplication/json
Max endpoints5 per account

Acknowledge fast. Return 200 immediately, then process async. Slow responses trigger retries.


// 05

Event Types

new_listing

New Spot Listing

Token newly listed for spot trading. Highest priority.

futures_listing

Futures / Perp

Perpetual or futures contract opened.

volume_spike

Volume Spike

Unusual volume signals major price action.

listing_preview

Listing Preview

AI-detected listing 12–72h ahead.

delisting

Delisting Alert

Token scheduled for delisting.

ping

Health Ping

Every 5 min to confirm endpoint is alive.


// 06

Payload Schema

JSON new_listing
{
  "event_id":    "cxp_01J9KR2MXTN4P8ZWH3QV",
  "type":         "new_listing",
  "timestamp":    1710432000,
  "exchange":     "Binance",
  "symbol":       "PEPE2USDT",
  "listing_type": "spot",
  "volume_24h":   2847392.50,
  "ai_score":     87,
  "latency_ms":   312
}
FieldTypeReqDescription
event_idstrreqUnique ID use for dedup
typestrreqEvent type
timestampintreqUnix timestamp (sec)
exchangestrreqExchange name
symbolstrreqe.g. PEPE2USDT
listing_typestrreqspot / futures / perp
volume_24hfloatopt24h USD volume
ai_scoreintoptAI score 0–100
latency_msintreqDetection latency ms

// 07

Signature Verification

Never skip in production. Without it, anyone can trigger your trading bot with fake events.

const crypto = require('crypto');
function verify(rawBody, header, secret) {
  const exp = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody).digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(exp), Buffer.from(header));
}
app.post('/webhook/cxp',
  express.raw({type:'*/*'}),(req,res) => {
  const sig = req.headers['x-cexpingz-signature'];
  if (!verify(req.body,sig,process.env.SECRET))
    return res.status(401).end();
  res.status(200).json({ ok:true });
});
import hmac, hashlib, os
SECRET = os.environ['CXP_SECRET'].encode()
def verify(body, header):
    d = hmac.new(SECRET,body,hashlib.sha256).hexdigest()
    return hmac.compare_digest(f'sha256={d}',header)
@app.route('/webhook/cxp',methods=['POST'])
def webhook():
    if not verify(request.data,
        request.headers.get('X-CEXPing-Signature','')):
        abort(401)
    return {'ok':True},200
<?php
$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_CEXPINGZ_SIGNATURE']??'';
$exp    = 'sha256='.hash_hmac('sha256',$body,$_ENV['CXP_SECRET']);
if(!hash_equals($exp,$header)){
    http_response_code(401);exit();
}

// 08

Full Node.js Example

Node.js + Express
const express = require('express');
const crypto  = require('crypto');
const app     = express();
const SECRET  = process.env.CXP_WEBHOOK_SECRET;
const seen    = new Set();
app.use(express.raw({type:'application/json'}));

app.post('/webhook/cxp',(req,res) => {
  const sig = req.headers['x-cexpingz-signature']??'';
  const exp = 'sha256='+crypto
    .createHmac('sha256',SECRET)
    .update(req.body).digest('hex');
  if(!crypto.timingSafeEqual(
    Buffer.from(exp),Buffer.from(sig)))
    return res.status(401).end();

  const event = JSON.parse(req.body);
  res.status(200).json({ok:true});

  if(seen.has(event.event_id)) return;
  seen.add(event.event_id);

  if(event.type==='new_listing')
    console.log(`🚀 ${event.symbol} ${event.exchange}`);
});
app.listen(3000);

// 09

Python Example

FastAPI
import hmac, hashlib, os
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
app    = FastAPI()
SECRET = os.environ["CXP_SECRET"].encode()
seen   = set()
@app.post("/webhook/cxp")
async def webhook(request: Request):
    body   = await request.body()
    header = request.headers.get(
        "x-cexpingz-signature","")
    digest = hmac.new(SECRET,body,hashlib.sha256).hexdigest()
    if not hmac.compare_digest(
        f"sha256={digest}",header):
        raise HTTPException(status_code=401)
    event = await request.json()
    if event["event_id"] not in seen:
        seen.add(event["event_id"])
        print(f"🚀 {event['symbol']}")
    return JSONResponse({"ok":True})

// 10

Retry Policy

Non-2xx or timeout (10s) triggers exponential backoff retries.

AttemptDelayTotal
1st (original)0s
2nd retry30s~30s
3rd retry5 min~5m
4th retry30 min~35m
5th retry2 hours~2.5h
Final (6th)6 hours~8.5h

After 6 failures → permanent fail. 3 consecutive endpoint failures → auto-disable + email notification.


// 11

HTTP Status Codes

200OK — Acknowledged. No retry.
201Created — Also treated as success.
429Rate Limited — Retry with doubled backoff.
401Unauthorized — Signature mismatch. Still retries.
4xxClient Error — Permanent fail. No retry.
5xxServer Error — Retry per backoff policy.
TXTTimeout — No response in 10s → treated as 5xx.

// 12

Rate Limits

LimitValue
Endpoints5 per account
Events/secUnlimited
Payload sizeMax 64 KB
Timeout10 seconds
Test events50 per day
Retries6 per event (~8.5h)

P95 latency >5s triggers a dashboard warning. Sustained timeouts may auto-suspend your endpoint.