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:
/v1/webhooksPro+Create a new webhook endpoint.
Request Body
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Required | - | HTTPS URL that will receive webhook events. Must be publicly accessible. |
events | string[] | Required | - | Array of event types to subscribe to |
secret | string | Optional | - | Shared secret for verifying webhook signatures. Auto-generated if not provided. |
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" }'{
"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:
| Event | Description | Trigger |
|---|---|---|
ipo.upcoming | New IPO announced | When a new IPO is added to the system |
ipo.opened | IPO subscription opened | When IPO subscription period begins |
ipo.closed | IPO subscription closed | When IPO subscription period ends |
ipo.allotment | IPO allotment announced | When share allotment is finalized |
ipo.listed | IPO listed on exchange | When shares begin trading on the exchange |
gmp.updated | GMP data updated | When GMP value changes for any IPO (every ~2 hours) |
nfo.opened | NFO subscription opened | When a new NFO opens for subscription |
nfo.closed | NFO subscription closed | When an NFO subscription period ends |
sgb.opened | SGB tranche opened | When 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:
{
"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"
}
}
}{
"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:
| Header | Description |
|---|---|
Content-Type | application/json |
X-Webhook-ID | Unique identifier for this webhook delivery (for deduplication) |
X-Webhook-Timestamp | Unix timestamp of when the event was sent |
X-Webhook-Signature | HMAC-SHA256 signature for verifying the payload authenticity |
User-Agent | IPOGuruji-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)
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:
| Attempt | Delay After Previous Attempt | Approximate Time |
|---|---|---|
| 1st retry | 1 minute | ~1 minute after initial |
| 2nd retry | 5 minutes | ~6 minutes after initial |
| 3rd retry | 30 minutes | ~36 minutes after initial |
| 4th retry | 2 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:
curl -X POST "https://api.ipoguruji.com/v1/webhooks/wh_abc123def456/test" \ -H "X-API-Key: ipg_live_your_api_key_here"{
"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.