Browse the documentation

MCP tools

RFQs and supplier quotes

MCP tools for supplier RFQs, recording their quotes in any currency, the price book and exchange rates.

An RFQ (request for quotation) is the buying side of a tender: a list of tender items you ask your suppliers to price, frozen when the request is created. Each supplier reply is recorded as a quote with its priced lines, in the supplier's own currency. These tools create and manage requests, record and correct quotes, and read the prices your organization has collected. The guide to the app side is RFQs.

Note:Supplier prices are cost data. Owner, admin, purchasing and viewer can read them, and owner, admin and purchasing can write them. The sales, technical and viewer (no pricing) roles cannot use these tools. All of them need the Pro or Enterprise plan, except fx_rates_get, which every role and plan can use.
Tip:Quotes are recorded as the supplier printed them: name the supplier's currency and send each price unchanged, and the server converts it to US dollars at the rate it reports back. To record a single price for one item, use `tenders_sourcing_price_add`. Those prices are kept on a per-tender holding request of kind sourcing, which shows in listings like any request but cannot be deleted or given another currency.
ToolWhat it does
rfqs_listList RFQs
rfqs_getGet an RFQ
rfqs_createCreate an RFQ
rfqs_updateSet an RFQ's currency
rfqs_deleteDelete an RFQ
rfq_excel_exportDownload the RFQ workbook
fx_rates_getGet exchange rates for quotes
rfq_responses_addRecord a supplier quote
rfq_responses_updateUpdate a supplier quote
rfq_responses_deleteDelete a supplier quote
tender_rfq_matrixGet a tender's supplier quotes
rfq_responses_listList supplier quote lines
rfq_price_bookGet the vendor price book

Requests

Create a request from a tender's items, read it back, change its currency, download the supplier workbook or delete it.

rfqs_list

Lists your organization's RFQs across all tenders, newest first, each with its tender and the number of items and supplier quotes. Narrow it to one tender with tender_id, or use kind to leave out the holding requests that single-item sourcing prices live on.

Read-only · scope rfqs.read · roles: owner, admin, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
tender_idintegerNoOnly the requests of this tender. The ID comes from the tender tools.
kindstringNoOnly requests of this kind: rfq for requests you created for a tender with rfqs_create, or sourcing for the holding request that keeps single-item sourcing prices.
pageintegerNoPage number, starting at 1.
page_sizeintegerNoResults per page: 20 by default, 100 at most.
{
  "tender_id": 48213,
  "kind": "rfq",
  "page": 1
}
Example arguments

Returns: A page of requests in data, with total, page, page_size and total_pages. Each request has its id, tender_id, title, kind, currency and created_at, its tender's name and agency, item_count and response_count.

  • Holding requests (kind sourcing) appear in the list unless you filter them out with kind. They hold prices typed onto single items and are not requests you send to a supplier.

rfqs_get

Returns one RFQ in full: its frozen item list, every supplier quote recorded on it and every priced line of those quotes. Use it to find the IDs, item numbers and NUPCO codes you need before recording a quote, or to check what suppliers have answered.

Read-only · scope rfqs.read · roles: owner, admin, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe RFQ's ID, from rfqs_list or the rfq_id that rfqs_create returns.

Returns: rfq (including tender_id, currency and kind), items (the frozen lines: id, item_number, description, quantity and unit, plus the live tender item's item_name and material_code), responses (one per quote: the supplier's details, source, submitted_at, currency, fx_rate with its date and source, and manufacturer_name) and response_items (the priced lines: unit_price in US dollars, quoted_unit_price as the supplier gave it, lead time, catalog number, weights, packing and product_id).

  • A line's description is the copy frozen at creation, while item_name and material_code are read from the tender item as it is now, so a later edit to the item shows in them.
  • The server answers 404 when the request is not your organization's.

rfqs_create

Creates an RFQ for a tender from the items you pick. The request freezes those items when it is created, so later edits to the tender never change a file already in a supplier's hands. Each call makes a separate request, so different item sets can go to different suppliers. Nothing is sent: download the workbook with rfq_excel_export and pass it on yourself.

Changes data · scope rfqs.write · roles: owner, admin, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
tender_idintegerYesThe tender's ID.
item_idsinteger[]YesIDs of the tender's live items to include, from 1 to 2000. They come from tenders_get, and repeats are merged.
currencystringNoISO 4217 code of the currency suppliers are asked to quote in, such as USD, SAR, EUR, CNY or GBP. Defaults to USD. It presets the workbook's Currency dropdown and becomes the default of rfq_responses_add, and a supplier may still quote in another. fx_rates_get lists every supported code.
{
  "tender_id": 48213,
  "item_ids": [
    902114,
    902115,
    902118
  ],
  "currency": "EUR"
}
Example arguments

Returns: The new request: rfq_id, item_count and currency.

  • The server answers 400 invalid_items when any ID is not a live item of this tender (a deleted item is not live), and 404 when the tender is not visible to your organization.
  • The request is titled with the tender's name (first 200 characters) and its items follow the tender's item order.

rfqs_update

Changes the currency an RFQ asks suppliers to quote in. It applies to workbooks you export from now on and to the default of rfq_responses_add. Quotes already recorded keep their own currency, and a workbook already sent still names the currency it went out with.

Changes data · scope rfqs.write · roles: owner, admin, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe RFQ's ID.
currencystringYesISO 4217 code of the new currency, such as USD, SAR, EUR, CNY or GBP. fx_rates_get lists every supported code.
{
  "id": 731,
  "currency": "CNY"
}
Example arguments

Returns: The request's id and its new currency.

  • The tool refuses the holding request (kind sourcing) with 400 sourcing_container, and answers 404 when the request is not your organization's.
  • To change the currency of a quote already recorded, use `rfq_responses_update`.

rfqs_delete

Deletes an RFQ together with its frozen item list and every supplier quote recorded on it. This cannot be undone.

Deletes or overwrites data · scope rfqs.write · roles: owner, admin, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe RFQ's ID.

Returns: A confirmation, with deleted_responses, the number of quotes that were deleted with the request.

  • The holding request (kind sourcing) cannot be deleted and the server answers 400 sourcing_container. Delete its prices one at a time with `rfq_responses_delete`.

rfq_excel_export

Builds the Excel workbook you send to suppliers for an RFQ and returns it as a file. It is rebuilt from the request's frozen item list and carries the request's identity in hidden data, so a copy filled in later can be matched back to its request. Its Currency dropdown is preset to the request's currency. Beside each item's description, a read-only Similar products column lists the manufacturer and catalog number of each product past NUPCO tenders awarded for the item's material code, unique and comma-separated.

Read-only · scope rfqs.read · roles: owner, admin, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe RFQ's ID.
localestringNoThe workbook's language: ar (the default) or en.

Returns: An Excel file: filename (like rfq-731-tender-48213.xlsx), content_type, size_bytes and base64.

  • The server answers 400 no_items when the request has no items. Every new download carries the same request identity, so every copy matches its request.
  • To record what a supplier sends back, read the filled workbook and record its prices with `rfq_responses_add`.

Currencies and exchange rates

A quote keeps its own currency and one exchange rate frozen when it is recorded. A rate reads as the units of the currency that buy one US dollar.

fx_rates_get

Lists the currencies a supplier quote can be recorded in and the rate each would use today, as units of the currency per 1 US dollar. Check it before recording a quote in a foreign currency to see which rate will apply and whether you must supply your own.

Read-only · scope rfqs.read · all roles · Pro and Enterprise plans

No parameters.

Returns: base (always USD), currencies (every supported code) and rates: for each currency that has a default, currency, fx_rate, rate_date (the ECB publication day, empty for fixed and pegged rates), source (identity, peg or ecb) and fixed.

  • The US dollar (1) and the Saudi riyal (3.75, the peg the platform converts to riyals at) are fixed: a quote in them cannot use another rate. The UAE dirham, Qatari riyal, Bahraini dinar, Omani rial and Jordanian dinar use their official pegs. Every other currency uses the latest European Central Bank reference rate, updated on working days.
  • A supported currency missing from rates has no rate on file (the Kuwaiti dinar, Egyptian pound and Pakistani rupee, for example), so pass fx_rate when recording a quote in it.
  • A recorded quote freezes its own rate, so these rates matter only for quotes you record from now on. This is the one tool on the page open to every role and plan.

Supplier quotes

A quote is one supplier's reply, covering any of the request's items. Record it, correct it as often as needed, or delete it.

rfq_responses_add

Records one supplier's quote against an RFQ, covering any of its items. Use it when a supplier replies in any format (a PDF, an email, a photo, a reworked spreadsheet): match each row of the reply to an item of the request and record its price as printed. The quote keeps the figures as the supplier gave them, in the supplier's currency, and the server converts them to US dollars for comparison at the rate it reports back.

Changes data · scope rfqs.write · roles: owner, admin, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
rfq_idintegerYesThe RFQ's ID.
manufacturer_idintegerNoThe supplier's record in your manufacturer directory, from manufacturers_list. Send null or leave it out for a supplier that is not in the directory. This or supplier_name is required.
supplier_namestringNoThe supplier or contact name shown on the quote, up to 200 characters. If you leave it out and give manufacturer_id, the manufacturer's directory name is used.
supplier_companystringNoThe supplier's company, up to 200 characters.
supplier_emailstringNoThe supplier's email address.
supplier_phonestringNoThe supplier's phone number, up to 50 characters.
incotermsstringNoThe delivery terms the supplier quoted, such as CIF Riyadh, up to 100 characters.
currencystringNoISO 4217 code of the currency the quote's prices are in, such as EUR. Defaults to the RFQ's own currency. Send each price exactly as printed in the document and name its currency here; do not convert prices yourself. fx_rates_get lists the supported codes.
fx_ratenumberNoUnits of the quote currency per 1 US dollar, for example 0.88 for EUR or 7.1 for CNY. Leave it out to use the default: USD and SAR are fixed (1 and 3.75, and any other value is refused), the Gulf currencies use their pegs, and other currencies the latest ECB rate. A currency with no rate on file, such as KWD, EGP or PKR, needs it.
notesstringNoNotes on the whole quote, up to 5,000 characters.
linesobject[]YesThe priced lines, from 1 to 2000. Each line names its item with exactly one of rfq_item_id, item_number or material_code.
lines[].rfq_item_idintegerNoThe request item's own ID, from rfqs_get.
lines[].item_numberintegerNoThe item number printed on the workbook sent to the supplier, an alternative to rfq_item_id. Refused when two request items carry the same number; use rfq_item_id then.
lines[].material_codestringNoThe NUPCO material code of the tender item, a third way to name the item. Refused when it matches more than one item of the request.
lines[].unit_pricenumberNoThe quoted unit price in the quote's currency, zero or more. Send null or leave it out to record the item's details with no price yet.
lines[].lead_time_daysintegerNoLead time in days, from 0 to 3650.
lines[].catalog_nostringNoThe supplier's catalog number, up to 100 characters.
lines[].weight_kgnumberNoUnit weight in kilograms.
lines[].units_per_caseintegerNoUnits in one case, a whole number above 0.
lines[].product_idintegerNoThe product in your catalog this price was quoted for, from products_list. It must be one of your organization's products.
lines[].notesstringNoNotes on the line, up to 2,000 characters.
{
  "rfq_id": 731,
  "supplier_name": "Li Wei",
  "supplier_company": "Shenzhen Medical Co",
  "incoterms": "CIF Riyadh",
  "currency": "CNY",
  "lines": [
    {
      "item_number": 1,
      "unit_price": 2.35,
      "lead_time_days": 45,
      "catalog_no": "SY-10ML"
    },
    {
      "material_code": "4111610529900",
      "unit_price": 14.8,
      "units_per_case": 100
    }
  ]
}
Example arguments

Returns: The new quote's response_id, the supplier_name recorded, the number of saved lines in lines, and the currency and fx_rate the quote was recorded at.

  • A reference that matches no item of the request, or more than one, is refused with a message naming the line and nothing is saved, so a price never lands on the wrong item.
  • The server answers 400 when you give neither a supplier name nor a manufacturer, 400 manufacturer_not_found when the manufacturer is not your organization's, and 400 product_not_found when a product_id is not one of your products.
  • The quote is recorded as a typed quote (source is manual). Lines with no price stay out of the comparisons and the price book.

rfq_responses_update

Changes a recorded quote without recording it again: the supplier's details, the lines, or the quote's currency and rate. Use it to fill a long supplier document in several passes, correct a mis-read price, or fix a quote recorded in the wrong currency. Only what you send changes.

Changes data · scope rfqs.write · roles: owner, admin, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
rfq_idintegerYesThe RFQ's ID.
response_idintegerYesThe quote's ID, from rfqs_get.
manufacturer_idintegerNoLinks the quote to a manufacturer in your directory. Send null to unlink it.
supplier_namestringNoThe new supplier name, 1 to 200 characters. It cannot be cleared.
supplier_companystringNoThe supplier's company. Send null to clear it.
supplier_emailstringNoThe supplier's email address. Send null to clear it.
supplier_phonestringNoThe supplier's phone number. Send null to clear it.
incotermsstringNoThe delivery terms. Send null to clear them.
currencystringNoISO 4217 code of the quote's currency. Sending a different currency, or fx_rate, re-denominates the whole quote: every line keeps its price as the supplier gave it and its US dollar price is recomputed at the new rate. Use it when the prices were recorded in the wrong currency (euros read as dollars). Send neither and the recorded rate stays frozen. A new currency with no fx_rate takes that currency's default rate.
fx_ratenumberNoA new rate, in units of the quote's currency per 1 US dollar, which reprices every line the same way. For USD and SAR only the fixed rate (1 and 3.75) is accepted.
notesstringNoNotes on the whole quote. Send null to clear them.
linesobject[]NoLines to add or change. A line for an item the quote already prices is updated field by field: what you leave out keeps its value and null clears it. A line for an item the quote does not price yet is added. Each line names its item as in rfq_responses_add.
lines[].rfq_item_idintegerNoThe request item's ID, from rfqs_get.
lines[].item_numberintegerNoThe item number printed on the supplier's workbook, an alternative to rfq_item_id.
lines[].material_codestringNoThe NUPCO material code of the tender item, a third way to name the item.
lines[].unit_pricenumberNoThe unit price in the quote's currency as it stands after this update. Send null to clear it.
lines[].lead_time_daysintegerNoLead time in days. Send null to clear it.
lines[].catalog_nostringNoThe supplier's catalog number. Send null to clear it.
lines[].weight_kgnumberNoUnit weight in kilograms. Send null to clear it.
lines[].units_per_caseintegerNoUnits in one case. Send null to clear it.
lines[].product_idintegerNoThe product in your catalog this price was quoted for. Send null to clear it.
lines[].notesstringNoNotes on the line. Send null to clear them.
remove_rfq_item_idsinteger[]NoIDs of the request items whose priced lines are removed from this quote, up to 2000.
{
  "rfq_id": 731,
  "response_id": 2087,
  "currency": "EUR",
  "lines": [
    {
      "item_number": 3,
      "unit_price": 4.1,
      "lead_time_days": 30
    }
  ],
  "remove_rfq_item_ids": [
    8812
  ]
}
Example arguments

Returns: response_id and supplier_name, the counts updated_lines, inserted_lines and removed_lines, the quote's currency and fx_rate after the change, and repriced_lines, the number of lines whose US dollar price was recomputed by a currency or rate change.

  • Send at least one change: an empty update is refused with a 400.
  • A currency or rate change applies first: lines you send in the same call are stored at the final rate, and their unit_price values are read in the final currency.
  • The server answers 409 when one request item appears more than once on the quote (remove the repeats with remove_rfq_item_ids first), 404 when the quote is not on this request, and 400 missing_supplier_name when the change would leave the quote with no supplier name and no manufacturer.
  • It works on a quote from any source: a returned Excel workbook, a typed quote or a single-item sourcing price.

rfq_responses_delete

Removes one supplier quote from an RFQ together with its lines, such as a mistyped sourcing price or a stale import. This cannot be undone, and the request itself stays.

Deletes or overwrites data · scope rfqs.write · roles: owner, admin, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
rfq_idintegerYesThe RFQ's ID.
response_idintegerYesThe quote's ID, from rfqs_get.

Returns: A confirmation: success is true.

  • The server answers 404 when the quote is not on this request. This is also how you remove a single-item sourcing price, which is kept on the tender's holding request.

Reading the collected prices

Three read-only views of the same data: one tender, every quote line in the organization, and the same lines grouped by product.

tender_rfq_matrix

Returns all supplier-quote data for one tender in a single call: every RFQ made for it, their items, every supplier quote and every priced line. It is the raw material for comparing suppliers' prices item by item.

Read-only · scope rfqs.read · roles: owner, admin, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
tender_idintegerYesThe tender's ID.

Returns: rfqs (each with item_count), items, responses (each with manufacturer_name) and response_items. All four are empty lists when the tender has no request.

  • The tool does not build the comparison for you: join response_items to items through rfq_item_id and to responses through response_id. unit_price is in US dollars and quoted_unit_price is as the supplier gave it.
  • items carry the frozen description, quantity, unit and item number, but not item_name or material_code. Read those from `rfqs_get`.
  • The result includes the tender's holding request (kind sourcing) with the prices typed onto single items.

rfq_responses_list

Lists every priced quote line your organization has collected from suppliers, from any request, Excel reply or single-item sourcing price, newest first, with a summary of each vendor. Use it to see what a supplier has quoted over time or to compare vendors across tenders.

Read-only · scope rfqs.read · roles: owner, admin, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
manufacturer_idintegerNoOnly lines from quotes linked to this manufacturer in your directory. The ID comes from manufacturers_list.
vendorstringNoOnly lines of one vendor, by the vendor key you find in the vendors list of an earlier call: mfr: plus the manufacturer ID for a vendor linked to your directory (mfr:512), or label: plus the supplier's company name (else contact name) in lowercase for a typed one (label:shenzhen medical co). Lines with no supplier identity at all are grouped under unknown. A display name does not match. 1 to 200 characters.
limitintegerNoThe most lines to return, from 1 to 2000. Defaults to 2000, which is also the ceiling.
{
  "manufacturer_id": 512,
  "limit": 200
}
Example arguments

Returns: vendors, a summary per vendor (key, name, lineCount, responseCount, productCount, firstQuoteAt and lastQuoteAt), and lines, newest first. Each line has its vendor, its product or item description, catalogNo, materialCode and quantity, the price in US dollars (unitPriceUsd), in riyals (unitPriceSar) and as the supplier quoted it (quotedUnitPrice with currency), then leadTimeDays, source, submittedAt and the request and tender it came from. Also total and truncated.

  • total is the count of all matching lines, and truncated is true when the 2000 cap cut the list. The vendor summaries cover the whole set and do not shrink when you filter.
  • Lines with no price are left out. source is excel for a returned workbook, manual for a typed quote (including single-item sourcing prices) or web for older replies through the web.

rfq_price_book

The same priced lines that `rfq_responses_list` returns, grouped by product: one row per product with every vendor that quoted it, their latest price and the vendor to beat. Use it to see who is cheapest for a product across all your requests.

Read-only · scope rfqs.read · roles: owner, admin, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
manufacturer_idintegerNoOnly products this manufacturer from your directory has quoted.
vendorstringNoOnly products quoted by one vendor, by its key as in rfq_responses_list: mfr: plus the ID, or label: plus the vendor name in lowercase.
sourcestringNoOnly products with at least one quote recorded this way: excel for a returned workbook, manual for a typed quote (including single-item sourcing prices) or web for older replies through the web.
limitintegerNoThe most products to return, from 1 to 2000. Defaults to 2000, which is also the ceiling.
{
  "source": "excel",
  "limit": 100
}
Example arguments

Returns: products, newest quote first. Each has name, kind, productId, vendorCount, quoteCount, its latest, lowest and highest price in US dollars and riyals, bestVendorKey, and vendors ordered cheapest latest price first. Also vendors for the whole set, total, truncated and quoteCount.

  • Each vendor inside a product carries its newest quote: the price in US dollars, riyals and its own currency, lead time, catalog number, source, and the request or tender it came from, with its quote count and price range. bestVendorKey is the vendor whose latest price is the cheapest, the price to beat.
  • A row is a product from your catalog when the line was tagged with it, you selected it on the quoted item, or the line's NUPCO code belongs to exactly one catalog product. Otherwise the row is the NUPCO code, or else the item description. kind says which: product, code or description.
  • Filters select products, not vendors: a product stays when one of its lines matches everything you sent, and it then keeps all its vendors so you can compare them. total counts the matching products, while vendors and quoteCount describe the whole set whatever you filter.