Ticket Dynamic Contents

Jason He Updated by Jason He

Ticket dynamic content is similar to dynamic field and dynamic content, it is available for both client portal and TECH portal. You will required to design your own API end point for our portal to hit. This is advanced feature, you can either develop the API yourselves or seek for consultation from us.

The goal of ticket dynamic contents is to provide content's that tailored for specific user or company. The information we will hand over to your API are following.

  • Ticket database ID. You can use it to get more detail of the ticket.
  • Access Token for current user, the token is available for maximum of one hour, portal will try to reuse the token, so please check with access token expiration parameter. Check here to see how you can use our access token.
    • Token provided security to verify given user
    • Token allow you to understand the current user. Either they are resource/member or contact that's under a company.
  • Database name, this is related to your instance. You don't have to utilize on this info, it is for our consulting team to provide solution for different customers.

API contract

Similar to Microsoft's Adaptive Card, DeskDirector will define the API contract, you as user of this feature have to respect the contract before the feature can be functional as expected.

API Request Design

Client portal or TECH portal will perform POST request against your API. The request body is in JSON format.

TypeScript definition of request body contract.

interface GetContents {
ticketId: number;
accessToken: string;
// Seconds before token expire
accessTokenExpiresIn: number;
// When will the token expire. ISO8601 format.
accessTokenExpiresOn: string;
database: string;

Request example

"ticketId": 12345,
"accessToken": "<token, use to verify user or get ticket information>",
"accessTokenExpiresIn": 3600,
"accessTokenExpiresOn": "2022-06-22T00:00:00Z"

API Response Design

Your API should respond with following format for our portal to understand. Do not use random 3rd party API, the payload won't be what our portal is expecting. This is not magic.

TypeScript definition of response body contract.

type ContentType = 'list' | 'description' | 'progress';
type ContentColor = 'default' | 'accent' | 'good' | 'warning' | 'attention' | 'light';

interface GetContentsResponse {
// if refresh rate is provided, portal will auto refresh on whole contents.
// valid value is between 30 and 300 (seconds)
refreshRate?: number;
// maximum of 3 items
value: Array<DynamicContent>;

type DynamicContent = ListContent | DescriptionContent | ProgressContent;

interface SvgContent {
fill?: string;
viewBox: string;
content: string;

interface Content<T> {
type: ContentType;

// if identifier has been provided, portal will allow this specific content to refresh
// refresh under path https://your.host.com/path/{identifier}
identifier?: string;
// if refresh rate is provided, portal will auto refresh this content block.
// valid value is between 30 and 300 (seconds)
refreshRate?: number;

// you can provide SVG icon, portal will use it to populate left side icon.
icon?: SvgContent;

title: string;
titleColor?: ContentColor;

// Portal treat description as markdown. Which allows you to provide rich content.
// System will not accept HTML within, for security reason. Any HTML will be removed.
description?: string;

borderColor?: ContentColor;

value: Array<T>;

interface ListContent extends Content<ContentListItem> {
type: 'list';

interface DescriptionContent extends Content<ContentDescriptionItem> {
type: 'description';

interface ProgressContent extends Content<ContentProgressItem> {
type: 'progress';

interface ContentListItem {
// max length of 200 chars
title: string;
// max length of 1,000 chars. This is for plain text, markdown does not work here.
description?: string;
url?: string;

type ProgressState =
| 'neutral'
| 'queued'
| 'in_progress'
| 'success'
| 'cancelled'
| 'failure';

interface ContentProgressItem {
// max length of 200 chars
title: string;
// max length of 500 chars. portal will treat this as plain text. Markdown does not work here.
description?: string;
state: ProgressState;
url?: string;

interface ContentDescriptionItem {
// max length of 50 chars
title: string;
// max length of 1,000 chars. Markdown does not work here.
detail?: string;
// Type used to determine detail's format. The format is restricted, if you don't know how to use, leave this blank. Portal will treat it as string.
type?: 'string' | 'number' | 'currency' | 'date' | 'date_time' | 'time';

Example payload

"value": [
"type": "description",
"title": "Additional PSA related ticket info",
"description": "This is only an demonstration for what you can achieve. We only provide consultation to utilize this feature.",
"identifier": "ticket-additional-info",
"refreshRate": 180,
"borderColor": "attention",
"value": [
"title": "Time spent",
"type": "number",
"detail": "3945.1"
"title": "Cost",
"type": "currency",
"detail": "2300.34"

Error Response

If your API want to return error, you should use following format. That way our portal can correctly display the error message.

"error": {
"code": "internal_error",
"message": "The system encountered a problem retrieving information; please try again later."

Portal will display as following to help diagnose issue also inform user. You can also return normal content format to make error looks nicer. How easiy you can fix your API determined by your API response, so consider wisely.

Description Content Format

In description content, we allow you to specify the format of your content. If content format is invalid, portal will fallback to normal display.

Special format allow portal to format your data according to user's current environment. Such as date time.

  1. currency: normal number format. e.g. 2300.342 will format as $2,300.34
  2. number: normal number format. e.g. 2300.34 will format as 2,300.34
  3. date: ISO8601 format. e.g. 2022-03-23 will format as 23rd of Mar 2022.
  4. date_time: ISO8601 format. e.g. 2022-03-23T00:00:00Z will format according to user local time. 22nd of Mar 2022, 03:00 PM.
  5. time: ISO8601 format. e.g. 13:30 will format as 01:30 PM.

Refresh Rate

You can provide refresh rate at individual content level, or global contents level. Global level will take priority over individual level when UI performs period check.

The refresh rate in seconds should be provided as an integer that's between 30 and 300 inclusive. UI will ignore the rate if the value is invalid.

Individual Content Request Contract

If you have provided identifier in one of content, portal will allow user to refresh that content. If your API is https://sample.com/your/api/contents. Then we will add identifier at end. Such as https://sample.com/your/api/contents/your-identifier.

The response of your API should be single content. Which is DynamicContent instead of GetContentsResponse.

Individual content query should now aware of query parameter. If your API URL is https://sample.com/your/api/contents?variants=psa_info&variants=security_check. Then, when append identifier, system will only append to URL path. Such as https://sample.com/your/api/contents/psa_info?variants=psa_info&variants=security_check.

Custom SVG Icon

By default, system will provide built in icon for individual content based on its type. You can specify custom icon by using SVG. Let's use following SVG as an example.

<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />

When translate to JSON for our UI to understand, you need to provide 3 properties.

"fill": "currentcolor",
"viewBox": "0 0 24 24",
"content": "<path d="M0 0h24v24H0z" fill="none" /> <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />"

  • fill: This is an optional property, without specify, UI will use currentcolor by default.
    • currentcolor: The text color of local scope
    • none: Do not fill any color. It is useful for certain SVG.
    • HTML color name. Such as red, blue etc.
    • Hash based color, e.g. #000000 as black
  • viewBox: The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.
  • content: The contents within the <svg> HTML tag. Be aware of new line when format in JSON. Replace new line as \n.

Interface Sample

You can view demo by visiting your TECH portal with following link.


How did we do?

Other DeskDirector Features