Webhooks

Receive real-time notifications for IPO and market events via HTTP callbacks.

Webhooks allow your application to receive real-time notifications when events occur, such as a new IPO opening, GMP updates, or listing events. Instead of polling the API, you register a URL and we push events to you.

Plan Requirement

Webhooks are available on Pro (up to 5 webhooks), Enterprise (up to 20 webhooks) plans. Free and Basic plans do not include webhook access.

Setting Up Webhooks

To start receiving webhook events, create a webhook endpoint by specifying a URL and the events you want to subscribe to:

POST/v1/webhooksPro+

Create a new webhook endpoint.

Request Body

ParameterTypeRequiredDefaultDescription
urlstringRequired-HTTPS URL that will receive webhook events. Must be publicly accessible.
eventsstring[]Required-Array of event types to subscribe to
secretstringOptional-Shared secret for verifying webhook signatures. Auto-generated if not provided.
Create Webhook
curl -X POST "https://api.ipoguruji.com/v1/webhooks" \  -H "X-API-Key: ipg_live_your_api_key_here" \  -H "Content-Type: application/json" \  -d '{    "url": "https://your-server.com/webhooks/ipoguruji",    "events": ["ipo.opened", "ipo.closed", "ipo.listed", "gmp.updated"],    "secret": "whsec_your_secret_here"  }'
Webhook Created201
{
  "success": true,
  "data": {
    "id": "wh_abc123def456",
    "url": "https://your-server.com/webhooks/ipoguruji",
    "events": ["ipo.opened", "ipo.closed", "ipo.listed", "gmp.updated"],
    "secret": "whsec_your_secret_here",
    "status": "active",
    "createdAt": "2026-02-09T14:30:00.000Z",
    "updatedAt": "2026-02-09T14:30:00.000Z"
  },
  "disclaimer": "Data aggregated from publicly accessible sources. Not investment advice.",
  "timestamp": "2026-02-09T14:30:00.000Z",
  "requestId": "req_w3b1h2k3c4"
}

Event Types

Subscribe to specific event types to receive only the notifications relevant to your application:

EventDescriptionTrigger
ipo.upcomingNew IPO announcedWhen a new IPO is added to the system
ipo.openedIPO subscription openedWhen IPO subscription period begins
ipo.closedIPO subscription closedWhen IPO subscription period ends
ipo.allotmentIPO allotment announcedWhen share allotment is finalized
ipo.listedIPO listed on exchangeWhen shares begin trading on the exchange
gmp.updatedGMP data updatedWhen GMP value changes for any IPO (every ~2 hours)
nfo.openedNFO subscription openedWhen a new NFO opens for subscription
nfo.closedNFO subscription closedWhen an NFO subscription period ends
sgb.openedSGB tranche openedWhen a new SGB series opens for subscription

Payload Format

Webhook events are delivered as HTTP POST requests with a JSON body. The payload includes the event type, timestamp, and the relevant data:

IPO Opened Event200
{
  "id": "evt_abc123def456",
  "type": "ipo.opened",
  "timestamp": "2026-02-10T09:00:00.000Z",
  "data": {
    "id": "ipo_nxs2026",
    "slug": "nexus-select-trust-reit",
    "name": "Nexus Select Trust REIT IPO",
    "company": "Nexus Select Trust",
    "type": "MAINBOARD",
    "status": "OPEN",
    "issuePrice": { "min": 95, "max": 100 },
    "lotSize": 150,
    "dates": {
      "openDate": "2026-02-10T00:00:00.000Z",
      "closeDate": "2026-02-12T00:00:00.000Z"
    }
  }
}
GMP Updated Event200
{
  "id": "evt_gmp789xyz",
  "type": "gmp.updated",
  "timestamp": "2026-02-10T12:00:00.000Z",
  "data": {
    "ipoSlug": "nexus-select-trust-reit",
    "ipoName": "Nexus Select Trust REIT IPO",
    "issuePrice": 100,
    "previousGmp": 40,
    "currentGmp": 45,
    "change": 5,
    "changePercent": 12.5,
    "estimatedListingPrice": 145,
    "estimatedListingGain": 45.0
  }
}

Webhook Request Headers

Each webhook delivery includes the following headers:

HeaderDescription
Content-Typeapplication/json
X-Webhook-IDUnique identifier for this webhook delivery (for deduplication)
X-Webhook-TimestampUnix timestamp of when the event was sent
X-Webhook-SignatureHMAC-SHA256 signature for verifying the payload authenticity
User-AgentIPOGuruji-Webhook/1.0

Verifying Webhook Signatures

Every webhook delivery is signed with your webhook secret using HMAC-SHA256. You should always verify the signature to ensure the event was sent by IPO Guruji and not a third party.

The signature is computed as: HMAC-SHA256(webhook_secret, timestamp.body)

Verify Webhook Signature
javascript
const crypto = require('crypto');function verifyWebhookSignature(payload, signature, timestamp, secret) {  // Prevent replay attacks: reject events older than 5 minutes  const currentTime = Math.floor(Date.now() / 1000);  if (Math.abs(currentTime - parseInt(timestamp)) > 300) {    return false;  }  // Compute expected signature  const signedPayload = `${timestamp}.${payload}`;  const expectedSignature = crypto    .createHmac('sha256', secret)    .update(signedPayload)    .digest('hex');  // Compare using timing-safe comparison  return crypto.timingSafeEqual(    Buffer.from(signature),    Buffer.from(expectedSignature)  );}// Express.js handlerapp.post('/webhooks/ipoguruji', express.raw({ type: 'application/json' }), (req, res) => {  const signature = req.headers['x-webhook-signature'];  const timestamp = req.headers['x-webhook-timestamp'];  const body = req.body.toString();  if (!verifyWebhookSignature(body, signature, timestamp, process.env.WEBHOOK_SECRET)) {    return res.status(401).json({ error: 'Invalid signature' });  }  const event = JSON.parse(body);  console.log('Received event:', event.type);  // Process the event  switch (event.type) {    case 'ipo.opened':      handleIpoOpened(event.data);      break;    case 'gmp.updated':      handleGmpUpdated(event.data);      break;  }  // Return 200 to acknowledge receipt  res.status(200).json({ received: true });});

Retry Policy

If your endpoint does not respond with a 2xx status code within 30 seconds, the delivery is considered failed and will be retried with exponential backoff:

AttemptDelay After Previous AttemptApproximate Time
1st retry1 minute~1 minute after initial
2nd retry5 minutes~6 minutes after initial
3rd retry30 minutes~36 minutes after initial
4th retry2 hours~2.5 hours after initial
5th retry (final)6 hours~8.5 hours after initial

After 5 failed retry attempts, the webhook delivery is marked as failed. If a webhook endpoint consistently fails, it will be automatically disabled after 10 consecutive failures. You can re-enable it from your dashboard.

Testing Webhooks

Use the test endpoint to send a sample event to your webhook URL and verify it is configured correctly:

Send Test Event
curl -X POST "https://api.ipoguruji.com/v1/webhooks/wh_abc123def456/test" \  -H "X-API-Key: ipg_live_your_api_key_here"
Test Result200
{
  "success": true,
  "data": {
    "webhookId": "wh_abc123def456",
    "testEventId": "evt_test_xyz789",
    "delivered": true,
    "statusCode": 200,
    "responseTime": 245,
    "timestamp": "2026-02-09T14:30:00.000Z"
  },
  "disclaimer": "Data aggregated from publicly accessible sources. Not investment advice.",
  "timestamp": "2026-02-09T14:30:00.000Z",
  "requestId": "req_t3s7w8h9k0"
}

Best Practices

Always verify signatures

Never process a webhook without verifying the HMAC signature to prevent spoofing.

Return 200 quickly

Acknowledge receipt with a 200 response immediately, then process the event asynchronously. The 30-second timeout is strict and slow responses will trigger retries.

Handle duplicate deliveries

Use the X-Webhook-ID header to deduplicate events. Store processed event IDs and skip duplicates.

Use HTTPS endpoints

Webhook URLs must use HTTPS. HTTP URLs are not accepted for security reasons.