nodes – Post content via JSON API: CURL works, PHP not?

I’ve got those modules enabled:

  • HAL
  • HTTP Basic Authentication
  • JSON:API
  • REST UI
  • RESTful Web Services
  • Serialization

When I run this command, the content is created.

curl 
--user demo:9aqW72MUbFQR4EYh 
--header 'Accept: application/vnd.api+json' 
--header 'Content-type: application/vnd.api+json' 
--request POST http://www.demo.drupal/jsonapi/node/article 
--data-binary @payload.json

Now I try to read via PHP, which works fine too.

require 'vendor/autoload.php';

use GuzzleHttpClient;

// Update to a user on your Drupal site that has permissions to create content
$user = 'demo';
$pass = '9aqW72MUbFQR4EYh';
$url = 'http://www.demo.drupal';

$content_client = new GuzzleHttpClient((
    'base_uri' => $url,
    'timeout'  => 20.0,
));

$res = $content_client->request('GET', '/jsonapi/node/mail/71adf560-044c-49e0-9461-af593bad0746');

$body = $res->getBody();
$stringBody = (string) $body;
var_dump(json_decode($stringBody, true));

I can’t post content. The code I am using returns a 401, 402, or 500 error.

$headers = (
  'Content-type' => 'application/vnd.api+json',
  'Accept' => 'application/vnd.api+json'
);
$payload('data') = (
  'type' => 'node--article',
  'attributes' => (
    "title" => "My custom title"
  )
); 

$guzzleResponse = $content_client->post('/jsonapi/node/article', (
  'json' => json_encode($payload),
  'headers' => $headers
));

if ($guzzleResponse->getStatusCode() == 200) {
  $response = json_decode($guzzleResponse->getBody());
}

What am I doing wrong?