Docs

Docs / Data Feed / Products

For Data Feed stores
Endpoint · Read what changed

GET/changes

What changed in your store since a cursor, oldest first. Keeps a copy of your catalog current.

Needs Products and changes: ReadBase URL https://backend.fflmonkey.com/api/v1Counts 1 toward 120 a minute

Query parameters

All optional. Needs Products and changes: Read.

ParameterTypeMeaning
cursorintegerThe meta.next_cursor of the answer before, or the meta.changes_cursor of GET /products. Without it the answer has no changes, and meta.next_cursor is where to start from now.
limitintegerChanges per answer, 1 to 500. Default 100.
  1. Read your products with GET /products and keep the meta.changes_cursor of its first page.
  2. Call GET /changes?cursor= with it. Apply each change, then call again with meta.next_cursor. Every answer has one, even when nothing changed, and it moves on past changes that are not for your key, so save it each time.
  3. When meta.has_more is true, call again straight away; otherwise, a few minutes later.

Each change

Exactly what a webhook delivery carries. Apply each once, by event_id; reading one twice is harmless.

FieldMeaning
event_idThe change's identity: the same change read twice has the same event_id.
event_typeWhat kind of change, such as merchant_price.recomputed. See the table below. Ignore a type you do not know.
event_versionThe version of the payload's shape.
license_idYour store's licence, or null for a change to the shared catalog (product.*).
aggregate_typeWhat kind of thing changed, such as product.
aggregate_idWhich one.
cursorThe change's position. It only grows.
occurred_atWhen it happened.
payloadThe state after the change, never a difference: apply it as it is.
metadataWhere the change came from. For information, not for deciding whether to apply it.

The changes your key gets

Permissionevent_typeWhat to do
Products and changesmerchant_price.*merchant_price.recomputed: your price, stock or availability moved. payload.products holds each product's new price, stock, sourced_from and is_visible; apply them as they are, and take a product with is_visible false off sale.
Products and changesproduct.*product.created and product.updated: a product in the shared catalog changed, its title, images or category, say. These are about the whole catalog, not only your products: fetch the product with GET /products?ids=, and one you have no price for comes back empty.
Pricing rulespricing_rule.*pricing_rule.created, pricing_rule.updated and pricing_rule.deleted: a rule was saved or removed, whoever did it; pricing_rule.reordered: the order changed, and payload.ordered_ids is the new one. A payload names categories, brands and product classes by internal ids, not slugs: read the rule with GET /pricing-rules/{id} (payload.pricing_rule_id), unless it was deleted. Your prices follow as merchant_price.recomputed. Only for a key that also has Pricing rules.
Pricing rulespricing_settings.*pricing_settings.updated: a store-wide pricing setting changed, on your Pricing screen or with PATCH /pricing-settings. Its payload holds all three, default_margin, price_rounding and enforce_map_floor, as GET /pricing-settings answers them. Your prices follow as merchant_price.recomputed. Only for a key that also has Pricing rules.
Restrictionsrestriction.*restriction.created, restriction.updated and restriction.deleted: a restriction was saved or removed, whoever did it. Its payload names catalog rows by internal ids too: read it with GET /restrictions/{id} (payload.restriction_id), unless it was deleted. What it hides follows as merchant_price.recomputed. Only for a key that also has Restrictions.
Distributorsdistributor_account.*, license.distributor_selection.*distributor_account.connected: credentials for a distributor were saved, or replaced, whoever did it; distributor_account.disconnected: they were deleted. payload.distributor_slug names the distributor, and no payload carries a credential. license.distributor_selection.changed: the distributors you buy from changed, and payload.selected_distributors is the new list. Your prices follow as merchant_price.recomputed. Only for a key that also has Distributors.
In-house inventorymerchant_inventory.*merchant_inventory.updated: a row of your in-house inventory was written or removed. Only for a key that also has In-house inventory.
Subscriptionlicense.activated, license.suspended, license.canceledYour licence started, stopped or ended serving: payload.status is the new status. Read GET /subscription for the detail. Only for a key that also has Subscription.
Subscriptionsubscription.*subscription.ending_soon: your subscription is set to end within seven days. payload.ends_at is when. Call GET /subscription for the link to renew; the change carries none.

You never get another store's changes. If your store switches catalog sync off, product, price and in-house inventory changes are left out while it is off, and are not replayed later, and meta.sync_paused is true. Once it is false again, read your products again. To have changes sent to you instead of asking for them, set a webhook.

What it answers

FieldMeaning
next_cursorWhere to read from next. On every answer, and it moves on even when no change was for your key.
has_moretrue when the answer is full: read again from next_cursor straight away.
sync_pausedtrue while your store has switched catalog sync off, so product, price and in-house inventory changes were left out of this answer. They are not replayed: when it turns false, read GET /products again.

Returns

  • 200The changes after the cursor, oldest first, in data, and meta.
  • 410cursor_expired: changes are kept for at least 30 days, and this cursor is older than what is kept. Read GET /products again and carry on from its meta.changes_cursor.
  • 422validation_failed: a query parameter broke a rule.

This endpoint can also answer 401 invalid_api_key, 403 license_not_active, 403 product_not_included, 403 insufficient_scope and 429 rate_limited.

Example

FFL Monkey Data Feed API, version 1. Questions: Support in your FFL Monkey account, or [email protected].