Bids API ======== This document presents all the features we support via the Bids API interface. This set of features allows you, as a integrator, negotiating freight prices for carriers you manage. Main features: 1. List and Detail Bids 2. Create Bids 3. Accept Bids 4. Webhook events How each feature works? *********************** This API is an extension of Load Offers API, thus, with the results from the `Search Offers endpoint`_, it is possible to create bids. Each offer's id is used as reference when `Creating a Bid`_. After creating a bid, it can whether be awarded or not. This information will be sent via Webhook communication. With an awarded bid, it's necessary to confirm it to `Accept Bid`_. If the user doesn't want to confirm, it's just necessary to ignore it. Once the bid is awarded, it will be kept in this state for 15 minutes until it expires. Bid Statuses ************ The bid is an object that only status in mutable. It worth to mention that the bid is linked to the offer object that can be found on Load Offers API. Bid Placed ++++++++++ It is the initial bid status and happens when the bid is created. From this status, the bid can move to **awarded**, **refused** or **expired** Bid Awarded +++++++++++ Loadsmart has approved the bid and it is waiting for the carrier's confirmation. From this status, the bid can move to **accepted**, **timed out** or **expired** Bid Accepted ++++++++++++ The carrier confirmed the bid and the deal is created. This is a final status, the bid can't be moved to another status. Bid Refused +++++++++++ Loadsmart rejected the bid. This is a final status, the bid can't be moved to another status. Bid timed out +++++++++++++ The carrier didn't confirm (accepted) the awarded bid within 15 minutes. This is a final status, the bid can't be moved to another status. Bid expired +++++++++++ The offer is no longer available. This is a final status, the bid can't be moved to another status. Webhooks ******** It is highly recommended to use webhooks to get notified whenever a bid changes status. Thus, register every webhook related to bid using `Webhooks API`_ Example:: curl --request POST 'https://api.sandbox.loadsmart.com/api/v2/webhooks/url' \ --header 'Authorization: JWT ' \ --header 'Content-Type: application/json' \ --data-raw '{ "url": "https://awesome.com/bid-webhooks", "events": [ "bid:expired", "bid:timed_out", "bid:refused", "bid:awarded", "bid:accepted", "bid:countered" ] }' { "data": { "uuid": "1c946391-d46f-4fc3-a60e-9f81653e3071", "events": [ "bid:expired", "bid:timed_out", "bid:refused", "bid:awarded", "bid:accepted", "bid:countered" ], "url": "https://awesome.com/bid-webhooks" } } Bidding Scenarios ***************** The Bid API provides the ability of negotiating loads, thus, it is expected to have different scenarios depending on the result of the negotiation. In this section, the possible scenarios are covered for the bidding flow. Bid Accepted ++++++++++++ In this section is presented the two possible scenarios for bid acceptance. Acceptance via API ------------------ The following flow describes the how to create and accept a bid via API. .. mermaid:: ../assets/bid-accepted.mmd 1. Search Offers The firs step is to search for offers by reaching the `Search Offers endpoint`_. Request:: curl --request GET 'https://api.sandbox.loadsmart.com/api/v2/load-offers/offers' \ --header 'Authorization: JWT 2. Get the Offer Id With the response, select the **id** field from the offer of interest. Response:: { "count": 1030, "next": "https://api.sandbox.loadsmart.com/api/v2/load-offers/offers?page=2", "previous": null, "results": [ { "id": "cabe944e-e51b-4344-9358-c2c5c56aafd0", <-- offer id "price": 4836.0, "load": { "equipment_type": "DRV", "commodity": null, "weight": 33277.0, "dimensions": { "length": null, "height": null, "width": null }, "distance": 1458.0, "stops": [ { "type": "PU", "address": "007-DHD/PNB3-MIKE", "city": "Omaha", "state": "NE", "country": "USA", "window_start": "2021-06-04T17:34:45Z", "window_end": "2021-06-04T19:34:45Z", "window_timezone": "America/Chicago", "requirements": { "blind_bol": false, "drop_trailer": true, "heavy_scale_ticket": false, "light_scale_ticket": false }, "latitude": 41.203996, "longitude": -96.115593, "zipcode": "68137", "facility_info": { "avg_time_spent": { "pickup": null, "delivery": 0 }, "detention_rate": 0 } }, { "type": "DEL", "address": "02186", "city": "Milton", "state": "MA", "country": "USA", "window_start": "2021-06-06T17:34:45Z", "window_end": "2021-06-06T19:34:45Z", "window_timezone": "America/New_York", "requirements": { "blind_bol": false, "drop_trailer": true, "heavy_scale_ticket": false, "light_scale_ticket": false }, "latitude": 42.233283, "longitude": -71.085432, "zipcode": "02186", "facility_info": { "avg_time_spent": { "pickup": 0, "delivery": 0 }, "detention_rate": 0 } } ], "requirements": { "beer": false, "chemicals": false, "ctpat": false, "food_grade": false, "frozen": false, "hazmat": false, "hvhr": false, "pharmaceuticals": false, "produce": false, "teams": false, "tsa": false, "twic": false, "vented_vans": false }, "ref_number": "158120" }, "actions": { "redirect_url": "https://carrier.sandbox.loadsmart.com/#/loads/02810766-a8f7-4e76-8a0d-e673835abc9b?utm_source=awesome-partner", "accept_url": "https://api.sandbox.loadsmart.com/api/v2/load-offers/offers/cabe944e-e51b-4344-9358-c2c5c56aafd0/accept" } },... ] } 3. Create Bid With the **Offer Id**, it is possible to create a bid for the load that is been offered by calling the `Creating a Bid`_ endpoint, as the example below. Request:: curl --request POST 'https://api.sandbox.loadsmart.com/api/v2/load-offers/bids' \ --header 'Authorization: JWT ' \ --header 'Content-Type: application/json' \ --data-raw '{ "offer_id": "cabe944e-e51b-4344-9358-c2c5c56aafd0", "price": "5000.00" }' 4. Get the Bid Id Once the bid is created, its status is **pending**. It means that is under review. Response:: { "id": "8800b633-a91c-4008-9e08-74a991bdb621", <-- Bid Id "offer_id": "cabe944e-e51b-4344-9358-c2c5c56aafd0", "created_at": "2022-10-05T13:30:01.785660Z", "expires_at": null, "expired_at": null, "price": "5000.00", "status": "pending" } 5. Receiving Bid Awarded webhook When a bid gets approved by Loadsmart side, the **bid:awarded** webhook even will be triggered. At this moment, the bid status is **awarded** and it is waiting for the acceptance by the Partner's side. Webhook:: { "created_at": "2022-10-05T13:30:01.785660Z", "type": "bid:awarded", "details": { "id": "8800b633-a91c-4008-9e08-74a991bdb621", "offer_id": "cabe944e-e51b-4344-9358-c2c5c56aafd0", "price": "5000.00", "created_at": "2022-10-05T13:30:01.785660Z", "expires_at": "2022-10-05T13:55:36.627695Z", "expired_at": null, "status": "awarded" } } 6. Accept Bid The acceptance is performed by calling the `Accept Bid`_ endpoint. Request:: curl --request POST 'https://api.sandbox.loadsmart.com/api/v2/load-offers/bids/8800b633-a91c-4008-9e08-74a991bdb621/accept' \ --header 'Authorization: JWT ' \ --header 'Content-Type: application/json' \ --data-raw '{ "offer_id": "cabe944e-e51b-4344-9358-c2c5c56aafd0", "price": "5000.00" }' 7. Get Load Id By calling the `Accept Bid`_ endpoint, the response is the **Load Id**. Similarly to the endpoint `Accept an Offer`_ behavior. Response:: { "id": "02810766-a8f7-4e76-8a0d-e673835abc9b" } 8. Bid Accepted Webhook After the acceptance, the webhook **bid:accepted** is emitted. Webhook:: { "created_at": "2022-10-05T13:30:01.785660Z", "type": "bid:accepted", "details": { "id": "8800b633-a91c-4008-9e08-74a991bdb621", "offer_id": "cabe944e-e51b-4344-9358-c2c5c56aafd0", "price": "5000.00", "created_at": "2022-10-05T13:30:01.785660Z", "expires_at": "2022-10-05T13:55:36.627695Z", "expired_at": null, "status": "accepted" } } Acceptance via Loadsmart ------------------------ This flow is similar to the previous one, but the acceptance. Once the bid is created, the user can accept it over Loadsmart platforms (web or mobile). In any case, the bid will keep linked to the platform that created it. It means that it is expected to receive the **bid:accepted** webhook event and it will be necessary to check the accepted load on `List Loads`_ endpoint. .. mermaid:: ../assets/bid-accepted-2.mmd Bid Refused +++++++++++ Loadsmart can refuse bids that are placed by carriers. When it happens, the webhook event **bid:refused** will be sent. .. mermaid:: ../assets/bid-refused.mmd With the steps 1, 2, 3, and 4 already described in the **Bid Accepted** section. 5. Bid Refused The bid that was created will be refused, thus, it is expected to receive the event **bid:refused** and its status will be **refused**. Webhook:: { "created_at": "2022-10-05T14:15:09.966432Z", "type": "bid:refused", "details": { "id": "8a079e13-f54e-4e6f-9bc6-ab979c5a7c74", "offer_id": "61a4ad77-887a-4d4d-826b-1c19a0372899", "price": "4000.00", "created_at": "2022-10-05T14:15:09.966432Z", "expires_at": null, "expired_at": null, "status": "refused" } } Bid countered +++++++++++++ .. note:: The counter bid feature is optional and disabled by default. Please let Loadsmart team know if you are interested in activating it. Similarly to what happens on in-person freight negotiation, the carrier sales can propose a new price when the carrier's dispatcher is trying to get a better price for a certain shipment. The counter bid happens when Loadsmart answers the created bid with a new bid with a different value. When a counter bid is created, its status will be **awarded**. Also, it is expected to receive the event **bid:countered**. Webhook:: { "created_at": "2022-10-05T14:15:09.966432Z", "type": "bid:countered", "details": { "previous_bid_id": "8a079e13-f54e-4e6f-9bc6-ab979c5a7c74", <-- the countered bid id "id": "06774f6d-3f1d-41a1-b74e-503b36e14d6e", <-- the counter bid id "offer_id": "61a4ad77-887a-4d4d-826b-1c19a0372899", "price": "4000.00", "created_at": "2022-10-05T14:15:09.966432Z", "expires_at": null, "expired_at": null, "status": "awarded" } } Accepting a counter bid ----------------------- .. mermaid:: ../assets/bid-countered.mmd You can accept a counter bid by following the step 6 described in the **Bid Accepted** section. Rejecting a counter bid ----------------------- When the counter bid is not interesting for the Partner's side, it is necessary to just ignore the **bid:countered** event. If a new bid is created to the same Load Offer, the webhook event **bid:expired** will be sent, otherwise, after 15 minutes the **bid:timed-out** will be sent. .. mermaid:: ../assets/bid-countered-2.mmd Bid Timed Out +++++++++++++ Once the bid is awarded, it will be available for 15 minutes. If the bid is not accepted during this period, the bid will be expired. .. mermaid:: ../assets/bid-timed-out.mmd The initial process described by steps 1 to 5 are the same described in the **Bid Accept** section. With the 15 minutes with no acceptance, the webhook event **bid:timed-out** will be sent, and the bid will transact to status **timed-out**. Webhook:: { "created_at": "2022-10-05T16:35:22.064834Z", "type": "bid:timed_out", "details": { "id": "de1bef1e-fc98-459c-96d1-92292380850a", "offer_id": "5fcf13ba-7163-4b49-8109-fc8ab8ad91b9", "price": "4000.00", "created_at": "2022-10-05T16:35:22.064834Z", "expires_at": "2022-10-05T16:50:33.622548Z", "expired_at": "2022-10-05T17:03:22.230276Z", "status": "timed_out" } } Bid Expired +++++++++++ The bid can be expired when the Load Offer is no longer available. This event can happen in any moment of the negotiation after the bid creation to a final bid state. The following diagrams shows a couple of examples that can happen for this scenario. .. mermaid:: ../assets/bid-expired-1.mmd .. mermaid:: ../assets/bid-expired-2.mmd For any case, receiving the **bid:expired** webhook event moves the bid status to the **expired** status. Webhook:: { "created_at": "2022-10-05T17:33:20.642590Z", "type": "bid:expired", "details": { "id": "d8d75030-2c7e-494e-b6eb-9e55ca8faa5f", "offer_id": "8ea25648-8741-4d22-ab0e-332ee96555ed", "price": "4001.00", "created_at": "2022-10-05T17:33:20.642590Z", "expires_at": null, "expired_at": "2022-10-05T17:34:21.666473Z", "status": "expired" } } .. _Search Offers endpoint: https://developer.loadsmart.com/api/#tag/Load-Offers/paths/~1api~1v2~1load-offers~1offers/get .. _Creating a Bid: https://developer.loadsmart.com/api/#tag/Bids/paths/~1api~1v2~1load-offers~1bids/post .. _Accept Bid: https://developer.loadsmart.com/api/#tag/Bids/paths/~1api~1v2~1load-offers~1bids~1%7Bbid_id%7D~1accept/post .. _Accept an Offer: https://developer.loadsmart.com/api/#tag/Load-Offers/paths/~1api~1v2~1load-offers~1offers~1%7Boffer_id%7D~1accept/post .. _List Loads: https://developer.loadsmart.com/api/#tag/Load-Offers/paths/~1api~1v2~1load-offers~1loads~1/get .. _Webhooks API: https://developer.loadsmart.com/api/#tag/Webhooks