Registers the technician’s own routes: the socket, the availability toggle, and the queue.
This page is generated from the Depot route table. Every operation carries the permission it needs and the anchor an agent can link to.
POST /api/v1/chat/available
Section titled “POST /api/v1/chat/available”POSTshared facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
setAvailable is the explicit toggle.
It is REST rather than a socket frame because it is a decision: a technician who says they are taking chats and then loses their connection has still said it, and the answer has to be a status code they can see.
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
availablerequired | boolean |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, object | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
409 | application/problem+json, ProblemDetails | Open the chat console before marking yourself available. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/chat/available' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "available": false}'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "available": false}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/available' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/available"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "available": False,}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "available": false}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/available", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/available";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "available": false }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "available": false}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/available");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/chat/presence
Section titled “GET /api/v1/chat/presence”GETshared facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Presence
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatPresenceResponse | Success. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
availablerequired | boolean | |
awayrequired | boolean | |
awayMinutesrequired | integer | |
connectedrequired | boolean | |
displayName | string | |
heldrequired | array of Card | |
held[].agentId | string | |
held[].assignedTo | string | |
held[].clientName | string | |
held[].clientPublicIdrequired | string | |
held[].hostname | string | |
held[].rating | integer | |
held[].requestedAtrequired | string (date-time) | |
held[].requesterId | string | |
held[].requesterName | string | |
held[].sessionIdrequired | string | |
held[].siteId | string | |
held[].statusrequired | string | |
held[].ticketId | string | |
held[].waitingSecondsrequired | integer | |
holdingrequired | integer | |
maxConcurrentrequired | integer | |
offersrequired | array of Card | |
offers[].agentId | string | |
offers[].assignedTo | string | |
offers[].clientName | string | |
offers[].clientPublicIdrequired | string | |
offers[].hostname | string | |
offers[].rating | integer | |
offers[].requestedAtrequired | string (date-time) | |
offers[].requesterId | string | |
offers[].requesterName | string | |
offers[].sessionIdrequired | string | |
offers[].siteId | string | |
offers[].statusrequired | string | |
offers[].ticketId | string | |
offers[].waitingSecondsrequired | integer | |
poolrequired | string | |
queueSecondsrequired | integer | |
userPublicIdrequired | string |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/chat/presence' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/chat/presence' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/presence"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/chat/presence", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/presence";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/chat/presence");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/chat/queue
Section titled “GET /api/v1/chat/queue”GETshared facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
queue is the waiting list.
With a tenant on the request it is that client’s queue, which is every mode but msp. Without one it is the msp fan-out: one request, one sort, and one honest statement about which client databases could not be read.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatQueueResponse | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No chat matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ChatSessionView | |
items[].acceptedAt | string (date-time) or null | |
items[].agentId | string | |
items[].assignedUserId | string | |
items[].clientName | string | |
items[].clientPublicIdrequired | string | |
items[].endedAt | string (date-time) or null | |
items[].endedBy | string | |
items[].hostname | string | |
items[].publicIdrequired | string | |
items[].ratingrequired | integer | |
items[].requestedAtrequired | string (date-time) | |
items[].requesterId | string | |
items[].requesterName | string | |
items[].siteId | string | |
items[].statusrequired | string | |
items[].ticketId | string | |
items[].waitingSecondsrequired | integer | |
techniciansOnlinerequired | integer | |
unavailableClientsrequired | array of string |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/chat/queue' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/chat/queue' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/queue"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/chat/queue", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/queue";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/chat/queue");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/chat/sessions
Section titled “GET /api/v1/chat/sessions”GETtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
List sessions
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
agentId | query | string | No | |
assignedTo | query | string | No | |
dir | query | string, one of asc, desc | No | Sort direction. |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
promoted | query | string | No | |
q | query | string | No | Free-text search term. |
rating | query | string | No | |
requesterId | query | string | No | |
siteId | query | string | No | |
sort | query | string, one of ended, requested | No | Sort key. |
status | query | string, one of active, ended, missed, waiting | No | Comma-separated set. An unrecognised value is refused. |
ticketId | query | string | No | |
unassigned | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultChatSessionView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No chat matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ChatSessionView | |
items[].acceptedAt | string (date-time) or null | |
items[].agentId | string | |
items[].assignedUserId | string | |
items[].clientName | string | |
items[].clientPublicIdrequired | string | |
items[].endedAt | string (date-time) or null | |
items[].endedBy | string | |
items[].hostname | string | |
items[].publicIdrequired | string | |
items[].ratingrequired | integer | |
items[].requestedAtrequired | string (date-time) | |
items[].requesterId | string | |
items[].requesterName | string | |
items[].siteId | string | |
items[].statusrequired | string | |
items[].ticketId | string | |
items[].waitingSecondsrequired | integer | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/chat/sessions?agentId=<agentId>&assignedTo=<assignedTo>&dir=asc&page=0&pageSize=0&promoted=<promoted>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/chat/sessions?agentId=<agentId>&assignedTo=<assignedTo>&dir=asc&page=0&pageSize=0&promoted=<promoted>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions"params = { "agentId": "<agentId>", "assignedTo": "<assignedTo>", "dir": "asc", "page": "0", "pageSize": "0", "promoted": "<promoted>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/chat/sessions?agentId=<agentId>&assignedTo=<assignedTo>&dir=asc&page=0&pageSize=0&promoted=<promoted>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/chat/sessions");url.searchParams.set("agentId", "<agentId>");url.searchParams.set("assignedTo", "<assignedTo>");url.searchParams.set("dir", "asc");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");url.searchParams.set("promoted", "<promoted>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/chat/sessions?agentId=<agentId>&assignedTo=<assignedTo>&dir=asc&page=0&pageSize=0&promoted=<promoted>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/chat/sessions/{sessionID}
Section titled “GET /api/v1/chat/sessions/{sessionID}”GETtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Get session
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatSessionView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptedAt | string (date-time) or null | |
agentId | string | |
assignedUserId | string | |
clientName | string | |
clientPublicIdrequired | string | |
endedAt | string (date-time) or null | |
endedBy | string | |
hostname | string | |
publicIdrequired | string | |
ratingrequired | integer | |
requestedAtrequired | string (date-time) | |
requesterId | string | |
requesterName | string | |
siteId | string | |
statusrequired | string | |
ticketId | string | |
waitingSecondsrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/chat/sessions/<sessionID>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/chat/sessions/<sessionID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/chat/sessions/<sessionID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/accept
Section titled “POST /api/v1/chat/sessions/{sessionID}/accept”POSTtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Accept
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatSessionView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptedAt | string (date-time) or null | |
agentId | string | |
assignedUserId | string | |
clientName | string | |
clientPublicIdrequired | string | |
endedAt | string (date-time) or null | |
endedBy | string | |
hostname | string | |
publicIdrequired | string | |
ratingrequired | integer | |
requestedAtrequired | string (date-time) | |
requesterId | string | |
requesterName | string | |
siteId | string | |
statusrequired | string | |
ticketId | string | |
waitingSecondsrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/accept' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/accept' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/accept"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/accept", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/accept";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/accept");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/decline
Section titled “POST /api/v1/chat/sessions/{sessionID}/decline”POSTtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
Decline
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/decline' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/decline' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/decline"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/decline", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/decline";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/decline");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/end
Section titled “POST /api/v1/chat/sessions/{sessionID}/end”POSTtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
End
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
endedByrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatSessionView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptedAt | string (date-time) or null | |
agentId | string | |
assignedUserId | string | |
clientName | string | |
clientPublicIdrequired | string | |
endedAt | string (date-time) or null | |
endedBy | string | |
hostname | string | |
publicIdrequired | string | |
ratingrequired | integer | |
requestedAtrequired | string (date-time) | |
requesterId | string | |
requesterName | string | |
siteId | string | |
statusrequired | string | |
ticketId | string | |
waitingSecondsrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/end' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "endedBy": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "endedBy": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/end' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/end"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "endedBy": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "endedBy": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/end", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/end";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "endedBy": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "endedBy": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/end");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/chat/sessions/{sessionID}/messages
Section titled “GET /api/v1/chat/sessions/{sessionID}/messages”GETtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
transcript is the read this feature is most careful about.
chat:read is the reviewer’s permission, and a technician does not hold it. But a technician may always re-read a conversation THEY personally handled: it is their own work, they were a party to it, and refusing would mean somebody could not check what they promised a customer an hour ago. That is the same shape Core’s messages route takes with requireAnyPermission.
Anything else - a technician reading a colleague’s chat - is refused, and a read by somebody who did not handle it is written to the audit chain even when it is allowed, because the reviewer’s read is the one nothing else records.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
since | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, array of ChatMessageView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
[].author | string | |
[].authorId | string | |
[].bodyrequired | string | |
[].createdAtrequired | string (date-time) | |
[].idrequired | integer | int64. |
[].publicIdrequired | string | |
[].senderrequired | string |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages?since=<since>' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages?since=<since>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages"params = { "since": "<since>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages?since=<since>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages");url.searchParams.set("since", "<since>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages?since=<since>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/messages
Section titled “POST /api/v1/chat/sessions/{sessionID}/messages”POSTtenant facehosteditmspremote
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
reply is the technician’s line.
Only the technician HOLDING the conversation may add one: a second technician typing into somebody else’s chat would appear to the customer as one person contradicting themselves.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
bodyrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ChatMessageView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
author | string | |
authorId | string | |
bodyrequired | string | |
createdAtrequired | string (date-time) | |
idrequired | integer | int64. |
publicIdrequired | string | |
senderrequired | string |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "body": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "body": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "body": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "body": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "body": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "body": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/messages");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/promote
Section titled “POST /api/v1/chat/sessions/{sessionID}/promote”POSTtenant facehosteditmspremote
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
promote raises a NEW ticket from the conversation, through the same path the missed-chat fallback uses.
A conversation that already has a ticket is refused: two tickets for one conversation is two queues for one problem.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, object | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/promote' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/promote' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/promote"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/promote", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/promote";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/promote");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/rate
Section titled “POST /api/v1/chat/sessions/{sessionID}/rate”POSTtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
rate records the thumbs on a finished conversation.
It exists on this face so a rating given out of band - over the phone, or on a machine that went off before the tray could send it - can still be recorded. The store refuses a second rating and refuses one on a chat that has not ended, so neither of those is checked again here.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
commentrequired | string | |
ratingrequired | integer |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatSessionView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptedAt | string (date-time) or null | |
agentId | string | |
assignedUserId | string | |
clientName | string | |
clientPublicIdrequired | string | |
endedAt | string (date-time) or null | |
endedBy | string | |
hostname | string | |
publicIdrequired | string | |
ratingrequired | integer | |
requestedAtrequired | string (date-time) | |
requesterId | string | |
requesterName | string | |
siteId | string | |
statusrequired | string | |
ticketId | string | |
waitingSecondsrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/rate' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "comment": "string", "rating": 0}'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "comment": "string", "rating": 0}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/rate' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/rate"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "comment": "string", "rating": 0,}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "comment": "string", "rating": 0}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/rate", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/rate";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "comment": "string", "rating": 0 }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "comment": "string", "rating": 0}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/rate");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/chat/sessions/{sessionID}/ticket
Section titled “POST /api/v1/chat/sessions/{sessionID}/ticket”POSTtenant facehosteditmspremoteIdempotent
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
linkTicket points a conversation at a ticket that already exists, for the common case of a chat about something already filed.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
sessionID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
ticketIdrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChatSessionView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
403 | application/problem+json, ProblemDetails | Another technician is on this chat. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
409 | application/problem+json, ProblemDetails | Another technician is already on this chat. |
500 | application/problem+json, ProblemDetails | No client context in request. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptedAt | string (date-time) or null | |
agentId | string | |
assignedUserId | string | |
clientName | string | |
clientPublicIdrequired | string | |
endedAt | string (date-time) or null | |
endedBy | string | |
hostname | string | |
publicIdrequired | string | |
ratingrequired | integer | |
requestedAtrequired | string (date-time) | |
requesterId | string | |
requesterName | string | |
siteId | string | |
statusrequired | string | |
ticketId | string | |
waitingSecondsrequired | integer |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.curl -X POST 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/ticket' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -b 'outpost_console=<console-session>' \ --data '{ "ticketId": "string"}'# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "ticketId": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/chat/sessions/<sessionID>/ticket' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/ticket"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "ticketId": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "ticketId": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/ticket", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/sessions/<sessionID>/ticket";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "ticketId": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "ticketId": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/chat/sessions/<sessionID>/ticket");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/chat/stream
Section titled “GET /api/v1/chat/stream”GETshared facehosteditmspremoteIdempotentWebSocket
From an MSP console, prefix the path with /api/v1/clients/{clientID} to reach one client.
Source: [object Object]
stream attaches one console window.
A technician may have several open at once - several monitors, sometimes several machines - and each gets its own Subscription. Every frame reaches all of them; an offer rings in exactly one and the rest are told where it went.
Every rejection happens BEFORE the upgrade, so a console that cannot connect gets a JSON problem document it can render rather than a socket that closes with no explanation - the same discipline liveMetrics keeps, and the reason the window cap is asked as a question here rather than enforced by evicting somebody’s oldest console.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
101 | None | Switching protocols. The connection continues as a websocket; see x-outpost-transport. |
401 | application/problem+json, ProblemDetails | Authentication is required. |
409 | application/problem+json, ProblemDetails | The chat console is already open in as many windows as this desk allows. Close one and try again. |
503 | application/problem+json, ProblemDetails | Live chat is not available on this server. |
Request samples
Section titled “Request samples”# Sign in first. outpost_console is a session cookie, so send it with every request.# This endpoint upgrades to a WebSocket. The sample shows the handshake only.# This operation is idempotent. Repeating it does not repeat its effect.curl -X GET 'https://depot.example.com/api/v1/chat/stream' \ -H 'X-CSRF-Token: <csrf-token>' \ -H 'Accept: application/json' \ -b 'outpost_console=<console-session>'# Sign in first. outpost_console is a session cookie, so send it with every request.# This endpoint upgrades to a WebSocket. The sample shows the handshake only.# This operation is idempotent. Repeating it does not repeat its effect.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/chat/stream' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.# This endpoint upgrades to a WebSocket. The sample shows the handshake only.# This operation is idempotent. Repeating it does not repeat its effect.
import requests
url = "https://depot.example.com/api/v1/chat/stream"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.// This endpoint upgrades to a WebSocket. The sample shows the handshake only.// This operation is idempotent. Repeating it does not repeat its effect.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/chat/stream", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// This endpoint upgrades to a WebSocket. The sample shows the handshake only.// This operation is idempotent. Repeating it does not repeat its effect.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/chat/stream";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.// This endpoint upgrades to a WebSocket. The sample shows the handshake only.// This operation is idempotent. Repeating it does not repeat its effect.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/chat/stream");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());Content is licensed CC BY 4.0. Code samples are MIT. Outpost and the Outpost mark are trademarks of Outpost Business Solutions, PBC and are not covered by either license.