Chapter 6: Webhooks

Use webhooks to react within seconds, and keep polling as a safety net. A webhook tells you that a record changed; your connector then fetches the current record from the API and runs the same handler the poller uses.

Register a webhook

Register through the API with your Integration API Key (or in the integration's Advanced section in the app). Choose a long random value for apikey: Pipe17 sends it back in the x-api-key header of every delivery, so your endpoint can reject calls that do not carry it.

curl -s -X POST "$PIPE17_BASE_URL/webhooks" \
  -H "X-Pipe17-Key: $PIPE17_INTEGRATION_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://connector.example.com/pipe17/webhooks",
    "apikey": "<long random secret>",
    "topics": ["shipments", "products", "integrations"]
  }'

The URL must be unique within the organization. Available topics include shipments, orders, fulfillments, inventory, products, locations, integrations, returns, arrivals, receipts and exceptions. Use GET /webhooks, PUT /webhooks/{webhookId} and DELETE /webhooks/{webhookId} to review and maintain your subscriptions.

# List your webhooks
curl -s "$PIPE17_BASE_URL/webhooks" \
  -H "X-Pipe17-Key: $PIPE17_INTEGRATION_KEY"

# Change the topics of one webhook
curl -s -X PUT "$PIPE17_BASE_URL/webhooks/<webhookId>" \
  -H "X-Pipe17-Key: $PIPE17_INTEGRATION_KEY" \
  -H "Content-Type: application/json" \
  -d '{"topics": ["shipments", "products", "integrations", "locations"]}'

# Remove a webhook
curl -s -X DELETE "$PIPE17_BASE_URL/webhooks/<webhookId>" \
  -H "X-Pipe17-Key: $PIPE17_INTEGRATION_KEY"

What Pipe17 sends

When a record of a subscribed topic is created, updated or deleted, Pipe17 sends a POST to your URL with an x-api-key header and a small JSON body. The body names the record; it does not contain it.

{
  "orgKey": "a5ad27e3a383b711",
  "entity": "shipments",
  "action": "update",
  "itemId": "930cfcd3018dffd5",
  "timestamp": "2026-10-12T07:18:31Z",
  "requestId": "b020289f41cc0aee"
}
Field Meaning
entity The topic, for example shipments or products
action create, update or delete
itemId The Pipe17 ID of the record that changed. Fetch it from the API to get its current data
timestamp When the change happened
requestId Unique per event. Use it to ignore repeat deliveries
orgKey The Pipe17 organization

Delivery rules. If Pipe17 cannot reach your endpoint, it retries 3 times over about 5 minutes and then drops the event. Any HTTP response, including 4xx and 5xx, counts as delivered and is not retried. A failure inside your receiver therefore loses the event, which is one reason polling must stay on.


Receive a webhook

Your endpoint should do as little as possible: check the call is genuine, record it, reply 200, and process it afterwards.

// webhooks.js – receiver (Node.js built-in http server; Express works the same way)
import http from 'node:http';
import { handleShippingRequest } from './flows/shippingRequests.js';
import { handleProduct } from './flows/products.js';
import { refreshSettings } from './settings.js';
import { p17 } from './p17.js';
import * as state from './state.js';

const SECRET = process.env.PIPE17_WEBHOOK_SECRET;   // the apikey you registered

const fetchers = {
  shipments: async (id) => (await p17('GET', `/shipping_requests/${id}`, { query: { keys: '*' } })).shipment,
  products:  async (id) => (await p17('GET', `/products/${id}`)).product,
};
const handlers = { shipments: handleShippingRequest, products: handleProduct };

http.createServer((req, res) => {
  if (req.method !== 'POST' || req.url !== '/pipe17/webhooks') return res.writeHead(404).end();
  if (req.headers['x-api-key'] !== SECRET) return res.writeHead(401).end();

  let raw = '';
  req.on('data', (chunk) => (raw += chunk));
  req.on('end', () => {
    res.writeHead(200).end();                         // acknowledge first, work later
    setImmediate(() => processDelivery(JSON.parse(raw)).catch(console.error));
  });
}).listen(process.env.PORT ?? 8080);

async function processDelivery({ orgKey, entity, action, itemId, requestId }) {
  const ctx = await contextFor(orgKey);              // your registry: integration, key and settings for this org
  if (state.wasProcessed(`webhook:${requestId}`)) return;   // repeat delivery
  if (entity === 'integrations') await refreshSettings();
  else if (handlers[entity] && action !== 'delete') {
    const record = await fetchers[entity](itemId);    // always re-read the current record
    await handlers[entity](ctx, record);                   // same idempotent handler the poller uses
  }
  state.markProcessed(`webhook:${requestId}`);
}

In production, write each delivery to a durable queue or table before replying, rather than setImmediate. Because Pipe17 does not retry once you respond, anything lost after the reply is only picked up by the next poll.

Two keys, two jobs. The x-api-key value proves a delivery came from your webhook subscription. Fetching the record still uses your Integration API Key in the X-Pipe17-Key header.

Fetching the record named in a delivery (itemId):

# entity = shipments
curl -s -G "$PIPE17_BASE_URL/shipping_requests/<itemId>" \
  -H "X-Pipe17-Key: $PIPE17_INTEGRATION_KEY" \
  --data-urlencode "keys=*"

# entity = products
curl -s "$PIPE17_BASE_URL/products/<itemId>" \
  -H "X-Pipe17-Key: $PIPE17_INTEGRATION_KEY"

Combine webhooks with polling

  Webhooks Polling
Speed Seconds One interval (minutes)
Can miss changes Yes: endpoint down, network errors, deploys No, if cursors are handled as in Chapter 5
Duplicates Possible Possible (overlap window)
Role in your connector Fast path Source of truth and catch-up

With webhooks on, you can lengthen poll intervals (for example from 5 to 15 minutes) but never turn polling off. Both paths call the same handler, and the event keys from Chapter 4 make repeats harmless.


Need Help?

If you need additional assistance:

  • Use Ask Pippen, our AI agent, located at the top of the app page.
  • Submit a support request with as much relevant detail as possible. Learn how to submit a request.

We're here to help you succeed with your operations.

Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.

Have more questions?
Submit a request
Share it, if you like it.