Introduction

The Zylo platform provides a modern, RESTful API to work with your subscription data. The API is built using resource-oriented URLs that are protected by HTTPS transport security and authenticated via secure tokens.

Authentication

Zylo uses API tokens for authentication. You can retrieve your token ID and token secret by going to your account, selecting Admin from the main menu, and then going to the Company Tokens tab. Once you select Request Token, you can create a named token and assign the permissions you wish to associate with it. You will need to record the Token ID anad Token Secret in order to authenticate against the API. Please note that the Token Secret will only be displayed when the key is generated - if you do not record it then you will need to generate a new token in order to use the API.

In order to authenticate individual API requests, you need to add a bearer token to your request. The value of the bearer token is your Token ID and Token Secret separated by a colon, i.e.:

curl 'https://api.zylo.com/v1/subscriptions' \
    -H 'Authorization: Bearer <TOKENID:TOKENSECRET>'

Errors

If you receive an error from the API, a response code will be set indicating the error with a payload that will optionally contain additional error details. The following is an example error message:

{"statusCode":401,"message":"Unauthorized"}

The API documentation for individual routes contains any potential error codes for that route.

Pagination

Resources that have a list method allow for the pagination of result sets. Each of these methods have a standard way of controlling pagination for the resource. When querying a list method, you will receive a response called nextPageToken which gives you a token that can be used to retrieve the next page of results.If there are no further results for a given requests, then an empty string "" will be returned for this value.

To retrieve the next set of results using the nextPageToken, pass the nextPageToken value as a pageToken in the query string, i.e.:

curl 'https://api.zylo.com/v1/subscriptions?pageToke=NEXT_PAGE_TOKEN_VALUE' \
    -H 'Authorization: Bearer <TOKENID:TOKENSECRET>'

Request IDs

Each API request has a request identifier associated with it under the response header: zylo-request-id. If you assistance with a particular API request, please provider the request identifier along with your inquiry.

Versioning

All APIs are versioned and contain the version of the API directly in the URI. APIs are guaranteed to be backwards compatible across all major version numbers.

Subscriptions

Subscriptions are configured instances of subscriptions that are created in the Zylo user interface. Subscriptions will usuallly have a 1:1 relationship to a given application, but you also may have multiple subscriptions to the same application within your organization.

Data Exports

Zylo provides the ability to retrieve the current state of user level subscription usage and utilization. Due to the size of the data, the subscription export is an asynchronous workflow where you first create an export job and then retrieve the results of the job when it is complete.

An example workflow for retrieving subscription data would be to first create the export job (note that in the URL, we are using the - character to denote that we want to create an Export Job for all Subscriptions. If you wish to just export data for a specific subscriptions, then you can pass it's ID in the URL instead):

$ curl -i -X POST \
  https://api.zylo.com/v1/subscriptions/-/exportJobs \
  -H 'Authorization: Bearer <TOKEN:SECRET>'

which will return the following payload:

{
  "id": "8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  "name":"subscriptions/*/exportJobs",
  "status":"IN_PROGRESS",
  "createTime": "2020-01-01T12:00:00+00:00",
  "companyId": "9234806a4-465a-aff2-83be8fcf0886",
}

Once you have the ID for the job, you can query the endpoint to see the status of the export:

$ curl -i -X GET \
  https://api.zylo.com/v1/subscriptions/-/exportJobs/2F8f42b1f6-06a4-465a-aff2-83be8fcf0886 \
  -H 'Authorization: Bearer <TOKEN:SECRET>'

When the status has been updated to COMPLETE, a downloadUri property will appear on the job. You can retrieve the data from that URL for 30 days before the link expires:

$ curl -o export.csv "$(curl -s -H "Authorization: Bearer <TOKEN:SECRET>" "https://api.zylo.com/v1/subscriptions/-/exportJobs/2F8f42b1f6-06a4-465a-aff2-83be8fcf0886" | jq -r '.downloadUri')"

Data Imports

In order to import data to a subscription, you must first associate the subscription with the API Integration. After logging into the Zylo application, select the Integrations option from the main menu. From the Utilization category, find the API Integration option and click Connect. Once you've arrived in the connection dialog, either create a new subscription or select one of your existing subscriptions in order to make it eligible for integration via API.

To get started with importing data to the subscription, you first create an import job:

$ curl -X POST "https://api.zylo.com/v1/subscriptions/9f797a9a-334a-44c1-81aa-1e4afdcb8595/importJob" -H  "accept: application/json" -H  "Authorization: Bearer <TOKEN:SECRET>" -d ""

which will return the payload:

{
  "id": "fa28d004-ec40-4c37-9603-f2cce9ed22aa",
  "name": "subscriptions/587d9c21-1c5e-4928-8fe9-3d1eba016d19/importJob",
  "companyId": "adc89494-3316-434c-b7a6-4aae12d12e86",
  "subscriptionId": "587d9c21-1c5e-4928-8fe9-3d1eba016d19",
  "status": "OPEN",
  "createTime": "2021-05-24T20:14:30.886Z",
  "updateTime": "2021-05-24T20:14:30.886Z"
}

and then upload a CSV file to the job to the import job ID returned from the previous create call:

$ curl -X POST "https://api.zylo.com/v1/subscriptions/9f797a9a-334a-44c1-81aa-1e4afdcb8595/importJob/f8537200-3b75-4d2c-9caf-9abf87025cb0" -H  "accept: application/json" -H  "Authorization: Bearer <TOKEN:SECRET>" -H  "Content-Type: multipart/form-data" -F "file=@import_file.csv;type=application/vnd.ms-excel"

The CSV file should contain the following fields:

Field Type
firstName string
lastName string
email email
lastActivityDate ISO-8601 date
daysActiveOfLast30 numeric
licenseNames string (comma separated)
isPaidUser boolean (all lowercase)
customFields JSON

(Note: customFields is not supported at this time so you must provide an empty field)

The format of the CSV file is documented as part of the route, but you can get an example file by exporting data from one of your existing subscriptions. Once a file has been uploaded to the job, you can check the status of the job:

curl -X GET "https://api.zylo.com/v1/subscriptions/9f797a9a-334a-44c1-81aa-1e4afdcb8595/importJob/f8537200-3b75-4d2c-9caf-9abf87025cb0" -H  "accept: application/json" -H  "Authorization: Bearer <TOKEN:SECRET>"

If the job status returns ERROR, then you will be provided with a URL to download a file that contains the error information for the job. The error information will provide a detailed list of errors for all of the rows that failed to import.

Get list of subscriptions

Authorizations:
query Parameters
pageSize
number

The size of the page to return. Defaults to 50.

pageToken
string

A page token, received from a previous call. Provide this token to retrieve the subsequent page. To retrieve the first page, supply an empty page token. When paginating, other parameters provided to the call must match the call that provided the page token.

Example: pageToken=1b6792d8-1aaf-4f00-9b53-5fe1fb32eca1

Responses

Request samples

curl -i -X GET \
  'https://api.zylo.com/v1/subscriptions?pageSize=0&pageToken=string' \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
[
  • {
    • "nextPageToken": "1b6792d8-1aaf-4f00-9b53-5fe1fb32eca1",
    • "subscriptions": [
      • {
        • "appId": "application/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
        • "appDescription": "string",
        • "id": "string",
        • "name": "subscription/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
        • "createTime": "2020-01-01T12:00:00+00:00",
        • "updateTime": "2020-01-01T12:00:00+00:00",
        • "category": "Collaboration & Productivity",
        • "subcategory": "Team Collaboration",
        • "status": "active",
        • "businessUnit": "string",
        • "ssoEnforced": true,
        • "launchUrl": "example.com",
        • "sources": [
          • "string"
          ],
        • "itSupported": true,
        • "type": "string",
        • "businessGoals": "string",
        • "tags": [
          • "string"
          ],
        • "supplierName": "string",
        • "holdsPii": true,
        • "notes": [
          • {
            • "text": "string",
            • "createTime": "2020-01-01T12:00:00+00:00",
            • "createdBy": "user@example.com",
            • "updateTime": "2020-01-01T12:00:00+00:00"
            }
          ],
        • "functionalities": [
          • "string"
          ],
        • "cloud": true,
        • "primaryCostCenter": {
          • "name": "string",
          • "annualSpend": {
            • "currencyCode": "USD",
            • "amount": "199.99"
            },
          • "numberOfCostCenters": 0
          },
        • "nextAction": "string",
        • "trueUp": true,
        • "primaryContract": {
          • "startDate": "2020-01-01T12:00:00+00:00",
          • "endDate": "2019-08-24T14:15:22Z",
          • "contractEndDate": "2020-01-01T12:00:00+00:00",
          • "totalContractValue": {
            • "currencyCode": "USD",
            • "amount": "199.99"
            },
          • "billFrequency": 0,
          • "cancellationNotificationLength": 0,
          • "licensesPurchased": "string"
          },
        • "usageStats": {
          • "uniqueActiveUsers": 0,
          • "uniqueProvisionedUsers": 0,
          • "activityThreshold": "string",
          • "provisionedUsers": 0,
          • "activeUsers": 0,
          • "percentActiveUsers": "string",
          • "percentLicensesProvisioned": "string"
          },
        • "payment": {
          • "yearToDateSpend": {
            • "currencyCode": "USD",
            • "amount": "199.99"
            },
          • "annualSpend": {
            • "currencyCode": "USD",
            • "amount": "199.99"
            },
          • "apSpend": {
            • "currencyCode": "USD",
            • "amount": "199.99"
            },
          • "expenseSpend": {
            • "currencyCode": "USD",
            • "amount": "199.99"
            },
          • "lastTransactionDate": "2020-01-01T12:00:00+00:00",
          • "lastApTransactionDate": "2020-01-01T12:00:00+00:00",
          • "lastExpenseTransactionDate": "2020-01-01T12:00:00+00:00",
          • "numberOfTransactions": 0,
          • "numberOfUsersExpensing": 0,
          • "numberOfCostCenters": 0,
          • "primaryCostCenter": {
            • "name": "string",
            • "annualSpend": {
              • "currencyCode": "USD",
              • "amount": "199.99"
              },
            • "numberOfCostCenters": 0
            }
          },
        • "owners": {
          • "app": "user@example.com",
          • "business": "user@example.com",
          • "it": "user@example.com"
          },
        • "customFields": [
          • {
            • "key": "myCustomField",
            • "value": "200"
            }
          ]
        }
      ]
    }
]

Get subscription by ID

Authorizations:
path Parameters
subscriptionId
required
string

Responses

Request samples

curl -i -X GET \
  https://api.zylo.com/v1/subscriptions/:subscriptionId \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
{
  • "appId": "application/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "appDescription": "string",
  • "id": "string",
  • "name": "subscription/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "createTime": "2020-01-01T12:00:00+00:00",
  • "updateTime": "2020-01-01T12:00:00+00:00",
  • "category": "Collaboration & Productivity",
  • "subcategory": "Team Collaboration",
  • "status": "active",
  • "businessUnit": "string",
  • "ssoEnforced": true,
  • "launchUrl": "example.com",
  • "sources": [
    • "string"
    ],
  • "itSupported": true,
  • "type": "string",
  • "businessGoals": "string",
  • "tags": [
    • "string"
    ],
  • "supplierName": "string",
  • "holdsPii": true,
  • "notes": [
    • {
      • "text": "string",
      • "createTime": "2020-01-01T12:00:00+00:00",
      • "createdBy": "user@example.com",
      • "updateTime": "2020-01-01T12:00:00+00:00"
      }
    ],
  • "functionalities": [
    • "string"
    ],
  • "cloud": true,
  • "primaryCostCenter": {
    • "name": "string",
    • "annualSpend": {
      • "currencyCode": "USD",
      • "amount": "199.99"
      },
    • "numberOfCostCenters": 0
    },
  • "nextAction": "string",
  • "trueUp": true,
  • "primaryContract": {
    • "startDate": "2020-01-01T12:00:00+00:00",
    • "endDate": "2019-08-24T14:15:22Z",
    • "contractEndDate": "2020-01-01T12:00:00+00:00",
    • "totalContractValue": {
      • "currencyCode": "USD",
      • "amount": "199.99"
      },
    • "billFrequency": 0,
    • "cancellationNotificationLength": 0,
    • "licensesPurchased": "string"
    },
  • "usageStats": {
    • "uniqueActiveUsers": 0,
    • "uniqueProvisionedUsers": 0,
    • "activityThreshold": "string",
    • "provisionedUsers": 0,
    • "activeUsers": 0,
    • "percentActiveUsers": "string",
    • "percentLicensesProvisioned": "string"
    },
  • "payment": {
    • "yearToDateSpend": {
      • "currencyCode": "USD",
      • "amount": "199.99"
      },
    • "annualSpend": {
      • "currencyCode": "USD",
      • "amount": "199.99"
      },
    • "apSpend": {
      • "currencyCode": "USD",
      • "amount": "199.99"
      },
    • "expenseSpend": {
      • "currencyCode": "USD",
      • "amount": "199.99"
      },
    • "lastTransactionDate": "2020-01-01T12:00:00+00:00",
    • "lastApTransactionDate": "2020-01-01T12:00:00+00:00",
    • "lastExpenseTransactionDate": "2020-01-01T12:00:00+00:00",
    • "numberOfTransactions": 0,
    • "numberOfUsersExpensing": 0,
    • "numberOfCostCenters": 0,
    • "primaryCostCenter": {
      • "name": "string",
      • "annualSpend": {
        • "currencyCode": "USD",
        • "amount": "199.99"
        },
      • "numberOfCostCenters": 0
      }
    },
  • "owners": {
    • "app": "user@example.com",
    • "business": "user@example.com",
    • "it": "user@example.com"
    },
  • "customFields": [
    • {
      • "key": "myCustomField",
      • "value": "200"
      }
    ]
}

Create new export job record

Authorizations:
path Parameters
subscriptionId
required
string
Request Body schema: application/json
tag
string

If you are doing a wildcard export, you can optionally specify a specific tag to export.

Responses

Request samples

Content type
application/json
{
  • "tag": "string"
}

Response samples

Content type
application/json
{}

Get export jobs by subscription ID

Authorizations:
path Parameters
subscriptionId
required
string

Responses

Request samples

curl -i -X GET \
  https://api.zylo.com/v1/subscriptions/:subscriptionId/exportJobs \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
[]

Get export job by ID

Authorizations:
path Parameters
subscriptionId
required
string
id
required
string

Responses

Request samples

curl -i -X GET \
  https://api.zylo.com/v1/subscriptions/:subscriptionId/exportJobs/:id \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
{}

Creates an import job for a subscription

Authorizations:
path Parameters
subscriptionId
required
string

Responses

Request samples

curl -i -X POST \
  https://api.zylo.com/v1/subscriptions/:subscriptionId/importJob \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
{
  • "id": "eabc3a85-b133-44cb-b125-ed4866d4308c",
  • "name": "name/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "companyId": "companyId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "subscriptionId": "subscriptionId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "description": "description/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "importFileUri": "importFileUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "resultsUri": "resultsUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "status": "COMPLETE",
  • "createTime": "2020-01-01T12:00:00+00:00",
  • "updateTime": "2020-01-01T12:00:00+00:00"
}

Returns a paginated list of import jobs for a subscription

Authorizations:
path Parameters
subscriptionId
required
string
query Parameters
pageSize
number

The size of the page to return. Defaults to 50.

pageToken
string

A page token, received from a previous call. Provide this token to retrieve the subsequent page. To retrieve the first page, supply an empty page token. When paginating, other parameters provided to the call must match the call that provided the page token.

Example: pageToken=1b6792d8-1aaf-4f00-9b53-5fe1fb32eca1

Responses

Request samples

curl -i -X GET \
  'https://api.zylo.com/v1/subscriptions/:subscriptionId/importJob?pageSize=0&pageToken=string' \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
{
  • "nextPageToken": "1b6792d8-1aaf-4f00-9b53-5fe1fb32eca1",
  • "importJobs": [
    • {
      • "id": "eabc3a85-b133-44cb-b125-ed4866d4308c",
      • "name": "name/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
      • "companyId": "companyId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
      • "subscriptionId": "subscriptionId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
      • "description": "description/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
      • "importFileUri": "importFileUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
      • "resultsUri": "resultsUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
      • "status": "COMPLETE",
      • "createTime": "2020-01-01T12:00:00+00:00",
      • "updateTime": "2020-01-01T12:00:00+00:00"
      }
    ]
}

Returns a single import job for a subscription

Authorizations:
path Parameters
subscriptionId
required
string
id
required
string

Responses

Request samples

curl -i -X GET \
  https://api.zylo.com/v1/subscriptions/:subscriptionId/importJob/:id \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>'

Response samples

Content type
application/json
{
  • "id": "eabc3a85-b133-44cb-b125-ed4866d4308c",
  • "name": "name/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "companyId": "companyId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "subscriptionId": "subscriptionId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "description": "description/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "importFileUri": "importFileUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "resultsUri": "resultsUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "status": "COMPLETE",
  • "createTime": "2020-01-01T12:00:00+00:00",
  • "updateTime": "2020-01-01T12:00:00+00:00"
}

Adds a CSV file to a single import job for a subscription

Authorizations:
path Parameters
subscriptionId
required
string
id
required
string
Request Body schema: multipart/form-data
file
string <binary>

Responses

Request samples

curl -i -X POST \
  https://api.zylo.com/v1/subscriptions/:subscriptionId/importJob/:id \
  -H 'Authorization: Bearer <YOUR_API_KEY_HERE>' \
  -H 'Content-Type: multipart/form-data' \
  -F file=string

Response samples

Content type
application/json
{
  • "id": "eabc3a85-b133-44cb-b125-ed4866d4308c",
  • "name": "name/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "companyId": "companyId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "subscriptionId": "subscriptionId/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "description": "description/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "importFileUri": "importFileUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "resultsUri": "resultsUri/8f42b1f6-06a4-465a-aff2-83be8fcf0886",
  • "status": "COMPLETE",
  • "createTime": "2020-01-01T12:00:00+00:00",
  • "updateTime": "2020-01-01T12:00:00+00:00"
}