Listings Webhooks

This guide explains how to receive real-time notifications when listings are accepted on the Plum Guide platform.

Overview

When a listing passes Plum Guide's review process and is accepted onto the platform, you can be notified via webhook. This eliminates the need to poll the API for listing status updates.

Options for Tracking Listing Status

MethodDescriptionRecommended For
WebhooksReceive instant notification when the listing is acceptedReal-time integrations
PollingPeriodically call GET /v2/listings to check statusSimple integrations

Quick Start

1. Configure Listings Webhook Endpoint

POST /v2/webhooks/config
Authorization: Bearer {your_token}
Content-Type: application/json

{
  "isActive": true,
  "endpoints": {
    "listings": "https://your-domain.com/webhooks/listings"
  }
}

2. Receive Listing Created Events

When a listing is accepted, your endpoint receives:

{
  "eventId": "660e8400-e29b-41d4-a716-446655440001",
  "timestamp": "2025-01-15T11:00:00Z",
  "bookingCode": null,
  "listingId": 12345
}

3. Fetch Listing Details

Use the listing ID to get full details:

GET /v2/listings/{listingId}
Authorization: Bearer {your_token}

Listing Events

EventDescription
Listing CreatedListing has been accepted and published on Plum Guide

Webhook Payload

{
  "eventId": "660e8400-e29b-41d4-a716-446655440001",
  "timestamp": "2025-01-15T11:00:00Z",
  "bookingCode": null,
  "listingId": 12345
}
FieldTypeDescription
eventIdUUIDUnique identifier for this event (use for idempotency)
timestampISO 8601When the listing was accepted
bookingCodenullAlways null for listing events
listingIdintegerThe accepted listing's ID

Configuration API

Create/Update Configuration

POST /v2/webhooks/config
Content-Type: application/json
Authorization: Bearer {token}

{
  "isActive": true,
  "endpoints": {
    "listings": "https://your-domain.com/webhooks/listings"
  }
}

Get Configuration

GET /v2/webhooks/config
Authorization: Bearer {token}

Toggle On/Off

PATCH /v2/webhooks/config/toggle?isActive=false
Authorization: Bearer {token}

Delete Configuration

DELETE /v2/webhooks/config
Authorization: Bearer {token}

Requirements:

  • Endpoint URL must use HTTPS
  • Your endpoint must return 200 OK within 30 seconds

Alternative: Polling

If you prefer not to use webhooks, you can poll the listings endpoint:

GET /v2/listings
Authorization: Bearer {your_token}

This returns all listings for your account with their current status:

  • InReview - Listing is being reviewed
  • Published - Listing is live on Plum Guide
  • Hidden - Listing has been delisted

Polling Recommendations:

  • Poll every 24 hours
  • Check the status field for changes
  • Store last known status to detect changes

Example Handler

app.post('/webhooks/listings', async (req, res) => {
  const { eventId, listingId } = req.body;

  // Acknowledge receipt immediately
  res.status(200).send('OK');

  // Fetch full listing details
  const listing = await plumApi.getListing(listingId);

  // Handle the accepted listing
  console.log(`Listing ${listingId} accepted: ${listing.listingName}`);

  // Update your system
  await updateListingStatus(listingId, 'published');
});

Best Practices

  1. Respond quickly - Return 200 OK immediately, process asynchronously
  2. Implement idempotency - Use eventId to avoid processing duplicates
  3. Fetch full details - The webhook payload is minimal; use the API for complete data
  4. Handle retries - The same event may be delivered multiple times

Troubleshooting

Not receiving webhooks?

  1. Verify configuration: GET /v2/webhooks/config
  2. Check isActive is true
  3. Ensure endpoints.listings is set
  4. Confirm URL is HTTPS and publicly accessible

Receiving duplicates?

This is expected. Use eventId for deduplication:

const processedEvents = new Set();

if (processedEvents.has(eventId)) {
  return res.status(200).send('Already processed');
}
processedEvents.add(eventId);