Note: This feature requires technical understanding of using the API.
The scheduler provides a useful way to run tasks on periodic basis. Most commonly it is used to render looks or dashboards and email the results to a recipient, or it can be used to place the results as a file in an S3 or sftp destination.
The scheduling is fairly flexible, but is based on times and dates. This sample code uses the API to execute the same kind of scheduled job based on some external trigger. For example, an ETL job might load data into a database. When the load is done, the orchestration software might use a script like this to kick off jobs based on the newly loaded data.
This sample code is produced using standard Unix/Linux shell scripting methods and utilities. The only tool that is not extremely common to experienced Unix programmers and operators is the jq utility. jq stands for JSON Query and allows one to parse JSON documents and extract particular values from the command line. It is available from standard repositories on many platforms include Debian/Ubuntu Linux, Fedora, OpenSuse, etc. For information go to https://stedolan.github.io/jq/download/.
The Looker API can be accessed not only though the simple shell scripting utilities as shown here, but from more advanced languages. Looker provides an Ruby based SDK. Swagger provides a method to generate an SDK for other languages such as Java, Python, C#, etc. The Ruby SDK and Swagger instructions can be found here: https://looker.com/docs/reference/api-and-integration/api-sdk.
#!/bin/bash
CLIENT_ID=AbCdEfGhIjKlMnOpQrStUv
CLIENT_SECRET=04e9e9665b66f0fe755b74
END_POINT=https://learn.looker.com:19999/api/3.0
DASHBOARD=73
DASHBOARD_FILTER='[ "Date=90 days", "State / Region=-Not State", "Brand=Calvin Klein" ]'
DESTINATION_ADDRESS=user@company.com
jq_location=`which jq`
status=$?
if [ $status -gt 0 ]
then
echo "This utility requires the jq command line utility to parse JSON data. Find more information here: https://stedolan.github.io/jq/"
echo "On a mac with the brew utility installed, you should be able to install jq with the command \"brew install jq\"."
exit 255
fi
echo "Logging in"
response=`curl --request POST --fail --silent --show-error \
-d "client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}" \
"${END_POINT}/login"`
status=$?
if [ $status -gt 0 ]
then
echo "Failed logging in"
exit 1
fi
ACCESS_TOKEN=`echo $response | jq --raw-output '.access_token'`
echo "Got access token \"${ACCESS_TOKEN}\""
echo "Encode the filter string"
encoded_filter=`echo "${DASHBOARD_FILTER}" | jq --raw-output 'join("&")' -`
echo $encoded_filter
status=$?
if [ $status -gt 0 ]
then
echo "Failed encoding Filter String"
exit 2
fi
echo "Execute the plan"
response=`curl --request POST --fail --silent --show-error \
--header "Authorization: token ${ACCESS_TOKEN}" \
--data "
{
\"name\": \"Business Pulse\",
\"enabled\": false,
\"dashboard_id\": 73,
\"require_results\": null,
\"require_no_results\": null,
\"require_change\": null,
\"timezone\": \"America/Los_Angeles\",
\"run_as_recipient\": false,
\"dashboard_filters\": \"?${encoded_filter}\",
\"send_all_results\": false,
\"scheduled_plan_destination\":
[
{
\"format\": \"wysiwyg_pdf\",
\"apply_formatting\": true,
\"address\": \"${DESTINATION_ADDRESS}\",
\"type\": \"email\"
}
]
}" \
"${END_POINT}/scheduled_plans/run_once"`
status=$?
if [ $status -gt 0 ]
then
echo "Failed executing the plan"
exit 3
fi
echo "Loggin out"
curl --request DELETE --header "Authorization: token ${ACCESS_TOKEN}" "${END_POINT}/logout"
The easiest way to figure out the parameters for the request bady is to create a scheduled plan for a Look or Dashboard through the UI with the appropriate settings, then retrieve it though the API. The get_all_scheduled_plans API call (https://looker.com/docs/reference/api-and-integration/api-reference/scheduled-plan#get_all_scheduled_plans) will retrieve an array JSON objects that represent the scheduled plans for the current user. The result looks like this:
[
{
"id": 683,
"created_at": "2017-02-24T00:05:31.259+00:00",
"title": "Business Pulse",
"last_run_at": "2017-02-24T00:05:31.328+00:00",
"user_id": 813,
"user": {
"id": 999,
"first_name": "John",
"last_name": "Smith",
"avatar_url": "https://gravatar.lookercdn.com/avatar/04e9e9665b66f0fe755b747747f39e43?s=156&d=blank",
"display_name": "John Smith",
"url": "https://localhost:19999/api/3.0/users/999",
"can": {
"show": true,
"index": true,
"show_details": true,
"index_details": true,
"sudo": false
}
},
"scheduled_plan_destination": [
{
"id": 665,
"scheduled_plan_id": 683,
"format": "wysiwyg_pdf",
"apply_formatting": true,
"address": "john_smith@company.com",
"type": "email",
"parameters": null,
"looker_recipient": true,
"can": {
"index": true,
"show": true,
"update": true,
"destroy": true,
"create": true,
"run": true
}
}
],
"name": "Business Pulse",
"enabled": false,
"look_id": null,
"dashboard_id": 73,
"lookml_dashboard_id": null,
"require_results": null,
"require_no_results": null,
"require_change": null,
"crontab": null,
"timezone": "America/Los_Angeles",
"run_as_recipient": false,
"dashboard_filters": "?Date=90 days&State / Region=-Not State&Brand=Calvin Klein",
"send_all_results": false,
"next_run_at": null,
"can": {
"index": true,
"email_to_others": true,
"create": true,
"run": true,
"update": true,
"show": true,
"destroy": true
}
}
]
Most of these fields are not needed. To figure out if a field is not needed, go to the API documentation and look at the Parameters “Model”. It will look like this:

Any field marked read-only should not be included in the request. Some fields in the “Model” might be marked write-only and these can only be used when building the request. The secret_parameters entry, for example, is write-only and is used to provide the password or private key used to authenticate for SFTP or S3 delivery. With this information (and sometimes a bit of trial and error) the proper request body can be defined.