Introduction
Welcome to the DSS Keesa API! You can use this API to access Keesa API endpoints.
We have language bindings in Shell, Ruby, JavaScript (using fetch), Nodejs, and Dart! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
Authentication
Overview
Keesa uses JWT (JSON Web Tokens) to authenticate and authorize access to all endpoints except login. The login endpoint returns both an access token and a refresh token.
- Access Token: Used to authenticate API requests. Set in the
Authorization: Bearer <token>header. Expires in 1 hour. - Refresh Token: Used to obtain a new access token when the current one expires. Expires in 10 days.
Login
Authenticates a user with email and password, returning access and refresh tokens along with user information.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/auth/login")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.generate({
user: "user@example.com",
password: "Password123"
})
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'post',
url: 'https://dss.mv/api/v1/auth/login',
headers: {
'Content-Type': 'application/json'
},
data: {
user: 'user@example.com',
password: 'Password123'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request POST 'https://dss.mv/api/v1/auth/login' \
--header 'Content-Type: application/json' \
--data-raw '{
"user": "user@example.com",
"password": "Password123"
}'
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({
"user": "user@example.com",
"password": "Password123"
});
const requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://dss.mv/api/v1/auth/login", requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Response (Status: 200 OK):
{
"access": "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjczNjU5NzUsInVzZXJfaWQiOjEsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSIsImZ1bGxfbmFtZSI6IkpvaG4gRG9lIiwibmlja19uYW1lIjoiSm9obiIsInJvbGVzIjpbImFkbWluIl0sInVzZXJfdHlwZSI6ImFkbWluIiwicGVybWlzc2lvbnMiOnsicHJvamVjdHMiOlsicmVhZCIsIndyaXRlIl0sInRpY2tldHMiOlsicmVhZCIsIndyaXRlIl19LCJzaWduX2luX2NvdW50IjoxfQ.abc123def456",
"access_expires_at": "2021-02-26T02:06:43.000+05:00",
"refresh": "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012",
"refresh_expires_at": "2021-03-08T01:06:43.000+05:00"
}
Error Response (Status: 422 Unprocessable Entity or 401 Unauthorized):
{
"error": "Invalid credentials"
}
Endpoint
POST /api/v1/auth/login
Request Parameters
| Parameter | Required | Description |
|---|---|---|
| user | true | Email address of the user |
| password | true | Password of the user |
Response Fields
| Field | Description |
|---|---|
| access | JWT access token to be used for subsequent API requests |
| access_expires_at | Timestamp when the access token expires |
| refresh | JWT refresh token to be used to obtain a new access token |
| refresh_expires_at | Timestamp when the refresh token expires |
The access token payload contains:
- user_id: ID of the authenticated user
- email: Email address of the user
- full_name: Full name of the user
- nick_name: Nickname of the user
- roles: Array of assigned roles
- user_type: Type of user (e.g., "admin", "customer")
- permissions: Object containing user permissions by resource
- sign_in_count: Number of times the user has signed in
Refresh Token
Obtains a new access token using a valid refresh token. Use this when your access token has expired.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/auth/refresh")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["X-Refresh-Token"] = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012"
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'post',
url: 'https://dss.mv/api/v1/auth/refresh',
headers: {
'X-Refresh-Token': 'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request POST 'https://dss.mv/api/v1/auth/refresh' \
--header 'X-Refresh-Token: eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012'
const myHeaders = new Headers();
myHeaders.append("X-Refresh-Token", "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012");
const requestOptions = {
method: 'POST',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://dss.mv/api/v1/auth/refresh", requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Response (Status: 200 OK):
{
"access": "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Mjc0NDI4NzUsInVzZXJfaWQiOjEsInJvbGVzIjpbImFkbWluIl0sInBlcm1pc3Npb25zIjp7InByb2plY3RzIjpbInJlYWQiLCJ3cml0ZSJdLCJ0aWNrZXRzIjpbInJlYWQiLCJ3cml0ZSJdfX0.def456ghi789",
"access_expires_at": "2021-02-27T02:06:43.000+05:00"
}
Endpoint
POST /api/v1/auth/refresh
Request Headers
| Header | Description |
|---|---|
| X-Refresh-Token | The refresh token obtained from the login endpoint |
Response Fields
| Field | Description |
|---|---|
| access | New JWT access token |
| access_expires_at | Timestamp when the new access token expires |
Logout
Logs out the user by invalidating their access token. Requires the access token in the Authorization header.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/auth/logout")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Delete.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjczNjU5NzUsInVzZXJfaWQiOjEsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSJ9.abc123def456"
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'delete',
url: 'https://dss.mv/api/v1/auth/logout',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjczNjU5NzUsInVzZXJfaWQiOjEsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSJ9.abc123def456'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request DELETE 'https://dss.mv/api/v1/auth/logout' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjczNjU5NzUsInVzZXJfaWQiOjEsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSJ9.abc123def456'
const myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjczNjU5NzUsInVzZXJfaWQiOjEsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSJ9.abc123def456");
const requestOptions = {
method: 'DELETE',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://dss.mv/api/v1/auth/logout", requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Response (Status: 200 OK):
{
"message": "Successfully logged out"
}
Endpoint
DELETE /api/v1/auth/logout
Request Headers
| Header | Description |
|---|---|
| Authorization | Bearer token with the access token from login |
Logout by Refresh Token
Logs out the user by invalidating their refresh token. Use this endpoint if you want to log out using only the refresh token.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/auth/logout_by_refresh")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Delete.new(url)
request["X-Refresh-Token"] = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012"
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'delete',
url: 'https://dss.mv/api/v1/auth/logout_by_refresh',
headers: {
'X-Refresh-Token': 'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request DELETE 'https://dss.mv/api/v1/auth/logout_by_refresh' \
--header 'X-Refresh-Token: eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012'
const myHeaders = new Headers();
myHeaders.append("X-Refresh-Token", "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzAxNDE2NzUsInVzZXJfaWQiOjF9.xyz789uvw012");
const requestOptions = {
method: 'DELETE',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://dss.mv/api/v1/auth/logout_by_refresh", requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Response (Status: 200 OK):
{
"message": "Successfully logged out"
}
Endpoint
DELETE /api/v1/auth/logout_by_refresh
Request Headers
| Header | Description |
|---|---|
| X-Refresh-Token | The refresh token obtained from the login endpoint |
Tickets
Overview
The Tickets API allows you to create, retrieve, and manage support tickets. Tickets represent requests for service, issues, or maintenance work that need to be tracked and resolved.
All endpoints require authentication with a valid access token sent in the Authorization: Bearer <token> header.
Create a Ticket
Creates a new support ticket in the system.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
request["Content-Type"] = "application/json"
request.body = JSON.generate({
ticket: {
title: "Network connection issue",
description: "Internet connection is unstable at the site",
category: "network",
ticket_type: "customer_support",
priority: 3,
product_id: 4
},
customer_id: 20
})
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'post',
url: 'https://dss.mv/api/v1/tickets',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...',
'Content-Type': 'application/json'
},
data: {
ticket: {
title: "Network connection issue",
description: "Internet connection is unstable at the site",
category: "network",
ticket_type: "customer_support",
priority: 3,
product_id: 4
},
customer_id: 20
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request POST 'https://dss.mv/api/v1/tickets' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \
--header 'Content-Type: application/json' \
--data-raw '{
"ticket": {
"title": "Network connection issue",
"description": "Internet connection is unstable at the site",
"category": "network",
"ticket_type": "customer_support",
"priority": 3,
"product_id": 4
},
"customer_id": 20
}'
Response (Status: 201 Created):
{
"id": 2024001,
"ticket_number": "2024001",
"title": "Network connection issue",
"description": "Internet connection is unstable at the site",
"status": "open",
"category": "network",
"ticket_type": "customer_support",
"priority": 3,
"customer_id": 20,
"product_id": 4,
"raised_by_id": 4,
"raised_by": "John Doe",
"created_at": "2024-06-28T10:15:30.000+05:00"
}
Endpoint
POST /api/v1/tickets
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| ticket | object | true | Main ticket object containing ticket details |
| ticket.title | string | true | Title of the ticket |
| ticket.description | string | true | Detailed description of the issue |
| ticket.category | string | true | Ticket category (e.g., network, hardware, software) |
| ticket.ticket_type | string | true | Type of ticket (e.g., customer_support, roc_support, eco_support) |
| ticket.priority | integer | false | Priority level (1-5, where 1 is highest) |
| ticket.product_id | integer | true | ID of the product related to the ticket |
| ticket.reference | string | false | Reference number or ID |
| customer_id | integer | conditional | Customer ID (required if eco_id not provided) |
| eco_id | integer | conditional | ECO/Equipment ID (required if customer_id not provided) |
Response Fields
| Field | Type | Description |
|---|---|---|
| id | integer | Internal ticket ID |
| ticket_number | string | Unique ticket number |
| title | string | Ticket title |
| description | string | Ticket description |
| status | string | Current ticket status (open, in_progress, closed, etc.) |
| category | string | Ticket category |
| ticket_type | string | Ticket type |
| priority | integer | Priority level |
| customer_id | integer | Associated customer ID |
| product_id | integer | Associated product ID |
| raised_by_id | integer | User ID who created the ticket |
| raised_by | string | Name of user who created the ticket |
| created_at | string | Timestamp when ticket was created |
Get All Tickets
Retrieves all tickets accessible to the current user. The returned tickets vary based on the user's role and permissions.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...'
Response (Status: 200 OK):
{
"data": {
"tickets": [
{
"id": 2024001,
"ticket_number": "2024001",
"title": "Network connection issue",
"customer": "Customer A",
"description": "Internet connection is unstable",
"status": "open",
"priority": 3,
"contact_number": 7735241,
"contact_name": "John",
"raised_on": "2024-06-28T10:15:30.000+05:00",
"raised_by": "Jane Doe",
"assigned_to": "John Smith",
"ticket_type": "customer_support",
"category": "network",
"image_urls": [],
"closed_date": null,
"ticket_notes": [
{
"comment": "Investigating the issue",
"added_on": "2024-06-28T12:30:15.000+05:00",
"commented_by": "John Doe (John)"
}
]
}
]
}
}
Endpoint
GET /api/v1/tickets
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | false | Number of tickets to return (default: 20) |
| open_page | integer | false | Page number for open tickets (default: 1) |
| closed_page | integer | false | Page number for closed tickets (default: 1) |
| active_page | integer | false | Page number for active tickets (default: 1) |
Response Fields
| Field | Type | Description |
|---|---|---|
| tickets | array | Array of ticket objects |
| id | integer | Ticket ID |
| ticket_number | string | Unique ticket number |
| title | string | Ticket title |
| description | string | Ticket description |
| status | string | Current status |
| priority | integer | Priority level |
| customer | string | Customer name |
| contact_number | integer | Customer contact number |
| contact_name | string | Contact person name |
| raised_on | string | When ticket was created |
| raised_by | string | User who created it |
| assigned_to | string | User assigned to the ticket (may be null) |
| ticket_type | string | Type of ticket |
| category | string | Ticket category |
| image_urls | array | URLs of attached images |
| closed_date | string | When ticket was closed (null if open) |
| ticket_notes | array | Array of notes added to the ticket |
Get Specific Ticket
Retrieves details for a single ticket by ID or ticket number.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/2024001")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets/2024001',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets/2024001' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...'
Response (Status: 200 OK):
{
"data": {
"ticket": {
"id": 2024001,
"ticket_number": "2024001",
"title": "Network connection issue",
"customer": "Customer A",
"description": "Internet connection is unstable at the site",
"status": "open",
"priority": 3,
"contact_number": 7735241,
"contact_name": "John",
"raised_on": "2024-06-28T10:15:30.000+05:00",
"raised_by": "Jane Doe",
"assigned_to": "John Smith",
"ticket_type": "customer_support",
"category": "network",
"image_urls": ["https://example.com/image1.jpg"],
"closed_date": null,
"ticket_statuses": [
{
"id": 1,
"status": "open",
"created_at": "2024-06-28T10:15:30.000+05:00"
}
],
"ticket_notes": [
{
"comment": "Investigating the issue",
"added_on": "2024-06-28T12:30:15.000+05:00",
"commented_by": "John Doe (John)"
}
]
}
}
}
Endpoint
GET /api/v1/tickets/<id>
URL Parameters
| Parameter | Type | Description |
|---|---|---|
| id | integer | Ticket ID |
Get Tickets by Type
Retrieves tickets filtered by ticket type and status.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/tickets_by_type?limit=10&order=desc")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
request["Content-Type"] = "application/json"
request.body = JSON.generate({
ticket: {
type: "customer_support",
status: "open"
}
})
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets/tickets_by_type?limit=10&order=desc',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...',
'Content-Type': 'application/json'
},
data: {
ticket: {
type: "customer_support",
status: "open"
}
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets/tickets_by_type?limit=10&order=desc' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \
--header 'Content-Type: application/json' \
--data-raw '{
"ticket": {
"type": "customer_support",
"status": "open"
}
}'
Response (Status: 200 OK):
{
"data": {
"count": 5,
"tickets": [
{
"id": 2024001,
"ticket_number": "2024001",
"title": "Network issue",
"customer": "Customer A",
"description": "Connection problems",
"status": "open",
"priority": 3,
"contact_number": 7735241,
"contact_name": "John",
"raised_on": "2024-06-28T10:15:30.000+05:00",
"raised_by": "Jane Doe",
"assigned_to": "John Smith",
"ticket_type": "customer_support",
"category": "network",
"image_urls": [],
"closed_date": null,
"ticket_notes": []
}
]
}
}
Endpoint
GET /api/v1/tickets/tickets_by_type
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | false | Number of tickets to return (default: 20) |
| order | string | false | Sort order: 'asc' or 'desc' (default: desc) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| ticket | object | true | Ticket filter object |
| ticket.type | string | true | Ticket type to filter by |
| ticket.status | string | true | Ticket status to filter by |
Get Tickets by Category
Retrieves tickets filtered by category.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/tickets_by_category?category=network&limit=10&page=1")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets/tickets_by_category?category=network&limit=10&page=1',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets/tickets_by_category?category=network&limit=10&page=1' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...'
Response (Status: 200 OK):
{
"data": {
"tickets": [
{
"id": 2024001,
"ticket_number": "2024001",
"title": "Network issue",
"customer": "Customer A",
"description": "Connection problems",
"status": "open",
"priority": 3,
"raised_on": "2024-06-28T10:15:30.000+05:00",
"raised_by": "Jane Doe",
"assigned_to": "John Smith",
"ticket_type": "customer_support",
"category": "network",
"closed_date": null
}
]
}
}
Endpoint
GET /api/v1/tickets/tickets_by_category
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| category | string | true | Ticket category to filter by |
| limit | integer | false | Number of tickets to return (default: 20) |
| page | integer | false | Page number for pagination (default: 1) |
| order | string | false | Sort order: 'asc' or 'desc' (default: desc) |
Get Tickets for Customer
Retrieves tickets for a specific customer (customer endpoint).
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/tickets_of_customer?customer_id=20&status=open&limit=10")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets/tickets_of_customer?customer_id=20&status=open&limit=10',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets/tickets_of_customer?customer_id=20&status=open&limit=10' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...'
Response (Status: 200 OK):
{
"data": {
"tickets": [
{
"id": 2024001,
"ticket_number": "2024001",
"title": "Network issue",
"status": "open",
"priority": 3,
"raised_on": "2024-06-28T10:15:30.000+05:00",
"assigned_to": "John Smith",
"ticket_type": "customer_support",
"category": "network"
}
]
}
}
Endpoint
GET /api/v1/tickets/tickets_of_customer
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| customer_id | integer | true | Customer ID to retrieve tickets for |
| status | string | false | Filter by status (open, closed, on_hold, etc.) |
| limit | integer | false | Number of tickets to return (default: 20) |
| order | string | false | Sort order: 'asc' or 'desc' (default: desc) |
Update Ticket Status
Updates the status of a ticket.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/2024001/status_update")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
request["Content-Type"] = "application/json"
request.body = JSON.generate({
ticket: {
status: "in_progress",
closed_date: "2024-06-28"
}
})
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'post',
url: 'https://dss.mv/api/v1/tickets/2024001/status_update',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...',
'Content-Type': 'application/json'
},
data: {
ticket: {
status: "in_progress",
closed_date: "2024-06-28"
}
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request POST 'https://dss.mv/api/v1/tickets/2024001/status_update' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \
--header 'Content-Type: application/json' \
--data-raw '{
"ticket": {
"status": "in_progress",
"closed_date": "2024-06-28"
}
}'
Response (Status: 200 OK):
{
"message": "Ticket status changed successfully"
}
Error Response (Status: 422 Unprocessable Entity):
{
"error": "Please assign an engineer before changing the ticket status"
}
Endpoint
POST /api/v1/tickets/<id>/status_update
URL Parameters
| Parameter | Type | Description |
|---|---|---|
| id | integer | Ticket ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| ticket | object | true | Ticket object with status update |
| ticket.status | string | true | New status for the ticket |
| ticket.closed_date | string | false | Date when ticket is closed (required if status is 'closed') |
Response
| Field | Type | Description |
|---|---|---|
| message | string | Success message |
Add Ticket Note
Adds a note/comment to an existing ticket.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/add_ticket_note")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
request["Content-Type"] = "application/json"
request.body = JSON.generate({
ticket_note: {
note: "Issue has been partially resolved"
},
ticket_number: "2024001"
})
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'post',
url: 'https://dss.mv/api/v1/tickets/add_ticket_note',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...',
'Content-Type': 'application/json'
},
data: {
ticket_note: {
note: "Issue has been partially resolved"
},
ticket_number: "2024001"
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request POST 'https://dss.mv/api/v1/tickets/add_ticket_note' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \
--header 'Content-Type: application/json' \
--data-raw '{
"ticket_note": {
"note": "Issue has been partially resolved"
},
"ticket_number": "2024001"
}'
Response (Status: 201 Created):
{
"success": {
"ticket_number": "2024001",
"comment": "Issue has been partially resolved"
}
}
Endpoint
POST /api/v1/tickets/add_ticket_note
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| ticket_note | object | true | Ticket note object |
| ticket_note.note | string | true | The note/comment text |
| ticket_number | string | true | Ticket number to add note to |
Response Fields
| Field | Type | Description |
|---|---|---|
| ticket_number | string | Ticket number the note was added to |
| comment | string | The note that was added |
Get Ticket Notes
Retrieves all notes/comments for a specific ticket.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/get_ticket_notes")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
request["Content-Type"] = "application/json"
request.body = JSON.generate({
ticket_number: "2024001"
})
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets/get_ticket_notes',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...',
'Content-Type': 'application/json'
},
data: {
ticket_number: "2024001"
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets/get_ticket_notes' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \
--header 'Content-Type: application/json' \
--data-raw '{
"ticket_number": "2024001"
}'
Response (Status: 200 OK):
{
"data": {
"count": 2,
"notes": [
{
"id": 271,
"note": "Issue investigation started",
"user_name": "John Doe",
"user_nick": "John",
"commented_on": "10:30 06/28/2024"
},
{
"id": 272,
"note": "Issue has been partially resolved",
"user_name": "Jane Smith",
"user_nick": "Jane",
"commented_on": "14:45 06/28/2024"
}
]
}
}
Endpoint
GET /api/v1/tickets/get_ticket_notes
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| ticket_number | string | true | Ticket number to retrieve notes for |
Response Fields
| Field | Type | Description |
|---|---|---|
| count | integer | Number of notes for the ticket |
| notes | array | Array of note objects |
| id | integer | Note ID |
| note | string | Note content |
| user_name | string | Full name of user who added the note |
| user_nick | string | Nickname of user who added the note |
| commented_on | string | Timestamp when note was added |
Get Specific Ticket for Bot
Internal endpoint used by bot integrations to verify a ticket belongs to a specific customer.
Example requests:
require "uri"
require "net/http"
url = URI("https://dss.mv/api/v1/tickets/2024001/get_specific_ticket_for_bot?customer_id=20")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer eyJhbGciOiJIUzI1NiJ9..."
response = http.request(request)
puts response.read_body
const axios = require('axios');
const config = {
method: 'get',
url: 'https://dss.mv/api/v1/tickets/2024001/get_specific_ticket_for_bot?customer_id=20',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9...'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
curl --location --request GET 'https://dss.mv/api/v1/tickets/2024001/get_specific_ticket_for_bot?customer_id=20' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...'
Response (Status: 200 OK):
{
"data": {
"ticket": {
"id": 2024001,
"ticket_number": "2024001",
"title": "Network issue",
"customer_id": 20,
"status": "open",
"description": "Connection problems"
}
}
}
Error Response (Status: 404 Not Found):
{
"error": "Ticket not found"
}
Endpoint
GET /api/v1/tickets/<id>/get_specific_ticket_for_bot
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | integer | true | Ticket ID |
| customer_id | integer | true | Customer ID to verify ticket ownership |
Response Codes
DSS Keesa API uses the following error codes:
Error Codes
| Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request is invalid. |
| 401 | Unauthorized -- Your access token has expired or is invalid. |
| 403 | Forbidden -- You're not authorized to access this resource. |
| 404 | Not Found -- The specified resource could not be found. |
| 418 | I'm a teapot -- Keesa server refuses the attempt to brew coffee with a teapot. |
| 422 | Unprocessable Entity -- Requested data could not be processed. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Success Codes
| Code | Meaning |
|---|---|
| 200 | OK -- Your request has succeeded. |
| 201 | Created -- The new resource you sent has been successfully created. |
| 202 | Accepted -- Your request has been accepted. |
| 204 | No Content -- Response has no content for the request. |
Reference List
Products
| ID | Product |
|---|---|
| 1 | PABX |
| 2 | Switch |
| 3 | Router |
| 4 | WIFI |
| 5 | DATA |
| 6 | GPON |
| 7 | Networks - Admin |
| 8 | Networks - Staff |
| 9 | Networks - Guest |
| 10 | CCTV Network |
| 11 | CCTV Servers |
| 12 | iHTV |
| 13 | Survey |
| 14 | CATV |
| 15 | TEL NETWORK |
| 16 | CORE NETWORK |
| 17 | IPTV |
| 18 | GATEWAY |
| 19 | Rejected - NWR |
| 20 | Access Control |
| 21 | Pending Classification |
| 22 | School Network |
| 23 | DJA Network |
| 24 | Eco |
Ticket Category
| Category | Key |
|---|---|
| Service Order | service_order |
| Fault | fault |
| Survey | survey |
Ticket Types
| Type | Key |
|---|---|
| ROC Support | roc_support |
| Project Support | project_support |
| Remote PMC | remote_support |
| Cross Department Support | cross_department_support |
| Customer Support | customer_support |
| Eco Support | eco_support |
| Routine Maintenance | routine_maintenance |