[PHP] Request body for Batch Archive Deals & Line Items inconsistent

The API docs for batch archiving Deals and Line Items would indicate they have consistent Schemas.

But in practice, this doesn’t seem to be the case?

Here’s a couple of snippets as an example:

 private function getClient(): Client
 {
 return new Client([
 'base_uri' => config('hubspot.base_url'),
 'headers' => [
 'Authorization' => 'Bearer ' . $this->bearerToken,
 ],
 ]);
 }

 private function getResponseBody(ResponseInterface $response): object|null
 {
 return json_decode($response->getBody()->getContents());
 }

 private function sendRequest(Request $request, array $options = []): object|null
 {
 try {
 $response = $this->getClient()->send($request, $options);
 return $this->getResponseBody($response);
 } catch (\GuzzleHttp\Exception\RequestException $e) {
 Log::error(($e->getResponse())->getBody()->getContents());
 throw $e;
 }
 }

 public function deleteDeals(int|string|array $dealIds): object|null
 {
 $dealIds = collect($dealIds)->map(fn ($id) => ['id' => (string) $id])->toArray();

 $request = new Request('POST', '/crm/v3/objects/deals/batch/archive');

 $options = [
 'json' => [
 'inputs' => $dealIds,
 ],
 ];

 Log::debug('DELETING DEALS');
 Log::debug($options);

 return $this->sendRequest($request, $options);
 }

 public function deleteLineItems(array|string|int $lineItemIds): object|null
 {
 $lineItemIds = collect($lineItemIds)->map(fn ($id) => ['id' => (string) $id])->toArray();

 $request = new Request('POST', '/crm/v3/objects/line_items/batch/archive');

 $options = [
 'json' => [
 'inputs' => $lineItemIds,
 ],
 ];

 Log::debug('DELETING LINE ITEMS');
 Log::debug($options);

 return $this->sendRequest($request, $options);
 }

And here are some of the outputs these two functions generate:

[2023-11-20 13:32:01] local.DEBUG: DELETING LINE ITEMS
[2023-11-20 13:32:01] local.DEBUG: array (
 'json' =>
 array (
 'inputs' =>
 array (
 0 =>
 array (
 'id' => '1234567',
 ),
 ),
 ),
)

[2023-11-20 13:29:23] local.DEBUG: DELETING DEALS
[2023-11-20 13:29:23] local.DEBUG: array (
 'json' =>
 array (
 'inputs' =>
 array (
 1 =>
 array (
 'id' => '9876543',
 ),
 ),
 ),
)

Now the issue here is, deleteLineItems works. No problems at all. Expected response etc.

But deleteLineItems does not. I always get an exception thrown, so this must mean that despite almost identical documentation and definitions in and out of my code, one of these functions works and the other (deleteDeals) always returns a 400 Bad Request.
Full error:

[2023-11-20 13:35:42] local.ERROR: Client error: POST https://api.hubapi.com/crm/v3/objects/deals/batch/archive` resulted in a 400 Bad Request response: {“status”:“error”,“message”:“Invalid input JSON on line 1, column 11: Cannot deserialize value of type java.util.ArrayList from Object value (token JsonToken.START_OBJECT)”,“correlationId”:“3b46c646-487b-4bb7-ac38-a822fd66a7ab”}`

I believe I’ve narrowed down this issue.

The HubSpot API is not internally capable of dealing with an array of objects if the element at index 0 is removed.

I was gathering a list of duplicated deals and removing the first item from the array before passing the duplicate IDs into the deleteDeals method. Then proceeding to update the remaining deal.

If you look at the log outputs above, you’ll notice the delete deals array starts at index 1.

The HubSpot API is not built to deal with arrays that don’t start at index 0.