Sep 2, 2015 - Brandon Barnes

Embed eSignature requests easily and quickly into your Laravel app using HelloSign

HelloSign is a service that provides for legally binding eSignatures for business. While you can use their service directly through their site, they also have an API that can be used to embed eSignature requests into your own site.

Integrating HelloSign into a Laravel app is made even easier as they provide a php SDK that wraps their API. This example is using Laravel 4.2, but should be pretty similar to what you'll need to do for Laravel 5.x.

1) Add the HelloSign php SDK via composer at the command line:


composer require "hellosign/hellosign-php-sdk:3.*@dev"


2) Create a basic callback route in routes.php that returns the success message that HelloSign is looking for. This will be expanded in a later step.


Route::post('hellosign-callback', function()
 return "Hello API Event Received";


3) Deploy your application somewhere publicly so that the HelloSign servers can access it.


4) Create or login into your HelloSign account and then create a HelloSign application through the API section of the settings at For the callback, point to your route defined in routes.php  earlier. If everything is configured correctly then HelloSign should be able to do a test POST and give back a success message. Record your Client ID and App ID for later.


5) Create a new template through the HelloSign admin at and record the Template ID for later. For this example, we will assume there will be one signer with role "Student". Note that you can do embedded signature request without a template, but having the template makes things much easier to work with for the developer and the end user.


6) Add environmental variables to your local environment. Alternatively, you could put these values into a configuration file but this example will assume environmental variables going forward. You should have the following defined at this point:


'HELLOSIGN_API_KEY' => 'Your64CharacterAPIKey',
'HELLOSIGN_CLIENT_KEY' => 'Your32CharacterClientKey',
'HELLOSIGN_EMAIL' => '[email protected]',
'HELLOSIGN_NAME' => 'Test HelloSign User',
'HELLOSIGN_TEMPLATE_ID' => 'Your40CharacterTemplateID',


7) In your app, add the code that will embed the template signature request. This could be put in your `routes.php` or in a controller you've defined for your app.


// Create the HelloSign client object that will
$client = new HelloSign\Client(getenv('HELLOSIGN_API_KEY'));
// Retrieve signature_request_id from database, or create a new one.
// In this example we will assume Student has an attribute for signature_request_id.
$student = Student::getCurrentStudent();
$request = new HelloSign\TemplateSignatureRequest;
if (getenv('HELLOSIGN_TEST_MODE') == 1)
// If you set a custom field in the template, you would add it here.
// The field_name parameter is the label in the template.
// $request->setCustomFieldValue('student_id', $student->id);
// Add who will be signing. Email and name are required.
$request->setSigner('Student', $student->email, $student->full_name));
// If needed by your template, you would add additional signers here.
// $request->setSigner('Customer', $customer->email, $customer->full_name);
// Check to see if the student has already started the signature request
// before creating a new one.
if (empty($student->signature_request_id))
 // Create the embedded request.
 $embedded_request = new HelloSign\EmbeddedSignatureRequest($request, getenv('HELLOSIGN_CLIENT_KEY'));
 $response = $client->createEmbeddedSignatureRequest($embedded_request);
 // At this point you should save the signature request id.
 // Get it like this:
 $signature_request_id = $response->getId();
 // In order to actually show the request, you need the signature
 // id of the person who needs to sign.
 // First, get a list of all signers.
 $signatures = $response->getSignatures();
 // Then, get the "Student" signature id.
 $signature_id = $signatures[0]->getId();
 // You could save the signature_id if needed but it's not required to
 // show the embedded signature again.
 // Note that this is different than the signature_request_id.
 $student->signature_request_id = $signature_request_id;
 $student->signature_id = $signature_id;
 // This is not the first time we are showing this signature request,
 // we need to check if it was already completed.
 // Otherwise, you will get an error.
 $signature_request = $client->getSignatureRequest($signature_request_id);
 if ($signature_request->isComplete())
   return Redirect::action('StudentController@getIndex')
       'message' => 'This agreement has already been signed.'
// Retrieve the URL to sign the document.
// This will be used in the javascript.
$response = $client->getEmbeddedSignUrl($signature_id);
$sign_url = $response->getSignUrl();
// Send values to the View.
return View::make('students.agreement')
     ->with('sign_url', $sign_url);


8) Next create the view that will show the embedded signature request. Where you put these sections will depend on your Views setup. This example assumes that you are using a layout.


 <div id="hs-container"></div>
 <script type="text/javascript" src=""></script>
 <script type="text/javascript">
   HelloSign.init("{{ getenv('HELLOSIGN_CLIENT_KEY') }}");{
     // Set the sign_url passed from the controller.
     url: "{{ $sign_url }}",
     allowCancel: false,
     redirectUrl: '{{ route('sign-agreement') }}',
     skipDomainVerification: false,
     height: 800,
     // Set the debug mode based on the test mode toggle.
     debug: {{ (getenv('HELLOSIGN_TEST_MODE') == 1 ? "true" : "false") }},
     // Point at the div we added in the content section.
     container: document.getElementById("hs-container"),
     // Define a callback for processing events.
     messageListener: function(e) {
       if (e.event == 'signature_request_signed') {
         // Process what to do once they are finished signing.


9) Expand the callback route you defined earlier to process HelloSign events. What you do with these events is up to your app requirements. You can see a list of the event types that HelloSign will send at In this example, we will download the fully signed document once it is ready and ignore any other events.


Route::post('hellosign-callback', function()
  // Get the json object sent by HelloSign.
  $data_input = Input::all();
  $data = json_decode($data_input['json']);
  // Get the event type.
  $event_type = $data->event->event_type;
  // The signature_request_all_signed event is called whenever the signature
  // request is completely signed by all signees, HelloSign has processed
  // the document and has it available for download.
  if ($event_type == 'signature_request_all_signed')
    $client = new HelloSign\Client(getenv('HELLOSIGN_API_KEY'));
    // Here you define where the file should download to. This should be
    // customized to your app's needs.
    $file_path = "/tmp/{$signature_request_id}.pdf";
    $client->getFiles($signature_request_id, $file_path, 'pdf');
  // Always be sure to return this response so that HelloSign knows
  // that your app processed the event successfully. Otherwise, HelloSign
  // will assume it failed and will retry a few more times.
  return "Hello API Event Received";


And that's all you’ll need for doing a basic embedded eSignature workflow for your application. Take note that in order to take your application out of the HelloSign test mode and have the documents be legally binding you'll need to sign up for their API pricing and have your app approved by their team after a screenshare. From my experience, this approval process was very friendly, painless, and they had approved our application before we were even off the call.

HelloSign API
HelloSign PHP SDK