/**
  * @test
  */
 public function should_upload_an_article_and_respond_with_article_instance()
 {
     $responseMock = $this->createResponseMock(200, __DIR__ . '/../../fixtures/articles/uploaded.json');
     $apiClient = $this->createTestApiClient($responseMock);
     $article = new UploadArticle();
     $article->setCollectionId(uniqid());
     $article->setName(uniqid('Uploaded Article '));
     $article->setFile(__DIR__ . '/../../fixtures/articles/article.html');
     $uploaded = $apiClient->uploadArticle($article, true);
     $this->assertInstanceOf(Article::class, $uploaded);
 }
<?php

use HelpScoutDocs\DocsApiClient;
use HelpScoutDocs\Models\UploadArticle;
require_once __DIR__ . '/../vendor/autoload.php';
$docsClient = new DocsApiClient();
$docsClient->setKey('API_KEY');
$upload = new UploadArticle();
$upload->setCollectionId('COLLECTION_ID');
$upload->setName(uniqid('Uploaded Article '));
$upload->setFile('REAL_PATH_TO_FILE');
$article = $docsClient->uploadArticle($upload, true);
 /**
  * @param UploadArticle $uploadArticle
  * @param bool $reload
  * @return bool|Article
  * @throws ApiException
  */
 public function uploadArticle(UploadArticle $uploadArticle, $reload = false)
 {
     if (!file_exists($uploadArticle->getFile())) {
         throw new ApiException(sprintf("Unable to locate file: %s", $uploadArticle->getFile()));
     }
     $multipart = [['name' => 'key', 'contents' => $this->apiKey], ['name' => 'collectionId', 'contents' => $uploadArticle->getCollectionId()], ['name' => 'file', 'contents' => fopen($uploadArticle->getFile(), 'r')], ['name' => 'categoryId', 'contents' => $uploadArticle->getCategoryId()], ['name' => 'slug', 'contents' => $uploadArticle->getSlug()], ['name' => 'type', 'contents' => $uploadArticle->getType()], ['name' => 'reload', 'contents' => $reload]];
     $response = $this->doPostMultipart("articles/upload", $multipart);
     $articleData = (array) $response;
     return $reload ? new Article(reset($articleData)) : true;
 }