DEV Community


Posted on • Originally published at


Download HelloSign Documents using Laravel

Ever need to download all HelloSign documents with Laravel without the SDK? It can be done by basic HTTP requests with an API key generated by HelloSign.

Things used

  1. Laravel's built in HTTP Client (Guzzle)
  2. Jobs to avoid HelloSign API rate limits
  3. Functions will be placed in routes file instead of a controller (to prototype faster)


  1. Get API key from HelloSign

  2. Add the api to the .env file

  3. Create hellosign.php in the config folder

    return [
      'api_key' => env('HELLO_SIGN_API_KEY')
  4. Create a migration create_signature_requests_table for the HelloSign document ids and add the following columns

  5. Create a model SignatureRequest and add the following

  6. Go to routes/web.php and add the following

    use App\Jobs\DownloadJob;
    Route::get('/', function () {
      $api_key = config('hellosign.api_key');
      $page = 1;
      $total_pages = 99; // just a temporary high number
      while($page <= $total_pages) {
          // max out the per page and documents from all accounts
          $response = Http::get("https://{$api_key}{$page}");
          $object = $response->object();
          // set the number of total pages of documents
          if($page == 1) {
              $total_pages = $object->list_info->num_pages;
          // loop through each result and get the signature_request_id if it exists
          foreach($object->signature_requests as $sig) {
                  SignatureRequest::create(['signature_request_id' => $sig->signature_request_id]);
          // increase the page
    Route::get('download', function() {
      // get all signature ids that are not downloaded yet
      $sigs = SignatureRequest::where('downloaded', false)->get();
      // chunk it into 20, HelloSign API limits 25 requests per minute
      $chunks = $sigs->chunk(20);
      // wait in minutes
      $wait = 0;
      foreach($chunks->all() as $chunk) {
          foreach($chunk as $sig) {
              // dispatch the download job and delay it by now + minutes
              dispatch(new DownloadJob($sig))->delay(now()->addMinutes($wait));
          // increase wait time
  7. Create a job DownloadJob and update with the following

    namespace App\Jobs;
    use Illuminate\Support\Facades\Http;
    use Illuminate\Support\Facades\Storage;
    use App\Models\SignatureRequest;
    public $sig;
      public function __construct(SignatureRequest $sig)
          $this->sig = $sig;
      public function handle()
          $api_key = config('hellosign.api_key');
          // request the document
          $response = Http::get("https://{$api_key}{$this->sig->signature_request_id}");
          // only download if response code is 200
          if($response->status() == 200) {
            // save the document into a `documents` folder in storage with the document id as it's file name
            Storage::put("documents/{$this->sig->signature_request_id}.pdf", $response->body() );
            // update db to downloaded
            $this->sig->downloaded = true;
  8. Run the migrations with php artisan migrate

  9. Start the queue with php artisan queue:work

  10. Go to localhost in the browser to start getting the all the document ids

  11. Once #10 is finished, in the browser go to localhost/download to add put the download into the queue

  12. Wait until the queue is clean and go back to #11 to make sure it's finished (repeat as many times as needed)

Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.