Telemetry API
The Telemetry API is currently in early beta. The API surface may change as development continues.
These endpoints are part of the Gram OpenAPI specification, available at app.getgram.ai/openapi.yaml .
The Gram Telemetry API allows for searching logs, providing OpenTelemetry-compatible interfaces for querying structured logs and HTTP tool call summaries.
Authentication
Requests must include authentication credentials in headers:
Gram-Key: Your API key (can be eitherConsumerorProducerscoped)Gram-Project: The project identifier (slug)
Search logs
POST https://app.getgram.ai/rpc/telemetry.searchLogsSearch and list telemetry logs that match a search filter.
Request body
| Field | Type | Description |
|---|---|---|
limit | number | Number of items to return (1-1000, default: 50) |
sort | string | Sort order: asc or desc (default: desc) |
cursor | string | Cursor for pagination |
filter | object | Filter criteria (see below) |
Filter parameters
| Field | Type | Description |
|---|---|---|
from | string | Start time in ISO 8601 format (e.g., 2025-12-19T10:00:00Z) |
to | string | End time in ISO 8601 format (e.g., 2025-12-19T11:00:00Z) |
deployment_id | string | Filter by deployment ID |
function_id | string | Filter by function ID |
gram_urn | string | Filter by Gram URN |
trace_id | string | Filter by trace ID |
severity_text | string | Filter by severity: DEBUG, INFO, WARN, ERROR, or FATAL |
http_status_code | number | Filter by HTTP status code |
http_route | string | Filter by HTTP route |
http_method | string | Filter by HTTP method: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
service_name | string | Filter by service name |
Response structure
{
"logs": [
{
"id": "uuid",
"time_unix_nano": 1734605400000000000,
"observed_time_unix_nano": 1734605400000000000,
"severity_text": "INFO",
"body": "GET /api/users -> 200 (45.23ms)",
"trace_id": "abc123def456789012345678901234ab",
"span_id": "1234567890abcdef",
"attributes": {
"http.server.url": "https://api.example.com",
"http.route": "/api/users",
"http.request.method": "GET",
"http.response.status_code": 200,
"http.duration_ms": 45.23
},
"resource_attributes": {
"service.name": "gram-server",
"gram.project.id": "project-uuid",
"gram.deployment.id": "deployment-uuid",
"gram.tool.urn": "urn:gram:tool:example"
},
"service": {
"name": "gram-server",
"version": "1.0.0"
}
}
],
"next_cursor": "cursor-string"
}Log record fields
Each log record follows the OpenTelemetry log data model:
id: Unique identifier for the log entrytime_unix_nano: When the event occurred (Unix nanoseconds)observed_time_unix_nano: When the event was observed (Unix nanoseconds)severity_text: Log severity level (DEBUG,INFO,WARN,ERROR,FATAL)body: The primary log messagetrace_id: W3C trace ID for distributed tracingspan_id: W3C span IDattributes: Log-level structured data describing what happenedresource_attributes: Metadata about who/where generated the log (i.e. the Gram server)service: Service information including name and version
Search tool calls
POST https://app.getgram.ai/rpc/telemetry.searchToolCallsSearch and list tool call summaries grouped by trace ID.
Request body
| Field | Type | Description |
|---|---|---|
limit | number | Number of items to return (1-1000, default: 50) |
sort | string | Sort order: asc or desc (default: desc) |
cursor | string | Cursor for pagination |
filter | object | Filter criteria (see below) |
Filter parameters
| Field | Type | Description |
|---|---|---|
from | string | Start time in ISO 8601 format (e.g., 2025-12-19T10:00:00Z) |
to | string | End time in ISO 8601 format (e.g., 2025-12-19T11:00:00Z) |
deployment_id | string | Filter by deployment ID |
function_id | string | Filter by function ID |
gram_urn | string | Filter by Gram URN |
Response structure
{
"tool_calls": [
{
"trace_id": "abc123def456789012345678901234ab",
"start_time_unix_nano": 1734605400000000000,
"log_count": 5,
"http_status_code": 200,
"gram_urn": "urn:gram:tool:example"
}
],
"next_cursor": "cursor-string"
}Tool call summary fields
trace_id: Trace ID grouping related logsstart_time_unix_nano: Earliest log timestamp in the trace (Unix nanoseconds)log_count: Total number of logs in this tool callhttp_status_code: HTTP status code (if applicable)gram_urn: Gram URN associated with this tool call
Pagination
Results are paginated using cursor-based pagination:
- Set
limitto control page size (maximum 1000) - Use
sortto control ordering (newest first withdescor oldest first withasc) - Check
next_cursorin the response to determine if more results exist - Use the
next_cursorvalue as thecursorparameter for the next request
The cursor is an opaque string that encodes the position in the result set. Always use the cursor value from the previous response rather than constructing your own.
Example usage
Basic log query
Retrieve the most recent telemetry logs:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchLogs" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{"limit": 50, "sort": "desc"}'Filter by time range
Get logs within a specific time window:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchLogs" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{
"limit": 100,
"filter": {
"from": "2025-12-01T00:00:00Z",
"to": "2025-12-15T23:59:59Z"
}
}'Filter by severity
Retrieve only error logs:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchLogs" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{
"limit": 100,
"filter": {
"severity_text": "ERROR"
}
}'Filter by trace ID
Get all logs for a specific distributed trace:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchLogs" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{
"limit": 100,
"filter": {
"trace_id": "abc123def456789012345678901234ab"
}
}'Filter by HTTP attributes
Get logs for specific HTTP endpoints:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchLogs" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{
"limit": 50,
"filter": {
"http_method": "POST",
"http_status_code": 500
}
}'List tool call summaries
Get aggregated tool call information:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchToolCalls" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{"limit": 50, "sort": "desc"}'Paginated query
Fetch the next page of results:
curl -X POST "https://app.getgram.ai/rpc/telemetry.searchLogs" \
-H "Content-Type: application/json" \
-H "Gram-Key: <your-api-key>" \
-H "Gram-Project: <your-project-slug>" \
-d '{"limit": 50, "cursor": "previous-cursor-value"}'Error handling
The API returns standard HTTP status codes:
200: Success400: Bad request (invalid parameters)401: Unauthorized (missing or invalid credentials)403: Forbidden (insufficient permissions)500: Internal server error
Last updated on