Theming API

Note: The Theming API is currently in early access. Learn more.

The Theming API lets you manage Guide themes and integrate more complex theme development workflows with Guide.

Themes are managed at a brand level. As a result, the Themes API requires you to provide a Brand ID as part of the endpoint URL. You can use the Brands API to retrieve the Brand ID prior to using the Theming API. If you're not using multiple brands, use the ID of the only brand available. If you are using multiple brands, please note that requests should always be sent to the account domain, and not to the brand domain.

Note: If using OAuth2 authentication, the global read or write scopes are required.

Themes

A Theme resource represents a Guide Theme.

JSON Format

Themes are represented by JSON objects with the following properties:

Name Type Comment
id string Automatically assigned when the theme is created
name string The name of the theme
version string The version number of the theme, specified in the theme manifest
author string The author of the theme, specified in the theme manifest
live boolean Whether the theme is currently published in Help Center or not
created_at timestamp The time at which the theme was created
updated_at timestamp The time at which the theme was last updated
Example
{
  "id":         "asdf123-asdf",
  "name":       "Copenhagen",
  "author":     "Zendesk",
  "version":    "1.7.5",
  "live":       true,
  "created_at": "2012-04-04T09:14:57Z",
  "updated_at": "2012-04-04T09:14:57Z"
}
List Themes

GET /api/guide/theming/{brand_id}/themes

Allowed for
  • Guide managers
Using curl
curl https://{subdomain}.zendesk.com/api/guide/theming/{brand_id}/themes.json \
  -v -u {email_address}:{password}
Example Response
Status: 200 OK

{
  "themes": [
    {
      "id":      "asdf123-asdf",
      "name":    "Copenhagen",
      "author":  "Zendesk",
      ...
    },
    ...
  ]
}
Show theme

GET /api/guide/theming/{brand_id}/themes/{id}

Allowed for
  • Guide managers
Using curl
curl https://{subdomain}.zendesk.com/api/guide/theming/{brand_id}/themes/{id}.json \
  -v -u {email_address}:{password}
Example Response
Status: 200 OK

{
  "theme": {
    "id":      "asdf123-asdf",
    "name":    "Copenhagen",
    "author":  "Zendesk",
    ...
  }
}
Delete theme

DELETE /api/guide/theming/{brand_id}/themes/{id}

Allowed for
  • Guide managers
Using curl
curl https://{subdomain}.zendesk.com/api/guide/theming/{brand_id}/themes/{id}.json \
  -v -u {email_address}:{password} -X DELETE
Example Response
Status: 204 No Content
Publish theme

POST /api/guide/theming/{brand_id}/themes/{id}/publish

Allowed for
  • Guide managers
Using curl
curl https://{subdomain}.zendesk.com/api/guide/theming/{brand_id}/themes/{id}/publish.json \
  -v -u {email_address}:{password} -X POST
Example Response
Status: 200 OK

{
  "theme": {
    "id":      "asdf123-asdf",
    "name":    "Copenhagen",
    "author":  "Zendesk",
    "live":    true
    ...
  }
}

Jobs

Jobs are used for asynchronous operations.

JSON format
Name Type Comment
status string The current status of the job - "pending", "completed" or "failed"
errors array An array of errors if the job failed; returns null if the job is pending or successful
data object Job specific data provided on job creation

The "errors" key may contain an array of "error" objects. The format of an "error" object is as follows:

Name Type Comment
title string The error message
code string A unique identifier of the error
meta object An object with further error information
Example
{
  "status": "pending",
  "errors": null,
  "data":   null
}
Show job

GET /api/guide/theming/{brand_id}/jobs/{id}

Allowed for
  • Guide managers
Using curl
curl https://{subdomain}.zendesk.com/api/guide/theming/{brand_id}/jobs/{id}.json \
  -v -u {email_address}:{password}
Example Response
Status: 200 OK

{
  "job": {
    "status": "failed",
    "errors": [
      {
        "title": "Theme not found",
        "code": "ThemeNotFound",
        "meta": { }
      }
    ]
  }
}
Create theme import job

POST /api/guide/theming/{brand_id}/jobs/themes/import/zip

This endpoint does not receive the ZIP file itself. Check the Further Information section below for a complete example.

This job's "data" object has the following format:

Name Type Comment
theme_id string Automatically assigned when the job is created
upload.url string One time URL for storage location
upload.parameters object params to be used when POSTing the ZIP file to the url above
Allowed for
  • Guide managers
Using curl
curl https://{subdomain}.zendesk.com/api/guide/theming/{brand_id}/jobs/themes/import/zip.json \
  -v -u {email_address}:{password} -X POST
Example Response
Status: 202 Accepted

{
  "job": {
    "id": "a66e7bde543c6b6d018f0e07a654feaf",
    "status": "pending",
    "errors": null,
    "data": {
      "theme_id": "asdf123-asdf",
      "upload": {
        "url": "storage.zdassets.com/storage-location",
        "parameters": { ... }
      }
    }
  }
}
Further information

Importing themes is a multi-step process. The following documents each step and also provides a complete example in Ruby.

Steps
  1. Request the creation of a new import job as documented above;

  2. Upload the file to the storage location provided in the upload object. The file is uploaded by sending a POST request to the provided url and the parameters for this request are provided by the parameters object. In addition to the parameters provided, the file should be one of the parameters and use the key file. No authentication headers should be provided;

  3. Poll the job status. Poll the job status as documented in Show Job. On "completed" status, a new Theme with theme_id will be available for use. Avoid polling too frequently to prevent being rate-limited (example: poll every 5 seconds).

Using ruby to upload a theme

This is a simplified example without error handing.

require 'faraday'
require 'faraday_middleware'

# brand_id =
# subdomain =
# file_path =
# email =
# password =

# Step 1

zendesk_connection = Faraday.new do |faraday|
  faraday.basic_auth(email, password)
  faraday.request :json
  faraday.response :json, content_type: /json/
  faraday.adapter :net_http
end

job_response = zendesk_connection.post("https://#{subdomain}.zendesk.com/api/guide/theming/#{brand_id}/jobs/themes/import/zip")

job_id = job_response.body['job']['id']
storage_url = job_response.body['job']['data']['upload']['url']
storage_parameters = job_response.body['job']['data']['upload']['parameters']

# Step 2

storage_connection = Faraday.new do |faraday|
  faraday.request :multipart
  faraday.request :url_encoded
  faraday.adapter :net_http
end

storage_body = storage_parameters.merge(file: Faraday::UploadIO.new(file_path, 'application/zip'))
storage_connection.post(storage_url, storage_body)

# Step 3

10.times do
  job_status_response = zendesk_connection.get("https://#{subdomain}.zendesk.com/api/guide/theming/#{brand_id}/jobs/#{job_id}")
  break unless job_status_response.body['job']['status'] == 'pending'
  sleep(5)
end