Labor API

Build With the Labor API

Use the Labor API to capture the start and end of an employee shift, and the hourly rate for the shift.

Languages Supported
Additional Resources
PHP (Connect SDK)
Connect SDK
Command Line
Save

Prerequisites

This document provides step-by-step guidance for integrating with the Labor API. For information on how the Labor API works, please read the Labor API How it Works guide.

To use the Labor API, the following must be true:

  • You have a Square account. Create a Square account in minutes if you do not already have one.
  • You have added employees to at least one location in the Square Dashboard
  • Your Labor API integration component is hosted on systems that support dynamic pages with server-side processing (e.g., PHP, Ruby, ASP, or Java pages). Hosting solutions that support only HTML pages cannot use the Labor API

Assumptions

This guide makes the following assumptions:

  • The Square Dashboard for your account has at least 1 active employee.
  • You have assigned at least one wage type per employee in the Square Dashboard.
  • You are using the Connect v2 PHP SDK on GitHub.

Shift time tracking at a glance

This guide walks you through the process of starting and ending an employee shift:

Open a new shift

  1. Configure the labor API with a valid access token and location ID.
  2. Get an employee ID.
  3. Get the wage type for the job to be done on the shift.
  4. Check for a previous open shift for the employee.
  5. Create and send a CreateShift request to start a shift.

End the shift

  1. Search for the open shift.
  2. Update the open shift with an end time to end it.

Configure the Labor API

Before you can use the Labor API, you must set the Location ID where the API is used and then authorize the API to access Shift and Employee resources for that location.

Step 1: Get your authorization ID

We recommend using a Personal Access Token and locations for testing and development. To get your Personal Access Token ID:

  1. Open your Application Dashboard
  2. If you DO have an application you want to use for managing employee shifts, click on the application.
  3. If you DO NOT have an application you want to use for managing employee shifts, click New Application, enter a name for your application (for example, "My Timeclock") and click Create Application.
  4. Copy the Personal Access Token on the Credentials tab of the application control panel

Instead of a personal access token, you can also use OAuth and the EMPLOYEES_READ and TIMECARDS_WRITE permissions.

Step 2: Set the API client configuration

No content

Initialize the API client with the default configuration and provide your access token to the client.

// Include the Square Connect API resources
require_once '/local/path/to/sdk/SquareConnect/autoload.php';

$authzToken = "MY_PERSONAL_ACCESS_TOKEN";   // put your access token here
$locationId = "";                 // we'll set this programmatically

// Create and configure a new API client object
$defaultApiConfig = new \SquareConnect\Configuration();
$defaultApiConfig->setAccessToken($authzToken);
$defaultApiClient = new \SquareConnect\ApiClient($defaultApiConfig) ;

Step 3: Get your location ID

All employee shifts processed with the Labor API must be associated with a valid location ID for the associated Square account. Use the Locations API to find your location ID:

Search for the location where the employee shift is starting. Use the Location.id for the Labor API operations in this guide.

Open a new shift

Step 1: Get an employee to start the shift

Retrieve a list of active employees for a location and select an employee from the list.

Use the following cURL command to get active employees for a location

Curl https://connect.squareup.com/v2/employees?location_id=YOUR_LOCATION_ID \
 -H 'Content-Type: application/json'                       \
 -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'     \

The response carries an array of Employee

{
    "employees": [
        {
            "id": "EMPLOYEE_ID",
            "first_name": "Babe",
            "last_name": "Ruth",
            "location_ids": [
                "YOUR_LOCATION_ID"
            ],
            "status": "ACTIVE",
            "created_at": "2019-02-19T21:52:48Z",
            "updated_at": "2019-02-19T21:55:16Z"
        }
    ]
}

SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken('YOUR_ACCESS_TOKEN');
$employeesApi = new SquareConnect\Api\EmployeesApi();

 //Get the first page of active employees and show in a list
 $listEmployeeResponse = $employeesApi->listEmployees(
                                           $locationId,
                                           "ACTIVE",
                                           $pageSize,
                                            $cursor);
 // add the results to a selectable list
 //Get next page of active employees until all pages have been processed
 while ($listEmployeeResponse->getCursor() != NULL) {
   $listEmployeeResponse = employeesApi->listEmployees(
     'YOUR_LOCATION_ID',
     "ACTIVE",
     $pageSize,
     $listEmployeeResponse->getCursor());
   // add the results to a selectable list
 }

Step 2: Get the employee wage types

An Employee can have multiple wage types. To assign the correct wage to a shift, get all of the EmployeeWage object for the employee and find the wage type for the job that the employee is performing in this shift.

Curl https://connect.squareup.com/v2/labor/employee-wages?employee_id=EMPLOYEE_ID \
 -H 'Content-Type: application/json'                       \
 -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'     \

The response carries an array of the EmployeeWage objects associated with an employee ID.

{
    "employee_wages": [
        {
            "id": "2Hm55mLKx3q1GyLUAAxhjim8",
            "employee_id": "EMPLOYEE_ID",
            "title": "Photographer",
            "hourly_rate": {
                "amount": 4500,
                "currency": "USD"
            }
        }
    ]
}
   //Call the LaborApi list endpoint to get a list of
   //wages for the specified employee and return the first 10 wage types
   $wagesResults = $this->laborApi->listEmployeeWages(
     $employeeID, 10, NULL);

   //If the results contain employee wages then iterate over the
   //wages until a wage that matches by job title is found.
   //Return the matching wage.
   //If no EmployeeWage items are returned in the results,
   //the getEmployeeWages method is NULL. 
   if (method_exists( $wagesResults,'getEmployeeWages')) {
     foreach($wagesResults->getEmployeeWages() as $employeeWage){
       if (strcmp($employeeWage->getTitle(),$jobTitle) == 0){
         return $employeeWage;
       }
     }
   }

Step 3: Check for an open Shift

A new shift cannot be started for an employee until the previous shift is ended.

The following shift search request asks for a set of shifts with the following instructions:

  • Shifts for one specified employee
  • At a specified location
  • With shifts whose status is "OPEN"
curl https://connect.squareup.com/v2/labor/shifts/search \
 -H 'Content-Type: application/json'                       \
 -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'     \
 -d '{
        "query": {
                "filter": {
                        "status": "OPEN", 
                        "employee_id": ["AN_EMPLOYEE_ID"]
                }
        }
}'

The response to the shift search request is an empty object if the employee does not have an OPEN shift.

{}

When checking for an open shift, use code like the following example and provide the ID of the employee associated with the open shift.

   $shiftQuery = new SquareConnect\model\ShiftQuery();
   $shiftFilter = new SquareConnect\model\ShiftFilter();
   $searchShiftsRequest = new SquareConnect\model\SearchShiftsRequest();
   $employees = Array("EMPLOYEE_ID");
   $shiftFilter->setEmployeeId($employees);
   $shiftFilter->setStatus("OPEN");
   $shiftQuery->setFilter($shiftFilter);
   $searchShiftsRequest->setQuery($shiftQuery);
   $searchShiftsResponse = $laborApi->searchShifts($searchShiftsRequest);
   if (method_exists($searchShiftsResponse,'getShifts')) {
      $openShift = $searchShiftsResponse->getShifts()[0];
    }

Step 4: Build a shift object

To create a new shift, use the location ID, employee ID, and EmployeeWage hourly rate to set values in a new ShiftWage. The shift start_at field can be set to local time or GMT. If GMT, Square's Labor endpoint calculates the local time based on the location of the shift.

POST a new shift using cURL at the command line.

curl https://connect.squareup.com/v2/labor/shifts \
 -H 'Content-Type: application/json'                       \
 -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'     \
 -d '{
        "idempotency_key": "UUID",
        "shift": {
                "employee_id": "AN_EMPLOYEE_ID",
                "location_id": "YOUR_LOCATION_ID",
                "start_at": "2019-02-05T12:00:00Z", 
                "wage": { 
                        "title": "Photographer",
                        "hourly_rate": {
                                "amount": 4500,
                                "currency": "USD"
                                }
                }
        }
}'

Create a Shift object and set the location ID, employee ID, shift wage, and start time.

   $shift = new SquareConnect\Model\Shift();
   $shift->setEmployeeId($employeeID);
   $shift->setLocationId($locationId);
   $shift->setStartAt(date(DATE_ATOM, time()));  //Set start time to now UTC time.
   $shiftWage = new SquareConnect\Model\ShiftWage();
   $shiftWage->setHourlyRate($employeeWage->getHourlyRate());
   $shiftWage->setTitle($employeeWage->getTitle());
   $shift->setWage($shiftWage);

Step 5: Call CreateShift

To request the new shift, create a new CreateShiftRequest, set the idempotency key, and then set the $shift object in the body of the request. On completion of the operation, a Shift is returned with server-calculated field values.

No content

   $laborApi = new SquareConnect\Api\LaborApi();
   $body = new \SquareConnect\Model\CreateShiftRequest();
   $body->setIdempotencyKey(uniqid());
   $body->setShift($shift);
   $shiftResponse = $laborApi->createShift($body);

Close the shift

Step 1: Get the Shift to close

Get the open shift for the employee by using the example in Step 3.

The response to the shift search request is an array of Shift objects that match the filter criteria.

{
    "shifts": [
        {
            "id": "3DBHNF9E8CG27",
            "employee_id": "AN_EMPLOYEE_ID",
            "location_id": "YOUR_LOCATION_ID",
            "timezone": "America/Los_Angeles",
            "start_at": "2018-10-04T04:00:00-07:00",
...
            "status": "OPEN",
            "version": 1,
            "created_at": "2019-02-20T01:28:49Z",
            "updated_at": "2019-02-20T01:28:49Z"
        }
    ]
}

   if (method_exists($searchShiftsResponse,'getShifts')) {
      $openShift = $searchShiftsResponse->getShifts()[0];
    }

Step 2: Update the Shift and call UpdateShift.

To close a shift, an end_at field is added to$openShift. If the shift has an open break, it must be closed before the shift can be closed.

curl https://connect.squareup.com/v2/labor/shifts/3DBHNF9E8CG27 \
 -H 'Content-Type: application/json'                       \
 -H 'Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN'     \
 -D '{
    "shift": {
        "id": "3DBHNF9E8CG27",
        "employee_id": "aq8XS-F0-VA0UrgH6h3w",
        "location_id": "YOUR_LOCATION_ID",
        "timezone": "America/Los_Angeles",
        "start_at": "2018-10-16T04:00:00-07:00",
        "end_at": "2018-10-16T12:00:00Z",
        "wage": {
            "title": "Photographer",
            "hourly_rate": {
                "amount": 4500,
                "currency": "USD"
            }
        },
        "status": "OPEN",
        "version": 3,
        "created_at": "2019-02-21T20:22:10Z",
        "updated_at": "2019-02-21T20:24:34Z"
    }
}
'

Before you POST the updated Shift, look for an array of Break objects that will be present if the employee took any breaks during the shift. If you find these object, confirm that they contain end_at properties and that those properties are not null.

The response is an updated version of the Shift object with a CLOSED status and an incremented version number:

{
    "shift": {
        "id": "3DBHNF9E8CG27",
...
        "start_at": "2018-10-16T04:00:00-07:00",
        "end_at": "2018-10-16T12:00:00-07:00",
...
        "status": "CLOSED",
        "version": 4,
...
    }
}

Update the $openShift with the following operations:

  • Set the $openShift end_at timestamp
  • Look for any open Break items. If break with no end time is found, the shift cannot be closed. You may close the break by setting the Break.end_at field to the $openShift end_at time or if the actual break end time if known.
  • Create an $UpdateShiftRequest, set the shift value with $openShift, and then send the request.
    //Close the open shift by setting the end timestamp
    $openShift->setEndAt(date(DATE_ATOM, time()));
    //Iterate shift breaks to find an open break and then 
    //close the break if open.
    if (method_exists($openShift,'getBreaks')) {
      foreach($openShift->getBreaks() as $break) {
        if (!method_exists($break,'getEndAt')) {
          $break->setEndAt(date(DATE_ATOM, time()));
        }
      }
    }

    $updateShiftRequest = new SquareConnect\Model\UpdateShiftRequest();
    $updateShiftRequest->setShift($openShift);
    $updatedShift = $laborApi->updateShift(
      $openShift->getId(),
       $updateShiftRequest);
Prev
< How it Works
Next
Add a break to an open shift >

Contact Developer Support, join our Slack channel, or ask for help on Stack Overflow