Skip to content

REST API Documentation ​

Butler provides a REST API that allows you to interact with some of its features programmatically.

Remember

The "Try it out" feature of the API documentation below does not work when accessed from butler.ptarmiganlabs.com. This is only expected as this site does not know anything about where your Butler instance is running.

The same feature is however also available from Butler itself, see this page.

API Overview ​

Butler's REST API is documented using the OpenAPI 3.0 specification and provides endpoints for:

  • System Management: Health checks, version information, configuration
  • File Operations: Copy, move, delete files, create directories
  • Task Management: Start Qlik Sense tasks, scheduling operations
  • Key-Value Store: Data storage and retrieval operations
  • Messaging: MQTT publishing, Slack notifications
  • Monitoring: New Relic integration, app dumping
  • Utility Functions: Base encoding conversions, app listings

Interactive API Documentation ​

Butler is a microservice that provides add-on features to Qlik Sense Enterprise on Windows.
Butler offers both a REST API and things like failed reload notifications etc.

This page contains the API documentation. Full documentation is available at https://butler.ptarmiganlabs.com

External Documentation​

Butler family of tools on GitHub

Servers​

http://localhost:8081

Default​


Get an array of all enabled API endpoints.​

GET
/v4/configfile/endpointsenabled

Get an array of all enabled API endpoints, using the key names from the Butler config file.

Note: Endpoints are enabled/disabled in the Butler main configuration file.

Responses​

Enabled API enpooints.

application/json
JSON
[
  
"string"
]

Playground​

Samples​


Converts strings from base62 to base16.​

GET
/v4/base62tobase16

Converts strings from base62 to base16.

Parameters​

Query Parameters

base62*

The base62 encoded string that should be converted to base16

Type
string
Required
Example"6DMW88LpSok9Z7P7hUK0wv7bF"

Responses​

Base conversion successful.

application/json
JSON
{
  
"base62": "string",
  
"base16": "string"
}

Playground​

Variables
Key
Value

Samples​


Converts strings from base16 to base62.​

GET
/v4/base16tobase62

Converts strings from base16 to base62.

Parameters​

Query Parameters

base16*

The base16 encoded string that should be converted to base62

Type
string
Required
Example"3199af08bfeeaf5d420f27ed9c01e74370077"

Responses​

Base conversion successful.

application/json
JSON
{
  
"base62": "string",
  
"base16": "string"
}

Playground​

Variables
Key
Value

Samples​


Tests if Butler is alive and responding​

GET
/v4/butlerping

Tests if Butler is alive and responding

Responses​

Butler is alive and well.

application/json
JSON
{
  
"response": "Butler reporting for duty",
  
"butlerVersion": "5.5.0"
}

Playground​

Samples​


Copy file(s) between well defined, approved locations.​

PUT
/v4/filecopy

Copying of files is only posttible between pre-approved directories.
Defining approved source and destination directories is done in Butler's config file.

If the source directory contains subdirectories, these will be copied too.

Request Body​

application/json
JSON
{
  
"fromFile": "subfolder/file1.qvd",
  
"toFile": "archive/file1_20200925.qvd",
  
"overwrite": false,
  
"preserveTimestamp": false
}

Responses​

File copied.

application/json
JSON
{
  
"fromFile": "subfolder/file1.qvd",
  
"toFile": "archive/file1_20200925.qvd",
  
"overwrite": false,
  
"preserveTimestamp": false
}

Playground​

Body

Samples​


Move file(s) between well defined, approved locations.​

PUT
/v4/filemove

Moving of files is only posttible between pre-approved directories.
Defining approved source and destination directories is done in Butler's config file.

If the source directory contains subdirectories, these will be moved too.

Request Body​

application/json
JSON
{
  
"fromFile": "subfolder/file1.qvd",
  
"toFile": "archive/file1_20200925.qvd",
  
"overwrite": false
}

Responses​

File moved.

application/json
JSON
{
  
"fromFile": "subfolder/file1.qvd",
  
"toFile": "archive/file1_20200925.qvd",
  
"overwrite": false
}

Playground​

Body

Samples​


Delete file(s) in well defined, approved locations.​

DELETE
/v4/filedelete

It is only possible to delete files in pre-approved directories, or subdirectories thereof.
Defining approved directories is done in Butler's config file.

Request Body​

application/json
JSON
{
  
"deleteFile": "data/qvdstore/sales/file1.qvd"
}

Responses​

File deleted.

application/json
JSON
{
}

Playground​

Body

Samples​


Creates a directory in designated QVD directory.​

POST
/v4/createdirqvd

Creates a directory in QVD directory (which is defined in Butler's config file).

Request Body​

application/json
JSON
{
  
"directory": "subfolder/2020-10"
}

Responses​

Directory created.

application/json
JSON
{
  
"directory": "subfolder/2020-10"
}

Playground​

Body

Samples​


Creates a directory anywhere in the file system.​

POST
/v4/createdir

If the directory already exists nothing will happen.
If permissions don't allow a directory to be created, or if the path is invalid, an error will be returned.

Request Body​

application/json
JSON
{
  
"directory": "/Users/joe/data/qvds/2020"
}

Responses​

Directory created.

application/json
JSON
{
  
"directory": "/Users/joe/data/qvds/2020"
}

Playground​

Body

Samples​


List all currently defined namespaces.​

GET
/v4/keyvaluesnamespaces

Responses​

Array of all namespaces.

application/json
JSON
[
  
"string"
]

Playground​

Samples​


Get the value associated with a key, in a specific namespace.​

GET
/v4/keyvalues/{namespace}

Parameters​

Path Parameters

namespace*
Type
string
Required
Example"Sales ETL step 2"

Query Parameters

key*
Type
string
Required
Example"Last extract timestamp"

Responses​

Key and it's associated value and metadata returned.

application/json
JSON
{
  
"namespace": "Sales ETL step 2",
  
"key": "Last extract timestamp",
  
"value": "2020-09-29 17:14:56"
}

Playground​

Variables
Key
Value

Samples​


Create a new key-value pair in the specified namespace.​

POST
/v4/keyvalues/{namespace}

If the specified key already exists it will be overwritten.

If the posted data has a TTL, it will start counting when the post occur.
I.e. if a previouly posted key also had a TTL, it will be replace with the most recent TTL.

Parameters​

Path Parameters

namespace*

Name of namespace.

Type
string
Required
Example"Sales ETL step 2"

Request Body​

application/json
JSON
{
  
"key": "ce68c8ca-b3ff-4371-8285-7c9ce5040e42_parameter_1",
  
"value": "12345.789",
  
"ttl": 10000
}

Responses​

Key successfully set.

application/json
JSON
{
  
"namespace": "Sales ETL step 2",
  
"key": "Last extract timestamp",
  
"value": "2020-09-29 17:14:56",
  
"ttl": 60000
}

Playground​

Variables
Key
Value
Body

Samples​


Delete a namespace and all key-value pairs in it.​

DELETE
/v4/keyvalues/{namespace}

Parameters​

Path Parameters

namespace*

Name of namespace.

Type
string
Required
Example"Sales ETL step 2"

Responses​

Namespace successfully deleted.

application/json
JSON
"string"

Playground​

Variables
Key
Value

Samples​


Checks if a key exists in a namespace.​

GET
/v4/keyvalues/{namespace}/keyexists

Returns true if the specified key exists, otherwise false.

Parameters​

Path Parameters

namespace*
Type
string
Required
Example"Sales ETL step 2"

Query Parameters

key*
Type
string
Required
Example"Last extract timestamp"

Responses​

Key exist/no-exist returned, together with the data if the does exist.

application/json
JSON
{
  
"keyExists": true,
  
"keyValue": {
  
  
"namespace": "Sales ETL step 2",
  
  
"key": "Last extract timestamp",
  
  
"value": "2020-09-29 17:14:56"
  
}
}

Playground​

Variables
Key
Value

Samples​


Delete a key-value pair in a specific namespace.​

DELETE
/v4/keyvalues/{namespace}/{key}

Parameters​

Path Parameters

namespace*

Name of namespace.

Type
string
Required
Example"Sales ETL step 2"
key*

Key to use

Type
string
Required
Example"ce68c8ca-b3ff-4371-8285-7c9ce5040e42_parameter_1"

Responses​

Key-value pair successfully deleted.

application/json
JSON
"string"

Playground​

Variables
Key
Value

Samples​


Retrieve a list of all keys present in the specified namespace.​

GET
/v4/keylist/{namespace}

Parameters​

Path Parameters

namespace*

Name of namespace whose keys should be returned.

Type
string
Required
Example"Sales ETL step 2"

Responses​

Object containing namespace name + list of allkeys in the namespace.

application/json
JSON
{
  
"namespace": "Sales ETL step 2",
  
"keys": [
  
  
{
  
  
}
  
]
}

Playground​

Variables
Key
Value

Samples​


Publish a message to a MQTT topic.​

PUT
/v4/mqttpublishmessage

Request Body​

application/json
JSON
{
  
"topic": "qliksense/new_data_notification/sales",
  
"message": "dt=20201028"
}

Responses​

MQTT message successfully published.

application/json
JSON
{
  
"topic": "qliksense/new_data_notification/sales",
  
"message": "dt=20201028"
}

Playground​

Body

Samples​


Post events to New Relic.​

POST
/v4/newrelic/event

This endpoint posts events to the New Relic event API.

Request Body​

application/json
JSON
{
  
"eventType": "relead-failed",
  
"timestamp": 1642164296053,
  
"attributes": [
  
  
{
  
  
  
"name": "host.name",
  
  
  
"value": "dev.server.com"
  
  
}
  
]
}

Responses​

Data accepted and sent to New Relic.

application/json
JSON
{
  
"newRelicResultCode": "202",
  
"newRelicResultText": "Data accepted."
}

Playground​

Body

Samples​


Post metrics to New Relic.​

POST
/v4/newrelic/metric

This endpoint posts metrics to the New Relic metrics API.

Request Body​

application/json
JSON
{
  
"name": "memory.heap",
  
"type": "gauge",
  
"value": 2.3,
  
"timestamp": 1642164296053,
  
"interval": 0,
  
"attributes": [
  
  
{
  
  
  
"name": "host.name",
  
  
  
"value": "dev.server.com"
  
  
}
  
]
}

Responses​

Data accepted and sent to New Relic.

application/json
JSON
{
  
"newRelicResultCode": "202",
  
"newRelicResultText": "Data accepted."
}

Playground​

Body

Samples​


Get all information available for existing schedule(s).​

GET
/v4/schedules

If a schedule ID is specified using a query parameter (and there exists a schedule with that ID), information about that schedule will be returned.
If no schedule ID is specified, all schedules will be returned.

Parameters​

Query Parameters

id

Scheduld ID

Type
string
Example"e4b1c455-aa15-4a51-a9cf-c5e4cfc91339"

Responses​

Schedule successfully retrieved.

application/json
JSON
[
  
{
  
  
"id": "e4b1c455-aa15-4a51-a9cf-c5e4cfc91339",
  
  
"created": "2020-09-29T14:29:12.283Z",
  
  
"name": "Reload sales metrics",
  
  
"cronSchedule": "0,30 6 * * 1-5",
  
  
"timezone": "Europe/Stockholm",
  
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
  
"startupState": "started",
  
  
"tags": [
  
  
  
[
  
  
  
  
"tag 1",
  
  
  
  
"tag 2"
  
  
  
]
  
  
],
  
  
"lastKnownState": "started"
  
}
]

Playground​

Variables
Key
Value

Samples​


Create a new schedule.​

POST
/v4/schedules

Request Body​

application/json
JSON
{
  
"name": "Reload sales metrics",
  
"cronSchedule": "0,30 6 * * 1-5",
  
"timezone": "Europe/Stockholm",
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
"startupState": "started",
  
"tags": [
  
  
[
  
  
  
"tag 1",
  
  
  
"tag 2"
  
  
]
  
]
}

Responses​

Schedule successfully retrieved.

application/json
JSON
[
  
{
  
  
"id": "e4b1c455-aa15-4a51-a9cf-c5e4cfc91339",
  
  
"created": "2020-09-29T14:29:12.283Z",
  
  
"name": "Reload sales metrics",
  
  
"cronSchedule": "0,30 6 * * 1-5",
  
  
"timezone": "Europe/Stockholm",
  
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
  
"startupState": "started",
  
  
"tags": [
  
  
  
[
  
  
  
  
"tag 1",
  
  
  
  
"tag 2"
  
  
  
]
  
  
],
  
  
"lastKnownState": "started"
  
}
]

Playground​

Body

Samples​


Delete a schedule.​

DELETE
/v4/schedules/{scheduleId}

Parameters​

Path Parameters

scheduleId*

Schedule ID.

Type
string
Required
Example"e4b1c455-aa15-4a51-a9cf-c5e4cfc91339"

Responses​

Schedule successfully deleted.

application/json
JSON
"string"

Playground​

Variables
Key
Value

Samples​


Start a schedule.​

PUT
/v4/schedules/{scheduleId}/start

Start a schedule, i.e. have the scheduler run the associated reload task according to the schedule's cron settings.

Parameters​

Path Parameters

scheduleId*

Schedule ID.

Type
string
Required
Example"e4b1c455-aa15-4a51-a9cf-c5e4cfc91339"

Responses​

Schedule successfully started.

An object with all information about the started schedule is returned.

application/json
JSON
{
  
"id": "e4b1c455-aa15-4a51-a9cf-c5e4cfc91339",
  
"created": "2020-09-29T14:29:12.283Z",
  
"name": "Reload sales metrics",
  
"cronSchedule": "0,30 6 * * 1-5",
  
"timezone": "Europe/Stockholm",
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
"startupState": "started",
  
"tags": [
  
  
[
  
  
  
"tag 1",
  
  
  
"tag 2"
  
  
]
  
],
  
"lastKnownState": "started"
}

Playground​

Variables
Key
Value

Samples​


Start all schedules.​

PUT
/v4/schedules/startall

Start all schedules, i.e. tell the scheduler to run each schedule and start associated tasks according to each schedule's settings.

Responses​

Schedules successfully started.

An array with all information about the started schedules is returned.

application/json
JSON
[
  
{
  
  
"id": "e4b1c455-aa15-4a51-a9cf-c5e4cfc91339",
  
  
"created": "2020-09-29T14:29:12.283Z",
  
  
"name": "Reload sales metrics",
  
  
"cronSchedule": "0,30 6 * * 1-5",
  
  
"timezone": "Europe/Stockholm",
  
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
  
"startupState": "started",
  
  
"tags": [
  
  
  
[
  
  
  
  
"tag 1",
  
  
  
  
"tag 2"
  
  
  
]
  
  
]
  
}
]

Playground​

Samples​


Stop a schedule.​

PUT
/v4/schedules/{scheduleId}/stop

Stop a schedule, i.e. tell the scheduler to no longer execute the schedule according to its cron settings.

Parameters​

Path Parameters

scheduleId*

Schedule ID.

Type
string
Required
Example"e4b1c455-aa15-4a51-a9cf-c5e4cfc91339"

Responses​

Schedule successfully stopped.

An object with all information about the stopped schedule is returned.

application/json
JSON
{
  
"id": "e4b1c455-aa15-4a51-a9cf-c5e4cfc91339",
  
"created": "2020-09-29T14:29:12.283Z",
  
"name": "Reload sales metrics",
  
"cronSchedule": "0,30 6 * * 1-5",
  
"timezone": "Europe/Stockholm",
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
"startupState": "started",
  
"tags": [
  
  
[
  
  
  
"tag 1",
  
  
  
"tag 2"
  
  
]
  
],
  
"lastKnownState": "started"
}

Playground​

Variables
Key
Value

Samples​


Stop all schedules.​

PUT
/v4/schedules/stopall

Stop all schedules, i.e. tell the scheduler to no longer execute any schedule according to its cron settings.

Responses​

Schedules successfully stopped.

An array with all information about the stopped schedules is returned.

application/json
JSON
[
  
{
  
  
"id": "e4b1c455-aa15-4a51-a9cf-c5e4cfc91339",
  
  
"created": "2020-09-29T14:29:12.283Z",
  
  
"name": "Reload sales metrics",
  
  
"cronSchedule": "0,30 6 * * 1-5",
  
  
"timezone": "Europe/Stockholm",
  
  
"qlikSenseTaskId": "210832b5-6174-4572-bd19-3e61eda675ef",
  
  
"startupState": "started",
  
  
"tags": [
  
  
  
[
  
  
  
  
"tag 1",
  
  
  
  
"tag 2"
  
  
  
]
  
  
]
  
}
]

Playground​

Samples​


Get scheduler status.​

GET
/v4/schedules/status

Get basic status from the core scheduler.

No schedule metadata beyond ID, cron setting and job state will be returned, but as this comes from the core scheduler it is the authorative truth about what jobs are running (and which ones are not).

Responses​

Status for all jobs that exist in the core scheduler.

text/plain
JSON
"string"

Playground​

Samples​


Do a stand-alone reload of a Qlik Sense app, without using a task.​

PUT
/v4/app/{appId}/reload

Parameters​

Path Parameters

appId*

ID of Qlik Sense app.

Type
string
Required
Example"210832b5-6174-4572-bd19-3e61eda675ef"

Request Body​

application/json
JSON
{
  
"reloadMode": 0,
  
"partialReload": true,
  
"startQSEoWTaskOnSuccess": [
  
  
[
  
  
  
"09b3c78f-04dd-45e3-a4bf-1b074d6572fa",
  
  
  
"eaf1da4f-fd44-4cea-b2de-7b67a6496ee3"
  
  
]
  
],
  
"startQSEoWTaskOnFailure": [
  
  
[
  
  
  
"09b3c78f-04dd-45e3-a4bf-1b074d6572fa",
  
  
  
"eaf1da4f-fd44-4cea-b2de-7b67a6496ee3"
  
  
]
  
]
}

Responses​

App successfully reloaded.

application/json
JSON
{
  
"appId": "210832b5-6174-4572-bd19-3e61eda675ef"
}

Playground​

Variables
Key
Value
Body

Samples​


Dump a Sense app to JSON.​

GET
/v4/senseappdump/{appId}

Does the same thing as /v4/app/:appId/dump

Parameters​

Path Parameters

appId*

ID of Qlik Sense app.

Type
string
Required
Example"210832b5-6174-4572-bd19-3e61eda675ef"

Responses​

App dump successful. App metadata returned as JSON.

application/json
JSON
{
}

Playground​

Variables
Key
Value

Samples​


Dump a Sense app to JSON.​

GET
/v4/app/{appId}/dump

Does the same thing as /v4/senseappdump/:appId

Parameters​

Path Parameters

appId*

ID of Qlik Sense app.

Type
string
Required
Example"210832b5-6174-4572-bd19-3e61eda675ef"

Responses​

App dump successful. App metadata returned as JSON.

application/json
JSON
{
}

Playground​

Variables
Key
Value

Samples​


Get a list of all apps in Sense environment.​

GET
/v4/senselistapps

Does the same thing as /v4/apps/list

Responses​

App list successfully retrieved.

application/json
JSON
[
  
{
  
  
"id": "5d7ae888-61cd-4539-97b2-6cf5baaa6f9d",
  
  
"name": "2021 sales targets"
  
}
]

Playground​

Samples​


Get a list of all apps in Sense environment.​

GET
/v4/apps/list

Does the same thing as /v4/senselistapps

Responses​

App list successfully retrieved.

application/json
JSON
[
  
{
  
  
"id": "5d7ae888-61cd-4539-97b2-6cf5baaa6f9d",
  
  
"name": "2021 sales targets"
  
}
]

Playground​

Samples​


Start a Qlik Sense task.​

PUT
/v4/reloadtask/{taskId}/start

An optional array of zero or more objects can be passed in the message body. It is used to pass additional info related to the reload task being started.

Currently supported values in this array are:

  • A key-value pair that will be stored in Butler's KV store. If Butler's key-value store is not enabled, any key-value information passed in this parameter will simply be ignored.
    Setting ttl=0 disables the TTL feature, i.e. the KV pair will not expire.
  • A task identified by its taskId that should be started.
  • Tasks identified by tags set on tasks in the QMC.
  • Tasks identified by custom properties set in the QMC.

This parameter uses a generic JSON/object format (type + payload).
It's thus possible to add new integrations in future Butler versions.

Parameters​

Path Parameters

taskId*

ID of Qlik Sense task.
Butler will ignore the "magic" task ID of "-" (=dash, hyphen). This ID will not be reported as invalid.

Type
string
Required
Example"210832b5-6174-4572-bd19-3e61eda675ef"

Query Parameters

allTaskIdsMustExist

If set to true, all specified taskIds must exist. If one or more taskIds does not exist in the Sense server, no tasks will be started.

If set to false, all existing taskIds will be started. Missing/invalid taskIds will be ignored.

In either case, missing/invalid taskIds will be reported in the result set back to the client calling the API.

Note: Tasks started by specifying tags and/or custom properties are not affected by this.

Type
boolean
Exampletrue

Request Body​

application/json
JSON
[
  
{
  
  
"type": "keyvaluestore",
  
  
"payload": {
  
  
}
  
}
]

Responses​

Task successfully started.

application/json
JSON
{
}

Playground​

Variables
Key
Value
Body

Samples​


Start a Qlik Sense task.​

POST
/v4/reloadtask/{taskId}/start

An optional array of zero or more objects can be passed in the message body. It is used to pass additional info related to the reload task being started.

Currently supported values in this array are:

  • A key-value pair that will be stored in Butler's KV store. If Butler's key-value store is not enabled, any key-value information passed in this parameter will simply be ignored.
    Setting ttl=0 disables the TTL feature, i.e. the KV pair will not expire.
  • A task identified by its taskId that should be started.
  • Tasks identified by tags set on tasks in the QMC.
  • Tasks identified by custom properties set in the QMC.

This parameter uses a generic JSON/object format (type + payload).
It's thus possible to add new integrations in future Butler versions.

Parameters​

Path Parameters

taskId*

ID of Qlik Sense task.
Butler will ignore the "magic" task ID of "-" (=dash, hyphen). This ID will not be reported as invalid.

Type
string
Required
Example"210832b5-6174-4572-bd19-3e61eda675ef"

Query Parameters

allTaskIdsMustExist

If set to true, all specified taskIds must exist. If one or more taskIds does not exist in the Sense server, no tasks will be started.

If set to false, all existing taskIds will be started. Missing/invalid taskIds will be ignored.

In either case, missing/invalid taskIds will be reported in the result set back to the client calling the API.

Note: Tasks started by specifying tags and/or custom properties are not affected by this.

Type
boolean
Exampletrue

Request Body​

application/json
JSON
[
  
{
  
  
"type": "keyvaluestore",
  
  
"payload": {
  
  
}
  
}
]

Responses​

Task successfully started.

application/json
JSON
{
}

Playground​

Variables
Key
Value
Body

Samples​


Send message to Slack.​

PUT
/v4/slackpostmessage

Sends a basic message to Slack.

Request Body​

application/json
JSON
{
  
"channel": "#reload-notification",
  
"from_user": "Butler the Bot",
  
"msg": "This is a message from Qlik Sense",
  
"emoji": "thumbsup"
}

Responses​

Message successfully sent to Slack.

application/json
JSON
{
  
"channel": "#reload-notification",
  
"from_user": "Butler the Bot",
  
"msg": "This is a message from Qlik Sense",
  
"emoji": "thumbsup"
}

Playground​

Body

Samples​


Powered by VitePress OpenAPI

Additional Resources ​

Getting Started with the API ​

  1. Enable API endpoints in your Butler configuration file
  2. Configure authentication if required
  3. Test connectivity using the /v4/butlerping endpoint
  4. Explore endpoints using the interactive documentation above

The Butler API follows REST principles and returns JSON responses. All endpoints are prefixed with /v4/ to indicate the API version.

Released under the MIT License.