400 Bad Request Fullfillments.json

Topic summary

A developer is encountering a 400 Bad Request error when attempting to POST a fulfillment via the Shopify API.

Request Details:

  • Using the /admin/api/2022-10/fulfillments.json endpoint
  • Includes fulfillment order ID, line items, tracking information (UPS), and customer notification settings
  • PHP code shows a try-catch block handling the request with proper headers and authentication token

Solution Provided:

  • The line_items_by_fulfillment_order field expects an array rather than a single object
  • A reference to the official Shopify REST API documentation was shared for proper formatting

Status: The issue appears to be a structural formatting error in the request body. The discussion remains open pending confirmation that the array format resolves the 400 error.

Summarized with AI on November 25. AI used: claude-sonnet-4-5-20250929.

Getting 400 bad request when I try to post a fulfillment - any ideas?

This is my body

{
   "fulfillment":{
      "line_items_by_fulfillment_order":{
         "fulfillment_order_id":XXXXXXXX,
         "fulfillment_order_line_items":[
            {
               "id":1XXXXXXXX,
               "quantity":1
            }
         ]
      },
      "tracking_info":{
         "number":"XXXXXXXXXXXXX",
         "url":"https:\/\/ups.com",
         "company":"UPS"
      },
      "notify_customer":true,
      "message":"Your items have been shipped."
   }
}

This is my request

function createFulfillmentCan($data){
  $client = new Client();
  $body = json_encode($data,true);

  try {
  $response = $client->request('POST', "https://xxxxxxxxx.myshopify.com/admin/api/2022-10/fulfillments.json", [
    
    'headers' => [
      'Content-Type' => 'application/json',
      'X-Shopify-Access-Token' => 'xxxx_XXXXXXXXXXXXXXXXXXXXX'
    ],
    'body' => $body
  ]

);
   if($response->getStatusCode() == 200){
    return true;
}

  } catch(\GuzzleHttp\Exception\RequestException $e){
    return false;
  }

Hey @1010101010

The docs say that the line_items_by_fulfillment_order field takes an array, rather than an object.

Hope that helps,