Bids
Place bids on inventory programmatically and read your team's bids. Placing a bid requires the bids.write scope and a token bound to a team via Login with MGX. Reading uses bids.read.
The counterparty (seller) on a bid stays null until both invoices on the resulting trade are paid.
Place a bid
Place a bid on a listing. MGX runs the same credit, payment, and eligibility rules as the web app. Pass an Idempotency-Key header to make retries safe.
Body
- Name
price- Type
- object
- Description
- amount in MT — for graded listings.
- Name
bids- Type
- array
- Description
- [ grade, price ] — for ungraded (multi-grade) listings.
- Name
quantity_mt- Type
- number
- Description
- Quantity in tonnes (required).
- Name
delivery- Type
- object
- Description
- from, to ISO dates (required).
- Name
fob_farm- Type
- boolean
- Description
- Defaults true.
- Name
delivery_location_id- Type
- integer
- Description
- Required when not FOB.
- Name
subject_to_sample_approval- Type
- boolean
- Description
- Name
additional_terms- Type
- string
- Description
- Free text (moderated).
- Name
expires_at- Type
- string
- Description
- ISO datetime; defaults to +7 days.
Request
curl https://api.mygrainexchange.com/v1/inventory/inv_3Kd9aZ/bids \
-H "Authorization: Bearer {token}" \
-H "Idempotency-Key: 7f1c..." \
-H "Content-Type: application/json" \
-d '{
"price": { "amount": 308.00, "unit": "MT" },
"quantity_mt": 86.0,
"delivery": { "from": "2026-08-15", "to": "2026-09-15" },
"fob_farm": true
}'
Response
{
"data": {
"id": "bid_7Qp2",
"reference": "BID-10482",
"inventory_id": "inv_3Kd9aZ",
"status": "pending",
"price": { "amount": 308.0, "currency": "CAD", "unit": "MT" },
"quantity_mt": 86.0,
"counterparty": null
}
}
List your bids
Bids placed by your team. Filter with status (pending, accepted, rejected, countered, expired). Poll this to discover lifecycle changes (e.g. a lot delisting).
Request
curl https://api.mygrainexchange.com/v1/bids?status=pending \
-H "Authorization: Bearer {token}"
Get a bid
Retrieve one of your team's bids by id. Returns 404 if it does not belong to your team.
Request
curl https://api.mygrainexchange.com/v1/bids/bid_7Qp2 \
-H "Authorization: Bearer {token}"
Respond to a counter-offer
When a seller counters your bid (the bid.countered webhook), respond with one of:
Accept
Accept the counter. This creates a trade and invoices. 404 if the bid is not your team's, 422 if it is not pending.
Request
curl -X POST https://api.mygrainexchange.com/v1/bids/bid_7Qp2/accept \
-H "Authorization: Bearer {token}"
Reject
Decline the counter.
Request
curl -X POST https://api.mygrainexchange.com/v1/bids/bid_7Qp2/reject \
-H "Authorization: Bearer {token}"
Counter back
Send your own counter. Same body shape as placing a bid (price, quantity, delivery).
Request
curl -X POST https://api.mygrainexchange.com/v1/bids/bid_7Qp2/counter \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{ "price": { "amount": 305.0, "unit": "MT" }, "quantity_mt": 86.0, "delivery": { "from": "2026-08-15", "to": "2026-09-15" }, "expires_at": "2026-06-25T17:00:00Z" }'
List your delivery locations
Elevators bidding for delivered grain (not FOB farm) must name one of their own delivery locations. List them here, then pass the integer id as delivery_location_id when placing the bid. FOB-farm bids need no location.
Request
curl https://api.mygrainexchange.com/v1/delivery-locations \
-H "Authorization: Bearer {token}"