Skip to content

Record an RFQ response

Procurement module

POST/rfq-responsesrfqResponses.create

Records a sealed response and its quoted lines in one call (app.record_rfq_response) for a holder of procurement.rfq.write on the project. Only an invited vendor responds while the RFQ is Issued (rfq_not_invited, 422) and a response quotes at least one line (rfq_response_lines_required, 422). Answers 201 with a receipt: the response stays unreadable until the RFQ closes. Requires `Idempotency-Key`; a replay returns the original response. A rule that refuses the request returns 422 with `refusal` and `reason`.

  • Requires the capability procurement.rfq.read.
  • OAuth scopes: procurement.
  • Send an Idempotency-Key header. A replay with the same key returns the original response.
  • Error statuses: 400, 401, 409, 422, 429. Errors are RFC 9457 problem details.

Request body: RfqResponseCreate

rfqResponses.create: RfqResponseCreate
FieldTypeRequiredDescription
rfq_idstring (uuid)YesIdentifier of the RFQ.
vendor_idstring (uuid)YesIdentifier of the responding vendor; must have been invited.
valid_untilstring (date) | nullNoLast day the quoted prices hold.
currency_codestringYesISO 4217 currency of every quoted line.Constraints: pattern ^[A-Z]{3}$
linesarray of RfqResponseQuotedLineYesLines quoted, at least one.
{
  "rfq_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "vendor_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "valid_until": "2026-10-08",
  "currency_code": "USD",
  "lines": [
    {
      "description": "Line array, 12 boxes per side",
      "element_id": "0000.01.01-XOS-001",
      "quantity": 2,
      "unit_price_minor": 1800000
    }
  ]
}

Response 201: RfqResponseReceipt

rfqResponses.create: RfqResponseReceipt
FieldTypeRequiredDescription
rfq_response_idstring (uuid)YesIdentifier of the recorded response.
rfq_idstring (uuid)YesIdentifier of the RFQ.
vendor_idstring (uuid)YesIdentifier of the responding vendor.
line_countintegerYesLines recorded.Constraints: range 1 to any
sealedbooleanYesTrue while the RFQ is not Closed: the response stays unreadable until it closes.
{
  "rfq_response_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "rfq_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "vendor_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
  "line_count": 3,
  "sealed": true
}

Code samples

curl -X POST "$XOS_BASE_URL/rfq-responses" \
  -H "Authorization: Bearer $XOS_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"rfq_id":"0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f","vendor_id":"0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f","valid_until":"2026-10-08","currency_code":"USD","lines":[{"description":"Line array, 12 boxes per side","element_id":"0000.01.01-XOS-001","quantity":2,"unit_price_minor":1800000}]}'
const { data } = await xos.rfqResponses.create({
    "rfq_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
    "vendor_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
    "valid_until": "2026-10-08",
    "currency_code": "USD",
    "lines": [
      {
        "description": "Line array, 12 boxes per side",
        "element_id": "0000.01.01-XOS-001",
        "quantity": 2,
        "unit_price_minor": 1800000
      }
    ]
  });
response = xos.rfq_responses.create({"rfq_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f", "vendor_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f", "valid_until": "2026-10-08", "currency_code": "USD", "lines": [{"description": "Line array, 12 boxes per side", "element_id": "0000.01.01-XOS-001", "quantity": 2, "unit_price_minor": 1800000}]})
xos rfq-responses create --data '{"rfq_id":"0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f","vendor_id":"0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f","valid_until":"2026-10-08","currency_code":"USD","lines":[{"description":"Line array, 12 boxes per side","element_id":"0000.01.01-XOS-001","quantity":2,"unit_price_minor":1800000}]}'