Read and follow logs
Retrieve retained application logs with filters and numeric continuation cursors.
Read logs at GET /workspaces/{workspaceId}/services/{serviceId}/logs. Responses contain retained build, runtime, or system output available to the caller.
Read the newest batch
curl --fail-with-body --get \
--header "Authorization: Bearer $OPENSTEAD_API_KEY" \
--data-urlencode 'source=runtime' \
--data-urlencode 'limit=100' \
"https://api.openstead.tech/api/v1/workspaces/$OPENSTEAD_WORKSPACE_ID/services/$OPENSTEAD_SERVICE_ID/logs"{
"available": true,
"items": [
{
"id": 42,
"timestamp": "2026-09-28T12:00:00Z",
"source": "runtime",
"message": "Application ready",
"level": "info"
}
],
"cursor": 42,
"hasMore": false,
"limit": 100
}The first request retrieves the newest retained batch, ordered by numeric ID ascending. It is not an export of all historical lines.
Follow later lines
Pass the previous response's numeric cursor as after. Preserve the other filters:
GET .../logs?source=runtime&limit=100&after=42When hasMore is true, request the next batch immediately. When false, pause before polling again. A cursor should advance when new matching lines are returned. The SDKs detect non-advancing continuation loops.
Filters
| Query | Meaning |
|---|---|
limit | 1–500 lines; default 500. |
after | Numeric log ID to continue after. |
source | build, runtime, or system. |
deployment | A deployment UUID belonging to this service. |
search | Text filter, up to 200 characters. |
hours | Time window; default 24, bounded by the plan's retention. |
Persist the service, cursor, and filters together when resuming a reader. Changes to filters, retention expiry, and a late restart can leave gaps. There is no collection-style page envelope or opaque cursor here.
SDK helpers
Python logs.iter() drains available batches and logs.tail() polls for new lines. TypeScript provides logs.batches() and logs.tail().
import os
from openstead import PollTimeout, Openstead
with Openstead() as client:
try:
for line in client.logs.tail(
workspace_id=os.environ["OPENSTEAD_WORKSPACE_ID"],
service_id=os.environ["OPENSTEAD_SERVICE_ID"],
source="runtime",
timeout=30.0,
):
print(line.timestamp, line.level, line.message)
except PollTimeout:
passChoose a suitable destination for output: applications can log credentials, customer data, and other sensitive information.
Unavailable logs
A response may return available: false, an empty items array, and a reason without cursor metadata. Inspect that response before interpreting a quiet log reader as a healthy application. Tailing is HTTP polling over retained records, with no guarantee of an exhaustive archive.