LiteNet Developer API Release
All checks were successful
Deploy to Server / deploy (push) Successful in 1m55s
All checks were successful
Deploy to Server / deploy (push) Successful in 1m55s
This commit is contained in:
parent
70e12bf4fe
commit
e7a7839f26
|
|
@ -115,10 +115,10 @@ importers:
|
||||||
version: 0.468.0(react@19.1.0)
|
version: 0.468.0(react@19.1.0)
|
||||||
next:
|
next:
|
||||||
specifier: ^15.1.1
|
specifier: ^15.1.1
|
||||||
version: 15.1.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 15.1.1(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
next-plausible:
|
next-plausible:
|
||||||
specifier: ^3.12.4
|
specifier: ^3.12.4
|
||||||
version: 3.12.4(next@15.1.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 3.12.4(next@15.1.1(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: ^0.4.6
|
specifier: ^0.4.6
|
||||||
version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
|
@ -480,6 +480,10 @@ packages:
|
||||||
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
|
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
|
||||||
engines: {node: '>=12.4.0'}
|
engines: {node: '>=12.4.0'}
|
||||||
|
|
||||||
|
'@opentelemetry/api@1.9.0':
|
||||||
|
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||||
|
engines: {node: '>=8.0.0'}
|
||||||
|
|
||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
@ -1618,6 +1622,9 @@ packages:
|
||||||
csstype@3.1.3:
|
csstype@3.1.3:
|
||||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
|
|
||||||
|
csstype@3.2.3:
|
||||||
|
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||||
|
|
||||||
d3-array@3.2.4:
|
d3-array@3.2.4:
|
||||||
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
@ -3483,6 +3490,9 @@ snapshots:
|
||||||
|
|
||||||
'@nolyfill/is-core-module@1.0.39': {}
|
'@nolyfill/is-core-module@1.0.39': {}
|
||||||
|
|
||||||
|
'@opentelemetry/api@1.9.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -4232,7 +4242,7 @@ snapshots:
|
||||||
|
|
||||||
'@types/react@19.1.8':
|
'@types/react@19.1.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.1.3
|
csstype: 3.2.3
|
||||||
|
|
||||||
'@types/unist@2.0.11': {}
|
'@types/unist@2.0.11': {}
|
||||||
|
|
||||||
|
|
@ -4637,6 +4647,8 @@ snapshots:
|
||||||
|
|
||||||
csstype@3.1.3: {}
|
csstype@3.1.3: {}
|
||||||
|
|
||||||
|
csstype@3.2.3: {}
|
||||||
|
|
||||||
d3-array@3.2.4:
|
d3-array@3.2.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
internmap: 2.0.3
|
internmap: 2.0.3
|
||||||
|
|
@ -5789,9 +5801,9 @@ snapshots:
|
||||||
|
|
||||||
natural-compare@1.4.0: {}
|
natural-compare@1.4.0: {}
|
||||||
|
|
||||||
next-plausible@3.12.4(next@15.1.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
next-plausible@3.12.4(next@15.1.1(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
next: 15.1.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
next: 15.1.1(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-dom: 19.1.0(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
|
||||||
|
|
@ -5800,7 +5812,7 @@ snapshots:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-dom: 19.1.0(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
|
||||||
next@15.1.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
next@15.1.1(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 15.1.1
|
'@next/env': 15.1.1
|
||||||
'@swc/counter': 0.1.3
|
'@swc/counter': 0.1.3
|
||||||
|
|
@ -5820,6 +5832,7 @@ snapshots:
|
||||||
'@next/swc-linux-x64-musl': 15.1.1
|
'@next/swc-linux-x64-musl': 15.1.1
|
||||||
'@next/swc-win32-arm64-msvc': 15.1.1
|
'@next/swc-win32-arm64-msvc': 15.1.1
|
||||||
'@next/swc-win32-x64-msvc': 15.1.1
|
'@next/swc-win32-x64-msvc': 15.1.1
|
||||||
|
'@opentelemetry/api': 1.9.0
|
||||||
sharp: 0.33.5
|
sharp: 0.33.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
|
|
|
||||||
3
pnpm-workspace.yaml
Normal file
3
pnpm-workspace.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
allowBuilds:
|
||||||
|
sharp: true
|
||||||
|
unrs-resolver: true
|
||||||
1456
public/api-spec/openapi.json
Normal file
1456
public/api-spec/openapi.json
Normal file
File diff suppressed because it is too large
Load diff
781
public/api-spec/openapi.yaml
Normal file
781
public/api-spec/openapi.yaml
Normal file
|
|
@ -0,0 +1,781 @@
|
||||||
|
openapi: "3.0.3"
|
||||||
|
info:
|
||||||
|
title: LiteNet API
|
||||||
|
description: |
|
||||||
|
LiteNet is a free community PBX based on FreePBX. This API allows you to
|
||||||
|
manage your extension, access voicemails, view conferences, and interact
|
||||||
|
with the LiteNet PBX programmatically.
|
||||||
|
|
||||||
|
**Authentication:** Most endpoints require a Bearer token obtained via
|
||||||
|
Discord OAuth. Pass it in the `Authorization` header:
|
||||||
|
`Authorization: Bearer *** version: "1.0.0"
|
||||||
|
contact:
|
||||||
|
name: LiteNet
|
||||||
|
url: https://litenet.tel
|
||||||
|
servers:
|
||||||
|
- url: https://api.litenet.tel
|
||||||
|
description: Production API
|
||||||
|
- url: http://localhost:3001
|
||||||
|
description: Local development
|
||||||
|
paths:
|
||||||
|
/extensions/me:
|
||||||
|
get:
|
||||||
|
summary: Get current extension
|
||||||
|
description: Returns the authenticated user's extension details,
|
||||||
|
including their Discord profile and PBX device configuration.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Extension details
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ExtensionDetails"
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
/extensions/me/devicestatus:
|
||||||
|
get:
|
||||||
|
summary: Get device registration status
|
||||||
|
description: Returns whether the user's SIP device is currently
|
||||||
|
registered with the PBX. Polled every 5 seconds on the dashboard.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Device status
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
extension:
|
||||||
|
type: string
|
||||||
|
description: The extension number
|
||||||
|
example: "1010"
|
||||||
|
deviceState:
|
||||||
|
type: string
|
||||||
|
description: Human-readable state (e.g. "Registered", "In use")
|
||||||
|
example: In use
|
||||||
|
activeChannels:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
description: Active channel info or null if none
|
||||||
|
example: null
|
||||||
|
/extensions/me/calls:
|
||||||
|
get:
|
||||||
|
summary: List active calls
|
||||||
|
description: Returns all currently active calls for the authenticated
|
||||||
|
user's extension. Polled every 5 seconds on the dashboard.
|
||||||
|
tags:
|
||||||
|
- Calls
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of active calls
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/ActiveCall"
|
||||||
|
delete:
|
||||||
|
summary: Hangup all calls
|
||||||
|
description: Hangs up every active call for the user's extension.
|
||||||
|
tags:
|
||||||
|
- Calls
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: All calls hung up
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Successfully requested termination for 1 call(s) for extension 1010."
|
||||||
|
terminatedChannels:
|
||||||
|
type: array
|
||||||
|
description: List of terminated channel IDs
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: ["PJSIP/1010-00000002"]
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
/extensions/me/callme:
|
||||||
|
post:
|
||||||
|
summary: Call me
|
||||||
|
description: Triggers the PBX to call the user's extension. Supports
|
||||||
|
music on hold and echo test modes.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: mode
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [hold, echo]
|
||||||
|
description: |
|
||||||
|
`hold` — play music on hold
|
||||||
|
`echo` — echo test (play back what you say)
|
||||||
|
- in: query
|
||||||
|
name: callerId
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Custom caller ID to display (defaults to the extension number)
|
||||||
|
- in: query
|
||||||
|
name: autoAnswerMode
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Auto-answer mode for the call
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Call initiated
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Successfully initiated hold call to extension 1010."
|
||||||
|
/extensions/me/resetsecret:
|
||||||
|
post:
|
||||||
|
summary: Reset SIP secret
|
||||||
|
description: Resets the SIP password for the extension. Returns the
|
||||||
|
new secret once — it cannot be retrieved again.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Secret reset
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
newSecret:
|
||||||
|
type: string
|
||||||
|
description: The new SIP secret (displayed once)
|
||||||
|
example: "aB3xK9mP2qR7"
|
||||||
|
/extensions/me/dnd:
|
||||||
|
get:
|
||||||
|
summary: Get Do Not Disturb status
|
||||||
|
description: Returns whether Do Not Disturb is currently enabled.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: DND status
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
extension:
|
||||||
|
type: string
|
||||||
|
description: The extension number
|
||||||
|
example: "1010"
|
||||||
|
dndStatus:
|
||||||
|
type: boolean
|
||||||
|
description: Whether DND is enabled
|
||||||
|
example: false
|
||||||
|
post:
|
||||||
|
summary: Toggle Do Not Disturb
|
||||||
|
description: Enables or disables Do Not Disturb for the extension.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- dndStatus
|
||||||
|
properties:
|
||||||
|
dndStatus:
|
||||||
|
type: boolean
|
||||||
|
description: true to enable, false to disable
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: DND updated
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "DND status for extension 1010 set to true."
|
||||||
|
extension:
|
||||||
|
type: string
|
||||||
|
description: The extension number
|
||||||
|
example: "1010"
|
||||||
|
dndStatus:
|
||||||
|
type: boolean
|
||||||
|
description: Updated DND state
|
||||||
|
example: true
|
||||||
|
/extensions/me/endpoint:
|
||||||
|
get:
|
||||||
|
summary: List registered endpoints
|
||||||
|
description: Returns all SIP endpoints/devices registered to the
|
||||||
|
user's extension. Polled every 10 seconds on the dashboard.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of registered devices
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/RegisteredDevice"
|
||||||
|
|
||||||
|
/extensions/me/voicemails:
|
||||||
|
get:
|
||||||
|
summary: List voicemails
|
||||||
|
description: Returns voicemail messages for the authenticated user.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of voicemails
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Voicemail"
|
||||||
|
/extensions/me/voicemails/{messageId}/download:
|
||||||
|
get:
|
||||||
|
summary: Download voicemail audio
|
||||||
|
description: Downloads the WAV audio file for a specific voicemail.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: messageId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: WAV audio file
|
||||||
|
content:
|
||||||
|
audio/wav:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
/extensions/me/voicemails/{messageId}/move:
|
||||||
|
patch:
|
||||||
|
summary: Move voicemail to folder
|
||||||
|
description: Moves a voicemail into a different folder for organization.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: messageId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- targetFolder
|
||||||
|
properties:
|
||||||
|
targetFolder:
|
||||||
|
type: string
|
||||||
|
enum: [INBOX, Family, Friends, Old, Work, Urgent]
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Voicemail moved
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Voicemail moved from Old to Friends."
|
||||||
|
messageId:
|
||||||
|
type: string
|
||||||
|
description: The voicemail message ID
|
||||||
|
example: "849c9236"
|
||||||
|
sourceFolder:
|
||||||
|
type: string
|
||||||
|
description: Original folder
|
||||||
|
example: Old
|
||||||
|
targetFolder:
|
||||||
|
type: string
|
||||||
|
description: Destination folder
|
||||||
|
example: Friends
|
||||||
|
newMessageNumber:
|
||||||
|
type: string
|
||||||
|
description: New message number after move
|
||||||
|
example: msg0001
|
||||||
|
/extensions/me/voicemails/{messageId}:
|
||||||
|
delete:
|
||||||
|
summary: Delete voicemail
|
||||||
|
description: Permanently deletes a voicemail message.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: messageId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Voicemail deleted
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Voicemail msg0033 deleted permanently from Old."
|
||||||
|
messageId:
|
||||||
|
type: string
|
||||||
|
description: The voicemail message ID
|
||||||
|
example: "37aca380"
|
||||||
|
folder:
|
||||||
|
type: string
|
||||||
|
description: The folder the voicemail was in
|
||||||
|
example: Old
|
||||||
|
originalMessageId:
|
||||||
|
type: string
|
||||||
|
description: The original message number
|
||||||
|
example: msg0033
|
||||||
|
|
||||||
|
/conferences:
|
||||||
|
get:
|
||||||
|
summary: List conference rooms
|
||||||
|
description: Returns all currently active conference rooms and
|
||||||
|
their participant counts.
|
||||||
|
tags:
|
||||||
|
- Conferences
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of conference rooms
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/ConferenceRoom"
|
||||||
|
/conferences/{conferenceId}:
|
||||||
|
get:
|
||||||
|
summary: Get conference participants
|
||||||
|
description: Returns the list of participants currently in a
|
||||||
|
specific conference room.
|
||||||
|
tags:
|
||||||
|
- Conferences
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: conferenceId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of participants
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Participant"
|
||||||
|
/conferences/{conferenceId}/connectme:
|
||||||
|
post:
|
||||||
|
summary: Connect to conference
|
||||||
|
description: Dials the authenticated user's extension and bridges
|
||||||
|
them into the specified conference room.
|
||||||
|
tags:
|
||||||
|
- Conferences
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: conferenceId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Connected to conference
|
||||||
|
|
||||||
|
/system/records:
|
||||||
|
get:
|
||||||
|
summary: Get call statistics
|
||||||
|
description: Returns aggregate call statistics for the LiteNet PBX.
|
||||||
|
Public endpoint — no authentication required.
|
||||||
|
tags:
|
||||||
|
- System
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Call statistics
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/CallRecords"
|
||||||
|
/system/survey:
|
||||||
|
get:
|
||||||
|
summary: Get hardware survey data
|
||||||
|
description: Returns aggregated hardware survey data showing device
|
||||||
|
types, brands, and devices needing categorization.
|
||||||
|
Public endpoint — no authentication required.
|
||||||
|
tags:
|
||||||
|
- System
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Survey data
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SurveyData"
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
BearerAuth:
|
||||||
|
type: http
|
||||||
|
scheme: bearer
|
||||||
|
bearerFormat: UUID
|
||||||
|
description: |
|
||||||
|
Obtain a token via Discord OAuth at `/auth/discord`.
|
||||||
|
Pass it as `Authorization: Bearer ***
|
||||||
|
schemas:
|
||||||
|
ExtensionDetails:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the request was successful
|
||||||
|
example: true
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Extension found successfully"
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
description: Base64-encoded extension identifier
|
||||||
|
example: "ZXh0ZW5zaW9uOjEwMTA="
|
||||||
|
extensionId:
|
||||||
|
type: string
|
||||||
|
description: The 4-digit extension number
|
||||||
|
example: "1010"
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
description: User profile and PBX settings
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Discord display name
|
||||||
|
example: rocord
|
||||||
|
outboundCid:
|
||||||
|
type: string
|
||||||
|
description: Outbound caller ID override
|
||||||
|
example: ""
|
||||||
|
voicemail:
|
||||||
|
type: string
|
||||||
|
description: Voicemail context
|
||||||
|
example: default
|
||||||
|
ringtimer:
|
||||||
|
type: integer
|
||||||
|
description: Ring time in seconds before voicemail
|
||||||
|
example: 0
|
||||||
|
noanswer:
|
||||||
|
type: string
|
||||||
|
description: No-answer destination
|
||||||
|
example: ""
|
||||||
|
noanswerDestination:
|
||||||
|
type: string
|
||||||
|
description: No-answer destination context
|
||||||
|
example: ""
|
||||||
|
noanswerCid:
|
||||||
|
type: string
|
||||||
|
description: Caller ID on no-answer
|
||||||
|
example: ""
|
||||||
|
busyCid:
|
||||||
|
type: string
|
||||||
|
description: Caller ID on busy
|
||||||
|
example: ""
|
||||||
|
sipname:
|
||||||
|
type: string
|
||||||
|
description: SIP display name
|
||||||
|
example: ""
|
||||||
|
extPassword:
|
||||||
|
type: string
|
||||||
|
description: SIP secret (masked in dashboard)
|
||||||
|
example: "REDACTED"
|
||||||
|
coreDevice:
|
||||||
|
type: object
|
||||||
|
description: PBX device configuration
|
||||||
|
properties:
|
||||||
|
deviceId:
|
||||||
|
type: string
|
||||||
|
description: Device identifier
|
||||||
|
example: "1010"
|
||||||
|
dial:
|
||||||
|
type: string
|
||||||
|
description: Asterisk dial string
|
||||||
|
example: PJSIP/1010
|
||||||
|
devicetype:
|
||||||
|
type: string
|
||||||
|
description: Device type (fixed, adhoc, etc.)
|
||||||
|
example: fixed
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
description: Human-readable device description
|
||||||
|
example: rocord
|
||||||
|
emergencyCid:
|
||||||
|
type: string
|
||||||
|
description: Emergency caller ID override
|
||||||
|
example: ""
|
||||||
|
tech:
|
||||||
|
type: string
|
||||||
|
description: SIP technology driver
|
||||||
|
example: pjsip
|
||||||
|
ActiveCall:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
description: Asterisk channel identifier
|
||||||
|
example: PJSIP/1010-00000002
|
||||||
|
uniqueId:
|
||||||
|
type: string
|
||||||
|
description: Unique call identifier
|
||||||
|
example: "1781687772.6"
|
||||||
|
caller:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
type: string
|
||||||
|
description: Caller number
|
||||||
|
example: "1010"
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Caller display name
|
||||||
|
example: "Call Me Test (MusicOnHold)"
|
||||||
|
connectedLine:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
type: string
|
||||||
|
description: Connected line number
|
||||||
|
example: "1010"
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Connected line display name
|
||||||
|
example: "Call Me Test (MusicOnHold)"
|
||||||
|
state:
|
||||||
|
type: string
|
||||||
|
description: Call state (e.g. "Up", "Ring")
|
||||||
|
example: Up
|
||||||
|
duration:
|
||||||
|
type: string
|
||||||
|
description: Call duration in HH:MM:SS format
|
||||||
|
example: "00:01:49"
|
||||||
|
application:
|
||||||
|
type: string
|
||||||
|
description: Asterisk application name
|
||||||
|
example: MusicOnHold
|
||||||
|
applicationData:
|
||||||
|
type: string
|
||||||
|
description: Application data/arguments
|
||||||
|
example: ""
|
||||||
|
RegisteredDevice:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
uri:
|
||||||
|
type: string
|
||||||
|
description: SIP contact URI
|
||||||
|
example: sip:1010@192.168.1.100:5060
|
||||||
|
useragent:
|
||||||
|
type: string
|
||||||
|
description: User-Agent header from the device
|
||||||
|
example: Linphone/4.4.0
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
description: Client IP address
|
||||||
|
example: 192.168.1.100
|
||||||
|
port:
|
||||||
|
type: string
|
||||||
|
description: Client port
|
||||||
|
example: "5060"
|
||||||
|
pingMs:
|
||||||
|
type: string
|
||||||
|
description: Round-trip latency in milliseconds
|
||||||
|
example: "12.34"
|
||||||
|
Voicemail:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
messageId:
|
||||||
|
type: string
|
||||||
|
description: Unique voicemail identifier
|
||||||
|
callerIdNum:
|
||||||
|
type: string
|
||||||
|
description: Caller's phone number
|
||||||
|
callerIdName:
|
||||||
|
type: string
|
||||||
|
description: Caller's name (if available)
|
||||||
|
date:
|
||||||
|
type: string
|
||||||
|
description: Timestamp of the voicemail
|
||||||
|
example: "Wed Mar 18 11:57:09 PM UTC 2026"
|
||||||
|
duration:
|
||||||
|
type: number
|
||||||
|
description: Duration in seconds
|
||||||
|
fileSize:
|
||||||
|
type: integer
|
||||||
|
description: Audio file size in bytes
|
||||||
|
hasAudio:
|
||||||
|
type: boolean
|
||||||
|
description: Whether audio is available for playback
|
||||||
|
folder:
|
||||||
|
type: string
|
||||||
|
enum: [INBOX, Family, Friends, Old, Work, Urgent]
|
||||||
|
description: Current folder
|
||||||
|
originalMessageId:
|
||||||
|
type: string
|
||||||
|
description: Original message ID before any moves
|
||||||
|
ConferenceRoom:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
conferenceId:
|
||||||
|
type: string
|
||||||
|
description: Conference room identifier
|
||||||
|
example: "400"
|
||||||
|
parties:
|
||||||
|
type: integer
|
||||||
|
description: Number of participants
|
||||||
|
example: 1
|
||||||
|
marked:
|
||||||
|
type: integer
|
||||||
|
description: Number of marked participants
|
||||||
|
example: 0
|
||||||
|
locked:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the room is locked
|
||||||
|
example: false
|
||||||
|
Participant:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
description: Asterisk channel identifier
|
||||||
|
callerIdNum:
|
||||||
|
type: string
|
||||||
|
description: Participant's extension number
|
||||||
|
callerIdName:
|
||||||
|
type: string
|
||||||
|
description: Participant's display name
|
||||||
|
muted:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the participant is muted
|
||||||
|
admin:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the participant is a conference admin
|
||||||
|
talking:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the participant is currently speaking
|
||||||
|
CallRecords:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
records:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
total_calls_ever_placed:
|
||||||
|
type: integer
|
||||||
|
description: Total calls since launch
|
||||||
|
example: 5324
|
||||||
|
record_calls:
|
||||||
|
type: object
|
||||||
|
description: Single-day call record
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
date:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
last_updated:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
description: Monthly call totals (e.g. monthly_total_2025-01)
|
||||||
|
SurveyData:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
phoneTypes:
|
||||||
|
type: object
|
||||||
|
description: Device types and their counts
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
example:
|
||||||
|
softphone: 45
|
||||||
|
ip_phone: 23
|
||||||
|
ata: 8
|
||||||
|
brands:
|
||||||
|
type: object
|
||||||
|
description: Device brands and their counts
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
example:
|
||||||
|
Polycom: 12
|
||||||
|
Cisco: 8
|
||||||
|
Yealink: 7
|
||||||
|
needsCategorization:
|
||||||
|
type: array
|
||||||
|
description: Devices that couldn't be automatically categorized
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ua:
|
||||||
|
type: string
|
||||||
|
description: User-Agent string
|
||||||
|
lastUpdated:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: When the survey data was last refreshed
|
||||||
1066
src/app/developers/DevelopersClient.jsx
Normal file
1066
src/app/developers/DevelopersClient.jsx
Normal file
File diff suppressed because it is too large
Load diff
24
src/app/developers/page.jsx
Normal file
24
src/app/developers/page.jsx
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import Header from '@/components/header';
|
||||||
|
import Footer from '@/components/footer';
|
||||||
|
import DevelopersClient from './DevelopersClient';
|
||||||
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
|
function DevelopersPageContent() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Header />
|
||||||
|
<main className="flex-grow">
|
||||||
|
<DevelopersClient />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DevelopersPage() {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
|
<DevelopersPageContent />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -50,6 +50,10 @@ export default function Footer() {
|
||||||
Ban Appeal
|
Ban Appeal
|
||||||
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-blue-400 transition-all duration-300 group-hover:w-full" />
|
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-blue-400 transition-all duration-300 group-hover:w-full" />
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link href="/developers" className="hover:text-blue-400 transition-colors duration-300 relative group">
|
||||||
|
Developers
|
||||||
|
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-blue-400 transition-all duration-300 group-hover:w-full" />
|
||||||
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* Legal links */}
|
{/* Legal links */}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@ export default function Header() {
|
||||||
<Link href="/conferences" className="text-gray-300 hover:text-white" onClick={() => plausible('Nav Click', {props: {section: 'Conferences'}})}>
|
<Link href="/conferences" className="text-gray-300 hover:text-white" onClick={() => plausible('Nav Click', {props: {section: 'Conferences'}})}>
|
||||||
Conferences
|
Conferences
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link href="/developers" className="text-gray-300 hover:text-white" onClick={() => plausible('Nav Click', {props: {section: 'Developers'}})}>
|
||||||
|
Developers
|
||||||
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -151,6 +154,13 @@ export default function Header() {
|
||||||
>
|
>
|
||||||
Conferences
|
Conferences
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/developers"
|
||||||
|
className="text-gray-300 hover:text-white transition-colors px-2 py-2 rounded-md hover:bg-gray-800/50"
|
||||||
|
onClick={() => { plausible('Nav Click', {props: {section: 'Developers'}}); setMobileMenuOpen(false); }}
|
||||||
|
>
|
||||||
|
Developers
|
||||||
|
</Link>
|
||||||
|
|
||||||
<div className="pt-4 border-t border-gray-800 space-y-3">
|
<div className="pt-4 border-t border-gray-800 space-y-3">
|
||||||
<div onClick={() => setMobileMenuOpen(false)}>
|
<div onClick={() => setMobileMenuOpen(false)}>
|
||||||
|
|
|
||||||
781
src/data/api-spec/openapi.yaml
Normal file
781
src/data/api-spec/openapi.yaml
Normal file
|
|
@ -0,0 +1,781 @@
|
||||||
|
openapi: "3.0.3"
|
||||||
|
info:
|
||||||
|
title: LiteNet API
|
||||||
|
description: |
|
||||||
|
LiteNet is a free community PBX based on FreePBX. This API allows you to
|
||||||
|
manage your extension, access voicemails, view conferences, and interact
|
||||||
|
with the LiteNet PBX programmatically.
|
||||||
|
|
||||||
|
**Authentication:** Most endpoints require a Bearer token obtained via
|
||||||
|
Discord OAuth. Pass it in the `Authorization` header:
|
||||||
|
`Authorization: Bearer *** version: "1.0.0"
|
||||||
|
contact:
|
||||||
|
name: LiteNet
|
||||||
|
url: https://litenet.tel
|
||||||
|
servers:
|
||||||
|
- url: https://api.litenet.tel
|
||||||
|
description: Production API
|
||||||
|
- url: http://localhost:3001
|
||||||
|
description: Local development
|
||||||
|
paths:
|
||||||
|
/extensions/me:
|
||||||
|
get:
|
||||||
|
summary: Get current extension
|
||||||
|
description: Returns the authenticated user's extension details,
|
||||||
|
including their Discord profile and PBX device configuration.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Extension details
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ExtensionDetails"
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
/extensions/me/devicestatus:
|
||||||
|
get:
|
||||||
|
summary: Get device registration status
|
||||||
|
description: Returns whether the user's SIP device is currently
|
||||||
|
registered with the PBX. Polled every 5 seconds on the dashboard.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Device status
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
extension:
|
||||||
|
type: string
|
||||||
|
description: The extension number
|
||||||
|
example: "1010"
|
||||||
|
deviceState:
|
||||||
|
type: string
|
||||||
|
description: Human-readable state (e.g. "Registered", "In use")
|
||||||
|
example: In use
|
||||||
|
activeChannels:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
description: Active channel info or null if none
|
||||||
|
example: null
|
||||||
|
/extensions/me/calls:
|
||||||
|
get:
|
||||||
|
summary: List active calls
|
||||||
|
description: Returns all currently active calls for the authenticated
|
||||||
|
user's extension. Polled every 5 seconds on the dashboard.
|
||||||
|
tags:
|
||||||
|
- Calls
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of active calls
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/ActiveCall"
|
||||||
|
delete:
|
||||||
|
summary: Hangup all calls
|
||||||
|
description: Hangs up every active call for the user's extension.
|
||||||
|
tags:
|
||||||
|
- Calls
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: All calls hung up
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Successfully requested termination for 1 call(s) for extension 1010."
|
||||||
|
terminatedChannels:
|
||||||
|
type: array
|
||||||
|
description: List of terminated channel IDs
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: ["PJSIP/1010-00000000"]
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
/extensions/me/callme:
|
||||||
|
post:
|
||||||
|
summary: Call me
|
||||||
|
description: Triggers the PBX to call the user's extension. Supports
|
||||||
|
music on hold and echo test modes.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: mode
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [hold, echo]
|
||||||
|
description: |
|
||||||
|
`hold` — play music on hold
|
||||||
|
`echo` — echo test (play back what you say)
|
||||||
|
- in: query
|
||||||
|
name: callerId
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Custom caller ID to display (defaults to the extension number)
|
||||||
|
- in: query
|
||||||
|
name: autoAnswerMode
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: Auto-answer mode for the call
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Call initiated
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Successfully initiated hold call to extension 1010."
|
||||||
|
/extensions/me/resetsecret:
|
||||||
|
post:
|
||||||
|
summary: Reset SIP secret
|
||||||
|
description: Resets the SIP password for the extension. Returns the
|
||||||
|
new secret once — it cannot be retrieved again.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Secret reset
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
newSecret:
|
||||||
|
type: string
|
||||||
|
description: The new SIP secret (displayed once)
|
||||||
|
example: "aB3xK9mP2qR7"
|
||||||
|
/extensions/me/dnd:
|
||||||
|
get:
|
||||||
|
summary: Get Do Not Disturb status
|
||||||
|
description: Returns whether Do Not Disturb is currently enabled.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: DND status
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
extension:
|
||||||
|
type: string
|
||||||
|
description: The extension number
|
||||||
|
example: "1010"
|
||||||
|
dndStatus:
|
||||||
|
type: boolean
|
||||||
|
description: Whether DND is enabled
|
||||||
|
example: false
|
||||||
|
post:
|
||||||
|
summary: Toggle Do Not Disturb
|
||||||
|
description: Enables or disables Do Not Disturb for the extension.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- dndStatus
|
||||||
|
properties:
|
||||||
|
dndStatus:
|
||||||
|
type: boolean
|
||||||
|
description: true to enable, false to disable
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: DND updated
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "DND status for extension 1010 set to true."
|
||||||
|
extension:
|
||||||
|
type: string
|
||||||
|
description: The extension number
|
||||||
|
example: "1010"
|
||||||
|
dndStatus:
|
||||||
|
type: boolean
|
||||||
|
description: Updated DND state
|
||||||
|
example: true
|
||||||
|
/extensions/me/endpoint:
|
||||||
|
get:
|
||||||
|
summary: List registered endpoints
|
||||||
|
description: Returns all SIP endpoints/devices registered to the
|
||||||
|
user's extension. Polled every 10 seconds on the dashboard.
|
||||||
|
tags:
|
||||||
|
- Extensions
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of registered devices
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/RegisteredDevice"
|
||||||
|
|
||||||
|
/extensions/me/voicemails:
|
||||||
|
get:
|
||||||
|
summary: List voicemails
|
||||||
|
description: Returns voicemail messages for the authenticated user.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of voicemails
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Voicemail"
|
||||||
|
/extensions/me/voicemails/{messageId}/download:
|
||||||
|
get:
|
||||||
|
summary: Download voicemail audio
|
||||||
|
description: Downloads the WAV audio file for a specific voicemail.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: messageId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: WAV audio file
|
||||||
|
content:
|
||||||
|
audio/wav:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
/extensions/me/voicemails/{messageId}/move:
|
||||||
|
patch:
|
||||||
|
summary: Move voicemail to folder
|
||||||
|
description: Moves a voicemail into a different folder for organization.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: messageId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- targetFolder
|
||||||
|
properties:
|
||||||
|
targetFolder:
|
||||||
|
type: string
|
||||||
|
enum: [INBOX, Family, Friends, Old, Work, Urgent]
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Voicemail moved
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Voicemail moved from INBOX to Work."
|
||||||
|
messageId:
|
||||||
|
type: string
|
||||||
|
description: The voicemail message ID
|
||||||
|
example: "849c9236"
|
||||||
|
sourceFolder:
|
||||||
|
type: string
|
||||||
|
description: Original folder
|
||||||
|
example: Old
|
||||||
|
targetFolder:
|
||||||
|
type: string
|
||||||
|
description: Destination folder
|
||||||
|
example: Friends
|
||||||
|
newMessageNumber:
|
||||||
|
type: string
|
||||||
|
description: New message number after move
|
||||||
|
example: msg0000
|
||||||
|
/extensions/me/voicemails/{messageId}:
|
||||||
|
delete:
|
||||||
|
summary: Delete voicemail
|
||||||
|
description: Permanently deletes a voicemail message.
|
||||||
|
tags:
|
||||||
|
- Voicemail
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: messageId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Voicemail deleted
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Voicemail msg0033 deleted permanently from Old."
|
||||||
|
messageId:
|
||||||
|
type: string
|
||||||
|
description: The voicemail message ID
|
||||||
|
example: "37aca380"
|
||||||
|
folder:
|
||||||
|
type: string
|
||||||
|
description: The folder the voicemail was in
|
||||||
|
example: Old
|
||||||
|
originalMessageId:
|
||||||
|
type: string
|
||||||
|
description: The original message number
|
||||||
|
example: msg0033
|
||||||
|
|
||||||
|
/conferences:
|
||||||
|
get:
|
||||||
|
summary: List conference rooms
|
||||||
|
description: Returns all currently active conference rooms and
|
||||||
|
their participant counts.
|
||||||
|
tags:
|
||||||
|
- Conferences
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of conference rooms
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/ConferenceRoom"
|
||||||
|
/conferences/{conferenceId}:
|
||||||
|
get:
|
||||||
|
summary: Get conference participants
|
||||||
|
description: Returns the list of participants currently in a
|
||||||
|
specific conference room.
|
||||||
|
tags:
|
||||||
|
- Conferences
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: conferenceId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: List of participants
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Participant"
|
||||||
|
/conferences/{conferenceId}/connectme:
|
||||||
|
post:
|
||||||
|
summary: Connect to conference
|
||||||
|
description: Dials the authenticated user's extension and bridges
|
||||||
|
them into the specified conference room.
|
||||||
|
tags:
|
||||||
|
- Conferences
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: conferenceId
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Connected to conference
|
||||||
|
|
||||||
|
/system/records:
|
||||||
|
get:
|
||||||
|
summary: Get call statistics
|
||||||
|
description: Returns aggregate call statistics for the LiteNet PBX.
|
||||||
|
Public endpoint — no authentication required.
|
||||||
|
tags:
|
||||||
|
- System
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Call statistics
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/CallRecords"
|
||||||
|
/system/survey:
|
||||||
|
get:
|
||||||
|
summary: Get hardware survey data
|
||||||
|
description: Returns aggregated hardware survey data showing device
|
||||||
|
types, brands, and devices needing categorization.
|
||||||
|
Public endpoint — no authentication required.
|
||||||
|
tags:
|
||||||
|
- System
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Survey data
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SurveyData"
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
BearerAuth:
|
||||||
|
type: http
|
||||||
|
scheme: bearer
|
||||||
|
bearerFormat: UUID
|
||||||
|
description: |
|
||||||
|
Obtain a token via Discord OAuth at `/auth/discord`.
|
||||||
|
Pass it as `Authorization: Bearer ***
|
||||||
|
schemas:
|
||||||
|
ExtensionDetails:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the request was successful
|
||||||
|
example: true
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
description: Status message
|
||||||
|
example: "Extension found successfully"
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
description: Base64-encoded extension identifier
|
||||||
|
example: "S3BlY2lhbFZvaWNlbWFpbE1lc3NhZ2U="
|
||||||
|
extensionId:
|
||||||
|
type: string
|
||||||
|
description: The 4-digit extension number
|
||||||
|
example: "1010"
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
description: User profile and PBX settings
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Discord display name
|
||||||
|
example: rocord
|
||||||
|
outboundCid:
|
||||||
|
type: string
|
||||||
|
description: Outbound caller ID override
|
||||||
|
example: ""
|
||||||
|
voicemail:
|
||||||
|
type: string
|
||||||
|
description: Voicemail context
|
||||||
|
example: default
|
||||||
|
ringtimer:
|
||||||
|
type: integer
|
||||||
|
description: Ring time in seconds before voicemail
|
||||||
|
example: 0
|
||||||
|
noanswer:
|
||||||
|
type: string
|
||||||
|
description: No-answer destination
|
||||||
|
example: ""
|
||||||
|
noanswerDestination:
|
||||||
|
type: string
|
||||||
|
description: No-answer destination context
|
||||||
|
example: ""
|
||||||
|
noanswerCid:
|
||||||
|
type: string
|
||||||
|
description: Caller ID on no-answer
|
||||||
|
example: ""
|
||||||
|
busyCid:
|
||||||
|
type: string
|
||||||
|
description: Caller ID on busy
|
||||||
|
example: ""
|
||||||
|
sipname:
|
||||||
|
type: string
|
||||||
|
description: SIP display name
|
||||||
|
example: ""
|
||||||
|
extPassword:
|
||||||
|
type: string
|
||||||
|
description: SIP secret (masked in dashboard)
|
||||||
|
example: "REDACTED"
|
||||||
|
coreDevice:
|
||||||
|
type: object
|
||||||
|
description: PBX device configuration
|
||||||
|
properties:
|
||||||
|
deviceId:
|
||||||
|
type: string
|
||||||
|
description: Device identifier
|
||||||
|
example: "1010"
|
||||||
|
dial:
|
||||||
|
type: string
|
||||||
|
description: Asterisk dial string
|
||||||
|
example: PJSIP/1010
|
||||||
|
devicetype:
|
||||||
|
type: string
|
||||||
|
description: Device type (fixed, adhoc, etc.)
|
||||||
|
example: fixed
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
description: Human-readable device description
|
||||||
|
example: rocord
|
||||||
|
emergencyCid:
|
||||||
|
type: string
|
||||||
|
description: Emergency caller ID override
|
||||||
|
example: ""
|
||||||
|
tech:
|
||||||
|
type: string
|
||||||
|
description: SIP technology driver
|
||||||
|
example: pjsip
|
||||||
|
ActiveCall:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
description: Asterisk channel identifier
|
||||||
|
example: PJSIP/1010-00000002
|
||||||
|
uniqueId:
|
||||||
|
type: string
|
||||||
|
description: Unique call identifier
|
||||||
|
example: "00000000.0"
|
||||||
|
caller:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
type: string
|
||||||
|
description: Caller number
|
||||||
|
example: "1010"
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Caller display name
|
||||||
|
example: "Call Me Test (Example)"
|
||||||
|
connectedLine:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
type: string
|
||||||
|
description: Connected line number
|
||||||
|
example: "1010"
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Connected line display name
|
||||||
|
example: "Call Me Test (Example)"
|
||||||
|
state:
|
||||||
|
type: string
|
||||||
|
description: Call state (e.g. "Up", "Ring")
|
||||||
|
example: Up
|
||||||
|
duration:
|
||||||
|
type: string
|
||||||
|
description: Call duration in HH:MM:SS format
|
||||||
|
example: "00:01:49"
|
||||||
|
application:
|
||||||
|
type: string
|
||||||
|
description: Asterisk application name
|
||||||
|
example: MusicOnHold
|
||||||
|
applicationData:
|
||||||
|
type: string
|
||||||
|
description: Application data/arguments
|
||||||
|
example: ""
|
||||||
|
RegisteredDevice:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
uri:
|
||||||
|
type: string
|
||||||
|
description: SIP contact URI
|
||||||
|
example: sip:1010@192.168.1.100:5060
|
||||||
|
useragent:
|
||||||
|
type: string
|
||||||
|
description: User-Agent header from the device
|
||||||
|
example: Linphone/4.4.0
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
description: Client IP address
|
||||||
|
example: 192.168.1.100
|
||||||
|
port:
|
||||||
|
type: string
|
||||||
|
description: Client port
|
||||||
|
example: "5060"
|
||||||
|
pingMs:
|
||||||
|
type: string
|
||||||
|
description: Round-trip latency in milliseconds
|
||||||
|
example: "12.34"
|
||||||
|
Voicemail:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
messageId:
|
||||||
|
type: string
|
||||||
|
description: Unique voicemail identifier
|
||||||
|
callerIdNum:
|
||||||
|
type: string
|
||||||
|
description: Caller's phone number
|
||||||
|
callerIdName:
|
||||||
|
type: string
|
||||||
|
description: Caller's name (if available)
|
||||||
|
date:
|
||||||
|
type: string
|
||||||
|
description: Timestamp of the voicemail
|
||||||
|
example: "Wed Mar 18 11:57:09 PM UTC 2026"
|
||||||
|
duration:
|
||||||
|
type: number
|
||||||
|
description: Duration in seconds
|
||||||
|
fileSize:
|
||||||
|
type: integer
|
||||||
|
description: Audio file size in bytes
|
||||||
|
hasAudio:
|
||||||
|
type: boolean
|
||||||
|
description: Whether audio is available for playback
|
||||||
|
folder:
|
||||||
|
type: string
|
||||||
|
enum: [INBOX, Family, Friends, Old, Work, Urgent]
|
||||||
|
description: Current folder
|
||||||
|
originalMessageId:
|
||||||
|
type: string
|
||||||
|
description: Original message ID before any moves
|
||||||
|
ConferenceRoom:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
conferenceId:
|
||||||
|
type: string
|
||||||
|
description: Conference room identifier
|
||||||
|
example: "400"
|
||||||
|
parties:
|
||||||
|
type: integer
|
||||||
|
description: Number of participants
|
||||||
|
example: 1
|
||||||
|
marked:
|
||||||
|
type: integer
|
||||||
|
description: Number of marked participants
|
||||||
|
example: 0
|
||||||
|
locked:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the room is locked
|
||||||
|
example: false
|
||||||
|
Participant:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
description: Asterisk channel identifier
|
||||||
|
callerIdNum:
|
||||||
|
type: string
|
||||||
|
description: Participant's extension number
|
||||||
|
callerIdName:
|
||||||
|
type: string
|
||||||
|
description: Participant's display name
|
||||||
|
muted:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the participant is muted
|
||||||
|
admin:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the participant is a conference admin
|
||||||
|
talking:
|
||||||
|
type: boolean
|
||||||
|
description: Whether the participant is currently speaking
|
||||||
|
CallRecords:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
records:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
total_calls_ever_placed:
|
||||||
|
type: integer
|
||||||
|
description: Total calls since launch
|
||||||
|
example: 5324
|
||||||
|
record_calls:
|
||||||
|
type: object
|
||||||
|
description: Single-day call record
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
date:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
last_updated:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
description: Monthly call totals (e.g. monthly_total_2025-01)
|
||||||
|
SurveyData:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
phoneTypes:
|
||||||
|
type: object
|
||||||
|
description: Device types and their counts
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
example:
|
||||||
|
softphone: 45
|
||||||
|
ip_phone: 23
|
||||||
|
ata: 8
|
||||||
|
brands:
|
||||||
|
type: object
|
||||||
|
description: Device brands and their counts
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
example:
|
||||||
|
Polycom: 12
|
||||||
|
Cisco: 8
|
||||||
|
Yealink: 7
|
||||||
|
needsCategorization:
|
||||||
|
type: array
|
||||||
|
description: Devices that couldn't be automatically categorized
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ua:
|
||||||
|
type: string
|
||||||
|
description: User-Agent string
|
||||||
|
lastUpdated:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: When the survey data was last refreshed
|
||||||
Loading…
Reference in a new issue