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 Read-only Mandatory Comment
id string yes no Automatically assigned when the theme is created
name string yes no The name of the theme
version string yes no The version number of the theme, specified in the theme manifest
author string yes no The author of the theme, specified in the theme manifest
live boolean no no Whether the theme is currently published in Help Center or not
created_at timestamp yes no The time at which the theme was created
updated_at timestamp yes no 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 Read-only Mandatory Comment
status string yes no The current status of the job - "pending", "completed" or "failed"
errors array yes no An array of errors if the job failed; returns null if the job is pending or successful
data object yes no 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 Read-only Mandatory Comment
title string yes no The error message
code string yes no A unique identifier of the error
meta object yes no 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 job's "data" object has the following format:

Name Type Read-only Mandatory Comment
theme_id string yes no Automatically assigned when the job is created
upload.url string yes no One time URL for storage location
upload.parameters object yes no 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. Follow the redirect location provided to finish the upload. You will need to provide your Zendesk credentials in this request;

  4. 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_response = storage_connection.post(storage_url, storage_body)

# Step 3

zendesk_connection.get(storage_response.headers['location'])

# Step 4

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