Displays: Screenshot API
Section titled “Displays: Screenshot API”Capture, retrieve, and manage display screenshots, thumbnails, window listings, and clipboard contents from a containerized display instance. Use these endpoints to integrate visual capture into automated workflows, build screenshot-based user interfaces, query historical captures, or inspect the state of windows on the display. All requests target the display service hostname of your container.
Display Information
Section titled “Display Information”GET /api/v1/display/info
Section titled “GET /api/v1/display/info”Retrieve information about the current display, including the list of available screenshots.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/info" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.getInformation();{ "display": 6, "screenshots": [ { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } } ]}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/screenshots
Section titled “GET /api/v1/display/screenshots”List all available screenshots for the current display with their metadata. Useful for screenshot management applications and historical browsing.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/screenshots" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.listScreenshots();{ "display": 6, "screenshots": [ { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": null } ]}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
Window Management
Section titled “Window Management”GET /api/v1/display/windows
Section titled “GET /api/v1/display/windows”List the windows currently present on the display, including their geometry, class, focus state, and EWMH states.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/windows?onlyVisible=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.listWindows({ onlyVisible: true });{ "success": true, "display": 6, "focusedWindowId": 12345, "windows": [ { "windowId": 12345, "name": "Mozilla Firefox", "class": ["firefox", "Firefox"], "desktop": 0, "geometry": { "x": 0, "y": 0, "width": 1920, "height": 1080 }, "focused": true, "states": ["Normal"] } ]}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Input action failed"}{ "statusCode": 503, "error": "Service Unavailable", "message": "Display not available"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
| onlyVisible | query | boolean | No | If true, only include visible windows. |
GET /api/v1/display/window/{windowId}/properties
Section titled “GET /api/v1/display/window/{windowId}/properties”Retrieve extended EWMH properties (such as wmClass, wmName, wmRole, pid, wmState, wmType, and transientFor) for a specific window.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/window/12345/properties" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.getWindowProperties('12345');{ "success": true, "windowId": "12345", "properties": { "wmClass": ["firefox", "Firefox"], "wmName": "Mozilla Firefox", "wmRole": null, "pid": 1234, "wmState": ["Normal"], "wmType": ["Normal"], "transientFor": null }}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 404, "error": "Not Found", "message": "Window not found"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Input action failed"}{ "statusCode": 503, "error": "Service Unavailable", "message": "Display not available"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| windowId | path | string | Yes | Window ID (decimal or hex 0x...). |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
Clipboard
Section titled “Clipboard”GET /api/v1/display/clipboard
Section titled “GET /api/v1/display/clipboard”Read the text content of the display’s clipboard. The buffer selection defaults to clipboard, but primary and secondary are also supported on X11.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/clipboard?selection=clipboard" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.getClipboard({ selection: 'clipboard' });{ "success": true, "text": "Hello from clipboard", "selection": "clipboard"}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Input action failed"}{ "statusCode": 503, "error": "Service Unavailable", "message": "Display not available"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
| selection | query | string | No | Clipboard buffer selection. Defaults to "clipboard". One of "clipboard", "primary", "secondary". |
POST /api/v1/display/clipboard
Section titled “POST /api/v1/display/clipboard”Write text to the display’s clipboard.
curl -X POST "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/clipboard" \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "Copied via API", "selection": "clipboard" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.setClipboard({ text: 'Copied via API', selection: 'clipboard'});{ "success": true, "action": "set_clipboard", "details": {}}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Input action failed"}{ "statusCode": 503, "error": "Service Unavailable", "message": "Display not available"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
| text | string | Yes | Clipboard text content. Maximum length 1048576 characters. |
| selection | string | No | Clipboard buffer selection. Defaults to "clipboard". One of "clipboard", "primary", "secondary". |
Screenshots
Section titled “Screenshots”GET /api/v1/display/screenshot
Section titled “GET /api/v1/display/screenshot”Capture a fresh screenshot of the display and return the image. Returns binary PNG by default; pass base64=true to receive a base64-encoded JSON envelope.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/screenshot?base64=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.screenshots.capture({ base64: true });{ "info": { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } }, "image": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...", "mimeType": "image/png", "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." }}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Screenshot failed"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| base64 | query | boolean | No | Return base64-encoded JSON response instead of binary image. Useful for AI agents and systems that can’t handle binary data. |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/screenshot/{timestamp}
Section titled “GET /api/v1/display/screenshot/{timestamp}”Retrieve a previously captured screenshot by its Unix timestamp.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/screenshot/1749541160?base64=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.screenshots.getByTimestamp('1749541160', { base64: true });{ "info": { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } }, "image": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...", "mimeType": "image/png", "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid timestamp format"}{ "statusCode": 404, "error": "Not Found", "message": "Screenshot not found"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| timestamp | path | string | Yes | Unix timestamp of the screenshot. Use the timestamp field returned by screenshot metadata/list endpoints. Must be numeric only for security. |
| base64 | query | boolean | No | Return base64-encoded JSON response instead of binary image. Useful for AI agents and systems that can’t handle binary data. |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/screenshot/info
Section titled “GET /api/v1/display/screenshot/info”Capture a new screenshot and return only the metadata, without the image payload.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/screenshot/info" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.screenshots.captureMetadata();{ "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 }}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Screenshot failed"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/screenshot/last
Section titled “GET /api/v1/display/screenshot/last”Return the most recently captured screenshot.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/screenshot/last?base64=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.screenshots.getLatest({ base64: true });{ "info": { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } }, "image": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...", "mimeType": "image/png", "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." }}{ "statusCode": 400, "error": "Bad Request", "message": "No display context available"}{ "statusCode": 404, "error": "Not Found", "message": "Screenshot not found"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Screenshot failed"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| base64 | query | boolean | No | Return base64-encoded JSON response instead of binary image. Useful for AI agents and systems that can’t handle binary data. |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/screenshot/last/info
Section titled “GET /api/v1/display/screenshot/last/info”Return metadata for the most recent screenshot without downloading the image payload.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/screenshot/last/info" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.screenshots.getLatestMetadata();{ "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 }}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
Thumbnails
Section titled “Thumbnails”GET /api/v1/display/thumbnail
Section titled “GET /api/v1/display/thumbnail”Capture a new screenshot and return the thumbnail version (320x180 scaled). Returns binary PNG by default; pass base64=true to receive a base64-encoded JSON envelope.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/thumbnail?base64=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.thumbnails.capture({ base64: true });{ "info": { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } }, "image": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...", "mimeType": "image/png", "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." }}{ "statusCode": 404, "error": "Not Found", "message": "Thumbnail not found"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| base64 | query | boolean | No | Return base64-encoded JSON response instead of binary image. Useful for AI agents and systems that can’t handle binary data. |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/thumbnail/{timestamp}
Section titled “GET /api/v1/display/thumbnail/{timestamp}”Retrieve the thumbnail for a specific screenshot by its Unix timestamp.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/thumbnail/1749541160?base64=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.thumbnails.getByTimestamp('1749541160', { base64: true });{ "info": { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } }, "image": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...", "mimeType": "image/png", "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." }}{ "statusCode": 404, "error": "Not Found", "message": "Thumbnail not found"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| timestamp | path | string | Yes | Unix timestamp of the screenshot. Use the timestamp field returned by screenshot metadata/list endpoints. Must be numeric only for security. |
| base64 | query | boolean | No | Return base64-encoded JSON response instead of binary image. Useful for AI agents and systems that can’t handle binary data. |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |
GET /api/v1/display/thumbnail/last
Section titled “GET /api/v1/display/thumbnail/last”Return the thumbnail of the most recent screenshot.
curl -X GET "https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com/api/v1/display/thumbnail/last?base64=true" \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-display-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.display.thumbnails.getLatest({ base64: true });{ "info": { "timestamp": "1749541160", "timestamp_human": "2026-02-23T16:57:02+00:00", "full": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160.png", "size": 245760, "width": 1920, "height": 1080 }, "thumbnail": { "path": "/hoody/storage/hoody-display/screenshots/display_6_1749541160_thumb.png", "size": 18432, "width": 320, "height": 180 } }, "image": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...", "mimeType": "image/png", "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." }}{ "statusCode": 404, "error": "Not Found", "message": "Thumbnail not found"}Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| base64 | query | boolean | No | Return base64-encoded JSON response instead of binary image. Useful for AI agents and systems that can’t handle binary data. |
| displayId | query | integer | No | Display ID to use (overrides the *-display-N.* hostname pattern). Valid range: 1-999999. |