Documentation is a work in progress.

Automations

Each event type has its own automation—a JavaScript function that runs when the event fires. You write the logic; Pulsify handles execution.

The handler function

Every automation follows the same pattern:

function handle(event, context) {
  // Your logic here
  return context;
}

The function receives two arguments and returns the modified context.

The event object

The event object is the raw notification payload from Amazon, nested exactly as Amazon sends it — there are no flattened convenience fields. Its shape depends on the event type. Most SQS notification types use PascalCase and carry:

  • event.NotificationType — notification type (e.g., ANY_OFFER_CHANGED)
  • event.EventTime — when the event occurred

For ANY_OFFER_CHANGED, the data lives under event.Payload.AnyOfferChangedNotification:

  • OfferChangeTrigger.ASIN — the affected ASIN
  • OfferChangeTrigger.MarketplaceId — marketplace identifier (e.g., ATVPDKIKX0DER for US)
  • Summary.BuyBoxPrices — Buy Box prices keyed by item condition; pick yours with .find((p) => p.Condition === "New") rather than indexing [0]. Amounts are decimal numbers in the marketplace's major currency unit (19.99 for USD, 6440 whole yen for JPY), exactly as Amazon sent them.
  • Offers — the top 20 competing offers. Find your own offer by matching its SellerId against the payload's own event.Payload.AnyOfferChangedNotification.SellerId, then derive Buy Box ownership from its IsBuyBoxWinner; your offer isn't always present, so guard for it.

PRICING_HEALTH arrives over SQS too, but its envelope is camelCase: event.notificationType and event.eventTime replace event.NotificationType and event.EventTime. The payload follows suit: event.payload.offerChangeTrigger.asin, event.payload.summary.buyBoxPrices.

The context object

The context object contains your listing data and tools for taking action. Modify it and return it to apply changes.

context.listing

Your listing's current state and settings:

  • context.listing.price — current price as a decimal number in the marketplace's major currency unit (19.99 for USD, 6440 whole yen for JPY), matching what you see in Seller Central. Writes through context.listing.set use the same unit.
  • context.listing.floor — minimum allowed price (guardrail)
  • context.listing.ceiling — maximum allowed price (guardrail)
  • context.listing.asin — the listing's ASIN
  • context.listing.fulfillmentChannel"Amazon" for FBA or "Merchant" for MFN
  • context.listing.fba — raw FBA report data, or null for MFN listings
  • context.listing.b2bUnitsSold — units sold at the B2B price over the trailing 30 days

To change the price, call context.listing.set({ price: newPrice }). Pulsify enforces floor and ceiling automatically.

context.campaign

Control associated advertising campaigns:

  • context.campaign.enabled — whether the campaign is active
  • context.campaign.resume() — resume the campaign
  • context.campaign.pause() — pause the campaign

context.webhooks

Send data to external systems:

  • context.webhooks.slack.post(data) — send a POST request to the webhook you configured under the name slack. See the Webhooks page for setup.

Example

A simple repricing strategy that matches the Buy Box price when you're not winning:

function handle(event, context) {
  const notification = event.Payload?.AnyOfferChangedNotification;
  const offers = notification?.Offers || [];
  // Offers carries the top 20 — your own offer isn't always present
  const myOffer = offers.find((o) => o.SellerId === notification?.SellerId);
  if (!myOffer) return context;
  if (myOffer.IsBuyBoxWinner) return context; // Already winning, do nothing

  // BuyBoxPrices is keyed by condition — don't index [0]
  const buyBox = (notification?.Summary?.BuyBoxPrices || []).find(
    (p) => p.Condition === "New",
  );
  if (!buyBox) return context;

  const buyBoxPrice = buyBox.ListingPrice.Amount;
  // Match the Buy Box price if within guardrails
  if (buyBoxPrice >= context.listing.floor) {
    context.listing.set({ price: buyBoxPrice });
  }
  return context;
}

Templates

We provide starter templates for common strategies. Use them as-is or customize to match your needs. Templates are available in the automation editor when you create or edit an automation.