post/v1/offers
Create an offer. listingIdsA is the existing listing(s) being offered ON, owned by toSellerId; listingIdsB is the listing(s) offered IN EXCHANGE, owned by fromSellerId — see docs/business/conflict-resolution-log.md item 3.
Request body
| Field | Type | Required |
|---|
| fromSellerId | string (uuid) | yes |
| toSellerId | string (uuid) | yes |
| listingIdsA | string[] | yes |
| listingIdsB | string[] | yes |
| extraAmountOffered | number | — |
| expiresAt | string (date-time) | — |
Response (201)
| Field | Type | Required |
|---|
| id | string (uuid) | — |
| fromSellerId | string (uuid) | — |
| toSellerId | string (uuid) | — |
| status | DRAFT | PENDING | ACCEPTED | REJECTED | CANCELLED | EXPIRED | COUNTERED | — |
| extraAmountOffered | numbernull | — |
| expiresAt | string,null (date-time) | — |
| createdAt | string (date-time) | — |
| offerListingsA | object[] | — |
| offerListingsB | object[] | — |
post/v1/offers/{id}/accept
Accept a PENDING offer — only the recipient (toSellerId) may accept. Does not create a trade session directly; trade-session-service reacts to the resulting offer.accepted event.
Request body
| Field | Type | Required |
|---|
| actingSellerId | string (uuid) | yes |
Response (201)
| Field | Type | Required |
|---|
| id | string (uuid) | — |
| fromSellerId | string (uuid) | — |
| toSellerId | string (uuid) | — |
| status | DRAFT | PENDING | ACCEPTED | REJECTED | CANCELLED | EXPIRED | COUNTERED | — |
| extraAmountOffered | numbernull | — |
| expiresAt | string,null (date-time) | — |
| createdAt | string (date-time) | — |
| offerListingsA | object[] | — |
| offerListingsB | object[] | — |
post/v1/offers/{id}/reject
Reject a PENDING offer — only the recipient (toSellerId) may reject
Request body
| Field | Type | Required |
|---|
| actingSellerId | string (uuid) | yes |
Response (201)
| Field | Type | Required |
|---|
| id | string (uuid) | — |
| fromSellerId | string (uuid) | — |
| toSellerId | string (uuid) | — |
| status | DRAFT | PENDING | ACCEPTED | REJECTED | CANCELLED | EXPIRED | COUNTERED | — |
| extraAmountOffered | numbernull | — |
| expiresAt | string,null (date-time) | — |
| createdAt | string (date-time) | — |
| offerListingsA | object[] | — |
| offerListingsB | object[] | — |
post/v1/offers/{id}/cancel
Cancel a DRAFT or PENDING offer — only the sender (fromSellerId) may cancel
Request body
| Field | Type | Required |
|---|
| actingSellerId | string (uuid) | yes |
Response (201)
| Field | Type | Required |
|---|
| id | string (uuid) | — |
| fromSellerId | string (uuid) | — |
| toSellerId | string (uuid) | — |
| status | DRAFT | PENDING | ACCEPTED | REJECTED | CANCELLED | EXPIRED | COUNTERED | — |
| extraAmountOffered | numbernull | — |
| expiresAt | string,null (date-time) | — |
| createdAt | string (date-time) | — |
| offerListingsA | object[] | — |
| offerListingsB | object[] | — |
post/v1/offers/{id}/counter
Counter a PENDING offer — only the recipient may counter. Creates a brand-new offer with sender/recipient roles swapped and moves the original offer to COUNTERED; the two are linked only via the offer.countered event, not a foreign key.
Request body
| Field | Type | Required |
|---|
| actingSellerId | string (uuid) | yes |
| listingIdsA | string[] | yes |
| listingIdsB | string[] | yes |
| extraAmountOffered | number | — |
| expiresAt | string (date-time) | — |
Response (201)
| Field | Type | Required |
|---|
| id | string (uuid) | — |
| fromSellerId | string (uuid) | — |
| toSellerId | string (uuid) | — |
| status | DRAFT | PENDING | ACCEPTED | REJECTED | CANCELLED | EXPIRED | COUNTERED | — |
| extraAmountOffered | numbernull | — |
| expiresAt | string,null (date-time) | — |
| createdAt | string (date-time) | — |
| offerListingsA | object[] | — |
| offerListingsB | object[] | — |