Docs

Docs / Data Feed / Distributors

For Data Feed stores
Endpoint · Work out how to buy an order

POST/sourcing-plan

Every distributor you buy from that carries each line of an order, and the cheapest way to buy the lot with shipping, a box at a time. Nothing is written.

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

Fields

Needs Distributors: Read. The body is the order: where its lines go, and the lines. Nothing is written, and the plan is worked out afresh on every call, so ask again just before you buy.

FieldTypeRule
store_stateoptionalstring or nullYour store's own state, two letters, which a line going through your store must be allowed to reach.
destinationsrequiredarrayWhere the order's lines go: 1 to 8.
destinations[].keyrequiredstringYour name for it, up to 32 characters, each once in the body.
destinations[].kindrequiredstringdealer, the dealer the buyer chose; address, the order's shipping address; store, the buyer collects at your store; or pending, a dealer not chosen yet, so no state is checked.
destinations[].stateoptionalstring or nullIts state, two letters.
linesrequiredarrayThe order's lines: 1 to 100.
lines[].keyrequiredstringYour own id for the line, up to 32 characters. It comes back unchanged.
lines[].product_idrequiredintegerThe product_id GET /products answers with.
lines[].quantityrequiredinteger1 to 9,999.
lines[].destinationrequiredstringThe key of one of the body's destinations. One the body does not declare is 422.
pinsoptionalarrayThe distributor you chose for a line: the plan buys that line from it, choosing its route and every other line around it. Up to 100, each line at most once.
pins[].linerequiredstringA line's key. One the body does not send is 422.
pins[].distributorrequiredstringThe distributor's slug, as a carrier names it. One that can no longer fill the line is ignored, and the line is planned as if not pinned.
  • Priced at what you pay: each offer's cost, not your price, and each distributor's published shipping terms, a box at a time. Lines one distributor sends to one place travel in one box.
  • Two ways to send a line: direct, drop-shipped by the distributor, or via_store, to your store and on from there, with both legs priced: the distributor's box to you and your own box on, from FFL Monkey's estimate of a store's shipping. A line for a buyer collecting at your store goes to_store, one leg.
  • The cheapest plan, not each line's cheapest offer: shipping is per box, so the plan prices whole combinations. cheapest_items is each line's cheapest offer on its own, priced the same way, and savings what the plan saves against it.
  • Every selected distributor is listed for each line, in stock or not, once. One that cannot fill it says why in refusal. The plan weighs every offer, because a distributor can list a product under two SKUs that ship differently; it lists the offer its plan buys.
  • What another distributor would cost: each carrier that can fill a line says in if_chosen what the order would cost with that distributor, every other line kept with its distributor and every offer and route chosen again. Pin every line that way and the plan you get is that one, while costs and stock hold. An order too large to price every alternative has if_chosen only on the carriers the plan uses.
  • A pin that cannot be kept is set aside: when the distributor you pinned can no longer fill the line, the plan buys it elsewhere and the line says pin_ignored.

What it answers

data is the plan:

FieldMeaning
quoted_atWhen it was worked out. Offers and stock move: ask again before you buy.
linesEach line, in the order sent, with every carrier, below.
planThe cheapest way to buy the lines that can be filled, below, or null when none can.
cheapest_itemsEach line's cheapest offer on its own, priced with shipping: the plan's totals without its boxes, or null when no line can be filled.
savingsWhat the plan saves against cheapest_items when both are fully priced, a decimal string, or null.
cheapest_planThe cheapest way with no pins, its totals as in cheapest_items: the same totals as plan when you pin nothing, or null when no line can be filled.
Each of linesMeaning
keyAs sent.
product_idAs sent.
upcThe product's UPC, or null.
titleThe product's title, or null.
quantityAs sent.
destinationThe destination's key, as you sent it.
parcel_destinationWhere its parcel goes: the same key, except for a firearm you sent to an address, which goes on through your store to a dealer not chosen yet. That is your pending destination when you declared one, else a key the plan adds, pending_dealer (or the first free variant), of kind pending with no state.
shipping_classhandgun, long_gun, ammunition or other: which of a distributor's rates applies to it.
in_house_stockUnits you hold yourself, for information: the plan only buys from distributors.
statusplanned: a carrier can fill it. no_carrier: none can. unknown_product: no such product.
carriersEvery selected distributor's offer for it, one per distributor (the offer its plan buys), cheapest first, below.
pin_ignoredtrue when you pinned this line to a distributor that can no longer fill it, so the plan chose another; else false.
Each of carriersMeaning
distributorThe distributor's slug, as GET /distributors lists it.
distributor_nameIts name.
costWhat you pay for one, or null when its feed sent no cost.
map_priceThe minimum advertised price, or null.
stockUnits it has.
drop_shipWhether this offer may be drop-shipped: allowed, blocked or unknown, which counts as allowed.
drop_ship_programWhether the distributor's terms offer drop-ship at all: offered, not_offered or unknown.
routesHow it can reach the destination: direct, via_store or to_store.
refusalWhy it cannot fill the line: short_stock (fewer than the quantity), no_cost or state_restricted (it will not ship it to any state the line could go through). Null when it can.
planned_routeThe route the plan uses it by, or null when the plan does not use it.
logo_urlThe distributor's logo, or null when there is none.
if_chosenWhat the order would cost with it filling the line: its route, the order's total, complete, unknown_shipments and the difference from the plan's total, negative when it costs less. The plan itself for the carrier the plan uses; null when it cannot fill the line.
planMeaning
items_totalCost times quantity, every line the plan fills.
distributor_shippingEvery distributor box's shipping that is published.
store_shippingEvery box you ship on, from FFL Monkey's estimate.
totalAll three.
completetrue when every box has a published rate.
unknown_shipmentsBoxes with no published rate, left out of the totals.
shipmentsThe boxes, below.
Each of shipmentsMeaning
kinddistributor, a distributor's box, or store, your own box on to the destination.
distributorIts slug; null for a store box.
distributor_nameIts name; null for a store box.
routeWhich of the shipping terms priced it: drop_ship, store or any.
ship_todestination or store.
destinationThe destination's key its lines were sent to, as you sent it; null when it goes to your store.
parcel_destinationWhere the box goes: its lines' parcel_destination; null when it goes to your store.
linesThe lines in it, each its key, quantity, unit_cost and line_cost.
subtotalThe lines in it.
shippingIts shipping, or null when the rate is not published.
chargesThe rate and fees that make up shipping, each a label and an amount.
terms_sourceWhere the shipping terms were read, or null.
terms_checked_onWhen they were last checked, or null.
logo_urlThe distributor's logo, or null for a store box.

Returns

  • 200The plan, in data. A plan nobody can fill is still 200, with plan null.
  • 422validation_failed: the body broke a rule, a line naming an undeclared destination or a pin naming a line not sent included.

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].