feat: phase 3 observability — IMS telemetry merge

Port IMS telemetry into Primora conventions:

- core.components/core.events (migration 00004 + sqlc) scoped to projects
- POST /api/v1/ingest — single or <=500-event batches via project prm_
  keys (X-Primora-Key alias), auto-registering components, permissive CORS
- Issues: fingerprint-grouped errors with count/severity/first+last seen
- Reads: events w/ filters + before-cursor, components, stats (1h/24h/7d/30d
  bucketed series + component health + totals + metric names), metric
  series (avg/p50/p95/max)
- GET .../telemetry/stream — project-scoped SSE through an in-process hub
  (buffered subs, drop-on-slow, 25s keepalives); ?api_key=/?token= auth
  for EventSource
- Telemetry page: health/issues/events/metrics/integrate tabs, live badge,
  390px-clean; demo stubs
- @primora/client SDK (createPrimoraClient: capture*/heartbeat/installAuto,
  queued keepalive flushes)
- MCP: primora_list_issues/list_events/telemetry_stats/metric_series
- IMS README deprecation note pointing here

Also fixes workspace pins to 0.3.0 — npm ci in the frontend image was
resolving the unpublished 0.2.0 spec from the registry.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-16 16:21:03 +02:00
1 parent 6507eee606
commit 8cfddf9184
60 files changed
+3694 -30

No files matched your search

@@ -23,6 +23,8 @@ export type { BucketObjectListResponse } from './models/BucketObjectListResponse
export type { Collection } from './models/Collection';
export type { CollectionID } from './models/CollectionID';
export type { CollectionListResponse } from './models/CollectionListResponse';
export type { ComponentHealth } from './models/ComponentHealth';
export type { ComponentID } from './models/ComponentID';
export type { ConnectionID } from './models/ConnectionID';
export type { CopyBucketObjectRequest } from './models/CopyBucketObjectRequest';
export type { CreateApiKeyRequest } from './models/CreateApiKeyRequest';
@@ -55,10 +57,16 @@ export type { Document } from './models/Document';
export type { DocumentID } from './models/DocumentID';
export type { DocumentListResponse } from './models/DocumentListResponse';
export type { ErrorEnvelope } from './models/ErrorEnvelope';
export type { EventSeriesBucket } from './models/EventSeriesBucket';
export type { HealthStatus } from './models/HealthStatus';
export { IngestEvent } from './models/IngestEvent';
export type { IngestRequest } from './models/IngestRequest';
export type { IngestResponse } from './models/IngestResponse';
export type { Invitation } from './models/Invitation';
export type { InvitationID } from './models/InvitationID';
export type { MeResponse } from './models/MeResponse';
export type { MetricPoint } from './models/MetricPoint';
export type { MetricSeriesResponse } from './models/MetricSeriesResponse';
export type { ObjectKey } from './models/ObjectKey';
export type { OrganizationID } from './models/OrganizationID';
export { OrganizationInvitation } from './models/OrganizationInvitation';
@@ -76,6 +84,13 @@ export type { ProjectSummary } from './models/ProjectSummary';
export type { ReadinessStatus } from './models/ReadinessStatus';
export type { SchemaQuery } from './models/SchemaQuery';
export type { TableQuery } from './models/TableQuery';
export type { TelemetryComponent } from './models/TelemetryComponent';
export type { TelemetryComponentListResponse } from './models/TelemetryComponentListResponse';
export type { TelemetryEvent } from './models/TelemetryEvent';
export type { TelemetryEventListResponse } from './models/TelemetryEventListResponse';
export type { TelemetryIssue } from './models/TelemetryIssue';
export type { TelemetryIssueListResponse } from './models/TelemetryIssueListResponse';
export type { TelemetryStats } from './models/TelemetryStats';
export type { UpdateBucketObjectRequest } from './models/UpdateBucketObjectRequest';
export { UpdateBucketRequest } from './models/UpdateBucketRequest';
export type { UpdateCollectionRequest } from './models/UpdateCollectionRequest';
@@ -103,6 +118,8 @@ export { $BucketObjectListResponse } from './schemas/$BucketObjectListResponse';
export { $Collection } from './schemas/$Collection';
export { $CollectionID } from './schemas/$CollectionID';
export { $CollectionListResponse } from './schemas/$CollectionListResponse';
export { $ComponentHealth } from './schemas/$ComponentHealth';
export { $ComponentID } from './schemas/$ComponentID';
export { $ConnectionID } from './schemas/$ConnectionID';
export { $CopyBucketObjectRequest } from './schemas/$CopyBucketObjectRequest';
export { $CreateApiKeyRequest } from './schemas/$CreateApiKeyRequest';
@@ -135,10 +152,16 @@ export { $Document } from './schemas/$Document';
export { $DocumentID } from './schemas/$DocumentID';
export { $DocumentListResponse } from './schemas/$DocumentListResponse';
export { $ErrorEnvelope } from './schemas/$ErrorEnvelope';
export { $EventSeriesBucket } from './schemas/$EventSeriesBucket';
export { $HealthStatus } from './schemas/$HealthStatus';
export { $IngestEvent } from './schemas/$IngestEvent';
export { $IngestRequest } from './schemas/$IngestRequest';
export { $IngestResponse } from './schemas/$IngestResponse';
export { $Invitation } from './schemas/$Invitation';
export { $InvitationID } from './schemas/$InvitationID';
export { $MeResponse } from './schemas/$MeResponse';
export { $MetricPoint } from './schemas/$MetricPoint';
export { $MetricSeriesResponse } from './schemas/$MetricSeriesResponse';
export { $ObjectKey } from './schemas/$ObjectKey';
export { $OrganizationID } from './schemas/$OrganizationID';
export { $OrganizationInvitation } from './schemas/$OrganizationInvitation';
@@ -156,6 +179,13 @@ export { $ProjectSummary } from './schemas/$ProjectSummary';
export { $ReadinessStatus } from './schemas/$ReadinessStatus';
export { $SchemaQuery } from './schemas/$SchemaQuery';
export { $TableQuery } from './schemas/$TableQuery';
export { $TelemetryComponent } from './schemas/$TelemetryComponent';
export { $TelemetryComponentListResponse } from './schemas/$TelemetryComponentListResponse';
export { $TelemetryEvent } from './schemas/$TelemetryEvent';
export { $TelemetryEventListResponse } from './schemas/$TelemetryEventListResponse';
export { $TelemetryIssue } from './schemas/$TelemetryIssue';
export { $TelemetryIssueListResponse } from './schemas/$TelemetryIssueListResponse';
export { $TelemetryStats } from './schemas/$TelemetryStats';
export { $UpdateBucketObjectRequest } from './schemas/$UpdateBucketObjectRequest';
export { $UpdateBucketRequest } from './schemas/$UpdateBucketRequest';
export { $UpdateCollectionRequest } from './schemas/$UpdateCollectionRequest';
@@ -174,3 +204,4 @@ export { OrganizationsService } from './services/OrganizationsService';
export { PlatformService } from './services/PlatformService';
export { ProjectsService } from './services/ProjectsService';
export { StorageService } from './services/StorageService';
export { TelemetryService } from './services/TelemetryService';
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ComponentHealth = {
id: string;
name: string;
kind: string;
last_seen_at?: string | null;
last_status?: string;
errors_24h: number;
events_24h: number;
meta?: Record<string, any>;
};
@@ -0,0 +1,5 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ComponentID = string;
@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type EventSeriesBucket = {
ts: string;
counts: Record<string, number>;
};
@@ -0,0 +1,39 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type IngestEvent = {
type: IngestEvent.type;
/**
* Auto-registered under the project on first use
*/
component?: string;
kind?: IngestEvent.kind;
severity?: string;
message?: string;
payload?: Record<string, any>;
/**
* Error grouping key; derived from message when omitted
*/
fingerprint?: string;
ts?: string;
};
export namespace IngestEvent {
export enum type {
ERROR = 'error',
METRIC = 'metric',
LOG = 'log',
HEARTBEAT = 'heartbeat',
EVENT = 'event',
}
export enum kind {
FRONTEND = 'frontend',
BACKEND = 'backend',
DATABASE = 'database',
ANDROID = 'android',
DESKTOP = 'desktop',
WEB = 'web',
OTHER = 'other',
}
}
@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { IngestEvent } from './IngestEvent';
export type IngestRequest = (IngestEvent | {
events: Array<IngestEvent>;
});
@@ -0,0 +1,8 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type IngestResponse = {
accepted: number;
};
@@ -0,0 +1,13 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type MetricPoint = {
ts: string;
avg?: number | null;
p50?: number | null;
p95?: number | null;
max?: number | null;
count: number;
};
@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { MetricPoint } from './MetricPoint';
export type MetricSeriesResponse = {
items: Array<MetricPoint>;
};
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TelemetryComponent = {
id: string;
name: string;
kind: string;
last_seen_at?: string | null;
last_status?: string;
errors_24h: number;
events_24h: number;
meta?: Record<string, any>;
};
@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { TelemetryComponent } from './TelemetryComponent';
export type TelemetryComponentListResponse = {
items: Array<TelemetryComponent>;
};
@@ -0,0 +1,17 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TelemetryEvent = {
id: number;
project_id: string;
component_id?: string | null;
component_name?: string;
type: string;
severity: string;
message: string;
payload?: Record<string, any>;
fingerprint?: string;
ts: string;
};
@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { TelemetryEvent } from './TelemetryEvent';
export type TelemetryEventListResponse = {
items: Array<TelemetryEvent>;
};
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TelemetryIssue = {
fingerprint: string;
message: string;
component_id?: string | null;
component_name?: string;
count: number;
first_seen: string;
last_seen: string;
severity: string;
};
@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { TelemetryIssue } from './TelemetryIssue';
export type TelemetryIssueListResponse = {
items: Array<TelemetryIssue>;
};
@@ -0,0 +1,17 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ComponentHealth } from './ComponentHealth';
import type { EventSeriesBucket } from './EventSeriesBucket';
export type TelemetryStats = {
window: number;
bucket_sec: number;
series: Array<EventSeriesBucket>;
components: Array<ComponentHealth>;
errors: number;
events: number;
metrics: number;
metric_names: Array<string>;
};
@@ -0,0 +1,44 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ComponentHealth = {
properties: {
id: {
type: 'string',
isRequired: true,
format: 'uuid',
},
name: {
type: 'string',
isRequired: true,
},
kind: {
type: 'string',
isRequired: true,
},
last_seen_at: {
type: 'string',
isNullable: true,
format: 'date-time',
},
last_status: {
type: 'string',
},
errors_24h: {
type: 'number',
isRequired: true,
},
events_24h: {
type: 'number',
isRequired: true,
},
meta: {
type: 'dictionary',
contains: {
properties: {
},
},
},
},
} as const;
@@ -0,0 +1,8 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ComponentID = {
type: 'string',
format: 'uuid',
} as const;
@@ -0,0 +1,20 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $EventSeriesBucket = {
properties: {
ts: {
type: 'string',
isRequired: true,
format: 'date-time',
},
counts: {
type: 'dictionary',
contains: {
type: 'number',
},
isRequired: true,
},
},
} as const;
@@ -0,0 +1,40 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $IngestEvent = {
properties: {
type: {
type: 'Enum',
isRequired: true,
},
component: {
type: 'string',
description: `Auto-registered under the project on first use`,
},
kind: {
type: 'Enum',
},
severity: {
type: 'string',
},
message: {
type: 'string',
},
payload: {
type: 'dictionary',
contains: {
properties: {
},
},
},
fingerprint: {
type: 'string',
description: `Error grouping key; derived from message when omitted`,
},
ts: {
type: 'string',
format: 'date-time',
},
},
} as const;
@@ -0,0 +1,20 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $IngestRequest = {
type: 'one-of',
contains: [{
type: 'IngestEvent',
}, {
properties: {
events: {
type: 'array',
contains: {
type: 'IngestEvent',
},
isRequired: true,
},
},
}],
} as const;
@@ -0,0 +1,12 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $IngestResponse = {
properties: {
accepted: {
type: 'number',
isRequired: true,
},
},
} as const;
@@ -0,0 +1,33 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $MetricPoint = {
properties: {
ts: {
type: 'string',
isRequired: true,
format: 'date-time',
},
avg: {
type: 'number',
isNullable: true,
},
p50: {
type: 'number',
isNullable: true,
},
p95: {
type: 'number',
isNullable: true,
},
max: {
type: 'number',
isNullable: true,
},
count: {
type: 'number',
isRequired: true,
},
},
} as const;
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $MetricSeriesResponse = {
properties: {
items: {
type: 'array',
contains: {
type: 'MetricPoint',
},
isRequired: true,
},
},
} as const;
@@ -0,0 +1,44 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryComponent = {
properties: {
id: {
type: 'string',
isRequired: true,
format: 'uuid',
},
name: {
type: 'string',
isRequired: true,
},
kind: {
type: 'string',
isRequired: true,
},
last_seen_at: {
type: 'string',
isNullable: true,
format: 'date-time',
},
last_status: {
type: 'string',
},
errors_24h: {
type: 'number',
isRequired: true,
},
events_24h: {
type: 'number',
isRequired: true,
},
meta: {
type: 'dictionary',
contains: {
properties: {
},
},
},
},
} as const;
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryComponentListResponse = {
properties: {
items: {
type: 'array',
contains: {
type: 'TelemetryComponent',
},
isRequired: true,
},
},
} as const;
@@ -0,0 +1,52 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryEvent = {
properties: {
id: {
type: 'number',
isRequired: true,
},
project_id: {
type: 'string',
isRequired: true,
format: 'uuid',
},
component_id: {
type: 'string',
isNullable: true,
format: 'uuid',
},
component_name: {
type: 'string',
},
type: {
type: 'string',
isRequired: true,
},
severity: {
type: 'string',
isRequired: true,
},
message: {
type: 'string',
isRequired: true,
},
payload: {
type: 'dictionary',
contains: {
properties: {
},
},
},
fingerprint: {
type: 'string',
},
ts: {
type: 'string',
isRequired: true,
format: 'date-time',
},
},
} as const;
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryEventListResponse = {
properties: {
items: {
type: 'array',
contains: {
type: 'TelemetryEvent',
},
isRequired: true,
},
},
} as const;
@@ -0,0 +1,42 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryIssue = {
properties: {
fingerprint: {
type: 'string',
isRequired: true,
},
message: {
type: 'string',
isRequired: true,
},
component_id: {
type: 'string',
isNullable: true,
format: 'uuid',
},
component_name: {
type: 'string',
},
count: {
type: 'number',
isRequired: true,
},
first_seen: {
type: 'string',
isRequired: true,
format: 'date-time',
},
last_seen: {
type: 'string',
isRequired: true,
format: 'date-time',
},
severity: {
type: 'string',
isRequired: true,
},
},
} as const;
@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryIssueListResponse = {
properties: {
items: {
type: 'array',
contains: {
type: 'TelemetryIssue',
},
isRequired: true,
},
},
} as const;
@@ -0,0 +1,49 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $TelemetryStats = {
properties: {
window: {
type: 'number',
isRequired: true,
},
bucket_sec: {
type: 'number',
isRequired: true,
},
series: {
type: 'array',
contains: {
type: 'EventSeriesBucket',
},
isRequired: true,
},
components: {
type: 'array',
contains: {
type: 'ComponentHealth',
},
isRequired: true,
},
errors: {
type: 'number',
isRequired: true,
},
events: {
type: 'number',
isRequired: true,
},
metrics: {
type: 'number',
isRequired: true,
},
metric_names: {
type: 'array',
contains: {
type: 'string',
},
isRequired: true,
},
},
} as const;
@@ -0,0 +1,225 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { IngestRequest } from '../models/IngestRequest';
import type { IngestResponse } from '../models/IngestResponse';
import type { MetricSeriesResponse } from '../models/MetricSeriesResponse';
import type { TelemetryComponentListResponse } from '../models/TelemetryComponentListResponse';
import type { TelemetryEventListResponse } from '../models/TelemetryEventListResponse';
import type { TelemetryIssueListResponse } from '../models/TelemetryIssueListResponse';
import type { TelemetryStats } from '../models/TelemetryStats';
import type { CancelablePromise } from '../core/CancelablePromise';
import { OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
export class TelemetryService {
/**
* Ingest one telemetry event or a batch of up to 500
* @returns IngestResponse Accepted event count
* @throws ApiError
*/
public static ingestTelemetry({
requestBody,
}: {
requestBody: IngestRequest,
}): CancelablePromise<IngestResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/ingest',
body: requestBody,
mediaType: 'application/json',
errors: {
400: `Error response`,
401: `Error response`,
413: `Error response`,
},
});
}
/**
* @returns TelemetryEventListResponse Telemetry events, newest first
* @throws ApiError
*/
public static listTelemetryEvents({
projectId,
type,
component,
fingerprint,
before,
limit,
}: {
projectId: string,
type?: 'error' | 'metric' | 'log' | 'heartbeat' | 'event',
component?: string,
fingerprint?: string,
before?: number,
limit?: number,
}): CancelablePromise<TelemetryEventListResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/projects/{projectID}/events',
path: {
'projectID': projectId,
},
query: {
'type': type,
'component': component,
'fingerprint': fingerprint,
'before': before,
'limit': limit,
},
errors: {
401: `Error response`,
},
});
}
/**
* @returns TelemetryIssueListResponse Error groups by fingerprint
* @throws ApiError
*/
public static listTelemetryIssues({
projectId,
days,
}: {
projectId: string,
days?: number,
}): CancelablePromise<TelemetryIssueListResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/projects/{projectID}/issues',
path: {
'projectID': projectId,
},
query: {
'days': days,
},
errors: {
401: `Error response`,
},
});
}
/**
* @returns TelemetryComponentListResponse Registered telemetry components
* @throws ApiError
*/
public static listTelemetryComponents({
projectId,
}: {
projectId: string,
}): CancelablePromise<TelemetryComponentListResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/projects/{projectID}/components',
path: {
'projectID': projectId,
},
errors: {
401: `Error response`,
},
});
}
/**
* @returns void
* @throws ApiError
*/
public static deleteTelemetryComponent({
projectId,
componentId,
}: {
projectId: string,
componentId: string,
}): CancelablePromise<void> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/projects/{projectID}/components/{componentID}',
path: {
'projectID': projectId,
'componentID': componentId,
},
errors: {
401: `Error response`,
},
});
}
/**
* @returns TelemetryStats Aggregated telemetry statistics
* @throws ApiError
*/
public static getTelemetryStats({
projectId,
window,
}: {
projectId: string,
window?: '1h' | '24h' | '7d' | '30d',
}): CancelablePromise<TelemetryStats> {
return __request(OpenAPI, {
method: 'GET',
url: '/projects/{projectID}/telemetry/stats',
path: {
'projectID': projectId,
},
query: {
'window': window,
},
errors: {
401: `Error response`,
},
});
}
/**
* @returns MetricSeriesResponse Aggregated metric series
* @throws ApiError
*/
public static getTelemetryMetricSeries({
projectId,
name,
window,
}: {
projectId: string,
name: string,
window?: '1h' | '24h' | '7d' | '30d',
}): CancelablePromise<MetricSeriesResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/projects/{projectID}/telemetry/metrics/series',
path: {
'projectID': projectId,
},
query: {
'name': name,
'window': window,
},
errors: {
401: `Error response`,
},
});
}
/**
* Server-sent events stream of live telemetry. EventSource clients pass `?api_key=` or `?token=` since headers cannot be set.
* @returns any text/event-stream of TelemetryEvent messages
* @throws ApiError
*/
public static streamTelemetryEvents({
projectId,
apiKey,
token,
}: {
projectId: string,
apiKey?: string,
token?: string,
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'GET',
url: '/projects/{projectID}/telemetry/stream',
path: {
'projectID': projectId,
},
query: {
'api_key': apiKey,
'token': token,
},
errors: {
401: `Error response`,
},
});
}
}