curl --request GET \
--url https://api.protodesk.io/v1/realtime/events/poll \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.protodesk.io/v1/realtime/events/poll"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.protodesk.io/v1/realtime/events/poll', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.protodesk.io/v1/realtime/events/poll",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.protodesk.io/v1/realtime/events/poll"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.protodesk.io/v1/realtime/events/poll")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.protodesk.io/v1/realtime/events/poll")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"type": "<string>",
"resourceType": "<string>",
"resourceId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"conversationId": "<string>"
}
],
"nextCursor": "<string>",
"hasMore": true,
"pollAfterSeconds": 3
}{
"error": {
"code": "route.not_found",
"message": "Not found",
"requestId": "req_x6q5vl75f5d53m7oet2k4r5w6a"
}
}Check workspace event notifications
Bounded, immediate JSON polling for REST and MCP. Requires realtime:read. The first call without a cursor returns no events and a starting nextCursor. Pass that cursor on subsequent calls, keeping the same filters, to read up to 100 notifications in chronological order. Save nextCursor after processing a page; retry the same input cursor to replay that page. Notifications contain resource identifiers and event types only, never message bodies, outbox payloads or private AI results. Fetch current resources using their separate read scopes. On hasMore, drain the next page; otherwise wait at least pollAfterSeconds before polling again. Cursors are workspace-specific and differ from SSE event IDs. Invalid or unavailable cursors return 400; restart and reconcile resources rather than silently assuming no changes. This is a change-hint feed, not an exactly-once delivery log: reconcile authoritative resource state, and use webhooks for durable background processing. MCP calls do not create a subscription or schedule future checks. Resource IDs and event types are visible across the workspace to holders of this scope.
curl --request GET \
--url https://api.protodesk.io/v1/realtime/events/poll \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.protodesk.io/v1/realtime/events/poll"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.protodesk.io/v1/realtime/events/poll', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.protodesk.io/v1/realtime/events/poll",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.protodesk.io/v1/realtime/events/poll"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.protodesk.io/v1/realtime/events/poll")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.protodesk.io/v1/realtime/events/poll")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"type": "<string>",
"resourceType": "<string>",
"resourceId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"conversationId": "<string>"
}
],
"nextCursor": "<string>",
"hasMore": true,
"pollAfterSeconds": 3
}{
"error": {
"code": "route.not_found",
"message": "Not found",
"requestId": "req_x6q5vl75f5d53m7oet2k4r5w6a"
}
}Authorizations
Use a workspace API key in the Authorization header. Keys use pk_live_<key_id> for production and pk_test<key_id>_ for test mode.
Query Parameters
Opaque nextCursor from the preceding poll. Omit to establish a new checkpoint.
5121 <= x <= 100Only notifications associated with this conversation.
128Comma-separated supported event types. Keep filters unchanged while resuming.
1024