Documentation Index
Fetch the complete documentation index at: https://atp.hypertext.studio/llms.txt
Use this file to discover all available pages before exploring further.
Overview
For clients unable to maintain persistent WebSocket connections, the REST polling endpoint provides an alternative notification retrieval mechanism. This approach supports battery-constrained devices and simplified client implementations.
Fetch Pending Notifications
Endpoint: GET /api/v1/client/notifications
Authentication: Requires Bearer token using user credentials
Query Parameters
| Parameter | Type | Required | Description |
|---|
status | string | No | Filter by notification state, e.g., “pending” (default: all) |
limit | integer | No | Maximum notifications to return (default: 50, max: 100) |
cursor | string | No | Pagination cursor from previous response |
service_id | string | No | Filter by originating service ID |
project | string | No | Filter by project identifier |
sort | string | No | Sort order, either “newest” or “oldest” (default: “newest”) |
Response
{
"notifications": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": "1.0",
"timestamp": "2025-05-25T10:30:00Z",
"deadline": "2025-05-25T11:00:00Z",
"service": {
"id": "lovelace-ide",
"name": "Lovelace IDE",
"icon": "https://lovelace.dev/icon.png"
},
"context": {
"title": "Deploy to Production?",
"description": "New version 2.1.0 is ready for deployment to production servers.",
"project": "backend-api",
"metadata": {
"version": "2.1.0",
"changes": 47,
"test_coverage": "98.3%"
}
},
"actions": [
{
"id": "approve",
"label": "Approve Deployment",
"response_type": "simple",
"flags": ["irreversible"]
},
{
"id": "reject",
"label": "Reject",
"response_type": "text",
"constraints": {
"placeholder": "Reason for rejection"
}
}
],
"status": "delivered"
},
// Additional notifications...
],
"pagination": {
"next_cursor": "cursor_for_next_page",
"has_more": true,
"total_count": 156
}
}
The pagination object contains:
| Field | Type | Description |
|---|
next_cursor | string | Cursor to use for fetching the next page |
has_more | boolean | Indicates if more results are available |
total_count | integer | Total count of matching notifications |
The pagination mechanism ensures efficient retrieval of large notification sets while maintaining consistent ordering.
Error Responses
| Status Code | Error Code | Description |
|---|
400 Bad Request | INVALID_PARAMETER | Invalid query parameter |
401 Unauthorized | AUTH_INVALID_TOKEN | User token is invalid |
429 Too Many Requests | RATE_LIMIT_EXCEEDED | Rate limit exceeded |
Fetch Single Notification
Endpoint: GET /api/v1/client/notifications/{id}
Authentication: Requires Bearer token using user credentials
Path Parameters
| Parameter | Type | Description |
|---|
id | string | The UUID of the notification to retrieve |
Response
Returns a single notification object with the same structure as in the list endpoint.
Error Responses
| Status Code | Error Code | Description |
|---|
401 Unauthorized | AUTH_INVALID_TOKEN | User token is invalid |
403 Forbidden | NOTIFICATION_ACCESS_DENIED | User does not have access to this notification |
404 Not Found | NOTIFICATION_NOT_FOUND | Notification with specified ID does not exist |
Acknowledge Notification
Endpoint: POST /api/v1/client/notifications/{id}/acknowledge
Authentication: Requires Bearer token using user credentials
This endpoint allows clients to acknowledge receipt of a notification, updating its status to acknowledged.
Path Parameters
| Parameter | Type | Description |
|---|
id | string | The UUID of the notification to acknowledge |
Response
Status Code: 200 OK
{
"notification_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "acknowledged",
"acknowledged_at": "2025-05-25T10:32:15Z"
}
Error Responses
| Status Code | Error Code | Description |
|---|
401 Unauthorized | AUTH_INVALID_TOKEN | User token is invalid |
403 Forbidden | NOTIFICATION_ACCESS_DENIED | User does not have access to this notification |
404 Not Found | NOTIFICATION_NOT_FOUND | Notification with specified ID does not exist |
409 Conflict | NOTIFICATION_ALREADY_RESPONDED | Notification has already been responded to |
Examples
Fetch Pending Notifications - JavaScript
async function fetchPendingNotifications() {
try {
const response = await fetch(
'https://atp.example.com/api/v1/client/notifications?status=pending&limit=20',
{
headers: {
'Authorization': 'Bearer user_token_xyz789'
}
}
);
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
const data = await response.json();
// Process notifications
for (const notification of data.notifications) {
displayNotification(notification);
}
// Store pagination cursor for next request
if (data.pagination.has_more) {
sessionStorage.setItem('notifications_cursor', data.pagination.next_cursor);
}
return data;
} catch (error) {
console.error('Error fetching notifications:', error);
throw error;
}
}
Fetch Pending Notifications - Python
import requests
def fetch_pending_notifications(token, cursor=None, limit=20):
url = 'https://atp.example.com/api/v1/client/notifications'
params = {
'status': 'pending',
'limit': limit
}
if cursor:
params['cursor'] = cursor
headers = {
'Authorization': f'Bearer {token}'
}
response = requests.get(url, params=params, headers=headers)
response.raise_for_status()
data = response.json()
# Process notifications
for notification in data['notifications']:
display_notification(notification)
# Return pagination cursor for next request
next_cursor = None
if data['pagination']['has_more']:
next_cursor = data['pagination']['next_cursor']
return data['notifications'], next_cursor
Acknowledge Notification - JavaScript
async function acknowledgeNotification(notificationId) {
try {
const response = await fetch(
`https://atp.example.com/api/v1/client/notifications/${notificationId}/acknowledge`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer user_token_xyz789',
'Content-Type': 'application/json'
}
}
);
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
const data = await response.json();
console.log(`Notification ${notificationId} acknowledged`);
return data;
} catch (error) {
console.error('Error acknowledging notification:', error);
throw error;
}
}
Polling Strategy
For applications that use REST polling instead of WebSockets, implement an efficient polling strategy to minimize battery consumption and server load:
- Adaptive Polling: Adjust polling frequency based on notification activity
- Background Polling: Use platform-specific background fetch capabilities for mobile apps
- Exponential Backoff: Increase polling interval after periods of inactivity
- Priority-Based: Poll more frequently for high-priority projects or services
Example Adaptive Polling Strategy
class AdaptivePoller {
constructor(options = {}) {
this.minInterval = options.minInterval || 30000; // 30 seconds
this.maxInterval = options.maxInterval || 300000; // 5 minutes
this.scaleFactor = options.scaleFactor || 1.5;
this.currentInterval = this.minInterval;
this.timer = null;
this.lastNotificationCount = 0;
}
start(callback) {
this.stop();
const poll = async () => {
try {
const result = await callback();
// Adjust polling interval based on activity
if (result.notifications.length > 0) {
// Activity detected, decrease interval
this.currentInterval = this.minInterval;
this.lastNotificationCount = result.notifications.length;
} else if (this.lastNotificationCount === 0) {
// No recent activity, increase interval
this.currentInterval = Math.min(
this.currentInterval * this.scaleFactor,
this.maxInterval
);
} else {
// Had notifications before but none now, reset counter
this.lastNotificationCount = 0;
}
} catch (error) {
console.error('Polling error:', error);
// Increase interval on error
this.currentInterval = Math.min(
this.currentInterval * this.scaleFactor,
this.maxInterval
);
}
// Schedule next poll
this.timer = setTimeout(poll, this.currentInterval);
};
// Start polling
poll();
}
stop() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
}
// Usage
const poller = new AdaptivePoller();
poller.start(fetchPendingNotifications);
Best Practices
- Use WebSockets When Possible: Prefer WebSocket connections for real-time updates when available
- Efficient Polling: Implement adaptive polling to reduce server load and battery consumption
- Use Pagination: Always handle pagination correctly to retrieve all notifications
- Cache Results: Cache notification data to reduce redundant API calls
- Batch Operations: Use the bulk acknowledge endpoint for marking multiple notifications
- Error Handling: Implement proper error handling and retries for network failures