From f8a1d3614d5e2db12d5d63ed904184d38ebd0bb5 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Fri, 27 Jun 2025 23:36:21 +0000 Subject: [PATCH] feat(actors): expose container system metrics --- docker/dev-full/docker-compose.yml | 2 + docker/dev-full/otel-collector/config.yaml | 10 +- docker/universal/Dockerfile | 19 +- docker/universal/client-full-entrypoint.sh | 17 + .../components/actors/actors-provider.tsx | 56 +++ .../project/queries/actors/query-options.ts | 132 +++++- .../components/src/actors/actor-context.tsx | 10 + .../src/actors/actor-editable-state.tsx | 4 +- .../src/actors/actor-metrics-tab.tsx | 25 ++ .../components/src/actors/actor-metrics.tsx | 424 ++++++++++++++++++ .../src/actors/actors-actor-details.tsx | 15 + .../errors/actor/metrics/invalid-interval.md | 9 + .../errors/actor/metrics/invalid-metrics.md | 9 + .../errors/actor/metrics/no-metrics.md | 9 + .../actor/metrics/unsupported-metrics.md | 9 + packages/common/migrate/src/migrate.rs | 4 +- packages/core/api/actor/src/route/metrics.rs | 321 +++++++++++++ packages/core/api/actor/src/route/mod.rs | 12 + packages/core/infra/server/src/run_config.rs | 8 + .../install/install_scripts/components/mod.rs | 58 ++- .../files/cadvisor_metric_exporter.sh | 42 ++ .../server/install/install_scripts/mod.rs | 2 +- .../migrations/20200101000000_noop.down.sql | 0 .../migrations/20200101000000_noop.up.sql | 2 + packages/edge/infra/client/config/src/lib.rs | 1 + .../edge/infra/client/config/src/utils.rs | 11 + .../client/container-runner/src/container.rs | 6 +- .../infra/client/container-runner/src/main.rs | 16 +- .../container-runner/tests/common/setup.rs | 2 +- .../infra/client/manager/src/actor/mod.rs | 4 + .../infra/client/manager/src/actor/setup.rs | 5 +- packages/edge/infra/client/manager/src/ctx.rs | 1 + .../edge/infra/client/manager/src/runner.rs | 3 +- sdks/api/fern/definition/actors/metrics.yml | 36 ++ sdks/api/full/go/actors/client/client.go | 5 +- sdks/api/full/go/actors/metrics.go | 50 +++ sdks/api/full/go/actors/metrics/client.go | 130 ++++++ sdks/api/full/openapi/openapi.yml | 117 +++++ sdks/api/full/openapi_compat/openapi.yml | 117 +++++ sdks/api/full/rust/.openapi-generator/FILES | 4 + sdks/api/full/rust/README.md | 2 + .../docs/ActorsGetActorMetricsResponse.md | 15 + sdks/api/full/rust/docs/ActorsMetricsApi.md | 44 ++ .../full/rust/src/apis/actors_metrics_api.rs | 88 ++++ sdks/api/full/rust/src/apis/mod.rs | 1 + .../actors_get_actor_metrics_response.rs | 41 ++ sdks/api/full/rust/src/models/mod.rs | 2 + .../src/api/resources/actors/client/Client.ts | 6 + .../api/resources/actors/resources/index.ts | 3 + .../actors/resources/metrics/client/Client.ts | 209 +++++++++ .../actors/resources/metrics/client/index.ts | 1 + .../requests/GetActorMetricsRequestQuery.ts | 21 + .../metrics/client/requests/index.ts | 1 + .../actors/resources/metrics/index.ts | 2 + .../metrics/types/GetActorMetricsResponse.ts | 11 + .../actors/resources/metrics/types/index.ts | 1 + .../resources/actors/resources/index.ts | 2 + .../actors/resources/metrics/index.ts | 1 + .../metrics/types/GetActorMetricsResponse.ts | 34 ++ .../actors/resources/metrics/types/index.ts | 1 + .../content/docs/api/actors/metrics/get.mdx | 37 ++ site/src/content/docs/api/errors.mdx | 49 +- site/src/content/docs/api/spec.json | 2 +- site/src/generated/apiPages.json | 5 + 64 files changed, 2217 insertions(+), 69 deletions(-) create mode 100644 docker/universal/client-full-entrypoint.sh create mode 100644 frontend/packages/components/src/actors/actor-metrics-tab.tsx create mode 100644 frontend/packages/components/src/actors/actor-metrics.tsx create mode 100644 packages/common/formatted-error/errors/actor/metrics/invalid-interval.md create mode 100644 packages/common/formatted-error/errors/actor/metrics/invalid-metrics.md create mode 100644 packages/common/formatted-error/errors/actor/metrics/no-metrics.md create mode 100644 packages/common/formatted-error/errors/actor/metrics/unsupported-metrics.md create mode 100644 packages/core/api/actor/src/route/metrics.rs create mode 100644 packages/core/services/cluster/src/workflows/server/install/install_scripts/files/cadvisor_metric_exporter.sh create mode 100644 packages/core/services/otel/db/otel/migrations/20200101000000_noop.down.sql create mode 100644 packages/core/services/otel/db/otel/migrations/20200101000000_noop.up.sql create mode 100644 packages/edge/infra/client/config/src/utils.rs create mode 100644 sdks/api/fern/definition/actors/metrics.yml create mode 100644 sdks/api/full/go/actors/metrics.go create mode 100644 sdks/api/full/go/actors/metrics/client.go create mode 100644 sdks/api/full/rust/docs/ActorsGetActorMetricsResponse.md create mode 100644 sdks/api/full/rust/docs/ActorsMetricsApi.md create mode 100644 sdks/api/full/rust/src/apis/actors_metrics_api.rs create mode 100644 sdks/api/full/rust/src/models/actors_get_actor_metrics_response.rs create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/Client.ts create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/index.ts create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/GetActorMetricsRequestQuery.ts create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/index.ts create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/index.ts create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts create mode 100644 sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/index.ts create mode 100644 sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/index.ts create mode 100644 sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts create mode 100644 sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/index.ts create mode 100644 site/src/content/docs/api/actors/metrics/get.mdx diff --git a/docker/dev-full/docker-compose.yml b/docker/dev-full/docker-compose.yml index 5f0185a783..5c47847ab7 100644 --- a/docker/dev-full/docker-compose.yml +++ b/docker/dev-full/docker-compose.yml @@ -233,6 +233,8 @@ services: # We only reserve 100 ports instead of the default 22,000. See # rivet-guard for explanation. - "7600-7699:7600-7699" + # cAdvisor metrics endpoint + - "7780:7780" networks: - rivet-network diff --git a/docker/dev-full/otel-collector/config.yaml b/docker/dev-full/otel-collector/config.yaml index 52964e8a95..0e430ca6e2 100644 --- a/docker/dev-full/otel-collector/config.yaml +++ b/docker/dev-full/otel-collector/config.yaml @@ -5,6 +5,14 @@ receivers: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 + prometheus: + config: + scrape_configs: + - job_name: 'cadvisor' + static_configs: + - targets: ['rivet-client:7780'] + metrics_path: /metrics + scrape_interval: 30s processors: batch: @@ -52,7 +60,7 @@ service: processors: [batch] exporters: [clickhouse] metrics: - receivers: [otlp] + receivers: [otlp, prometheus] processors: [batch] exporters: [clickhouse] diff --git a/docker/universal/Dockerfile b/docker/universal/Dockerfile index e13102837e..7e542bf207 100644 --- a/docker/universal/Dockerfile +++ b/docker/universal/Dockerfile @@ -120,8 +120,8 @@ RUN apt-get update -y && \ apt-get install -y ca-certificates openssl curl tini curl && \ curl -Lf -o /lib/libfdb_c.so "https://github.com/apple/foundationdb/releases/download/7.1.60/libfdb_c.x86_64.so" -# MARK: Runner (Full) -FROM --platform=linux/amd64 base-runner AS client-full +# MARK: Runner (Slim) +FROM --platform=linux/amd64 base-runner AS client-slim ARG CNI_PLUGINS_VERSION=1.3.0 RUN apt-get install -y skopeo iproute2 runc dnsutils && \ echo "Downloading lz4" && \ @@ -142,6 +142,21 @@ COPY ./docker/dev-full/rivet-client/rivet-actor.conflist /opt/cni/config/rivet-a COPY --from=builder /app/dist/rivet-client /app/dist/rivet-container-runner /usr/local/bin/ ENTRYPOINT ["/usr/bin/tini", "--", "entrypoint.sh"] +# MARK: Runner (Full) +FROM client-slim AS client-full +ARG CADVISOR_VERSION=v0.52.0 +RUN apt-get update -y && \ + apt-get install -y wget && \ + wget -O /usr/local/bin/cadvisor "https://github.com/google/cadvisor/releases/download/${CADVISOR_VERSION}/cadvisor-${CADVISOR_VERSION}-linux-amd64" && \ + chmod +x /usr/local/bin/cadvisor && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +COPY docker/universal/client-full-entrypoint.sh /usr/local/bin/client-full-entrypoint.sh +RUN chmod +x /usr/local/bin/client-full-entrypoint.sh + +ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/client-full-entrypoint.sh"] + # MARK: Monlith FROM --platform=linux/amd64 debian:12.9-slim AS monolith ENV DEBIAN_FRONTEND=noninteractive diff --git a/docker/universal/client-full-entrypoint.sh b/docker/universal/client-full-entrypoint.sh new file mode 100644 index 0000000000..a08d6b138e --- /dev/null +++ b/docker/universal/client-full-entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +# Start cadvisor in the background +cadvisor \ + --port=7780 \ + --listen_ip=0.0.0.0 \ + --prometheus_endpoint="/metrics" \ + --enable_metrics=cpu,cpuLoad,memory,network,disk,diskIO,oom_event,process,tcp,udp \ + --docker_only=false \ + --disable_root_cgroup_stats=false & + +# TODO: +# --raw_cgroup_prefix_whitelist="" \ + +# Start rivet-client with all passed arguments +exec rivet-client "$@" diff --git a/frontend/apps/hub/src/domains/project/components/actors/actors-provider.tsx b/frontend/apps/hub/src/domains/project/components/actors/actors-provider.tsx index 120a352534..59b263c7cb 100644 --- a/frontend/apps/hub/src/domains/project/components/actors/actors-provider.tsx +++ b/frontend/apps/hub/src/domains/project/components/actors/actors-provider.tsx @@ -12,6 +12,7 @@ import { actorBuildsAtom, createActorAtom, type Logs, + type Metrics, actorsQueryAtom, actorsInternalFilterAtom, type Actor, @@ -30,6 +31,7 @@ import { createActorEndpoint, destroyActorMutationOptions, actorLogsQueryOptions, + actorMetricsQueryOptions, actorRegionsQueryOptions, actorBuildsQueryOptions, } from "../../queries"; @@ -257,9 +259,63 @@ export function ActorsProvider({ }; }; + const metrics = atom({ + metrics: { cpu: null, memory: null } as Metrics, + status: "pending", + }); + metrics.onMount = (set) => { + const metricsObserver = new QueryObserver( + queryClient, + actorMetricsQueryOptions({ + projectNameId, + environmentNameId, + actorId: actor.id, + }, { refetchInterval: 5000 }), + ); + + type MetricsQuery = { + status: string; + data?: Awaited< + ReturnType< + Exclude< + ReturnType< + typeof actorMetricsQueryOptions + >["queryFn"], + undefined + > + > + >; + }; + + function updateMetrics(query: MetricsQuery) { + const data = query.data; + set((prev) => ({ + ...prev, + ...data, + status: query.status, + })); + } + + const subMetrics = metricsObserver.subscribe( + (query) => { + updateMetrics(query); + }, + ); + + updateMetrics( + metricsObserver.getCurrentQuery().state, + ); + + return () => { + metricsObserver.destroy(); + subMetrics(); + }; + }; + return { ...actor, logs, + metrics, destroy, status: getActorStatus(actor), }; diff --git a/frontend/apps/hub/src/domains/project/queries/actors/query-options.ts b/frontend/apps/hub/src/domains/project/queries/actors/query-options.ts index 6141176000..061a31de82 100644 --- a/frontend/apps/hub/src/domains/project/queries/actors/query-options.ts +++ b/frontend/apps/hub/src/domains/project/queries/actors/query-options.ts @@ -10,7 +10,7 @@ import { keepPreviousData, queryOptions, } from "@tanstack/react-query"; -import stripAnsi from 'strip-ansi'; +import stripAnsi from "strip-ansi"; export const projectActorsQueryOptions = ({ projectNameId, @@ -243,11 +243,10 @@ export const actorLogsQueryOptions = ( line: raw, message: "", properties: {}, - } as const + } as const; }); - - return {...response, logs }; + return { ...response, logs }; }, meta: { watch: mergeWatchStreams, @@ -255,6 +254,131 @@ export const actorLogsQueryOptions = ( }); }; +export const actorMetricsQueryOptions = ( + { + projectNameId, + environmentNameId, + actorId, + }: { + projectNameId: string; + environmentNameId: string; + actorId: string; + }, + opts: { refetchInterval?: number } = {}, +) => { + return queryOptions({ + ...opts, + queryKey: [ + "project", + projectNameId, + "environment", + environmentNameId, + "actor", + actorId, + "metrics", + ] as const, + queryFn: async ({ + signal: abortSignal, + queryKey: [, project, , environment, , actorId], + }) => { + const pollOffset = 5_000; + const pollInterval = 15_000; + + const now = Date.now(); + const start = now - pollInterval * 2 - pollOffset; // Last minute + 2 data points + const end = now - pollOffset; // Metrics have a minimum a 5 second latency based on poll interval + + const response = await rivetClient.actors.metrics.get( + actorId, + { + project, + environment, + start, + end, + interval: pollInterval, + }, + { abortSignal }, + ); + + // Process the new response format + const metrics: Record = {}; + const rawData: Record = {}; + + if ( + response.metricNames && + response.metricValues && + response.metricAttributes && + response.metricNames.length > 0 + ) { + response.metricNames.forEach((metricName, index) => { + const metricValues = response.metricValues[index]; + const attributes = response.metricAttributes[index] || {}; + + // Create the metric key based on the metric name and attributes + let metricKey = metricName; + + // Handle specific attribute mappings to match UI expectations + if (attributes.failure_type && attributes.scope) { + metricKey = `memory_failures_${attributes.failure_type}_${attributes.scope}`; + } else if (attributes.tcp_state) { + if (metricName.includes('tcp6')) { + metricKey = `network_tcp6_usage_${attributes.tcp_state}`; + } else { + metricKey = `network_tcp_usage_${attributes.tcp_state}`; + } + } else if (attributes.udp_state) { + if (metricName.includes('udp6')) { + metricKey = `network_udp6_usage_${attributes.udp_state}`; + } else { + metricKey = `network_udp_usage_${attributes.udp_state}`; + } + } else if (attributes.state) { + metricKey = `tasks_state_${attributes.state}`; + } else if (attributes.interface) { + // Handle network interface attributes + const baseMetric = metricName.replace(/^container_/, ''); + metricKey = `${baseMetric}_${attributes.interface}`; + } else if (attributes.device) { + // Handle filesystem device attributes + const baseMetric = metricName.replace(/^container_/, ''); + metricKey = `${baseMetric}_${attributes.device}`; + } else { + // Remove "container_" prefix to match UI expectations + metricKey = metricName.replace(/^container_/, ''); + } + + // Store raw time series data for rate calculations + rawData[metricKey] = metricValues || []; + + if (metricValues && metricValues.length > 0) { + // Get the latest non-zero value (last value is often 0) + let value = null; + for (let i = metricValues.length - 1; i >= 0; i--) { + if (metricValues[i] !== 0) { + value = metricValues[i]; + break; + } + } + // If all values are 0, use the last value anyway + if (value === null && metricValues.length > 0) { + value = metricValues[metricValues.length - 1]; + } + metrics[metricKey] = value; + } else { + metrics[metricKey] = null; + } + }); + } + + return { + metrics, + rawData, + interval: pollInterval, + }; + }, + }); +}; + export const actorBuildsQueryOptions = ({ projectNameId, environmentNameId, diff --git a/frontend/packages/components/src/actors/actor-context.tsx b/frontend/packages/components/src/actors/actor-context.tsx index c624ac952a..a76cdec19a 100644 --- a/frontend/packages/components/src/actors/actor-context.tsx +++ b/frontend/packages/components/src/actors/actor-context.tsx @@ -13,6 +13,7 @@ export enum ActorFeature { State = "state", Console = "console", Runtime = "runtime", + Metrics = "metrics", InspectReconnectNotification = "inspect_reconnect_notification", } @@ -25,6 +26,7 @@ export type Actor = Omit< lifecycle?: Rivet.actor.Lifecycle; endpoint?: string; logs: LogsAtom; + metrics: MetricsAtom; network?: Rivet.actor.Network | null; resources?: Rivet.actor.Resources | null; runtime?: Rivet.actor.Runtime | null; @@ -43,6 +45,8 @@ export type Logs = { properties: Record; }[]; +export type Metrics = Record; + export type Build = Rivet.actor.Build; export type DestroyActor = { isDestroying: boolean; @@ -55,6 +59,11 @@ export type LogsAtom = Atom<{ // query status status: string; }>; +export type MetricsAtom = Atom<{ + metrics: Metrics; + // query status + status: string; +}>; export type BuildAtom = Atom; export type DestroyActorAtom = Atom; @@ -378,6 +387,7 @@ const commonActorFeatures = [ ActorFeature.Logs, ActorFeature.Config, ActorFeature.Runtime, + ActorFeature.Metrics, ActorFeature.InspectReconnectNotification, ]; diff --git a/frontend/packages/components/src/actors/actor-editable-state.tsx b/frontend/packages/components/src/actors/actor-editable-state.tsx index fdef3dd91b..e54e474548 100644 --- a/frontend/packages/components/src/actors/actor-editable-state.tsx +++ b/frontend/packages/components/src/actors/actor-editable-state.tsx @@ -1,4 +1,4 @@ -import { Badge, Button, LiveBadge, WithTooltip } from "@rivet-gg/components"; +import { Badge, Button, WithTooltip } from "@rivet-gg/components"; import { type CodeMirrorRef, EditorView, @@ -42,8 +42,6 @@ export function ActorEditableState({ state }: ActorEditableStateProps) { <>
- -
diff --git a/frontend/packages/components/src/actors/actor-metrics-tab.tsx b/frontend/packages/components/src/actors/actor-metrics-tab.tsx new file mode 100644 index 0000000000..227fdbac1d --- /dev/null +++ b/frontend/packages/components/src/actors/actor-metrics-tab.tsx @@ -0,0 +1,25 @@ +import { Button, DocsSheet, ScrollArea } from "@rivet-gg/components"; +import { Icon, faBooks } from "@rivet-gg/icons"; +import { ActorMetrics } from "./actor-metrics"; +import type { ActorAtom } from "./actor-context"; + +interface ActorMetricsTabProps { + actor: ActorAtom; +} + +export function ActorMetricsTab(props: ActorMetricsTabProps) { + return ( + +
+ +
+ +
+ ); +} diff --git a/frontend/packages/components/src/actors/actor-metrics.tsx b/frontend/packages/components/src/actors/actor-metrics.tsx new file mode 100644 index 0000000000..ed4940ff88 --- /dev/null +++ b/frontend/packages/components/src/actors/actor-metrics.tsx @@ -0,0 +1,424 @@ +import { useAtomValue } from "jotai"; +import { selectAtom } from "jotai/utils"; +import equal from "fast-deep-equal"; +import { useState, useEffect } from "react"; +import { Dd, Dl, Dt, Flex, Button } from "@rivet-gg/components"; +import type { Actor, ActorAtom } from "./actor-context"; + +const selector = (a: Actor) => ({ + metrics: a.metrics, + status: a.status, +}); + +export interface ActorMetricsProps { + actor: ActorAtom; +} + +export function ActorMetrics({ actor }: ActorMetricsProps) { + const { metrics, status } = useAtomValue(selectAtom(actor, selector, equal)); + const metricsData = useAtomValue(metrics); + const [showAdvanced, setShowAdvanced] = useState(false); + const [cpuPercentage, setCpuPercentage] = useState("n/a"); + + const isActorRunning = status === "running"; + + const formatBytes = (bytes: number | null | undefined) => { + if (!isActorRunning || bytes === null || bytes === undefined) return "n/a"; + const mb = bytes / 1024 / 1024; + if (mb < 1024) { + return `${mb.toFixed(1)} MB`; + } else { + return `${(mb / 1024).toFixed(1)} GB`; + } + }; + + const formatCpuUsage = (cpu: number | null | undefined) => { + if (!isActorRunning || cpu === null || cpu === undefined) return "n/a"; + return `${(cpu * 100).toFixed(2)}%`; + }; + + const formatNumber = (value: number | null | undefined) => { + if (!isActorRunning || value === null || value === undefined) return "n/a"; + return value.toLocaleString(); + }; + + const formatTimestamp = (timestamp: number | null | undefined) => { + if (!isActorRunning || timestamp === null || timestamp === undefined) return "n/a"; + return new Date(timestamp * 1000).toLocaleString(); + }; + + // Calculate CPU percentage using time series data points + useEffect(() => { + if (!isActorRunning) { + setCpuPercentage("n/a"); + return; + } + + const data = metricsData; + if (!data || !data.rawData || !data.interval) { + setCpuPercentage("n/a"); + return; + } + + const cpuValues = data.rawData.cpu_usage_seconds_total; + if (!cpuValues || cpuValues.length < 2) { + setCpuPercentage("n/a"); + return; + } + + // Find two non-zero consecutive data points to calculate rate + let cpuRate = 0; + for (let i = cpuValues.length - 1; i > 0; i--) { + const currentCpu = cpuValues[i]; + const previousCpu = cpuValues[i - 1]; + + if (currentCpu !== 0 && previousCpu !== 0 && currentCpu >= previousCpu) { + const cpuDelta = currentCpu - previousCpu; + const timeDelta = data.interval / 1000; // Convert ms to seconds + + // Rate calculation: CPU seconds used per second of real time + // This gives the fraction of available CPU used (0-1) + cpuRate = (cpuDelta / timeDelta) * 100; + break; + } + } + + setCpuPercentage(`${Math.min(cpuRate, 100).toFixed(2)}%`); + }, [metricsData, isActorRunning]); + + const calculateMemoryPercentage = (usage: number | null | undefined, limit: number | null | undefined) => { + if (!isActorRunning || usage === null || usage === undefined || limit === null || limit === undefined || limit === 0) { + return null; + } + return (usage / limit) * 100; + }; + + const isLoading = metricsData.status === "pending"; + const hasError = metricsData.status === "error"; + const data = metricsData.metrics || {}; + + if (isLoading) { + return ( +
+

Metrics

+
Loading...
+
+ ); + } + + if (hasError) { + return ( +
+

Metrics

+
Error loading metrics
+
+ ); + } + + const memoryPercentage = calculateMemoryPercentage(data.memory_usage_bytes, data.spec_memory_limit_bytes); + + return ( +
+

Container Metrics

+ + {/* Main Metrics */} +
+
+
+
CPU Usage
+
+ {cpuPercentage} +
+
+
+
Memory Usage
+
+ {formatBytes(data.memory_usage_bytes)} + {memoryPercentage !== null && ( + + ({memoryPercentage.toFixed(1)}%) + + )} +
+
+
+
+ + {/* Advanced Section Toggle */} +
+ +
+ + {/* Advanced Metrics */} + {showAdvanced && ( + + {/* CPU & Performance */} +
+

CPU & Performance

+
+
CPU Load Average (10s)
+
{formatCpuUsage(data.cpu_load_average_10s)}
+
CPU Usage Seconds Total
+
{formatNumber(data.cpu_usage_seconds_total)}
+
CPU User Seconds Total
+
{formatNumber(data.cpu_user_seconds_total)}
+
CPU System Seconds Total
+
{formatNumber(data.cpu_system_seconds_total)}
+
CPU Schedstat Run Periods
+
{formatNumber(data.cpu_schedstat_run_periods_total)}
+
CPU Schedstat Run Seconds
+
{formatNumber(data.cpu_schedstat_run_seconds_total)}
+
CPU Schedstat Runqueue Seconds
+
{formatNumber(data.cpu_schedstat_runqueue_seconds_total)}
+
+
+ + {/* Memory */} +
+

Memory

+
+
Memory Usage
+
{formatBytes(data.memory_usage_bytes)}
+
Memory Working Set
+
{formatBytes(data.memory_working_set_bytes)}
+
Memory RSS
+
{formatBytes(data.memory_rss)}
+
Memory Cache
+
{formatBytes(data.memory_cache)}
+
Memory Swap
+
{formatBytes(data.memory_swap)}
+
Memory Max Usage
+
{formatBytes(data.memory_max_usage_bytes)}
+
Memory Mapped File
+
{formatBytes(data.memory_mapped_file)}
+
Memory Failcnt
+
{formatNumber(data.memory_failcnt)}
+
+
+ + {/* Memory Failures */} +
+

Memory Failures

+
+
Page Fault (Container)
+
{formatNumber(data.memory_failures_pgfault_container)}
+
Page Fault (Hierarchy)
+
{formatNumber(data.memory_failures_pgfault_hierarchy)}
+
Major Page Fault (Container)
+
{formatNumber(data.memory_failures_pgmajfault_container)}
+
Major Page Fault (Hierarchy)
+
{formatNumber(data.memory_failures_pgmajfault_hierarchy)}
+
+
+ + {/* Memory Limits */} +
+

Memory Limits

+
+
Memory Limit
+
{formatBytes(data.spec_memory_limit_bytes)}
+
Memory Reservation Limit
+
{formatBytes(data.spec_memory_reservation_limit_bytes)}
+
Memory Swap Limit
+
{formatBytes(data.spec_memory_swap_limit_bytes)}
+
+
+ + {/* Processes & Threads */} +
+

Processes & Threads

+
+
Processes
+
{formatNumber(data.processes)}
+
Threads
+
{formatNumber(data.threads)}
+
Max Threads
+
{formatNumber(data.threads_max)}
+
Tasks Running
+
{formatNumber(data.tasks_state_running)}
+
Tasks Sleeping
+
{formatNumber(data.tasks_state_sleeping)}
+
Tasks Stopped
+
{formatNumber(data.tasks_state_stopped)}
+
Tasks IO Waiting
+
{formatNumber(data.tasks_state_iowaiting)}
+
Tasks Uninterruptible
+
{formatNumber(data.tasks_state_uninterruptible)}
+
+
+ + {/* Filesystem */} +
+

Filesystem

+
+
Reads Bytes Total (sda)
+
{formatBytes(data.fs_reads_bytes_total_sda)}
+
Writes Bytes Total (sda)
+
{formatBytes(data.fs_writes_bytes_total_sda)}
+
+
+ + {/* Network - Receive */} +
+

Network - Receive

+
+
Bytes Total (eth0)
+
{formatBytes(data.network_receive_bytes_total_eth0)}
+
Bytes Total (eth1)
+
{formatBytes(data.network_receive_bytes_total_eth1)}
+
Errors Total (eth0)
+
{formatNumber(data.network_receive_errors_total_eth0)}
+
Errors Total (eth1)
+
{formatNumber(data.network_receive_errors_total_eth1)}
+
Packets Dropped (eth0)
+
{formatNumber(data.network_receive_packets_dropped_total_eth0)}
+
Packets Dropped (eth1)
+
{formatNumber(data.network_receive_packets_dropped_total_eth1)}
+
Packets Total (eth0)
+
{formatNumber(data.network_receive_packets_total_eth0)}
+
Packets Total (eth1)
+
{formatNumber(data.network_receive_packets_total_eth1)}
+
+
+ + {/* Network - Transmit */} +
+

Network - Transmit

+
+
Bytes Total (eth0)
+
{formatBytes(data.network_transmit_bytes_total_eth0)}
+
Bytes Total (eth1)
+
{formatBytes(data.network_transmit_bytes_total_eth1)}
+
Errors Total (eth0)
+
{formatNumber(data.network_transmit_errors_total_eth0)}
+
Errors Total (eth1)
+
{formatNumber(data.network_transmit_errors_total_eth1)}
+
Packets Dropped (eth0)
+
{formatNumber(data.network_transmit_packets_dropped_total_eth0)}
+
Packets Dropped (eth1)
+
{formatNumber(data.network_transmit_packets_dropped_total_eth1)}
+
Packets Total (eth0)
+
{formatNumber(data.network_transmit_packets_total_eth0)}
+
Packets Total (eth1)
+
{formatNumber(data.network_transmit_packets_total_eth1)}
+
+
+ + {/* TCP Connections */} +
+

TCP Connections

+
+
Close
+
{formatNumber(data.network_tcp_usage_close)}
+
Close Wait
+
{formatNumber(data.network_tcp_usage_closewait)}
+
Closing
+
{formatNumber(data.network_tcp_usage_closing)}
+
Established
+
{formatNumber(data.network_tcp_usage_established)}
+
Fin Wait 1
+
{formatNumber(data.network_tcp_usage_finwait1)}
+
Fin Wait 2
+
{formatNumber(data.network_tcp_usage_finwait2)}
+
Last Ack
+
{formatNumber(data.network_tcp_usage_lastack)}
+
Listen
+
{formatNumber(data.network_tcp_usage_listen)}
+
Syn Recv
+
{formatNumber(data.network_tcp_usage_synrecv)}
+
Syn Sent
+
{formatNumber(data.network_tcp_usage_synsent)}
+
Time Wait
+
{formatNumber(data.network_tcp_usage_timewait)}
+
+
+ + {/* TCP6 Connections */} +
+

TCP6 Connections

+
+
Close
+
{formatNumber(data.network_tcp6_usage_close)}
+
Close Wait
+
{formatNumber(data.network_tcp6_usage_closewait)}
+
Closing
+
{formatNumber(data.network_tcp6_usage_closing)}
+
Established
+
{formatNumber(data.network_tcp6_usage_established)}
+
Fin Wait 1
+
{formatNumber(data.network_tcp6_usage_finwait1)}
+
Fin Wait 2
+
{formatNumber(data.network_tcp6_usage_finwait2)}
+
Last Ack
+
{formatNumber(data.network_tcp6_usage_lastack)}
+
Listen
+
{formatNumber(data.network_tcp6_usage_listen)}
+
Syn Recv
+
{formatNumber(data.network_tcp6_usage_synrecv)}
+
Syn Sent
+
{formatNumber(data.network_tcp6_usage_synsent)}
+
Time Wait
+
{formatNumber(data.network_tcp6_usage_timewait)}
+
+
+ + {/* UDP Connections */} +
+

UDP Connections

+
+
Dropped
+
{formatNumber(data.network_udp_usage_dropped)}
+
Listen
+
{formatNumber(data.network_udp_usage_listen)}
+
RX Queued
+
{formatNumber(data.network_udp_usage_rxqueued)}
+
TX Queued
+
{formatNumber(data.network_udp_usage_txqueued)}
+
+
+ + {/* UDP6 Connections */} +
+

UDP6 Connections

+
+
Dropped
+
{formatNumber(data.network_udp6_usage_dropped)}
+
Listen
+
{formatNumber(data.network_udp6_usage_listen)}
+
RX Queued
+
{formatNumber(data.network_udp6_usage_rxqueued)}
+
TX Queued
+
{formatNumber(data.network_udp6_usage_txqueued)}
+
+
+ + {/* System */} +
+

System

+
+
File Descriptors
+
{formatNumber(data.file_descriptors)}
+
Sockets
+
{formatNumber(data.sockets)}
+
Last Seen
+
{formatTimestamp(data.last_seen)}
+
Start Time
+
{formatTimestamp(data.start_time_seconds)}
+
CPU Shares
+
{formatNumber(data.spec_cpu_shares)}
+
CPU Period
+
{formatNumber(data.spec_cpu_period)}
+
+
+
+ )} +
+ ); +} diff --git a/frontend/packages/components/src/actors/actors-actor-details.tsx b/frontend/packages/components/src/actors/actors-actor-details.tsx index 62a1178df4..26ed422932 100644 --- a/frontend/packages/components/src/actors/actors-actor-details.tsx +++ b/frontend/packages/components/src/actors/actors-actor-details.tsx @@ -11,6 +11,7 @@ import { ActorConfigTab } from "./actor-config-tab"; import { ActorConnectionsTab } from "./actor-connections-tab"; import { ActorDetailsSettingsProvider } from "./actor-details-settings"; import { ActorLogsTab } from "./actor-logs-tab"; +import { ActorMetricsTab } from "./actor-metrics-tab"; import { ActorStateTab } from "./actor-state-tab"; import { AtomizedActorStatus } from "./actor-status"; import { ActorStopButton } from "./actor-stop-button"; @@ -100,6 +101,7 @@ export function ActorTabs({ const supportsLogs = features?.includes(ActorFeature.Logs); const supportsConnections = features?.includes(ActorFeature.Connections); const supportsConfig = features?.includes(ActorFeature.Config); + const supportsMetrics = features?.includes(ActorFeature.Metrics); const defaultTab = supportsState ? "state" : "logs"; const value = disabled ? undefined : tab || defaultTab; @@ -138,6 +140,11 @@ export function ActorTabs({ Config ) : null} + {supportsMetrics ? ( + + Metrics + + ) : null} {actor ? ( ) : null} + {supportsMetrics ? ( + + + + ) : null} ) : null} {children} diff --git a/packages/common/formatted-error/errors/actor/metrics/invalid-interval.md b/packages/common/formatted-error/errors/actor/metrics/invalid-interval.md new file mode 100644 index 0000000000..3e64dfcd5c --- /dev/null +++ b/packages/common/formatted-error/errors/actor/metrics/invalid-interval.md @@ -0,0 +1,9 @@ +--- +name = "ACTOR_METRICS_INVALID_INTERVAL" +description = "Invalid interval provided." +http_status = 400 +--- + +# Invalid Interval + +The provided interval must be greater than 0. Please provide a valid interval value in milliseconds. \ No newline at end of file diff --git a/packages/common/formatted-error/errors/actor/metrics/invalid-metrics.md b/packages/common/formatted-error/errors/actor/metrics/invalid-metrics.md new file mode 100644 index 0000000000..3f755dd0b7 --- /dev/null +++ b/packages/common/formatted-error/errors/actor/metrics/invalid-metrics.md @@ -0,0 +1,9 @@ +--- +name = "ACTOR_METRICS_INVALID_METRICS" +description = "Invalid metrics format." +http_status = 400 +--- + +# Invalid Metrics + +The provided list of metrics is not in a valid JSON format. Please provide a valid JSON array of metric names. \ No newline at end of file diff --git a/packages/common/formatted-error/errors/actor/metrics/no-metrics.md b/packages/common/formatted-error/errors/actor/metrics/no-metrics.md new file mode 100644 index 0000000000..cc2da592b4 --- /dev/null +++ b/packages/common/formatted-error/errors/actor/metrics/no-metrics.md @@ -0,0 +1,9 @@ +--- +name = "ACTOR_METRICS_NO_METRICS" +description = "No metrics specified." +http_status = 400 +--- + +# No Metrics + +No metrics were specified in the request. Please provide at least one metric name to query. \ No newline at end of file diff --git a/packages/common/formatted-error/errors/actor/metrics/unsupported-metrics.md b/packages/common/formatted-error/errors/actor/metrics/unsupported-metrics.md new file mode 100644 index 0000000000..a843c91868 --- /dev/null +++ b/packages/common/formatted-error/errors/actor/metrics/unsupported-metrics.md @@ -0,0 +1,9 @@ +--- +name = "ACTOR_METRICS_UNSUPPORTED_METRICS" +description = "Unsupported metrics requested." +http_status = 400 +--- + +# Unsupported Metrics + +The requested metrics are not supported. Supported metrics include: cpu, memory, memory_limit, network_rx_bytes, network_tx_bytes. \ No newline at end of file diff --git a/packages/common/migrate/src/migrate.rs b/packages/common/migrate/src/migrate.rs index fb956af111..8bb8e4001a 100644 --- a/packages/common/migrate/src/migrate.rs +++ b/packages/common/migrate/src/migrate.rs @@ -349,7 +349,7 @@ async fn run_migration(config: rivet_config::Config, cmd: &MigrateCmd) -> Result .await .expect("Failed to read stdout") { - tracing::debug!("migrate stdout: {}", line); + tracing::info!("migrate stdout: {}", line); } }); @@ -360,7 +360,7 @@ async fn run_migration(config: rivet_config::Config, cmd: &MigrateCmd) -> Result .await .expect("Failed to read stderr") { - tracing::debug!("migrate stderr: {}", line); + tracing::info!("migrate stderr: {}", line); } }); diff --git a/packages/core/api/actor/src/route/metrics.rs b/packages/core/api/actor/src/route/metrics.rs new file mode 100644 index 0000000000..a8bd553cf9 --- /dev/null +++ b/packages/core/api/actor/src/route/metrics.rs @@ -0,0 +1,321 @@ +use api_helper::{ + anchor::{WatchIndexQuery, WatchResponse}, + ctx::Ctx, +}; +use rivet_api::models; +use rivet_operation::prelude::*; +use serde::Deserialize; +use std::collections::{BTreeMap, HashMap}; + +use crate::{ + assert, + auth::{Auth, CheckOpts, CheckOutput}, + utils::build_global_query_compat, +}; + +use super::GlobalQuery; + +#[derive(Debug, Deserialize)] +pub struct GetActorMetricsQuery { + #[serde(flatten)] + pub global: GlobalQuery, + pub start: i64, + pub end: i64, + pub interval: i64, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum MetricType { + Counter, + Gauge, +} + +impl MetricType { + pub fn as_str(&self) -> &'static str { + match self { + MetricType::Counter => "counter", + MetricType::Gauge => "gauge", + } + } +} + +#[derive(Debug, clickhouse::Row, serde::Deserialize)] +pub struct MetricRow { + pub time_bucket_index: u32, + pub metric_name: String, + pub value: f64, + pub tcp_state: String, + pub udp_state: String, + pub device: String, + pub failure_type: String, + pub scope: String, + pub task_state: String, + pub interface: String, +} + +#[derive(Debug)] +pub struct ProcessedMetricRow { + pub row: MetricRow, + pub metric_type: MetricType, +} + +#[tracing::instrument(skip_all)] +pub async fn get_metrics( + ctx: Ctx, + actor_id: Uuid, + watch_index: WatchIndexQuery, + query: GetActorMetricsQuery, +) -> GlobalResult { + let CheckOutput { game_id, env_id } = ctx + .auth() + .check( + ctx.op_ctx(), + CheckOpts { + query: &query.global, + allow_service_token: false, + opt_auth: false, + }, + ) + .await?; + + // Validate the actor belongs to this game/env + assert::actor_for_env(&ctx, &[actor_id], game_id, env_id, None).await?; + + let clickhouse = ctx.clickhouse().await?; + + // Convert milliseconds to seconds for ClickHouse + let start_seconds = query.start / 1000; + let end_seconds = query.end / 1000; + let interval_seconds = query.interval / 1000; + + if interval_seconds == 0 { + return Err(formatted_error::code::ACTOR_METRICS_INVALID_INTERVAL); + } + + let actor_prefix = format!("/system.slice/pegboard-actor-{}-", actor_id); + + // Query gauge metrics (current values) + let gauge_query = indoc! {" + SELECT + toUInt32(floor((toUnixTimestamp(TimeUnix) - ?) / ?)) as time_bucket_index, + MetricName as metric_name, + max(Value) as value, + COALESCE(Attributes['tcp_state'], '') as tcp_state, + COALESCE(Attributes['udp_state'], '') as udp_state, + COALESCE(Attributes['device'], '') as device, + COALESCE(Attributes['failure_type'], '') as failure_type, + COALESCE(Attributes['scope'], '') as scope, + COALESCE(Attributes['state'], '') as task_state, + COALESCE(Attributes['interface'], '') as interface + FROM otel.otel_metrics_gauge + WHERE + TimeUnix >= fromUnixTimestamp(?) + AND TimeUnix <= fromUnixTimestamp(?) + AND MetricName IN [ + 'container_cpu_load_average_10s', + 'container_file_descriptors', + 'container_last_seen', + 'container_memory_usage_bytes', + 'container_memory_working_set_bytes', + 'container_memory_cache', + 'container_memory_rss', + 'container_memory_swap', + 'container_memory_mapped_file', + 'container_memory_max_usage_bytes', + 'container_network_tcp_usage_total', + 'container_network_tcp6_usage_total', + 'container_network_udp_usage_total', + 'container_network_udp6_usage_total', + 'container_sockets', + 'container_spec_cpu_period', + 'container_spec_cpu_shares', + 'container_spec_memory_limit_bytes', + 'container_spec_memory_reservation_limit_bytes', + 'container_spec_memory_swap_limit_bytes', + 'container_start_time_seconds', + 'container_tasks_state', + 'container_threads', + 'container_threads_max', + 'container_processes' + ] + AND has(Attributes, 'id') + AND startsWith(Attributes['id'], ?) + GROUP BY time_bucket_index, metric_name, tcp_state, udp_state, device, failure_type, scope, task_state, interface + ORDER BY time_bucket_index ASC, metric_name + "}; + + let gauge_future = clickhouse + .query(&gauge_query) + .bind(start_seconds) + .bind(interval_seconds) + .bind(start_seconds) + .bind(end_seconds) + .bind(&actor_prefix) + .fetch_all::(); + + // Query sum metrics (rates/counters) + let sum_query = indoc! {" + SELECT + toUInt32(floor((toUnixTimestamp(TimeUnix) - ?) / ?)) as time_bucket_index, + MetricName as metric_name, + max(Value) as value, + COALESCE(Attributes['tcp_state'], '') as tcp_state, + COALESCE(Attributes['udp_state'], '') as udp_state, + COALESCE(Attributes['device'], '') as device, + COALESCE(Attributes['failure_type'], '') as failure_type, + COALESCE(Attributes['scope'], '') as scope, + COALESCE(Attributes['state'], '') as task_state, + COALESCE(Attributes['interface'], '') as interface + FROM otel.otel_metrics_sum + WHERE + TimeUnix >= fromUnixTimestamp(?) + AND TimeUnix <= fromUnixTimestamp(?) + AND MetricName IN [ + 'container_cpu_schedstat_run_periods_total', + 'container_cpu_schedstat_run_seconds_total', + 'container_cpu_schedstat_runqueue_seconds_total', + 'container_cpu_system_seconds_total', + 'container_cpu_user_seconds_total', + 'container_cpu_usage_seconds_total', + 'container_memory_failcnt', + 'container_memory_failures_total', + 'container_fs_reads_bytes_total', + 'container_fs_writes_bytes_total', + 'container_network_receive_bytes_total', + 'container_network_receive_errors_total', + 'container_network_receive_packets_dropped_total', + 'container_network_receive_packets_total', + 'container_network_transmit_bytes_total', + 'container_network_transmit_errors_total', + 'container_network_transmit_packets_dropped_total', + 'container_network_transmit_packets_total' + ] + AND has(Attributes, 'id') + AND startsWith(Attributes['id'], ?) + GROUP BY time_bucket_index, metric_name, tcp_state, udp_state, device, failure_type, scope, task_state, interface + ORDER BY time_bucket_index ASC, metric_name + "}; + + let sum_future = clickhouse + .query(&sum_query) + .bind(start_seconds) + .bind(interval_seconds) + .bind(start_seconds) + .bind(end_seconds) + .bind(&actor_prefix) + .fetch_all::(); + + let (gauge_rows, sum_rows) = + tokio::try_join!(gauge_future, sum_future).map_err(|err| GlobalError::from(err))?; + + // Map metric types based on query source + let gauge_rows: Vec = gauge_rows + .into_iter() + .map(|row| ProcessedMetricRow { + row, + metric_type: MetricType::Gauge, + }) + .collect(); + + let sum_rows: Vec = sum_rows + .into_iter() + .map(|row| ProcessedMetricRow { + row, + metric_type: MetricType::Counter, + }) + .collect(); + + // Combine both result sets + let mut rows = gauge_rows; + rows.extend(sum_rows); + + // Calculate the number of time buckets we expect + let num_buckets = ((end_seconds - start_seconds) / interval_seconds + 1) as usize; + + // Use HashMap to store metrics with their attributes and types + let mut metrics: HashMap<(String, BTreeMap), (String, Vec)> = + HashMap::new(); + + // Process rows and organize by metric name + attributes + for processed_row in rows { + let row = &processed_row.row; + if row.time_bucket_index >= num_buckets as u32 { + continue; + } + let bucket_idx = row.time_bucket_index as usize; + + // Build attributes map for this row + let mut attributes = BTreeMap::new(); + + // Add non-empty attributes + if !row.tcp_state.is_empty() { + attributes.insert("tcp_state".to_string(), row.tcp_state.clone()); + } + if !row.udp_state.is_empty() { + attributes.insert("udp_state".to_string(), row.udp_state.clone()); + } + if !row.device.is_empty() { + attributes.insert("device".to_string(), row.device.clone()); + } + if !row.failure_type.is_empty() { + attributes.insert("failure_type".to_string(), row.failure_type.clone()); + } + if !row.scope.is_empty() { + attributes.insert("scope".to_string(), row.scope.clone()); + } + if !row.task_state.is_empty() { + attributes.insert("state".to_string(), row.task_state.clone()); + } + if !row.interface.is_empty() { + attributes.insert("interface".to_string(), row.interface.clone()); + } + + // Create metric key (metric name + attributes) + let metric_key = (row.metric_name.clone(), attributes); + + // Initialize metric entry if it doesn't exist + let (existing_type, metric_values) = metrics.entry(metric_key).or_insert_with(|| { + ( + processed_row.metric_type.as_str().to_string(), + vec![0.0; num_buckets], + ) + }); + + // Add or set the value based on metric type + match processed_row.metric_type { + MetricType::Counter => { + metric_values[bucket_idx] += row.value; + } + MetricType::Gauge => { + metric_values[bucket_idx] = row.value; + } + } + } + + // Convert HashMap to ordered vectors for response + let mut metric_names = Vec::new(); + let mut metric_attributes = Vec::new(); + let mut metric_types = Vec::new(); + let mut metric_values = Vec::new(); + + // Sort metrics by name for consistent ordering + let mut sorted_metrics: Vec<_> = metrics.into_iter().collect(); + sorted_metrics.sort_by(|a, b| a.0 .0.cmp(&b.0 .0)); + + for ((name, attributes), (metric_type, values)) in sorted_metrics { + metric_names.push(name); + // Convert BTreeMap back to HashMap for the API response + let attributes_hashmap: HashMap = attributes.into_iter().collect(); + metric_attributes.push(attributes_hashmap); + metric_types.push(metric_type); + metric_values.push(values); + } + + Ok(models::ActorsGetActorMetricsResponse { + actor_ids: vec![actor_id.to_string()], + metric_names, + metric_attributes, + metric_types, + metric_values, + }) +} diff --git a/packages/core/api/actor/src/route/mod.rs b/packages/core/api/actor/src/route/mod.rs index 6eaa115384..50deb4e608 100644 --- a/packages/core/api/actor/src/route/mod.rs +++ b/packages/core/api/actor/src/route/mod.rs @@ -8,6 +8,7 @@ use uuid::Uuid; pub mod actors; pub mod builds; pub mod logs; +pub mod metrics; pub mod regions; pub mod routes; @@ -124,6 +125,17 @@ define_router! { ), }, + "actors" / Uuid / "metrics" / "history": { + GET: metrics::get_metrics( + query: metrics::GetActorMetricsQuery, + opt_auth: true, + rate_limit: { + buckets: [ + { count: 100, bucket: duration::minutes(1) }, + ], + }, + ), + }, "builds": { GET: builds::list( diff --git a/packages/core/infra/server/src/run_config.rs b/packages/core/infra/server/src/run_config.rs index ab5dd4196f..cde022a1bb 100644 --- a/packages/core/infra/server/src/run_config.rs +++ b/packages/core/infra/server/src/run_config.rs @@ -283,6 +283,14 @@ pub fn config(rivet_config: rivet_config::Config) -> Result { ), db_name: "db_pegboard_analytics", }, + // This schema is automatically set up by OTEL collector + // + // We still have to create this database so we can grant users access to read from it + SqlService { + kind: SqlServiceKind::ClickHouse, + migrations: include_dir!("$CARGO_MANIFEST_DIR/../../../core/services/otel/db/otel"), + db_name: "otel", + }, ]; let s3_buckets = vec![ diff --git a/packages/core/services/cluster/src/workflows/server/install/install_scripts/components/mod.rs b/packages/core/services/cluster/src/workflows/server/install/install_scripts/components/mod.rs index c75338adf8..b04439ef07 100644 --- a/packages/core/services/cluster/src/workflows/server/install/install_scripts/components/mod.rs +++ b/packages/core/services/cluster/src/workflows/server/install/install_scripts/components/mod.rs @@ -32,6 +32,12 @@ pub mod process_exporter { } } +pub mod cadvisor_metric_exporter { + pub fn install() -> String { + include_str!("../files/cadvisor_metric_exporter.sh").to_string() + } +} + pub mod otel_collector { use chirp_workflow::prelude::*; use serde_json::json; @@ -42,19 +48,41 @@ pub mod otel_collector { const VERSION: &str = "0.125.0"; pub fn install(pool_type: PoolType) -> GlobalResult { - let config = json!({ - "receivers": { - "otlp": { - "protocols": { - "grpc": { - "endpoint": "0.0.0.0:4317" - }, - "http": { - "endpoint": "0.0.0.0:4318" - } + let mut receivers = json!({ + "otlp": { + "protocols": { + "grpc": { + "endpoint": "0.0.0.0:4317" + }, + "http": { + "endpoint": "0.0.0.0:4318" } } - }, + } + }); + + // Add prometheus receiver for cadvisor on Pegboard pools + if matches!(pool_type, PoolType::Pegboard) { + receivers["prometheus"] = json!({ + "config": { + "scrape_configs": [ + { + "job_name": "cadvisor", + "static_configs": [ + { + "targets": ["127.0.0.1:7780"] + } + ], + "metrics_path": "/metrics", + "scrape_interval": "5s" + } + ] + } + }); + } + + let config = json!({ + "receivers": receivers, "processors": { "batch": { "timeout": "5s", @@ -162,9 +190,11 @@ pub mod otel_collector { ] }, "metrics": { - "receivers": [ - "otlp" - ], + "receivers": if matches!(pool_type, PoolType::Pegboard | PoolType::PegboardIsolate) { + json!(["otlp", "prometheus"]) + } else { + json!(["otlp"]) + }, "processors": [ "batch" ], diff --git a/packages/core/services/cluster/src/workflows/server/install/install_scripts/files/cadvisor_metric_exporter.sh b/packages/core/services/cluster/src/workflows/server/install/install_scripts/files/cadvisor_metric_exporter.sh new file mode 100644 index 0000000000..6e5a3d5f1c --- /dev/null +++ b/packages/core/services/cluster/src/workflows/server/install/install_scripts/files/cadvisor_metric_exporter.sh @@ -0,0 +1,42 @@ +# Download cadvisor binary +# +# v0.38 +echo 'Installing cadvisor' +apt install -y cadvisor + +# Disable the default cadvisor service +systemctl stop cadvisor || true +systemctl disable cadvisor || true + +# Create new service file with updated flags +# +# See all metrics: https://github.com/google/cadvisor/blob/95fd3aff63650e37c3825c58fbf4db85f68b8c26/container/factory.go#L45 +# +# See also packages/edge/infra/client/config/src/utils.rs for cgroup prefix +cat > /lib/systemd/system/rivet-cadvisor.service << 'EOF' +[Unit] +Description=cAdvisor +Documentation=man:cadvisor +Documentation=https://github.com/google/cadvisor +After=docker.service containerd.service + +[Service] +EnvironmentFile=/etc/default/cadvisor +ExecStart=/usr/bin/cadvisor \ + --port=7780 \ + --listen_ip=0.0.0.0 \ + --prometheus_endpoint="/metrics" \ + --disable_metrics=memory_numa,disk,advtcp,accelerator,hugetlb,referenced_memory,resctrl \ + --docker_only=false \ + --raw_cgroup_prefix_whitelist=/system.slice/pegboard-actor- + +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload + +# Enable and start the new rivet-cadvisor service +systemctl enable rivet-cadvisor +systemctl start rivet-cadvisor + diff --git a/packages/core/services/cluster/src/workflows/server/install/install_scripts/mod.rs b/packages/core/services/cluster/src/workflows/server/install/install_scripts/mod.rs index 4a373d06e4..e6b14ab73d 100644 --- a/packages/core/services/cluster/src/workflows/server/install/install_scripts/mod.rs +++ b/packages/core/services/cluster/src/workflows/server/install/install_scripts/mod.rs @@ -53,6 +53,7 @@ pub async fn gen_install( } PoolType::Pegboard | PoolType::PegboardIsolate => { script.push(components::docker::install()); + script.push(components::cadvisor_metric_exporter::install()); script.push(components::otel_collector::install(pool_type)?); script.push(components::lz4::install()); script.push(components::skopeo::install()); @@ -83,7 +84,6 @@ pub async fn gen_install( } PoolType::Guard => { script.push(components::otel_collector::install(pool_type)?); - script.push(components::ok_server::install(initialize_immediately)); script.push(components::rivet::guard::install(config)?); } } diff --git a/packages/core/services/otel/db/otel/migrations/20200101000000_noop.down.sql b/packages/core/services/otel/db/otel/migrations/20200101000000_noop.down.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/core/services/otel/db/otel/migrations/20200101000000_noop.up.sql b/packages/core/services/otel/db/otel/migrations/20200101000000_noop.up.sql new file mode 100644 index 0000000000..ddc12f7d40 --- /dev/null +++ b/packages/core/services/otel/db/otel/migrations/20200101000000_noop.up.sql @@ -0,0 +1,2 @@ +SELECT 1; + diff --git a/packages/edge/infra/client/config/src/lib.rs b/packages/edge/infra/client/config/src/lib.rs index 91298c6155..024438915b 100644 --- a/packages/edge/infra/client/config/src/lib.rs +++ b/packages/edge/infra/client/config/src/lib.rs @@ -1,4 +1,5 @@ pub mod isolate_runner; mod manager; pub mod runner_protocol; +pub mod utils; pub use manager::*; diff --git a/packages/edge/infra/client/config/src/utils.rs b/packages/edge/infra/client/config/src/utils.rs new file mode 100644 index 0000000000..8952e8057b --- /dev/null +++ b/packages/edge/infra/client/config/src/utils.rs @@ -0,0 +1,11 @@ +// IMPORTANT: This cannot be just `rivet-` because this is used as a prefix to filter cgroup names +// in cadvisor. +// +// If this was "rivet-", we'd have to report on non-actor cgropus with cadvisor. +// +// See also packages/core/services/cluster/src/workflows/server/install/install_scripts/files/cadvisor_metric_exporter.sh & packages/core/api/actor/src/route/metrics.rs +pub const RIVET_CONTAINER_PREFIX: &str = "pegboard-actor-"; + +pub fn format_container_id(actor_id: &str, generation: u32) -> String { + format!("{RIVET_CONTAINER_PREFIX}{actor_id}-{generation}") +} diff --git a/packages/edge/infra/client/container-runner/src/container.rs b/packages/edge/infra/client/container-runner/src/container.rs index 3da4d11956..17da27e621 100644 --- a/packages/edge/infra/client/container-runner/src/container.rs +++ b/packages/edge/infra/client/container-runner/src/container.rs @@ -23,6 +23,7 @@ const MAX_PREVIEW_LINES: usize = 128; pub fn run( msg_tx: Option>, actor_path: &Path, + container_id: &str, root_user_enabled: bool, ) -> Result { // Extract actor id from path @@ -71,7 +72,7 @@ pub fn run( let mut runc_child = Command::new("runc") .arg("run") - .arg(&actor_id) + .arg(&container_id) .arg("-b") .arg(fs_path) .stdout(Stdio::piped()) @@ -86,13 +87,14 @@ pub fn run( // This will wait for the child to exit and then exit itself so we have time to ship all of the // required logs let mut signals = Signals::new(&[SIGTERM])?; + let container_id2 = container_id.to_owned(); thread::spawn(move || { for _ in signals.forever() { println!("Received SIGTERM, forwarding to runc container {actor_id}"); let status = Command::new("runc") .arg("kill") .arg("--all") - .arg(&actor_id) + .arg(&container_id2) .arg("SIGTERM") .stdout(Stdio::null()) .stderr(Stdio::null()) diff --git a/packages/edge/infra/client/container-runner/src/main.rs b/packages/edge/infra/client/container-runner/src/main.rs index 154f87e692..81346fdc03 100644 --- a/packages/edge/infra/client/container-runner/src/main.rs +++ b/packages/edge/infra/client/container-runner/src/main.rs @@ -16,11 +16,10 @@ const MAX_BUFFER_BYTES: usize = 1024 * 1024; const LOGS_RETENTION: Duration = Duration::from_secs(7 * 24 * 60 * 60); fn main() -> Result<()> { - let actor_path = std::env::args() - .skip(1) - .next() - .context("`actor_path` arg required")?; - let actor_path = Path::new(&actor_path); + let mut args = std::env::args().skip(1); + let actor_path_str = args.next().context("`actor_path` arg required")?; + let container_id = args.next().context("`container_id` arg required")?; + let actor_path = Path::new(&actor_path_str); rivet_logs::Logs::new(actor_path.join("logs"), LOGS_RETENTION).start_sync()?; @@ -57,7 +56,12 @@ fn main() -> Result<()> { }; // Run the container - let exit_code = match container::run(msg_tx.clone(), &actor_path, root_user_enabled) { + let exit_code = match container::run( + msg_tx.clone(), + &actor_path, + &container_id, + root_user_enabled, + ) { Result::Ok(exit_code) => exit_code, Err(err) => { eprintln!("run container failed: {err:?}"); diff --git a/packages/edge/infra/client/container-runner/tests/common/setup.rs b/packages/edge/infra/client/container-runner/tests/common/setup.rs index 24c7a72d2e..5f294789b1 100644 --- a/packages/edge/infra/client/container-runner/tests/common/setup.rs +++ b/packages/edge/infra/client/container-runner/tests/common/setup.rs @@ -38,7 +38,7 @@ impl Drop for Setup { Command::new("runc") .arg("delete") .arg("--force") - .arg(&self.actor_id) + .arg(&self.container_id) .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .status() diff --git a/packages/edge/infra/client/manager/src/actor/mod.rs b/packages/edge/infra/client/manager/src/actor/mod.rs index 419baa5b21..03e7265306 100644 --- a/packages/edge/infra/client/manager/src/actor/mod.rs +++ b/packages/edge/infra/client/manager/src/actor/mod.rs @@ -220,6 +220,10 @@ impl Actor { runner::Handle::spawn_orphaned( runner::Comms::Basic, &ctx.config().runner.container_runner_binary_path(), + &pegboard_config::utils::format_container_id( + &self.actor_id.to_string(), + self.generation, + ), ctx.actor_path(self.actor_id, self.generation), &runner_env, )? diff --git a/packages/edge/infra/client/manager/src/actor/setup.rs b/packages/edge/infra/client/manager/src/actor/setup.rs index bd4fab3fd1..82a20238ea 100644 --- a/packages/edge/infra/client/manager/src/actor/setup.rs +++ b/packages/edge/infra/client/manager/src/actor/setup.rs @@ -611,7 +611,10 @@ impl Actor { match Command::new("runc") .arg("delete") .arg("--force") - .arg(format!("{}-{}", self.actor_id, self.generation)) + .arg(pegboard_config::utils::format_container_id( + &self.actor_id.to_string(), + self.generation, + )) .output() .await { diff --git a/packages/edge/infra/client/manager/src/ctx.rs b/packages/edge/infra/client/manager/src/ctx.rs index 90c824be02..faaa8028dd 100644 --- a/packages/edge/infra/client/manager/src/ctx.rs +++ b/packages/edge/infra/client/manager/src/ctx.rs @@ -533,6 +533,7 @@ impl Ctx { let runner = runner::Handle::spawn_orphaned( runner::Comms::socket(), &self.config().runner.isolate_runner_binary_path(), + "", working_path, &[], )?; diff --git a/packages/edge/infra/client/manager/src/runner.rs b/packages/edge/infra/client/manager/src/runner.rs index 153b02dd45..ffe4e1878c 100644 --- a/packages/edge/infra/client/manager/src/runner.rs +++ b/packages/edge/infra/client/manager/src/runner.rs @@ -179,11 +179,12 @@ impl Handle { pub fn spawn_orphaned( comms: Comms, runner_binary_path: &Path, + container_id: &str, working_path: PathBuf, env: &[(&str, String)], ) -> Result { // Prepare the arguments for the runner - let runner_args = vec![working_path.to_str().context("bad path")?]; + let runner_args = vec![working_path.to_str().context("bad path")?, container_id]; // NOTE: Pipes are automatically closed on drop // Pipe communication between processes diff --git a/sdks/api/fern/definition/actors/metrics.yml b/sdks/api/fern/definition/actors/metrics.yml new file mode 100644 index 0000000000..7bbbbcad72 --- /dev/null +++ b/sdks/api/fern/definition/actors/metrics.yml @@ -0,0 +1,36 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + commons: ../common.yml + +service: + auth: true + base-path: /actors + endpoints: + get: + path: /{actor}/metrics/history + method: GET + docs: >- + Returns the metrics for a given actor. + path-parameters: + actor: + docs: The id of the actor to destroy + type: uuid + request: + name: GetActorMetricsRequestQuery + query-parameters: + project: optional + environment: optional + start: integer + end: integer + interval: integer + response: GetActorMetricsResponse + +types: + GetActorMetricsResponse: + properties: + actor_ids: list + metric_names: list + metric_attributes: list> + metric_types: list + metric_values: list> diff --git a/sdks/api/full/go/actors/client/client.go b/sdks/api/full/go/actors/client/client.go index 122522fa3e..c809490ff2 100644 --- a/sdks/api/full/go/actors/client/client.go +++ b/sdks/api/full/go/actors/client/client.go @@ -15,6 +15,7 @@ import ( sdk "sdk" actors "sdk/actors" logs "sdk/actors/logs" + metrics "sdk/actors/metrics" core "sdk/core" ) @@ -23,7 +24,8 @@ type Client struct { caller *core.Caller header http.Header - Logs *logs.Client + Logs *logs.Client + Metrics *metrics.Client } func NewClient(opts ...core.ClientOption) *Client { @@ -36,6 +38,7 @@ func NewClient(opts ...core.ClientOption) *Client { caller: core.NewCaller(options.HTTPClient), header: options.ToHeader(), Logs: logs.NewClient(opts...), + Metrics: metrics.NewClient(opts...), } } diff --git a/sdks/api/full/go/actors/metrics.go b/sdks/api/full/go/actors/metrics.go new file mode 100644 index 0000000000..35bcd7b764 --- /dev/null +++ b/sdks/api/full/go/actors/metrics.go @@ -0,0 +1,50 @@ +// This file was auto-generated by Fern from our API Definition. + +package actors + +import ( + json "encoding/json" + fmt "fmt" + core "sdk/core" +) + +type GetActorMetricsRequestQuery struct { + Project *string `json:"-"` + Environment *string `json:"-"` + Start int `json:"-"` + End int `json:"-"` + Interval int `json:"-"` +} + +type GetActorMetricsResponse struct { + ActorIds []string `json:"actor_ids,omitempty"` + MetricNames []string `json:"metric_names,omitempty"` + MetricAttributes []map[string]string `json:"metric_attributes,omitempty"` + MetricTypes []string `json:"metric_types,omitempty"` + MetricValues [][]float64 `json:"metric_values,omitempty"` + + _rawJSON json.RawMessage +} + +func (g *GetActorMetricsResponse) UnmarshalJSON(data []byte) error { + type unmarshaler GetActorMetricsResponse + var value unmarshaler + if err := json.Unmarshal(data, &value); err != nil { + return err + } + *g = GetActorMetricsResponse(value) + g._rawJSON = json.RawMessage(data) + return nil +} + +func (g *GetActorMetricsResponse) String() string { + if len(g._rawJSON) > 0 { + if value, err := core.StringifyJSON(g._rawJSON); err == nil { + return value + } + } + if value, err := core.StringifyJSON(g); err == nil { + return value + } + return fmt.Sprintf("%#v", g) +} diff --git a/sdks/api/full/go/actors/metrics/client.go b/sdks/api/full/go/actors/metrics/client.go new file mode 100644 index 0000000000..01ec21a217 --- /dev/null +++ b/sdks/api/full/go/actors/metrics/client.go @@ -0,0 +1,130 @@ +// This file was auto-generated by Fern from our API Definition. + +package metrics + +import ( + bytes "bytes" + context "context" + json "encoding/json" + errors "errors" + fmt "fmt" + uuid "github.com/google/uuid" + io "io" + http "net/http" + url "net/url" + sdk "sdk" + actors "sdk/actors" + core "sdk/core" +) + +type Client struct { + baseURL string + caller *core.Caller + header http.Header +} + +func NewClient(opts ...core.ClientOption) *Client { + options := core.NewClientOptions() + for _, opt := range opts { + opt(options) + } + return &Client{ + baseURL: options.BaseURL, + caller: core.NewCaller(options.HTTPClient), + header: options.ToHeader(), + } +} + +// Returns the metrics for a given actor. +// +// The id of the actor to destroy +func (c *Client) Get(ctx context.Context, actor uuid.UUID, request *actors.GetActorMetricsRequestQuery) (*actors.GetActorMetricsResponse, error) { + baseURL := "https://api.rivet.gg" + if c.baseURL != "" { + baseURL = c.baseURL + } + endpointURL := fmt.Sprintf(baseURL+"/"+"actors/%v/metrics/history", actor) + + queryParams := make(url.Values) + if request.Project != nil { + queryParams.Add("project", fmt.Sprintf("%v", *request.Project)) + } + if request.Environment != nil { + queryParams.Add("environment", fmt.Sprintf("%v", *request.Environment)) + } + queryParams.Add("start", fmt.Sprintf("%v", request.Start)) + queryParams.Add("end", fmt.Sprintf("%v", request.End)) + queryParams.Add("interval", fmt.Sprintf("%v", request.Interval)) + if len(queryParams) > 0 { + endpointURL += "?" + queryParams.Encode() + } + + errorDecoder := func(statusCode int, body io.Reader) error { + raw, err := io.ReadAll(body) + if err != nil { + return err + } + apiError := core.NewAPIError(statusCode, errors.New(string(raw))) + decoder := json.NewDecoder(bytes.NewReader(raw)) + switch statusCode { + case 500: + value := new(sdk.InternalError) + value.APIError = apiError + if err := decoder.Decode(value); err != nil { + return apiError + } + return value + case 429: + value := new(sdk.RateLimitError) + value.APIError = apiError + if err := decoder.Decode(value); err != nil { + return apiError + } + return value + case 403: + value := new(sdk.ForbiddenError) + value.APIError = apiError + if err := decoder.Decode(value); err != nil { + return apiError + } + return value + case 408: + value := new(sdk.UnauthorizedError) + value.APIError = apiError + if err := decoder.Decode(value); err != nil { + return apiError + } + return value + case 404: + value := new(sdk.NotFoundError) + value.APIError = apiError + if err := decoder.Decode(value); err != nil { + return apiError + } + return value + case 400: + value := new(sdk.BadRequestError) + value.APIError = apiError + if err := decoder.Decode(value); err != nil { + return apiError + } + return value + } + return apiError + } + + var response *actors.GetActorMetricsResponse + if err := c.caller.Call( + ctx, + &core.CallParams{ + URL: endpointURL, + Method: http.MethodGet, + Headers: c.header, + Response: &response, + ErrorDecoder: errorDecoder, + }, + ); err != nil { + return nil, err + } + return response, nil +} diff --git a/sdks/api/full/openapi/openapi.yml b/sdks/api/full/openapi/openapi.yml index c655b8c7e2..f7bc9a608a 100644 --- a/sdks/api/full/openapi/openapi.yml +++ b/sdks/api/full/openapi/openapi.yml @@ -5394,6 +5394,89 @@ paths: schema: $ref: '#/components/schemas/ErrorBody' security: *ref_0 + /actors/{actor}/metrics/history: + get: + description: Returns the metrics for a given actor. + operationId: actors_metrics_get + tags: + - ActorsMetrics + parameters: + - name: actor + in: path + description: The id of the actor to destroy + required: true + schema: + type: string + format: uuid + - name: project + in: query + required: false + schema: + type: string + - name: environment + in: query + required: false + schema: + type: string + - name: start + in: query + required: true + schema: + type: integer + - name: end + in: query + required: true + schema: + type: integer + - name: interval + in: query + required: true + schema: + type: integer + responses: + '200': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ActorsGetActorMetricsResponse' + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + security: *ref_0 /auth/identity/email/start-verification: post: description: Starts the verification process for linking an email to your identity. @@ -10740,6 +10823,40 @@ components: - std_out - std_err - all + ActorsGetActorMetricsResponse: + type: object + properties: + actor_ids: + type: array + items: + type: string + metric_names: + type: array + items: + type: string + metric_attributes: + type: array + items: + type: object + additionalProperties: + type: string + metric_types: + type: array + items: + type: string + metric_values: + type: array + items: + type: array + items: + type: number + format: double + required: + - actor_ids + - metric_names + - metric_attributes + - metric_types + - metric_values AuthCompleteStatus: type: string enum: diff --git a/sdks/api/full/openapi_compat/openapi.yml b/sdks/api/full/openapi_compat/openapi.yml index 847d0b4b14..3ab5e446c8 100644 --- a/sdks/api/full/openapi_compat/openapi.yml +++ b/sdks/api/full/openapi_compat/openapi.yml @@ -5394,6 +5394,89 @@ paths: schema: $ref: '#/components/schemas/ErrorBody' security: *ref_0 + '/actors/{actor}/metrics/history': + get: + description: Returns the metrics for a given actor. + operationId: actors_metrics_get + tags: + - ActorsMetrics + parameters: + - name: actor + in: path + description: The id of the actor to destroy + required: true + schema: + type: string + format: uuid + - name: project + in: query + required: false + schema: + type: string + - name: environment + in: query + required: false + schema: + type: string + - name: start + in: query + required: true + schema: + type: integer + - name: end + in: query + required: true + schema: + type: integer + - name: interval + in: query + required: true + schema: + type: integer + responses: + '200': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ActorsGetActorMetricsResponse' + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '408': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '429': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBody' + security: *ref_0 /auth/identity/email/start-verification: post: description: Starts the verification process for linking an email to your identity. @@ -10740,6 +10823,40 @@ components: - std_out - std_err - all + ActorsGetActorMetricsResponse: + type: object + properties: + actor_ids: + type: array + items: + type: string + metric_names: + type: array + items: + type: string + metric_attributes: + type: array + items: + type: object + additionalProperties: + type: string + metric_types: + type: array + items: + type: string + metric_values: + type: array + items: + type: array + items: + type: number + format: double + required: + - actor_ids + - metric_names + - metric_attributes + - metric_types + - metric_values AuthCompleteStatus: type: string enum: diff --git a/sdks/api/full/rust/.openapi-generator/FILES b/sdks/api/full/rust/.openapi-generator/FILES index 82be060260..e09b03f5aa 100644 --- a/sdks/api/full/rust/.openapi-generator/FILES +++ b/sdks/api/full/rust/.openapi-generator/FILES @@ -13,10 +13,12 @@ docs/ActorsCreateActorRuntimeNetworkRequest.md docs/ActorsCreateActorRuntimeRequest.md docs/ActorsEndpointType.md docs/ActorsGetActorLogsResponse.md +docs/ActorsGetActorMetricsResponse.md docs/ActorsGetActorResponse.md docs/ActorsLifecycle.md docs/ActorsListActorsResponse.md docs/ActorsLogsApi.md +docs/ActorsMetricsApi.md docs/ActorsNetwork.md docs/ActorsNetworkMode.md docs/ActorsPort.md @@ -390,6 +392,7 @@ docs/WatchResponse.md git_push.sh src/apis/actors_api.rs src/apis/actors_logs_api.rs +src/apis/actors_metrics_api.rs src/apis/auth_identity_email_api.rs src/apis/auth_tokens_api.rs src/apis/builds_api.rs @@ -445,6 +448,7 @@ src/models/actors_create_actor_runtime_network_request.rs src/models/actors_create_actor_runtime_request.rs src/models/actors_endpoint_type.rs src/models/actors_get_actor_logs_response.rs +src/models/actors_get_actor_metrics_response.rs src/models/actors_get_actor_response.rs src/models/actors_lifecycle.rs src/models/actors_list_actors_response.rs diff --git a/sdks/api/full/rust/README.md b/sdks/api/full/rust/README.md index bed765e99a..b9456143de 100644 --- a/sdks/api/full/rust/README.md +++ b/sdks/api/full/rust/README.md @@ -32,6 +32,7 @@ Class | Method | HTTP request | Description *ActorsApi* | [**actors_upgrade**](docs/ActorsApi.md#actors_upgrade) | **POST** /actors/{actor}/upgrade | *ActorsApi* | [**actors_upgrade_all**](docs/ActorsApi.md#actors_upgrade_all) | **POST** /actors/upgrade | *ActorsLogsApi* | [**actors_logs_get**](docs/ActorsLogsApi.md#actors_logs_get) | **GET** /actors/logs | +*ActorsMetricsApi* | [**actors_metrics_get**](docs/ActorsMetricsApi.md#actors_metrics_get) | **GET** /actors/{actor}/metrics/history | *AuthIdentityEmailApi* | [**auth_identity_email_complete_email_verification**](docs/AuthIdentityEmailApi.md#auth_identity_email_complete_email_verification) | **POST** /auth/identity/email/complete-verification | *AuthIdentityEmailApi* | [**auth_identity_email_start_email_verification**](docs/AuthIdentityEmailApi.md#auth_identity_email_start_email_verification) | **POST** /auth/identity/email/start-verification | *AuthTokensApi* | [**auth_tokens_refresh_identity_token**](docs/AuthTokensApi.md#auth_tokens_refresh_identity_token) | **POST** /auth/tokens/identity | @@ -181,6 +182,7 @@ Class | Method | HTTP request | Description - [ActorsCreateActorRuntimeRequest](docs/ActorsCreateActorRuntimeRequest.md) - [ActorsEndpointType](docs/ActorsEndpointType.md) - [ActorsGetActorLogsResponse](docs/ActorsGetActorLogsResponse.md) + - [ActorsGetActorMetricsResponse](docs/ActorsGetActorMetricsResponse.md) - [ActorsGetActorResponse](docs/ActorsGetActorResponse.md) - [ActorsLifecycle](docs/ActorsLifecycle.md) - [ActorsListActorsResponse](docs/ActorsListActorsResponse.md) diff --git a/sdks/api/full/rust/docs/ActorsGetActorMetricsResponse.md b/sdks/api/full/rust/docs/ActorsGetActorMetricsResponse.md new file mode 100644 index 0000000000..1fb694e7a6 --- /dev/null +++ b/sdks/api/full/rust/docs/ActorsGetActorMetricsResponse.md @@ -0,0 +1,15 @@ +# ActorsGetActorMetricsResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**actor_ids** | **Vec** | | +**metric_names** | **Vec** | | +**metric_attributes** | [**Vec<::std::collections::HashMap>**](map.md) | | +**metric_types** | **Vec** | | +**metric_values** | [**Vec>**](array.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdks/api/full/rust/docs/ActorsMetricsApi.md b/sdks/api/full/rust/docs/ActorsMetricsApi.md new file mode 100644 index 0000000000..da0632ac74 --- /dev/null +++ b/sdks/api/full/rust/docs/ActorsMetricsApi.md @@ -0,0 +1,44 @@ +# \ActorsMetricsApi + +All URIs are relative to *https://api.rivet.gg* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**actors_metrics_get**](ActorsMetricsApi.md#actors_metrics_get) | **GET** /actors/{actor}/metrics/history | + + + +## actors_metrics_get + +> crate::models::ActorsGetActorMetricsResponse actors_metrics_get(actor, start, end, interval, project, environment) + + +Returns the metrics for a given actor. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**actor** | **uuid::Uuid** | The id of the actor to destroy | [required] | +**start** | **i32** | | [required] | +**end** | **i32** | | [required] | +**interval** | **i32** | | [required] | +**project** | Option<**String**> | | | +**environment** | Option<**String**> | | | + +### Return type + +[**crate::models::ActorsGetActorMetricsResponse**](ActorsGetActorMetricsResponse.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/sdks/api/full/rust/src/apis/actors_metrics_api.rs b/sdks/api/full/rust/src/apis/actors_metrics_api.rs new file mode 100644 index 0000000000..6244579e8d --- /dev/null +++ b/sdks/api/full/rust/src/apis/actors_metrics_api.rs @@ -0,0 +1,88 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +use reqwest; + +use super::{configuration, Error}; +use crate::apis::ResponseContent; + +/// struct for typed errors of method [`actors_metrics_get`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ActorsMetricsGetError { + Status400(crate::models::ErrorBody), + Status403(crate::models::ErrorBody), + Status404(crate::models::ErrorBody), + Status408(crate::models::ErrorBody), + Status429(crate::models::ErrorBody), + Status500(crate::models::ErrorBody), + UnknownValue(serde_json::Value), +} + +/// Returns the metrics for a given actor. +pub async fn actors_metrics_get( + configuration: &configuration::Configuration, + actor: &str, + start: i32, + end: i32, + interval: i32, + project: Option<&str>, + environment: Option<&str>, +) -> Result> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/actors/{actor}/metrics/history", + local_var_configuration.base_path, + actor = crate::apis::urlencode(actor) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + + if let Some(ref local_var_str) = project { + local_var_req_builder = + local_var_req_builder.query(&[("project", &local_var_str.to_string())]); + } + if let Some(ref local_var_str) = environment { + local_var_req_builder = + local_var_req_builder.query(&[("environment", &local_var_str.to_string())]); + } + local_var_req_builder = local_var_req_builder.query(&[("start", &start.to_string())]); + local_var_req_builder = local_var_req_builder.query(&[("end", &end.to_string())]); + local_var_req_builder = local_var_req_builder.query(&[("interval", &interval.to_string())]); + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} diff --git a/sdks/api/full/rust/src/apis/mod.rs b/sdks/api/full/rust/src/apis/mod.rs index aef72f80c9..c326b5a161 100644 --- a/sdks/api/full/rust/src/apis/mod.rs +++ b/sdks/api/full/rust/src/apis/mod.rs @@ -114,6 +114,7 @@ pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String pub mod actors_api; pub mod actors_logs_api; +pub mod actors_metrics_api; pub mod auth_identity_email_api; pub mod auth_tokens_api; pub mod builds_api; diff --git a/sdks/api/full/rust/src/models/actors_get_actor_metrics_response.rs b/sdks/api/full/rust/src/models/actors_get_actor_metrics_response.rs new file mode 100644 index 0000000000..5674d0cab2 --- /dev/null +++ b/sdks/api/full/rust/src/models/actors_get_actor_metrics_response.rs @@ -0,0 +1,41 @@ +/* + * Rivet API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.0.1 + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ActorsGetActorMetricsResponse { + #[serde(rename = "actor_ids")] + pub actor_ids: Vec, + #[serde(rename = "metric_names")] + pub metric_names: Vec, + #[serde(rename = "metric_attributes")] + pub metric_attributes: Vec<::std::collections::HashMap>, + #[serde(rename = "metric_types")] + pub metric_types: Vec, + #[serde(rename = "metric_values")] + pub metric_values: Vec>, +} + +impl ActorsGetActorMetricsResponse { + pub fn new( + actor_ids: Vec, + metric_names: Vec, + metric_attributes: Vec<::std::collections::HashMap>, + metric_types: Vec, + metric_values: Vec>, + ) -> ActorsGetActorMetricsResponse { + ActorsGetActorMetricsResponse { + actor_ids, + metric_names, + metric_attributes, + metric_types, + metric_values, + } + } +} diff --git a/sdks/api/full/rust/src/models/mod.rs b/sdks/api/full/rust/src/models/mod.rs index 414f7e4832..2b5319bfd9 100644 --- a/sdks/api/full/rust/src/models/mod.rs +++ b/sdks/api/full/rust/src/models/mod.rs @@ -16,6 +16,8 @@ pub mod actors_endpoint_type; pub use self::actors_endpoint_type::ActorsEndpointType; pub mod actors_get_actor_logs_response; pub use self::actors_get_actor_logs_response::ActorsGetActorLogsResponse; +pub mod actors_get_actor_metrics_response; +pub use self::actors_get_actor_metrics_response::ActorsGetActorMetricsResponse; pub mod actors_get_actor_response; pub use self::actors_get_actor_response::ActorsGetActorResponse; pub mod actors_lifecycle; diff --git a/sdks/api/full/typescript/src/api/resources/actors/client/Client.ts b/sdks/api/full/typescript/src/api/resources/actors/client/Client.ts index cc37f6993b..3767567b82 100644 --- a/sdks/api/full/typescript/src/api/resources/actors/client/Client.ts +++ b/sdks/api/full/typescript/src/api/resources/actors/client/Client.ts @@ -9,6 +9,7 @@ import * as serializers from "../../../../serialization/index"; import urlJoin from "url-join"; import * as errors from "../../../../errors/index"; import { Logs } from "../resources/logs/client/Client"; +import { Metrics } from "../resources/metrics/client/Client"; export declare namespace Actors { export interface Options { @@ -37,6 +38,7 @@ export declare namespace Actors { export class Actors { protected _logs: Logs | undefined; + protected _metrics: Metrics | undefined; constructor(protected readonly _options: Actors.Options = {}) {} @@ -44,6 +46,10 @@ export class Actors { return (this._logs ??= new Logs(this._options)); } + public get metrics(): Metrics { + return (this._metrics ??= new Metrics(this._options)); + } + /** * Gets a dynamic actor. * diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/index.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/index.ts index bb93a8b0c8..8b57b1caf5 100644 --- a/sdks/api/full/typescript/src/api/resources/actors/resources/index.ts +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/index.ts @@ -2,4 +2,7 @@ export * as common from "./common"; export * from "./common/types"; export * as logs from "./logs"; export * from "./logs/types"; +export * as metrics from "./metrics"; +export * from "./metrics/types"; export * from "./logs/client/requests"; +export * from "./metrics/client/requests"; diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/Client.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/Client.ts new file mode 100644 index 0000000000..e88ff026bc --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/Client.ts @@ -0,0 +1,209 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments"; +import * as core from "../../../../../../core"; +import * as Rivet from "../../../../../index"; +import urlJoin from "url-join"; +import * as serializers from "../../../../../../serialization/index"; +import * as errors from "../../../../../../errors/index"; + +export declare namespace Metrics { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + token?: core.Supplier; + /** Override the X-API-Version header */ + xApiVersion?: "25.4.2"; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional headers to include in the request. */ + headers?: Record; + /** Override the X-API-Version header */ + xApiVersion?: "25.4.2"; + } +} + +export class Metrics { + constructor(protected readonly _options: Metrics.Options = {}) {} + + /** + * Returns the metrics for a given actor. + * + * @param {string} actor - The id of the actor to destroy + * @param {Rivet.actors.GetActorMetricsRequestQuery} request + * @param {Metrics.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Rivet.InternalError} + * @throws {@link Rivet.RateLimitError} + * @throws {@link Rivet.ForbiddenError} + * @throws {@link Rivet.UnauthorizedError} + * @throws {@link Rivet.NotFoundError} + * @throws {@link Rivet.BadRequestError} + * + * @example + * await client.actors.metrics.get("d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32", { + * project: "string", + * environment: "string", + * start: 1, + * end: 1, + * interval: 1 + * }) + */ + public async get( + actor: string, + request: Rivet.actors.GetActorMetricsRequestQuery, + requestOptions?: Metrics.RequestOptions, + ): Promise { + const { project, environment, start, end, interval } = request; + const _queryParams: Record = {}; + if (project != null) { + _queryParams["project"] = project; + } + + if (environment != null) { + _queryParams["environment"] = environment; + } + + _queryParams["start"] = start.toString(); + _queryParams["end"] = end.toString(); + _queryParams["interval"] = interval.toString(); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.RivetEnvironment.Production, + `/actors/${encodeURIComponent(actor)}/metrics/history`, + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-API-Version": requestOptions?.xApiVersion ?? this._options?.xApiVersion ?? "25.4.2", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.actors.GetActorMetricsResponse.parseOrThrow(_response.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }); + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 500: + throw new Rivet.InternalError( + serializers.ErrorBody.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + case 429: + throw new Rivet.RateLimitError( + serializers.ErrorBody.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + case 403: + throw new Rivet.ForbiddenError( + serializers.ErrorBody.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + case 408: + throw new Rivet.UnauthorizedError( + serializers.ErrorBody.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + case 404: + throw new Rivet.NotFoundError( + serializers.ErrorBody.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + case 400: + throw new Rivet.BadRequestError( + serializers.ErrorBody.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + default: + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /actors/{actor}/metrics/history.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader(): Promise { + const bearer = await core.Supplier.get(this._options.token); + if (bearer != null) { + return `Bearer ${bearer}`; + } + + return undefined; + } +} diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/index.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/index.ts new file mode 100644 index 0000000000..415726b7fe --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/GetActorMetricsRequestQuery.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/GetActorMetricsRequestQuery.ts new file mode 100644 index 0000000000..060467b645 --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/GetActorMetricsRequestQuery.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * project: "string", + * environment: "string", + * start: 1, + * end: 1, + * interval: 1 + * } + */ +export interface GetActorMetricsRequestQuery { + project?: string; + environment?: string; + start: number; + end: number; + interval: number; +} diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/index.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/index.ts new file mode 100644 index 0000000000..7a8cf1debe --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/client/requests/index.ts @@ -0,0 +1 @@ +export { type GetActorMetricsRequestQuery } from "./GetActorMetricsRequestQuery"; diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/index.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/index.ts new file mode 100644 index 0000000000..c9240f83b4 --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts new file mode 100644 index 0000000000..35c68a3ffb --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetActorMetricsResponse { + actorIds: string[]; + metricNames: string[]; + metricAttributes: Record[]; + metricTypes: string[]; + metricValues: number[][]; +} diff --git a/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/index.ts b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/index.ts new file mode 100644 index 0000000000..c5cf235d4d --- /dev/null +++ b/sdks/api/full/typescript/src/api/resources/actors/resources/metrics/types/index.ts @@ -0,0 +1 @@ +export * from "./GetActorMetricsResponse"; diff --git a/sdks/api/full/typescript/src/serialization/resources/actors/resources/index.ts b/sdks/api/full/typescript/src/serialization/resources/actors/resources/index.ts index 6eaa67cdc2..3bb7903aa2 100644 --- a/sdks/api/full/typescript/src/serialization/resources/actors/resources/index.ts +++ b/sdks/api/full/typescript/src/serialization/resources/actors/resources/index.ts @@ -2,3 +2,5 @@ export * as common from "./common"; export * from "./common/types"; export * as logs from "./logs"; export * from "./logs/types"; +export * as metrics from "./metrics"; +export * from "./metrics/types"; diff --git a/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/index.ts b/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/index.ts new file mode 100644 index 0000000000..eea524d655 --- /dev/null +++ b/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts b/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts new file mode 100644 index 0000000000..ed4893ed16 --- /dev/null +++ b/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/GetActorMetricsResponse.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../../../index"; +import * as Rivet from "../../../../../../api/index"; +import * as core from "../../../../../../core"; + +export const GetActorMetricsResponse: core.serialization.ObjectSchema< + serializers.actors.GetActorMetricsResponse.Raw, + Rivet.actors.GetActorMetricsResponse +> = core.serialization.object({ + actorIds: core.serialization.property("actor_ids", core.serialization.list(core.serialization.string())), + metricNames: core.serialization.property("metric_names", core.serialization.list(core.serialization.string())), + metricAttributes: core.serialization.property( + "metric_attributes", + core.serialization.list(core.serialization.record(core.serialization.string(), core.serialization.string())), + ), + metricTypes: core.serialization.property("metric_types", core.serialization.list(core.serialization.string())), + metricValues: core.serialization.property( + "metric_values", + core.serialization.list(core.serialization.list(core.serialization.number())), + ), +}); + +export declare namespace GetActorMetricsResponse { + export interface Raw { + actor_ids: string[]; + metric_names: string[]; + metric_attributes: Record[]; + metric_types: string[]; + metric_values: number[][]; + } +} diff --git a/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/index.ts b/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/index.ts new file mode 100644 index 0000000000..c5cf235d4d --- /dev/null +++ b/sdks/api/full/typescript/src/serialization/resources/actors/resources/metrics/types/index.ts @@ -0,0 +1 @@ +export * from "./GetActorMetricsResponse"; diff --git a/site/src/content/docs/api/actors/metrics/get.mdx b/site/src/content/docs/api/actors/metrics/get.mdx new file mode 100644 index 0000000000..0721f415f2 --- /dev/null +++ b/site/src/content/docs/api/actors/metrics/get.mdx @@ -0,0 +1,37 @@ +{/* This file is auto-generated by `generateApi.js`. + * + * Do not edit this file directly. + */} + +import { JsonSchemaPreview, PropertyLabel } from '@/components/JsonSchemaPreview'; +import API_SCHEMA from './../../spec.json'; + +# actors.metrics.get + +## Description +Returns the metrics for a given actor. + +## Code Examples + + + +```bash {{ "title": "cURL" }} +curl -X GET 'https://api.rivet.gg/actors/{actor}/metrics/history' +``` + +```ts +// Create Rivet client +import { RivetClient } from '@rivet-gg/api'; +const RIVET = new RivetClient({ token: '[YOUR TOKEN HERE]' }); + +// Make request +await RIVET.actors.metrics.get({ + // Add your request body here +}); +``` + + + +## Schema + + diff --git a/site/src/content/docs/api/errors.mdx b/site/src/content/docs/api/errors.mdx index c3bf2be1bc..69d2d2e6d7 100644 --- a/site/src/content/docs/api/errors.mdx +++ b/site/src/content/docs/api/errors.mdx @@ -41,6 +41,24 @@ No actor IDs were provided in the request. Please provide at least one valid act None of the provided actor IDs are valid for this game/environment. Please provide valid actor IDs. +## Invalid Metrics + +{`ACTOR_METRICS_INVALID_METRICS`} + +The provided list of metrics is not in a valid JSON format. Please provide a valid JSON array of metric names. + +## No Metrics + +{`ACTOR_METRICS_NO_METRICS`} + +No metrics were specified in the request. Please provide at least one metric name to query. + +## Unsupported Metrics + +{`ACTOR_METRICS_UNSUPPORTED_METRICS`} + +The requested metrics are not supported. Supported metrics include: cpu, memory, memory_limit, network_rx_bytes, network_tx_bytes. + ## Actor Not Found {`ACTOR_NOT_FOUND`} @@ -456,34 +474,6 @@ The group attempting to be joined does not allow anyone to join it. The identity is not a member of the request/related group. -## Identity Not Admin - -{`IDENTITY_NOT_ADMIN`} - -The identity requesting this endpoint is not an admin. - - -## Identity Not Found - -{`IDENTITY_NOT_FOUND`} - -The requested identity does not exist or is not visible to whoever is requesting. - - -## Identity Not Registered - -{`IDENTITY_NOT_REGISTERED`} - -The identity that created this request is not registered. - - -## Wrong Identity - -{`IDENTITY_WRONG_IDENTITY`} - -The given resource is not available for the current identity. - - ## Project Not Found {`PROJECT_NOT_FOUND`} @@ -541,7 +531,7 @@ Valid: - `api-v1.job.example.com` - `my-service-123.job.example.com` -## invalid_name_id +## Invalid Name ID {`ROUTE_INVALID_NAME_ID`} @@ -562,6 +552,7 @@ Make sure your name_id: Invalid: `UPPERCASE-route`, `route--name`, `-route-name`, `route-name-` Valid: `my-route`, `route-123`, `api-v2` + ## invalid_path {`ROUTE_INVALID_PATH`} diff --git a/site/src/content/docs/api/spec.json b/site/src/content/docs/api/spec.json index 0a9f433624..886d8a40ab 100644 --- a/site/src/content/docs/api/spec.json +++ b/site/src/content/docs/api/spec.json @@ -1 +1 @@ -{"definitions":{"ActorsGetActorResponse":{"type":"object","properties":{"actor":{"$ref":"#/components/schemas/ActorsActor"}},"required":["actor"]},"ActorsCreateActorRequest":{"type":"object","properties":{"region":{"type":"string"},"tags":{},"build":{"type":"string","format":"uuid"},"build_tags":{},"runtime":{"$ref":"#/components/schemas/ActorsCreateActorRuntimeRequest"},"network":{"$ref":"#/components/schemas/ActorsCreateActorNetworkRequest"},"resources":{"$ref":"#/components/schemas/ActorsResources"},"lifecycle":{"$ref":"#/components/schemas/ActorsLifecycle"}},"required":["tags"]},"ActorsCreateActorRuntimeRequest":{"type":"object","properties":{"environment":{"type":"object","additionalProperties":{"type":"string"}},"network":{"$ref":"#/components/schemas/ActorsCreateActorRuntimeNetworkRequest"}}},"ActorsCreateActorRuntimeNetworkRequest":{"type":"object","properties":{"endpoint_type":{"$ref":"#/components/schemas/ActorsEndpointType"}},"required":["endpoint_type"]},"ActorsCreateActorNetworkRequest":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ActorsNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ActorsCreateActorPortRequest"}},"wait_ready":{"type":"boolean"}}},"ActorsCreateActorPortRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ActorsPortProtocol"},"internal_port":{"type":"integer"},"routing":{"$ref":"#/components/schemas/ActorsPortRouting"}},"required":["protocol"]},"ActorsCreateActorResponse":{"type":"object","properties":{"actor":{"$ref":"#/components/schemas/ActorsActor","description":"The actor that was created"}},"required":["actor"]},"ActorsDestroyActorResponse":{"type":"object","properties":{}},"ActorsUpgradeActorRequest":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"build_tags":{}}},"ActorsUpgradeActorResponse":{"type":"object","properties":{}},"ActorsUpgradeAllActorsRequest":{"type":"object","properties":{"tags":{},"build":{"type":"string","format":"uuid"},"build_tags":{}},"required":["tags"]},"ActorsUpgradeAllActorsResponse":{"type":"object","properties":{"count":{"type":"integer","format":"int64"}},"required":["count"]},"ActorsListActorsResponse":{"type":"object","properties":{"actors":{"type":"array","items":{"$ref":"#/components/schemas/ActorsActor"},"description":"A list of actors for the project associated with the token."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["actors","pagination"]},"BuildsGetBuildResponse":{"type":"object","properties":{"build":{"$ref":"#/components/schemas/BuildsBuild"}},"required":["build"]},"BuildsListBuildsResponse":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/BuildsBuild"},"description":"A list of builds for the project associated with the token."}},"required":["builds"]},"BuildsPatchBuildTagsRequest":{"type":"object","properties":{"tags":{},"exclusive_tags":{"type":"array","items":{"type":"string"},"description":"**Deprecated**\nRemoves the given tag keys from all other builds."}},"required":["tags"]},"BuildsPatchBuildTagsResponse":{"type":"object","properties":{}},"BuildsPrepareBuildRequest":{"type":"object","properties":{"image_tag":{"type":"string","description":"A tag given to the project build."},"image_file":{"$ref":"#/components/schemas/UploadPrepareFile"},"kind":{"$ref":"#/components/schemas/BuildsBuildKind"},"compression":{"$ref":"#/components/schemas/BuildsBuildCompression"}},"required":["image_file"]},"BuildsPrepareBuildResponse":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["build","presigned_requests"]},"BuildsBuildKind":{"type":"string","enum":["docker_image","oci_bundle","javascript"]},"BuildsBuildCompression":{"type":"string","enum":["none","lz4"]},"CloudBootstrapResponse":{"type":"object","properties":{"cluster":{"$ref":"#/components/schemas/CloudBootstrapCluster"},"access":{"$ref":"#/components/schemas/CloudBootstrapAccess"},"domains":{"$ref":"#/components/schemas/CloudBootstrapDomains"},"origins":{"$ref":"#/components/schemas/CloudBootstrapOrigins"},"captcha":{"$ref":"#/components/schemas/CloudBootstrapCaptcha"},"login_methods":{"$ref":"#/components/schemas/CloudBootstrapLoginMethods"},"deploy_hash":{"type":"string"}},"required":["cluster","access","domains","origins","captcha","login_methods","deploy_hash"]},"CloudBootstrapCluster":{"type":"string","enum":["enterprise","oss"],"description":"The type of cluster that the backend is currently running."},"CloudBootstrapAccess":{"type":"string","enum":["public","private","development"]},"CloudBootstrapDomains":{"type":"object","description":"Domains that host parts of Rivet","properties":{"cdn":{"type":"string"},"job":{"type":"string"},"main":{"type":"string"},"opengb":{"type":"string"}}},"CloudBootstrapOrigins":{"type":"object","description":"Origins used to build URLs from","properties":{"hub":{"type":"string"}},"required":["hub"]},"CloudBootstrapCaptcha":{"type":"object","properties":{"turnstile":{"$ref":"#/components/schemas/CloudBootstrapCaptchaTurnstile"}}},"CloudBootstrapCaptchaTurnstile":{"type":"object","properties":{"site_key":{"type":"string"}},"required":["site_key"]},"CloudBootstrapLoginMethods":{"type":"object","properties":{"email":{"type":"boolean"},"access_token":{"type":"boolean"}},"required":["email"]},"CloudGamesGetGamesResponse":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/GameGameSummary"},"description":"A list of game summaries."},"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"},"description":"A list of group summaries."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["games","groups","watch"]},"CloudGamesCreateGameRequest":{"type":"object","properties":{"name_id":{"$ref":"#/components/schemas/Identifier","description":"**Deprecated**"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"developer_group_id":{"type":"string","format":"uuid"}},"required":["display_name","developer_group_id"]},"CloudGamesCreateGameResponse":{"type":"object","properties":{"game_id":{"type":"string","format":"uuid"}},"required":["game_id"]},"CloudGamesValidateGameRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"name_id":{"$ref":"#/components/schemas/Identifier","description":"**Deprecated**"}},"required":["display_name"]},"CloudGamesValidateGameResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesGetGameByIdResponse":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/CloudGameFull"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["game","watch"]},"CloudGamesGameBannerUploadPrepareRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the game banner."},"mime":{"type":"string","description":"The MIME type of the game banner."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"CloudGamesGameBannerUploadPrepareResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"CloudGamesGameLogoUploadPrepareRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the game logo."},"mime":{"type":"string","description":"The MIME type of the game logo."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"CloudGamesGameLogoUploadPrepareResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"CloudGamesNamespacesInspectResponse":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/CloudAuthAgent"}},"required":["agent"]},"CloudGamesNamespacesCreateGameNamespaceRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"version_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."}},"required":["display_name","version_id","name_id"]},"CloudGamesNamespacesCreateGameNamespaceResponse":{"type":"object","properties":{"namespace_id":{"type":"string","format":"uuid"}},"required":["namespace_id"]},"CloudGamesNamespacesValidateGameNamespaceRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."}},"required":["display_name","name_id"]},"CloudGamesNamespacesValidateGameNamespaceResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesNamespacesGetGameNamespaceByIdResponse":{"type":"object","properties":{"namespace":{"$ref":"#/components/schemas/CloudNamespaceFull"}},"required":["namespace"]},"CloudGamesNamespacesUpdateNamespaceCdnAuthUserRequest":{"type":"object","properties":{"user":{"type":"string","description":"A user name."},"password":{"type":"string","description":"A bcrypt encrypted password. An error is returned if the given string is not properly encrypted."}},"required":["user","password"]},"CloudGamesNamespacesSetNamespaceCdnAuthTypeRequest":{"type":"object","properties":{"auth_type":{"$ref":"#/components/schemas/CloudCdnAuthType"}},"required":["auth_type"]},"CloudGamesNamespacesToggleNamespaceDomainPublicAuthRequest":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether or not to enable authentication based on domain."}},"required":["enabled"]},"CloudGamesNamespacesAddNamespaceDomainRequest":{"type":"object","properties":{"domain":{"type":"string","description":"A valid domain name (no protocol)."}},"required":["domain"]},"CloudGamesNamespacesUpdateGameNamespaceMatchmakerConfigRequest":{"type":"object","properties":{"lobby_count_max":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_count_max","max_players"]},"CloudGamesNamespacesGetGameNamespaceVersionHistoryResponse":{"type":"object","properties":{"versions":{"type":"array","items":{"$ref":"#/components/schemas/CloudNamespaceVersion"},"description":"A list of previously deployed namespace versions."}},"required":["versions"]},"CloudGamesNamespacesValidateGameNamespaceMatchmakerConfigRequest":{"type":"object","properties":{"lobby_count_max":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_count_max","max_players"]},"CloudGamesNamespacesValidateGameNamespaceMatchmakerConfigResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesNamespacesCreateGameNamespaceTokenDevelopmentRequest":{"type":"object","properties":{"hostname":{"type":"string","description":"The hostname used for the token."},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudMatchmakerDevelopmentPort"}},"lobby_ports":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerPort"},"description":"**Deprecated**\nA list of docker ports."}},"required":["hostname"]},"CloudGamesNamespacesCreateGameNamespaceTokenDevelopmentResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."}},"required":["token"]},"CloudGamesNamespacesValidateGameNamespaceTokenDevelopmentRequest":{"type":"object","properties":{"hostname":{"type":"string"},"lobby_ports":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerPort"},"description":"A list of docker ports."}},"required":["hostname","lobby_ports"]},"CloudGamesNamespacesValidateGameNamespaceTokenDevelopmentResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesNamespacesCreateGameNamespaceTokenPublicResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."}},"required":["token"]},"CloudGamesNamespacesUpdateGameNamespaceVersionRequest":{"type":"object","properties":{"version_id":{"type":"string","format":"uuid"}},"required":["version_id"]},"CloudVersionConfig":{"type":"object","description":"Cloud configuration for a given version.","properties":{"scripts":{"type":"object","additionalProperties":{"type":"string"}},"engine":{"$ref":"#/components/schemas/CloudVersionEngineEngineConfig"},"cdn":{"$ref":"#/components/schemas/CloudVersionCdnCdnConfig"},"matchmaker":{"$ref":"#/components/schemas/CloudVersionMatchmakerMatchmakerConfig"},"kv":{"$ref":"#/components/schemas/CloudVersionKvKvConfig"},"identity":{"$ref":"#/components/schemas/CloudVersionIdentityIdentityConfig"}}},"CloudVersionFull":{"type":"object","description":"A full version.","properties":{"version_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"config":{"$ref":"#/components/schemas/CloudVersionConfig"}},"required":["version_id","create_ts","display_name","config"]},"CloudVersionSummary":{"type":"object","description":"A version summary.","properties":{"version_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["version_id","create_ts","display_name"]},"CloudVersionCdnCdnConfig":{"type":"object","description":"CDN configuration for a given version.","properties":{"build_command":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"build_output":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"build_env":{"type":"object","additionalProperties":{"type":"string"},"description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"site_id":{"type":"string","format":"uuid"},"routes":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionCdnRoute"},"description":"Multiple CDN version routes."}}},"CloudVersionCdnRoute":{"type":"object","properties":{"glob":{"type":"string"},"priority":{"type":"integer","description":"Unsigned 32 bit integer."},"middlewares":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionCdnMiddleware"},"description":"Multiple CDN version middleware."}},"required":["glob","priority","middlewares"]},"CloudVersionCdnMiddleware":{"type":"object","properties":{"kind":{"$ref":"#/components/schemas/CloudVersionCdnMiddlewareKind"}},"required":["kind"]},"CloudVersionCdnMiddlewareKind":{"type":"object","properties":{"custom_headers":{"$ref":"#/components/schemas/CloudVersionCdnCustomHeadersMiddleware"}}},"CloudVersionCdnCustomHeadersMiddleware":{"type":"object","properties":{"headers":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionCdnHeader"}}},"required":["headers"]},"CloudVersionCdnHeader":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"CloudVersionEngineEngineConfig":{"type":"object","properties":{"unity":{"$ref":"#/components/schemas/CloudVersionEngineUnityConfig"},"unreal":{"$ref":"#/components/schemas/CloudVersionEngineUnrealConfig"},"godot":{"$ref":"#/components/schemas/CloudVersionEngineGodotConfig"},"html5":{"$ref":"#/components/schemas/CloudVersionEngineHtml5Config"},"custom":{"$ref":"#/components/schemas/CloudVersionEngineCustomConfig"}}},"CloudVersionIdentityIdentityConfig":{"type":"object","description":"**Deprecated**\nIdentity configuration for a given version.","properties":{"display_names":{"type":"array","items":{"type":"string"},"description":"**Deprecated**"},"avatars":{"type":"array","items":{"type":"string","format":"uuid"},"description":"**Deprecated**"},"custom_display_names":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionIdentityCustomDisplayName"},"description":"**Deprecated**"},"custom_avatars":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionIdentityCustomAvatar"},"description":"**Deprecated**"}}},"CloudVersionIdentityCustomDisplayName":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"CloudVersionIdentityCustomAvatar":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"}},"required":["upload_id"]},"CloudVersionKvKvConfig":{"type":"object","description":"KV configuration for a given version.","properties":{}},"CloudVersionMatchmakerMatchmakerConfig":{"type":"object","description":"Matchmaker configuration for a given version.","properties":{"game_modes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameMode"},"description":"A list of game modes."},"captcha":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptcha"},"dev_hostname":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"regions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRegion"}},"max_players":{"type":"integer"},"max_players_direct":{"type":"integer"},"max_players_party":{"type":"integer"},"docker":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker"},"tier":{"type":"string"},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig"},"lobby_groups":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroup"},"description":"**Deprecated: use `game_modes` instead**\nA list of game modes."}}},"CoreIntercomPegboardMarkClientRegisteredRequest":{"type":"object","properties":{"server_id":{"type":"string","format":"uuid"}},"required":["server_id"]},"EdgeIntercomPegboardPrewarmImageRequest":{"type":"object","properties":{"image_artifact_url_stub":{"type":"string"}},"required":["image_artifact_url_stub"]},"EdgeIntercomPegboardToggleClientDrainRequest":{"type":"object","properties":{"draining":{"type":"boolean"},"drain_complete_ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["draining"]},"GroupListSuggestedResponse":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"},"description":"A list of group summaries."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["groups","watch"]},"GroupCreateRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"GroupCreateResponse":{"type":"object","properties":{"group_id":{"type":"string","format":"uuid"}},"required":["group_id"]},"GroupPrepareAvatarUploadRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the group avatar."},"mime":{"type":"string","description":"The MIME type of the group avatar."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"GroupPrepareAvatarUploadResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"GroupValidateProfileRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"bio":{"$ref":"#/components/schemas/DisplayName"},"publicity":{"$ref":"#/components/schemas/GroupPublicity"}}},"GroupValidateProfileResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"GroupGetBansResponse":{"type":"object","properties":{"banned_identities":{"type":"array","items":{"$ref":"#/components/schemas/GroupBannedIdentity"},"description":"A list of banned group members."},"anchor":{"type":"string","description":"The pagination anchor."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["banned_identities","watch"]},"GroupGetJoinRequestsResponse":{"type":"object","properties":{"join_requests":{"type":"array","items":{"$ref":"#/components/schemas/GroupJoinRequest"},"description":"A list of group join requests."},"anchor":{"type":"string","description":"The pagination anchor."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["join_requests","watch"]},"GroupGetMembersResponse":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"},"description":"A list of group members."},"anchor":{"type":"string","description":"The pagination anchor."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["members","watch"]},"GroupGetProfileResponse":{"type":"object","properties":{"group":{"$ref":"#/components/schemas/GroupProfile"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["group","watch"]},"GroupUpdateProfileRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"bio":{"type":"string","description":"Detailed information about a profile."},"publicity":{"$ref":"#/components/schemas/GroupPublicity"}}},"GroupGetSummaryResponse":{"type":"object","properties":{"group":{"$ref":"#/components/schemas/GroupGroupSummary"}},"required":["group"]},"GroupTransferOwnershipRequest":{"type":"object","properties":{"new_owner_identity_id":{"type":"string","description":"Identity to transfer the group to.\nMust be a member of the group."}},"required":["new_owner_identity_id"]},"IdentitySetupResponse":{"type":"object","properties":{"identity_token":{"$ref":"#/components/schemas/Jwt","description":"Token used to authenticate the identity.\nShould be stored somewhere permanent.\nPass this to `rivet.api.identity#Setup$existing_identity_token` next time `rivet.api.identity#Setup` is called.\nToken has a 90 day TTL.\nThis means that if `rivet.api.identity#Setup` is not called again within 90 days, the token will no longer be valid.\nIf this happens, the user can recover their account through the linking process (see `rivet.api.identity#PrepareGameLink`).\nThis token should be stored locally and never sent to a server or another device.\nIf this token is compromised, anyone with access to this token has control of the identity."},"identity_token_expire_ts":{"$ref":"#/components/schemas/Timestamp"},"identity":{"$ref":"#/components/schemas/IdentityProfile","description":"Information about the identity that was just authenticated."},"game_id":{"type":"string","format":"uuid"}},"required":["identity_token","identity_token_expire_ts","identity","game_id"]},"IdentityGetProfileResponse":{"type":"object","properties":{"identity":{"$ref":"#/components/schemas/IdentityProfile"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identity","watch"]},"IdentityGetHandlesResponse":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/IdentityHandle"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identities","watch"]},"IdentityGetSummariesResponse":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/IdentitySummary"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identities","watch"]},"IdentityValidateProfileResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"}}},"required":["errors"]},"IdentityPrepareAvatarUploadResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"ProvisionDatacentersGetTlsResponse":{"type":"object","properties":{"job_cert_pem":{"type":"string"},"job_private_key_pem":{"type":"string"},"api_cert_pem":{"type":"string"},"api_private_key_pem":{"type":"string"}},"required":["job_cert_pem","job_private_key_pem","api_cert_pem","api_private_key_pem"]},"ProvisionDatacentersGetServersResponse":{"type":"object","properties":{"servers":{"type":"array","items":{"$ref":"#/components/schemas/ProvisionServer"}}},"required":["servers"]},"ProvisionServersGetInfoResponse":{"type":"object","properties":{"name":{"type":"string"},"server_id":{"type":"string","format":"uuid"},"datacenter_id":{"type":"string","format":"uuid"},"datacenter_name_id":{"type":"string"},"cluster_id":{"type":"string","format":"uuid"},"lan_ip":{"type":"string"},"wan_ip":{"type":"string"},"vlan_ip":{"type":"string","description":"**Deprecated**: Use lan_ip"},"public_ip":{"type":"string","description":"**Deprecated**: Use wan_ip"}},"required":["name","server_id","datacenter_id","datacenter_name_id","cluster_id","lan_ip","wan_ip","vlan_ip","public_ip"]},"ProvisionTunnelGetTlsResponse":{"type":"object","properties":{"cert_pem":{"type":"string"},"root_ca_cert_pem":{"type":"string"},"private_key_pem":{"type":"string"}},"required":["cert_pem","root_ca_cert_pem","private_key_pem"]},"RegionsListRegionsResponse":{"type":"object","properties":{"regions":{"type":"array","items":{"$ref":"#/components/schemas/RegionsRegion"}}},"required":["regions"]},"RegionsRecommendRegionResponse":{"type":"object","properties":{"region":{"$ref":"#/components/schemas/RegionsRegion"}},"required":["region"]},"RoutesListRoutesResponse":{"type":"object","properties":{"routes":{"type":"array","items":{"$ref":"#/components/schemas/RoutesRoute"}}},"required":["routes"]},"RoutesUpdateRouteBody":{"type":"object","properties":{"hostname":{"type":"string"},"path":{"type":"string"},"strip_prefix":{"type":"boolean","description":"Whether to remove the path prefix before sending the request to the actor."},"route_subpaths":{"type":"boolean","description":"Whether to route all subpaths of this path"},"target":{"$ref":"#/components/schemas/RoutesRouteTarget"}},"required":["hostname","path","strip_prefix","route_subpaths","target"]},"RoutesUpdateRouteResponse":{"type":"object","properties":{}},"RoutesDeleteRouteResponse":{"type":"object","properties":{}},"ServersGetServerResponse":{"type":"object","properties":{"server":{"$ref":"#/components/schemas/ServersServer"}},"required":["server"]},"ServersCreateServerRequest":{"type":"object","properties":{"datacenter":{"type":"string","format":"uuid"},"tags":{},"runtime":{"$ref":"#/components/schemas/ServersCreateServerRuntimeRequest"},"network":{"$ref":"#/components/schemas/ServersCreateServerNetworkRequest"},"resources":{"$ref":"#/components/schemas/ServersResources"},"lifecycle":{"$ref":"#/components/schemas/ServersLifecycle"}},"required":["datacenter","tags","runtime","network","resources"]},"ServersCreateServerRuntimeRequest":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"arguments":{"type":"array","items":{"type":"string"}},"environment":{"type":"object","additionalProperties":{"type":"string"}}},"required":["build"]},"ServersCreateServerNetworkRequest":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ServersNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ServersCreateServerPortRequest"}}},"required":["ports"]},"ServersCreateServerPortRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ServersPortProtocol"},"internal_port":{"type":"integer"},"routing":{"$ref":"#/components/schemas/ServersPortRouting"}},"required":["protocol"]},"ServersCreateServerResponse":{"type":"object","properties":{"server":{"$ref":"#/components/schemas/ServersServer","description":"The server that was created"}},"required":["server"]},"ServersDestroyServerResponse":{"type":"object","properties":{}},"ServersListServersResponse":{"type":"object","properties":{"servers":{"type":"array","items":{"$ref":"#/components/schemas/ServersServer"},"description":"A list of servers for the game associated with the token."}},"required":["servers"]},"ActorsActor":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"region":{"type":"string"},"tags":{},"runtime":{"$ref":"#/components/schemas/ActorsRuntime"},"network":{"$ref":"#/components/schemas/ActorsNetwork"},"resources":{"$ref":"#/components/schemas/ActorsResources"},"lifecycle":{"$ref":"#/components/schemas/ActorsLifecycle"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"started_at":{"$ref":"#/components/schemas/Timestamp"},"destroyed_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","region","tags","runtime","network","resources","lifecycle","created_at"]},"ActorsRuntime":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"arguments":{"type":"array","items":{"type":"string"}},"environment":{"type":"object","additionalProperties":{"type":"string"}}},"required":["build"]},"ActorsLifecycle":{"type":"object","properties":{"kill_timeout":{"type":"integer","format":"int64","description":"The duration to wait for in milliseconds before killing the actor. This should be set to a safe default, and can be overridden during a DELETE request if needed."},"durable":{"type":"boolean","description":"If true, the actor will try to reschedule itself automatically in the event of a crash or a datacenter failover. The actor will not reschedule if it exits successfully."}}},"ActorsResources":{"type":"object","properties":{"cpu":{"type":"integer","description":"The number of CPU cores in millicores, or 1/1000 of a core. For example,\n1/8 of a core would be 125 millicores, and 1 core would be 1000\nmillicores."},"memory":{"type":"integer","description":"The amount of memory in megabytes"}},"required":["cpu","memory"]},"ActorsNetwork":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ActorsNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ActorsPort"}}},"required":["mode","ports"]},"ActorsNetworkMode":{"type":"string","enum":["bridge","host"]},"ActorsPort":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ActorsPortProtocol"},"internal_port":{"type":"integer"},"hostname":{"type":"string"},"port":{"type":"integer"},"path":{"type":"string"},"url":{"type":"string","description":"Fully formed connection URL including protocol, hostname, port, and path, if applicable."},"routing":{"$ref":"#/components/schemas/ActorsPortRouting"}},"required":["protocol","routing"]},"ActorsPortProtocol":{"type":"string","enum":["http","https","tcp","tcp_tls","udp"]},"ActorsPortRouting":{"type":"object","properties":{"guard":{"$ref":"#/components/schemas/ActorsGuardRouting"},"host":{"$ref":"#/components/schemas/ActorsHostRouting"}}},"ActorsGuardRouting":{"type":"object","properties":{}},"ActorsHostRouting":{"type":"object","properties":{}},"ActorsEndpointType":{"type":"string","enum":["hostname","path"]},"ActorsGetActorLogsResponse":{"type":"object","properties":{"actor_ids":{"type":"array","items":{"type":"string"},"description":"List of actor IDs in these logs. The order of these correspond to the index in the log entry."},"lines":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"timestamps":{"type":"array","items":{"$ref":"#/components/schemas/Timestamp"},"description":"Sorted old to new."},"streams":{"type":"array","items":{"type":"integer"},"description":"Streams the logs came from.\n\n0 = stdout\n1 = stderr"},"actor_indices":{"type":"array","items":{"type":"integer"},"description":"Index of the actor that this log was for. Use this index to look the full ID in `actor_ids`."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["actor_ids","lines","timestamps","streams","actor_indices","watch"]},"ActorsQueryLogStream":{"type":"string","enum":["std_out","std_err","all"]},"AuthCompleteStatus":{"type":"string","enum":["switch_identity","linked_account_added","already_complete","expired","too_many_attempts","incorrect"],"description":"Represents the state of an external account linking process."},"AuthIdentityStartEmailVerificationRequest":{"type":"object","properties":{"email":{"type":"string"},"captcha":{"$ref":"#/components/schemas/CaptchaConfig"},"game_id":{"type":"string","format":"uuid"}},"required":["email"]},"AuthIdentityStartEmailVerificationResponse":{"type":"object","properties":{"verification_id":{"type":"string","format":"uuid"}},"required":["verification_id"]},"AuthIdentityCompleteEmailVerificationRequest":{"type":"object","properties":{"verification_id":{"type":"string","format":"uuid"},"code":{"type":"string","description":"The code sent to the requestee's email."}},"required":["verification_id","code"]},"AuthIdentityCompleteEmailVerificationResponse":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AuthCompleteStatus"}},"required":["status"]},"AuthRefreshIdentityTokenRequest":{"type":"object","properties":{"logout":{"type":"boolean","description":"When `true`, the current identity for the provided cookie will be logged out and a new identity will be returned."}}},"AuthRefreshIdentityTokenResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."},"exp":{"type":"string","description":"Token expiration time (in milliseconds)."},"identity_id":{"type":"string","format":"uuid"}},"required":["token","exp","identity_id"]},"BuildsBuild":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of this build"}},"required":["id","name","created_at","content_length","tags"]},"CaptchaConfig":{"type":"object","description":"Methods to verify a captcha","properties":{"hcaptcha":{"$ref":"#/components/schemas/CaptchaConfigHcaptcha"},"turnstile":{"$ref":"#/components/schemas/CaptchaConfigTurnstile"}}},"CaptchaConfigHcaptcha":{"type":"object","description":"Captcha configuration.","properties":{"client_response":{"type":"string"}},"required":["client_response"]},"CaptchaConfigTurnstile":{"type":"object","description":"Captcha configuration.","properties":{"client_response":{"type":"string"}},"required":["client_response"]},"CloudInspectResponse":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/CloudAuthAgent"}},"required":["agent"]},"CloudSvcPerf":{"type":"object","description":"A service performance summary.","properties":{"svc_name":{"type":"string","description":"The name of the service."},"ts":{"$ref":"#/components/schemas/Timestamp"},"duration":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"req_id":{"type":"string","format":"uuid"},"spans":{"type":"array","items":{"$ref":"#/components/schemas/CloudLogsPerfSpan"},"description":"A list of performance spans."},"marks":{"type":"array","items":{"$ref":"#/components/schemas/CloudLogsPerfMark"},"description":"A list of performance marks."}},"required":["svc_name","ts","duration","spans","marks"]},"CloudLogsPerfSpan":{"type":"object","description":"A performance span.","properties":{"label":{"type":"string","description":"The label given to this performance span."},"start_ts":{"$ref":"#/components/schemas/Timestamp"},"finish_ts":{"$ref":"#/components/schemas/Timestamp"},"req_id":{"type":"string","format":"uuid"}},"required":["label","start_ts"]},"CloudLogsPerfMark":{"type":"object","description":"A performance mark.","properties":{"label":{"type":"string","description":"The label given to this performance mark."},"ts":{"$ref":"#/components/schemas/Timestamp"},"ray_id":{"type":"string","format":"uuid"},"req_id":{"type":"string","format":"uuid"}},"required":["label","ts"]},"CloudLobbySummaryAnalytics":{"type":"object","description":"Analytical information about a lobby.","properties":{"lobby_id":{"type":"string","format":"uuid"},"lobby_group_id":{"type":"string","format":"uuid"},"lobby_group_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"region_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"is_ready":{"type":"boolean","description":"Whether or not this lobby is ready."},"is_idle":{"type":"boolean","description":"Whether or not this lobby is idle."},"is_closed":{"type":"boolean","description":"Whether or not this lobby is in a closed state."},"is_outdated":{"type":"boolean","description":"Whether or not this lobby is outdated."},"max_players_normal":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_direct":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_party":{"type":"integer","description":"Unsigned 32 bit integer."},"total_player_count":{"type":"integer","description":"Unsigned 32 bit integer."},"registered_player_count":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_id","lobby_group_id","lobby_group_name_id","region_id","create_ts","is_ready","is_idle","is_closed","is_outdated","max_players_normal","max_players_direct","max_players_party","total_player_count","registered_player_count"]},"CloudLogsLobbySummary":{"type":"object","description":"A logs summary for a lobby.","properties":{"lobby_id":{"type":"string","format":"uuid"},"namespace_id":{"type":"string","format":"uuid"},"lobby_group_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"region_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"start_ts":{"$ref":"#/components/schemas/Timestamp"},"ready_ts":{"$ref":"#/components/schemas/Timestamp"},"status":{"$ref":"#/components/schemas/CloudLogsLobbyStatus"}},"required":["lobby_id","namespace_id","lobby_group_name_id","region_id","create_ts","status"]},"CloudLogsLobbyStatus":{"type":"object","description":"A union representing the state of a lobby.","properties":{"running":{"$ref":"#/components/schemas/EmptyObject"},"stopped":{"$ref":"#/components/schemas/CloudLogsLobbyStatusStopped"}},"required":["running"]},"CloudLogsLobbyStatusStopped":{"type":"object","description":"The status of a stopped lobby.","properties":{"stop_ts":{"$ref":"#/components/schemas/Timestamp"},"failed":{"type":"boolean","description":"Whether or not the lobby failed or stopped successfully."},"exit_code":{"type":"integer","description":"The exit code returned by the lobby's main process when stopped."}},"required":["stop_ts","failed","exit_code"]},"CloudSvcMetrics":{"type":"object","description":"Metrics relating to a job service.","properties":{"job":{"type":"string","description":"The job name."},"cpu":{"type":"array","items":{"type":"number","format":"double"},"description":"CPU metrics."},"memory":{"type":"array","items":{"type":"number","format":"double"},"description":"Memory metrics."},"allocated_memory":{"type":"number","format":"double","description":"Total allocated memory (MB)."}},"required":["job","cpu","memory"]},"CloudAuthAgent":{"type":"object","description":"The current authenticated agent.","properties":{"identity":{"$ref":"#/components/schemas/CloudAuthAgentIdentity"},"game_cloud":{"$ref":"#/components/schemas/CloudAuthAgentGameCloud"}}},"CloudAuthAgentIdentity":{"type":"object","description":"The current authenticated identity.","properties":{"identity_id":{"type":"string","format":"uuid"}},"required":["identity_id"]},"CloudAuthAgentGameCloud":{"type":"object","description":"The current authenticated game cloud.","properties":{"game_id":{"type":"string","format":"uuid"}},"required":["game_id"]},"CloudCustomAvatarSummary":{"type":"object","description":"A custom avatar summary.","properties":{"upload_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"url":{"type":"string","description":"The URL of this custom avatar image. Only present if upload is complete."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"complete":{"type":"boolean","description":"Whether or not this custom avatar has completely been uploaded."}},"required":["upload_id","display_name","create_ts","content_length","complete"]},"CloudBuildSummary":{"type":"object","description":"A build summary.","properties":{"build_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"complete":{"type":"boolean","description":"Whether or not this build has completely been uploaded."},"tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of this build"}},"required":["build_id","upload_id","display_name","create_ts","content_length","complete","tags"]},"CloudCdnSiteSummary":{"type":"object","description":"A CDN site summary.","properties":{"site_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"complete":{"type":"boolean","description":"Whether or not this site has completely been uploaded."}},"required":["site_id","upload_id","display_name","create_ts","content_length","complete"]},"CloudGameFull":{"type":"object","description":"A full game.","properties":{"game_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"display_name":{"$ref":"#/components/schemas/DisplayName"},"developer_group_id":{"type":"string","format":"uuid"},"total_player_count":{"type":"integer","description":"Unsigned 32 bit integer."},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."},"namespaces":{"type":"array","items":{"$ref":"#/components/schemas/CloudNamespaceSummary"},"description":"A list of namespace summaries."},"versions":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionSummary"},"description":"A list of version summaries."},"available_regions":{"type":"array","items":{"$ref":"#/components/schemas/CloudRegionSummary"},"description":"A list of region summaries."}},"required":["game_id","create_ts","name_id","display_name","developer_group_id","total_player_count","namespaces","versions","available_regions"]},"CloudNamespaceSummary":{"type":"object","description":"A namespace summary.","properties":{"namespace_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"version_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."}},"required":["namespace_id","create_ts","display_name","version_id","name_id"]},"CloudRegionSummary":{"type":"object","description":"A region summary.","properties":{"region_id":{"type":"string","format":"uuid"},"region_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"provider":{"type":"string","description":"The server provider of this region."},"universal_region":{"$ref":"#/components/schemas/CloudUniversalRegion","description":"**Deprecated**\nA universal region label given to this region."},"provider_display_name":{"$ref":"#/components/schemas/DisplayName"},"region_display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["region_id","region_name_id","provider","universal_region","provider_display_name","region_display_name"]},"CloudGameLobbyExpenses":{"type":"object","description":"Game lobby expenses.","properties":{"game":{"$ref":"#/components/schemas/GameHandle"},"namespaces":{"type":"array","items":{"$ref":"#/components/schemas/CloudNamespaceSummary"},"description":"A list of namespace summaries."},"expenses":{"type":"array","items":{"$ref":"#/components/schemas/CloudRegionTierExpenses"},"description":"A list of multiple region tier expenses."}},"required":["game","namespaces","expenses"]},"CloudRegionTierExpenses":{"type":"object","description":"Region tier expenses.","properties":{"namespace_id":{"type":"string","format":"uuid"},"region_id":{"type":"string","format":"uuid"},"tier_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"lobby_group_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"uptime":{"type":"number","format":"double","description":"How long a region tier has been active (in milliseconds)."},"expenses":{"type":"number","format":"double","description":"Amount of expenses for this region tier (in hundred-thousandths USD, 100,000 = $1.00)."}},"required":["namespace_id","region_id","tier_name_id","lobby_group_name_id","uptime","expenses"]},"CloudGroupBankSource":{"type":"object","properties":{"account_number":{"type":"string","description":"The bank account number of this group's bank source."},"routing_number":{"type":"string","description":"The bank routing number of this group's bank source."}},"required":["account_number","routing_number"]},"CloudRegionTier":{"type":"object","description":"A region server tier.","properties":{"tier_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"rivet_cores_numerator":{"type":"integer","description":"Together with the denominator, denotes the portion of the CPU a given server uses."},"rivet_cores_denominator":{"type":"integer","description":"Together with the numerator, denotes the portion of the CPU a given server uses."},"cpu":{"type":"integer","description":"CPU frequency (MHz)."},"memory":{"type":"integer","description":"Allocated memory (MB)."},"disk":{"type":"integer","description":"Allocated disk space (MB)."},"bandwidth":{"type":"integer","description":"Internet bandwidth (MB)."},"price_per_second":{"type":"integer","description":"**Deprecated**\nPrice billed for every second this server is running (in quadrillionth USD, 1,000,000,000,000 = $1.00)."}},"required":["tier_name_id","rivet_cores_numerator","rivet_cores_denominator","cpu","memory","disk","bandwidth","price_per_second"]},"CloudUniversalRegion":{"type":"string","enum":["unknown","local","amsterdam","atlanta","bangalore","dallas","frankfurt","london","mumbai","newark","new_york_city","san_francisco","singapore","sydney","tokyo","toronto","washington_dc","chicago","paris","seattle","sao_paulo","stockholm","chennai","osaka","milan","miami","jakarta","los_angeles"],"description":"**Deprecated**"},"CloudNamespaceFull":{"type":"object","description":"A full namespace.","properties":{"namespace_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"version_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"config":{"$ref":"#/components/schemas/CloudNamespaceConfig"}},"required":["namespace_id","create_ts","display_name","version_id","name_id","config"]},"CloudNamespaceConfig":{"type":"object","description":"Cloud configuration for a given namespace.","properties":{"cdn":{"$ref":"#/components/schemas/CloudCdnNamespaceConfig"},"matchmaker":{"$ref":"#/components/schemas/CloudMatchmakerNamespaceConfig"},"kv":{"$ref":"#/components/schemas/CloudKvNamespaceConfig"},"identity":{"$ref":"#/components/schemas/CloudIdentityNamespaceConfig"}},"required":["cdn","matchmaker","kv","identity"]},"CloudCdnNamespaceConfig":{"type":"object","description":"CDN configuration for a given namespace.","properties":{"enable_domain_public_auth":{"type":"boolean","description":"Whether or not to allow users to connect to the given namespace via domain name."},"domains":{"type":"array","items":{"$ref":"#/components/schemas/CloudCdnNamespaceDomain"},"description":"A list of CDN domains for a given namespace."},"auth_type":{"$ref":"#/components/schemas/CloudCdnAuthType"},"auth_user_list":{"type":"array","items":{"$ref":"#/components/schemas/CloudCdnNamespaceAuthUser"},"description":"A list of CDN authenticated users for a given namespace."}},"required":["enable_domain_public_auth","domains","auth_type","auth_user_list"]},"CloudMatchmakerNamespaceConfig":{"type":"object","description":"Matchmaker configuration for a given namespace.","properties":{"lobby_count_max":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_vpn":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_proxy":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_tor":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_hosting":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_count_max","max_players_per_client","max_players_per_client_vpn","max_players_per_client_proxy","max_players_per_client_tor","max_players_per_client_hosting"]},"CloudKvNamespaceConfig":{"type":"object","description":"KV configuration for a given namespace.","properties":{}},"CloudIdentityNamespaceConfig":{"type":"object","description":"Identity configuration for a given namespace.","properties":{}},"CloudCdnAuthType":{"type":"string","enum":["none","basic"],"description":"A value denoting what type of authentication to use for a game namespace's CDN."},"CloudCdnNamespaceDomain":{"type":"object","description":"A CDN domain for a given namespace.","properties":{"domain":{"type":"string","description":"A valid domain name (no protocol)."},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"verification_status":{"$ref":"#/components/schemas/CloudCdnNamespaceDomainVerificationStatus"},"verification_method":{"$ref":"#/components/schemas/CloudCdnNamespaceDomainVerificationMethod"},"verification_errors":{"type":"array","items":{"type":"string"}}},"required":["domain","create_ts","verification_status","verification_method","verification_errors"]},"CloudCdnNamespaceDomainVerificationMethod":{"type":"object","description":"A union representing the verification method used for this CDN domain.","properties":{"invalid":{"$ref":"#/components/schemas/EmptyObject"},"http":{"$ref":"#/components/schemas/CloudCdnNamespaceDomainVerificationMethodHttp"}}},"CloudCdnNamespaceDomainVerificationMethodHttp":{"type":"object","properties":{"cname_record":{"type":"string"}},"required":["cname_record"]},"CloudCdnNamespaceDomainVerificationStatus":{"type":"string","enum":["active","pending","failed"],"description":"A value denoting the status of a CDN domain's verification status."},"CloudCdnNamespaceAuthUser":{"type":"object","description":"An authenticated CDN user for a given namespace.","properties":{"user":{"type":"string","description":"A user name."}},"required":["user"]},"CloudMatchmakerDevelopmentPort":{"type":"object","description":"A port configuration used to create development tokens.","properties":{"port":{"type":"integer"},"port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange"},"protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol"}},"required":["protocol"]},"CloudNamespaceVersion":{"type":"object","description":"A previously deployed namespace version.","properties":{"namespace_id":{"type":"string","description":"A universally unique identifier."},"version_id":{"type":"string","description":"A universally unique identifier."},"deploy_ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["namespace_id","version_id","deploy_ts"]},"CloudDevicesPrepareDeviceLinkResponse":{"type":"object","properties":{"device_link_id":{"type":"string","format":"uuid"},"device_link_token":{"type":"string"},"device_link_url":{"type":"string"}},"required":["device_link_id","device_link_token","device_link_url"]},"CloudDevicesGetDeviceLinkResponse":{"type":"object","properties":{"cloud_token":{"type":"string"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["watch"]},"CloudDevicesCompleteDeviceLinkRequest":{"type":"object","properties":{"device_link_token":{"$ref":"#/components/schemas/Jwt"},"game_id":{"type":"string","format":"uuid"}},"required":["device_link_token","game_id"]},"CloudGamesListGameCustomAvatarsResponse":{"type":"object","properties":{"custom_avatars":{"type":"array","items":{"$ref":"#/components/schemas/CloudCustomAvatarSummary"},"description":"A list of custom avatar summaries."}},"required":["custom_avatars"]},"CloudGamesPrepareCustomAvatarUploadRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the custom avatar."},"mime":{"type":"string","description":"The MIME type of the custom avatar."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"CloudGamesPrepareCustomAvatarUploadResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"CloudGamesListGameBuildsResponse":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/CloudBuildSummary"},"description":"A list of build summaries."}},"required":["builds"]},"CloudGamesCreateGameBuildRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"image_tag":{"type":"string","description":"A tag given to the game build."},"image_file":{"$ref":"#/components/schemas/UploadPrepareFile"},"multipart_upload":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/CloudGamesBuildKind"},"compression":{"$ref":"#/components/schemas/CloudGamesBuildCompression"}},"required":["display_name","image_tag","image_file"]},"CloudGamesCreateGameBuildResponse":{"type":"object","properties":{"build_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"image_presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"},"image_presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["build_id","upload_id"]},"CloudGamesBuildKind":{"type":"string","enum":["docker_image","oci_bundle"]},"CloudGamesBuildCompression":{"type":"string","enum":["none","lz4"]},"CloudGamesListGameCdnSitesResponse":{"type":"object","properties":{"sites":{"type":"array","items":{"$ref":"#/components/schemas/CloudCdnSiteSummary"},"description":"A list of CDN site summaries."}},"required":["sites"]},"CloudGamesCreateGameCdnSiteRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"files":{"type":"array","items":{"$ref":"#/components/schemas/UploadPrepareFile"},"description":"A list of files preparing to upload."}},"required":["display_name","files"]},"CloudGamesCreateGameCdnSiteResponse":{"type":"object","properties":{"site_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["site_id","upload_id","presigned_requests"]},"CloudGamesExportMatchmakerLobbyHistoryRequest":{"type":"object","properties":{"query_start":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"query_end":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["query_start","query_end"]},"CloudGamesExportMatchmakerLobbyHistoryResponse":{"type":"object","properties":{"url":{"type":"string","description":"The URL to a CSV file for the given lobby history."}},"required":["url"]},"CloudGamesDeleteMatchmakerLobbyResponse":{"type":"object","properties":{"did_remove":{"type":"boolean","description":"Whether or not the lobby was successfully stopped."}},"required":["did_remove"]},"CloudGamesGetLobbyLogsResponse":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"timestamps":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["lines","timestamps","watch"]},"CloudGamesExportLobbyLogsRequest":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/CloudGamesLogStream"}},"required":["stream"]},"CloudGamesExportLobbyLogsResponse":{"type":"object","properties":{"url":{"type":"string","description":"The URL to a CSV file for the given lobby history."}},"required":["url"]},"CloudGamesLogStream":{"type":"string","enum":["std_out","std_err"]},"CloudGamesNamespacesGetAnalyticsMatchmakerLiveResponse":{"type":"object","properties":{"lobbies":{"type":"array","items":{"$ref":"#/components/schemas/CloudLobbySummaryAnalytics"},"description":"A list of analytics lobby summaries."}},"required":["lobbies"]},"CloudGamesNamespacesListNamespaceLobbiesResponse":{"type":"object","properties":{"lobbies":{"type":"array","items":{"$ref":"#/components/schemas/CloudLogsLobbySummary"},"description":"A list of lobby log summaries."}},"required":["lobbies"]},"CloudGamesNamespacesGetNamespaceLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/CloudLogsLobbySummary"},"metrics":{"$ref":"#/components/schemas/CloudSvcMetrics"},"stdout_presigned_urls":{"type":"array","items":{"type":"string"},"description":"**Deprecated**\nA list of URLs."},"stderr_presigned_urls":{"type":"array","items":{"type":"string"},"description":"**Deprecated**\nA list of URLs."},"perf_lists":{"type":"array","items":{"$ref":"#/components/schemas/CloudSvcPerf"},"description":"**Deprecated**\nA list of service performance summaries."}},"required":["lobby","stdout_presigned_urls","stderr_presigned_urls","perf_lists"]},"CloudGamesCreateCloudTokenResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."}},"required":["token"]},"CloudGamesCreateGameVersionRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"config":{"$ref":"#/components/schemas/CloudVersionConfig"}},"required":["display_name","config"]},"CloudGamesCreateGameVersionResponse":{"type":"object","properties":{"version_id":{"type":"string","format":"uuid"}},"required":["version_id"]},"CloudGamesReserveVersionNameResponse":{"type":"object","properties":{"version_display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["version_display_name"]},"CloudGamesValidateGameVersionRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"config":{"$ref":"#/components/schemas/CloudVersionConfig"}},"required":["display_name","config"]},"CloudGamesValidateGameVersionResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesGetGameVersionByIdResponse":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/CloudVersionFull"}},"required":["version"]},"CloudValidateGroupRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"CloudValidateGroupResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGetRayPerfLogsResponse":{"type":"object","properties":{"perf_lists":{"type":"array","items":{"$ref":"#/components/schemas/CloudSvcPerf"},"description":"A list of service performance summaries."}},"required":["perf_lists"]},"CloudGetRegionTiersResponse":{"type":"object","properties":{"tiers":{"type":"array","items":{"$ref":"#/components/schemas/CloudRegionTier"},"description":"A list of region server tiers."}},"required":["tiers"]},"CloudVersionEngineCustomConfig":{"type":"object","properties":{}},"CloudVersionEngineGodotConfig":{"type":"object","properties":{}},"CloudVersionEngineHtml5Config":{"type":"object","properties":{}},"CloudVersionEngineUnityConfig":{"type":"object","properties":{}},"CloudVersionEngineUnrealConfig":{"type":"object","properties":{"game_module":{"type":"string","description":"Name of the Unreal module that holds the game code.\nThis is usually the value of `$.Modules[0].Name` in the file `MyProject.unproject`.\n_Configures Rivet CLI behavior. Has no effect on server behavior._"}},"required":["game_module"]},"CloudVersionMatchmakerPortRange":{"type":"object","description":"Range of ports that can be connected to.\nIf configured, `network_mode` must equal `host`.\nPort ranges may overlap between containers, it is the responsibility of the developer to ensure ports are available before using.\nRead more about host networking [here](https://rivet.gg/docs/dynamic-servers/concepts/host-bridge-networking).\nOnly available on Rivet Open Source & Enterprise.\n\n### Related\n\n- cloud.version.matchmaker.PortProtocol\n- cloud.version.matchmaker.ProxyKind","properties":{"min":{"type":"integer","description":"Unsigned 32 bit integer."},"max":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["min","max"]},"CloudVersionMatchmakerPortProtocol":{"type":"string","enum":["http","https","tcp","tcp_tls","udp"],"description":"Signifies the protocol of the port.\nNote that when proxying through GameGuard (via `ProxyKind`), the port number returned by `/find`, `/join`, and `/create` will not be the same as the port number configured in the config:\n\n- With HTTP, the port will always be 80. The hostname of the port correctly routes the incoming\n connection to the correct port being used by the game server.\n- With HTTPS, the port will always be 443. The hostname of the port correctly routes the incoming\n connection to the correct port being used by the game server.\n- Using TCP/UDP, the port will be a random number between 26000 and 31999. This gets automatically\n routed to the correct port being used by the game server.\n\n### Related - cloud.version.matchmaker.GameModeRuntimeDockerPort - cloud.version.matchmaker.ProxyKind - /docs/dynamic-servers/concepts/game-guard - matchmaker.lobbies.find"},"CloudVersionMatchmakerProxyKind":{"type":"string","enum":["none","game_guard"],"description":"Range of ports that can be connected to.\n`game_guard` (default) proxies all traffic through [Game Guard](https://rivet.gg/docs/dynamic-servers/concepts/game-guard) to mitigate DDoS attacks and provide TLS termination.\n`none` sends traffic directly to the game server. If configured, `network_mode` must equal `host`. Read more about host networking [here](https://rivet.gg/docs/dynamic-servers/concepts/host-bridge-networking). Only available on Rivet Open Source & Enterprise.\n\n### Related - /docs/dynamic-servers/concepts/game-guard - cloud.version.matchmaker.PortProtocol"},"CloudVersionMatchmakerCaptcha":{"type":"object","description":"Matchmaker captcha configuration.","properties":{"requests_before_reverify":{"type":"integer","description":"Denotes how many requests a connection can make before it is required to reverify a captcha."},"verification_ttl":{"type":"integer","format":"int64","description":"Denotes how long a connection can continue to reconnect without having to reverify a captcha (in milliseconds)."},"hcaptcha":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptchaHcaptcha"},"turnstile":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptchaTurnstile"}},"required":["requests_before_reverify","verification_ttl"]},"CloudVersionMatchmakerCaptchaHcaptcha":{"type":"object","description":"hCpatcha configuration.","properties":{"level":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptchaHcaptchaLevel","description":"**Deprecated**"},"site_key":{"type":"string","description":"Site key for your hCaptcha application. Must be set."},"secret_key":{"type":"string","description":"Secret key for your hCaptcha application. Must be set."}}},"CloudVersionMatchmakerCaptchaHcaptchaLevel":{"type":"string","enum":["easy","moderate","difficult","always_on"],"description":"**Deprecated**\nHow hard a captcha should be."},"CloudVersionMatchmakerCaptchaTurnstile":{"type":"object","description":"Turnstile captcha configuration.","properties":{"site_key":{"type":"string"},"secret_key":{"type":"string"}},"required":["site_key","secret_key"]},"CloudVersionMatchmakerNetworkMode":{"type":"string","enum":["bridge","host"],"description":"Configures how the container's network is isolated from the host.\n`bridge` (default) networking isolates the container's network from the host & other containers.\n`host` networking removes isolation between the container and the host. Only available in Rivet Open Source & Enterprise.\nRead more about bridge vs host networking [here](https://rivet.gg/docs/dynamic-servers/concepts/host-bridge-networking)."},"CloudVersionMatchmakerGameMode":{"type":"object","description":"A game mode.","properties":{"regions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRegion"}},"max_players":{"type":"integer"},"max_players_direct":{"type":"integer"},"max_players_party":{"type":"integer"},"docker":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker"},"listable":{"type":"boolean"},"taggable":{"type":"boolean"},"allow_dynamic_max_players":{"type":"boolean"},"actions":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeActions"},"tier":{"type":"string"},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig"}}},"CloudVersionMatchmakerGameModeRegion":{"type":"object","description":"A game mode region.","properties":{"tier":{"type":"string"},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig"}}},"CloudVersionMatchmakerGameModeRuntimeDocker":{"type":"object","description":"A game mode runtime running through Docker.","properties":{"dockerfile":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"build_args":{"type":"object","additionalProperties":{"type":"string"},"description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"image":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"image_id":{"type":"string","format":"uuid"},"args":{"type":"array","items":{"type":"string"}},"env":{"type":"object","additionalProperties":{"type":"string"}},"network_mode":{"$ref":"#/components/schemas/CloudVersionMatchmakerNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDockerPort"}}}},"CloudVersionMatchmakerGameModeRuntimeDockerPort":{"type":"object","description":"Port config for a docker build.","properties":{"port":{"type":"integer","description":"The port number to connect to.\n\n### Related - cloud.version.matchmaker.PortProtocol - cloud.version.matchmaker.ProxyKind"},"port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange"},"protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol"},"proxy":{"$ref":"#/components/schemas/CloudVersionMatchmakerProxyKind","description":"How this port should be proxied. Defaults to 'game-guard`."},"dev_port":{"type":"integer","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"dev_port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"dev_protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"}}},"CloudVersionMatchmakerGameModeIdleLobbiesConfig":{"type":"object","description":"Configuration for how many idle lobbies a game version should have.","properties":{"min":{"type":"integer"},"max":{"type":"integer"}},"required":["min","max"]},"CloudVersionMatchmakerGameModeActions":{"type":"object","description":"Configuration for the connection types allowed for a game mode.","properties":{"find":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeFindConfig"},"join":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeJoinConfig"},"create":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeCreateConfig"}}},"CloudVersionMatchmakerGameModeIdentityRequirement":{"type":"string","enum":["none","guest","registered"],"description":"**Deprecated**\nThe registration requirement for a user when joining/finding/creating a lobby. \"None\" allows for connections without an identity."},"CloudVersionMatchmakerGameModeVerificationConfig":{"type":"object","description":"Configuration that tells Rivet where to send validation requests and with what headers. When set, Rivet will send the `verification_data` property (given by the user in the find/join/create endpoint) to the given url along with the headers provided and some information about the requested lobby. The response of this request will determine if the user can join that lobby or not.","properties":{"url":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}}},"required":["url","headers"]},"CloudVersionMatchmakerGameModeFindConfig":{"type":"object","description":"Configures the requirements and authentication for the /find endpoint. If this value is not set in the config, the /find endpoint is still enabled.","properties":{"enabled":{"type":"boolean","description":"Sets whether or not the /find endpoint is enabled."},"identity_requirement":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement"},"verification":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig"}},"required":["enabled"]},"CloudVersionMatchmakerGameModeJoinConfig":{"type":"object","description":"Configures the requirements and authentication for the /join endpoint. If this value is not set in the config, the /join endpoint is still enabled.","properties":{"enabled":{"type":"boolean","description":"Sets whether or not the /join endpoint is enabled."},"identity_requirement":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement"},"verification":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig"}},"required":["enabled"]},"CloudVersionMatchmakerGameModeCreateConfig":{"type":"object","description":"Configures the requirements and authentication for the /create endpoint. If this value is not set in the config, the /create endpoint is NOT enabled.","properties":{"enabled":{"type":"boolean","description":"Sets whether or not the /create endpoint is enabled."},"identity_requirement":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement"},"verification":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig"},"enable_public":{"type":"boolean","description":"Defaults to false when unset."},"enable_private":{"type":"boolean","description":"Defaults to true when unset."},"max_lobbies_per_identity":{"type":"integer","description":"**Deprecated**"}},"required":["enabled"]},"CloudVersionMatchmakerLobbyGroup":{"type":"object","description":"A game mode.","properties":{"name_id":{"type":"string","description":"**Deprecated: use GameMode instead**\nA human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"regions":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRegion"},"description":"A list of game mode regions."},"max_players_normal":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_direct":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_party":{"type":"integer","description":"Unsigned 32 bit integer."},"runtime":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntime"}},"required":["name_id","regions","max_players_normal","max_players_direct","max_players_party","runtime"]},"CloudVersionMatchmakerLobbyGroupRuntime":{"type":"object","description":"**Deprecated: use GameMode instead**\nA union representing the runtime a game mode runs on.","properties":{"docker":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDocker"}}},"CloudVersionMatchmakerLobbyGroupRegion":{"type":"object","description":"**Deprecated: use GameMode instead**\nA game mode region.","properties":{"region_id":{"type":"string","format":"uuid"},"tier_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig"}},"required":["region_id","tier_name_id"]},"CloudVersionMatchmakerLobbyGroupRuntimeDocker":{"type":"object","description":"**Deprecated: use GameMode instead**\nA game mode runtime running through Docker.","properties":{"build_id":{"type":"string","format":"uuid"},"args":{"type":"array","items":{"type":"string"}},"env_vars":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerEnvVar"}},"network_mode":{"$ref":"#/components/schemas/CloudVersionMatchmakerNetworkMode"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerPort"}}},"required":["args","env_vars","ports"]},"CloudVersionMatchmakerLobbyGroupRuntimeDockerEnvVar":{"type":"object","description":"**Deprecated: use GameMode instead**\nA docker environment variable.","properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"]},"CloudVersionMatchmakerLobbyGroupRuntimeDockerPort":{"type":"object","description":"**Deprecated: use GameMode instead**\nA docker port.","properties":{"label":{"type":"string","description":"The label of this docker port."},"target_port":{"type":"integer","description":"The port number to connect to."},"port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange"},"proxy_protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol"}},"required":["label","proxy_protocol"]},"CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig":{"type":"object","description":"**Deprecated: use GameMode instead**\nConfiguration for how many idle lobbies a game version should have.","properties":{"min_idle_lobbies":{"type":"integer","description":"Unsigned 32 bit integer."},"max_idle_lobbies":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["min_idle_lobbies","max_idle_lobbies"]},"Identifier":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `uuid` because this is intended to be human readable. Different than `DisplayName` because this should not include special characters and be short."},"Bio":{"type":"string","description":"Follows regex ^(?:[^\\n\\r]+\\n?|\\n){1,5}$"},"Email":{"type":"string","description":"A valid email address"},"Jwt":{"type":"string","description":"Documentation at https://jwt.io/"},"WatchQuery":{"type":"string","description":"A query parameter denoting the requests watch index."},"WatchResponse":{"type":"object","description":"Provided by watchable endpoints used in blocking loops.","properties":{"index":{"type":"string","description":"Index indicating the version of the data responded.\nPass this to `WatchQuery` to block and wait for the next response."}},"required":["index"]},"DisplayName":{"type":"string","description":"Represent a resource's readable display name."},"AccountNumber":{"type":"integer"},"Timestamp":{"type":"string","format":"date-time","description":"RFC3339 timestamp"},"GlobalEventNotification":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"thumbnail_url":{"type":"string"},"url":{"type":"string"}},"required":["title","description","thumbnail_url","url"]},"ValidationError":{"type":"object","description":"An error given by failed content validation.","properties":{"path":{"type":"array","items":{"type":"string"},"description":"A list of strings denoting the origin of a validation error."}},"required":["path"]},"EmptyObject":{"type":"object","properties":{}},"ErrorMetadata":{"description":"Unstructured metadata relating to an error. Must be manually parsed."},"ErrorBody":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"ray_id":{"type":"string"},"documentation":{"type":"string"},"metadata":{"$ref":"#/components/schemas/ErrorMetadata"}},"required":["code","message","ray_id"]},"Pagination":{"type":"object","properties":{"cursor":{"type":"string"}}},"GameHandle":{"type":"object","properties":{"game_id":{"type":"string","format":"uuid"},"name_id":{"$ref":"#/components/schemas/Identifier"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."}},"required":["game_id","name_id","display_name"]},"GameGameSummary":{"type":"object","properties":{"game_id":{"type":"string","format":"uuid"},"name_id":{"$ref":"#/components/schemas/Identifier"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."},"url":{"type":"string"},"developer":{"$ref":"#/components/schemas/GroupHandle"},"total_player_count":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["game_id","name_id","display_name","url","developer","total_player_count"]},"GameProfile":{"type":"object","description":"A game profile.","properties":{"game_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"display_name":{"$ref":"#/components/schemas/DisplayName"},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."},"url":{"type":"string","description":"The URL to this game's website."},"developer":{"$ref":"#/components/schemas/GroupGroupSummary"},"tags":{"type":"array","items":{"type":"string"},"description":"A list of game tags."},"description":{"type":"string","description":"A description of the given game."},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/GamePlatformLink"},"description":"A list of platform links."},"recommended_groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"},"description":"A list of group summaries."},"identity_leaderboard_categories":{"type":"array","items":{"$ref":"#/components/schemas/GameLeaderboardCategory"},"description":"A list of game leaderboard categories."},"group_leaderboard_categories":{"type":"array","items":{"$ref":"#/components/schemas/GameLeaderboardCategory"},"description":"A list of game leaderboard categories."}},"required":["game_id","name_id","display_name","url","developer","tags","description","platforms","recommended_groups","identity_leaderboard_categories","group_leaderboard_categories"]},"GamePlatformLink":{"type":"object","description":"A platform link denoting a supported platform.","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"url":{"type":"string","description":"The URL to the given game's method of distribution on this platform."}},"required":["display_name","url"]},"GameLeaderboardCategory":{"type":"object","description":"A game leaderboard category.","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"GameStatSummary":{"type":"object","description":"A game statistic summary.","properties":{"game":{"$ref":"#/components/schemas/GameHandle"},"stats":{"type":"array","items":{"$ref":"#/components/schemas/GameStat"}}},"required":["game","stats"]},"GameStat":{"type":"object","description":"A game statistic.","properties":{"config":{"$ref":"#/components/schemas/GameStatConfig"},"overall_value":{"type":"number","format":"double","description":"A single overall value of the given statistic."}},"required":["config","overall_value"]},"GameStatConfig":{"type":"object","description":"A game statistic config.","properties":{"record_id":{"type":"string","format":"uuid"},"icon_id":{"type":"string","format":"uuid"},"format":{"$ref":"#/components/schemas/GameStatFormatMethod"},"aggregation":{"$ref":"#/components/schemas/GameStatAggregationMethod"},"sorting":{"$ref":"#/components/schemas/GameStatSortingMethod"},"priority":{"type":"integer"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"postfix_singular":{"type":"string","description":"A string appended to the end of a singular game statistic's value. Example: 1 **dollar**."},"postfix_plural":{"type":"string","description":"A string appended to the end of a game statistic's value that is not exactly 1. Example: 45 **dollars**."},"prefix_singular":{"type":"string","description":"A string appended to the beginning of a singular game statistic's value. Example: **value** 1."},"prefix_plural":{"type":"string","description":"A string prepended to the beginning of a game statistic's value that is not exactly 1. Example: **values** 45."}},"required":["record_id","icon_id","format","aggregation","sorting","priority","display_name"]},"GameStatFormatMethod":{"type":"string","enum":["integer","float_1","float_2","float_3","duration_minute","duration_second","duration_hundredth_second"],"description":"A value denoting the format method of a game statistic."},"GameStatAggregationMethod":{"type":"string","enum":["sum","average","min","max"],"description":"A value denoting the aggregation method of a game statistic."},"GameStatSortingMethod":{"type":"string","enum":["desc","asc"],"description":"A value denoting the sorting method of a game statistic."},"GamesEnvironmentsCreateServiceTokenResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token."}},"required":["token"]},"GeoCoord":{"type":"object","description":"Geographical coordinates for a location on Planet Earth.","properties":{"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"}},"required":["latitude","longitude"]},"GeoDistance":{"type":"object","description":"Distance available in multiple units.","properties":{"kilometers":{"type":"number","format":"double"},"miles":{"type":"number","format":"double"}},"required":["kilometers","miles"]},"GroupGroupSummary":{"type":"object","properties":{"group_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"avatar_url":{"type":"string","description":"The URL of this group's avatar image."},"external":{"$ref":"#/components/schemas/GroupExternalLinks"},"is_developer":{"type":"boolean","description":"**Deprecated**\nWhether or not this group is a developer."},"bio":{"$ref":"#/components/schemas/Bio"},"is_current_identity_member":{"type":"boolean","description":"Whether or not the current identity is a member of this group."},"publicity":{"$ref":"#/components/schemas/GroupPublicity"},"member_count":{"type":"integer"},"owner_identity_id":{"type":"string","format":"uuid"}},"required":["group_id","display_name","external","is_developer","bio","is_current_identity_member","publicity","member_count","owner_identity_id"]},"GroupPublicity":{"type":"string","enum":["open","closed"],"description":"The current publicity value for the given group."},"GroupHandle":{"type":"object","description":"A group handle.","properties":{"group_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"avatar_url":{"type":"string","description":"The URL of this group's avatar image"},"external":{"$ref":"#/components/schemas/GroupExternalLinks"},"is_developer":{"type":"boolean","description":"Whether or not this group is a developer group."}},"required":["group_id","display_name","external"]},"GroupExternalLinks":{"type":"object","description":"External links for this group.","properties":{"profile":{"type":"string","description":"A link to this group's profile page."}},"required":["profile"]},"GroupJoinRequest":{"type":"object","description":"A group join request.","properties":{"identity":{"$ref":"#/components/schemas/IdentityHandle"},"ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["identity","ts"]},"GroupMember":{"type":"object","description":"A group member.","properties":{"identity":{"$ref":"#/components/schemas/IdentityHandle"}},"required":["identity"]},"GroupProfile":{"type":"object","description":"A list of group profiles.","properties":{"group_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"avatar_url":{"type":"string","description":"The URL of this group's avatar image."},"external":{"$ref":"#/components/schemas/GroupExternalLinks"},"is_developer":{"type":"boolean","description":"Whether or not this group is a developer."},"bio":{"type":"string","description":"Detailed information about a profile."},"is_current_identity_member":{"type":"boolean","description":"Whether or not the current identity is a member of this group."},"publicity":{"$ref":"#/components/schemas/GroupPublicity"},"member_count":{"type":"integer","description":"Unsigned 32 bit integer."},"members":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"},"description":"A list of group members."},"join_requests":{"type":"array","items":{"$ref":"#/components/schemas/GroupJoinRequest"},"description":"A list of group join requests."},"is_current_identity_requesting_join":{"type":"boolean","description":"Whether or not the current identity is currently requesting to join this group."},"owner_identity_id":{"type":"string","format":"uuid"}},"required":["group_id","display_name","external","bio","publicity","members","join_requests","owner_identity_id"]},"GroupBannedIdentity":{"type":"object","description":"A banned identity.","properties":{"identity":{"$ref":"#/components/schemas/IdentityHandle"},"ban_ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["identity","ban_ts"]},"GroupGetInviteResponse":{"type":"object","properties":{"group":{"$ref":"#/components/schemas/GroupHandle"}},"required":["group"]},"GroupConsumeInviteResponse":{"type":"object","properties":{"group_id":{"type":"string","format":"uuid"}}},"GroupCreateInviteRequest":{"type":"object","properties":{"ttl":{"type":"number","format":"double","description":"How long until the group invite expires (in milliseconds)."},"use_count":{"type":"number","format":"double","description":"How many times the group invite can be used."}}},"GroupCreateInviteResponse":{"type":"object","properties":{"code":{"type":"string","description":"The code that will be passed to `rivet.api.group#ConsumeInvite` to join a group."}},"required":["code"]},"GroupResolveJoinRequestRequest":{"type":"object","properties":{"resolution":{"type":"boolean"}}},"IdentityListActivitiesResponse":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/IdentityHandle"}},"games":{"type":"array","items":{"$ref":"#/components/schemas/GameGameSummary"}},"suggested_groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"}},"suggested_players":{"type":"array","items":{"$ref":"#/components/schemas/IdentityHandle"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identities","games","suggested_groups","suggested_players","watch"]},"IdentityGlobalEvent":{"type":"object","description":"An event relevant to the current identity.","properties":{"ts":{"$ref":"#/components/schemas/Timestamp"},"kind":{"$ref":"#/components/schemas/IdentityGlobalEventKind"},"notification":{"$ref":"#/components/schemas/IdentityGlobalEventNotification"}},"required":["ts","kind"]},"IdentityGlobalEventKind":{"type":"object","properties":{"identity_update":{"$ref":"#/components/schemas/IdentityGlobalEventIdentityUpdate"}}},"IdentityGlobalEventNotification":{"type":"object","description":"Notifications represent information that should be presented to the user\nimmediately.\nAt the moment, only chat message events have associated notifications.\n\n# Display\n\nNotifications should be displayed in an unobtrusive manner throughout the\nentire game. Notifications should disappear after a few seconds if not\ninteracted with.\n\n# Interactions\n\nIf your platform supports it, notifications should be able to be clicked or\ntapped in order to open the relevant context for the event.\nFor a simple implementation of notification interactions, open `url` in a\nweb browser to present the relevant context. For example, a chat message\nnotification will open the thread the chat message was sent in.\nFor advanced implementations that implement a custom chat UI, use\n`GlobalEvent.kind` to determine what action to take when the notification is interacted with.\nFor example, if the global event kind is `GlobalEventChatMessage`, then open\nthe chat UI for the given thread.","properties":{"title":{"type":"string"},"description":{"type":"string"},"thumbnail_url":{"type":"string","description":"URL to an image thumbnail that should be shown for this notification."},"url":{"type":"string","description":"Rivet Hub URL that holds the relevant context for this notification."}},"required":["title","description","thumbnail_url","url"]},"IdentityGlobalEventIdentityUpdate":{"type":"object","properties":{"identity":{"$ref":"#/components/schemas/IdentityProfile"}},"required":["identity"]},"IdentityUpdateGameActivity":{"type":"object","description":"Information about the identity's current game. This is information that all other identities can see about what the current identity is doing.","properties":{"message":{"type":"string","description":"A short message about the current game activity."},"public_metadata":{"description":"JSON data seen by anyone."},"mutual_metadata":{"description":"JSON data seen only by the given identity and their mutual followers."}}},"IdentityHandle":{"type":"object","description":"An identity handle.","properties":{"identity_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"account_number":{"$ref":"#/components/schemas/AccountNumber"},"avatar_url":{"type":"string","description":"The URL of this identity's avatar image."},"is_registered":{"type":"boolean","description":"Whether or not this identity is registered with a linked account."},"external":{"$ref":"#/components/schemas/IdentityExternalLinks"}},"required":["identity_id","display_name","account_number","avatar_url","is_registered","external"]},"IdentitySummary":{"type":"object","description":"An identity summary.","properties":{"identity_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"account_number":{"$ref":"#/components/schemas/AccountNumber"},"avatar_url":{"type":"string","description":"The URL of this identity's avatar image."},"is_registered":{"type":"boolean","description":"Whether or not this identity is registered with a linked account."},"external":{"$ref":"#/components/schemas/IdentityExternalLinks"},"following":{"type":"boolean","description":"Whether or not the requestee's identity is following this identity."},"is_following_me":{"type":"boolean","description":"Whether or not this identity is both following and is followed by the requestee's identity."},"is_mutual_following":{"type":"boolean"}},"required":["identity_id","display_name","account_number","avatar_url","is_registered","external","following","is_following_me","is_mutual_following"]},"IdentityProfile":{"type":"object","description":"An identity profile.","properties":{"identity_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"account_number":{"$ref":"#/components/schemas/AccountNumber"},"avatar_url":{"type":"string","description":"The URL of this identity's avatar image."},"is_registered":{"type":"boolean","description":"Whether or not this identity is registered with a linked account."},"external":{"$ref":"#/components/schemas/IdentityExternalLinks"},"is_admin":{"type":"boolean","description":"Whether or not this identity is an admin."},"is_game_linked":{"type":"boolean","description":"Whether or not this game user has been linked through the Rivet dashboard."},"dev_state":{"$ref":"#/components/schemas/IdentityDevState","description":"**Deprecated**"},"follower_count":{"type":"integer","format":"int64"},"following_count":{"type":"integer","format":"int64"},"following":{"type":"boolean","description":"Whether or not the requestee's identity is following this identity."},"is_following_me":{"type":"boolean","description":"Whether or not this identity is both following and is followed by the requestee's identity."},"is_mutual_following":{"type":"boolean"},"join_ts":{"$ref":"#/components/schemas/Timestamp"},"bio":{"$ref":"#/components/schemas/Bio"},"linked_accounts":{"type":"array","items":{"$ref":"#/components/schemas/IdentityLinkedAccount"}},"groups":{"type":"array","items":{"$ref":"#/components/schemas/IdentityGroup"}},"games":{"type":"array","items":{"$ref":"#/components/schemas/GameStatSummary"}},"awaiting_deletion":{"type":"boolean","description":"Whether or not this identity is awaiting account deletion. Only visible to when the requestee is\nthis identity."}},"required":["identity_id","display_name","account_number","avatar_url","is_registered","external","is_admin","follower_count","following_count","following","is_following_me","is_mutual_following","join_ts","bio","linked_accounts","groups","games"]},"IdentityExternalLinks":{"type":"object","description":"External links for an identity.","properties":{"profile":{"type":"string","description":"A link to this identity's profile page."},"settings":{"type":"string","description":"A link to the Rivet settings page."}},"required":["profile"]},"IdentityStatus":{"type":"string","enum":["online","away","offline"],"description":"The current status of an identity. This helps players understand if another player is currently playing or has their game in the background."},"IdentityGameActivity":{"type":"object","description":"The game an identity is currently participating in.","properties":{"game":{"$ref":"#/components/schemas/GameHandle"},"message":{"type":"string","description":"A short activity message about the current game activity."},"public_metadata":{"description":"JSON data seen by anyone."},"mutual_metadata":{"description":"JSON data seen only by the given identity and their mutual followers."}},"required":["game","message"]},"IdentityGroup":{"type":"object","description":"A group that the given identity.","properties":{"group":{"$ref":"#/components/schemas/GroupHandle"}},"required":["group"]},"IdentityLinkedAccount":{"type":"object","description":"A union representing an identity's linked accounts.","properties":{"email":{"$ref":"#/components/schemas/IdentityEmailLinkedAccount"},"default_user":{"type":"boolean"}}},"IdentityEmailLinkedAccount":{"type":"object","description":"An identity's linked email.","properties":{"email":{"$ref":"#/components/schemas/Email"}},"required":["email"]},"IdentityDevState":{"type":"string","enum":["inactive","pending","accepted"],"description":"The state of the given identity's developer status."},"IdentityGameLinkStatus":{"type":"string","enum":["incomplete","complete","cancelled"]},"IdentityWatchEventsResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/IdentityGlobalEvent"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["events","watch"]},"MatchmakerLobbyInfo":{"type":"object","description":"A public lobby in the lobby list.","properties":{"region_id":{"type":"string"},"game_mode_id":{"type":"string"},"lobby_id":{"type":"string","format":"uuid"},"max_players_normal":{"type":"integer"},"max_players_direct":{"type":"integer"},"max_players_party":{"type":"integer"},"total_player_count":{"type":"integer"},"state":{}},"required":["region_id","game_mode_id","lobby_id","max_players_normal","max_players_direct","max_players_party","total_player_count"]},"MatchmakerGameModeInfo":{"type":"object","description":"A game mode that the player can join.","properties":{"game_mode_id":{"$ref":"#/components/schemas/Identifier"}},"required":["game_mode_id"]},"MatchmakerRegionInfo":{"type":"object","description":"A region that the player can connect to.","properties":{"region_id":{"$ref":"#/components/schemas/Identifier"},"provider_display_name":{"$ref":"#/components/schemas/DisplayName"},"region_display_name":{"$ref":"#/components/schemas/DisplayName"},"datacenter_coord":{"$ref":"#/components/schemas/GeoCoord"},"datacenter_distance_from_client":{"$ref":"#/components/schemas/GeoDistance"}},"required":["region_id","provider_display_name","region_display_name","datacenter_coord","datacenter_distance_from_client"]},"MatchmakerJoinLobby":{"type":"object","description":"A matchmaker lobby.","properties":{"lobby_id":{"type":"string","format":"uuid"},"region":{"$ref":"#/components/schemas/MatchmakerJoinRegion"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"},"description":"**Deprecated**"},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer","description":"**Deprecated**"}},"required":["lobby_id","region","ports","player"]},"MatchmakerJoinRegion":{"type":"object","description":"A matchmaker lobby region.","properties":{"region_id":{"$ref":"#/components/schemas/Identifier"},"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["region_id","display_name"]},"MatchmakerJoinPort":{"type":"object","properties":{"host":{"type":"string","description":"The host for the given port. Will be null if using a port range."},"hostname":{"type":"string"},"port":{"type":"integer","description":"The port number for this lobby. Will be null if using a port range."},"port_range":{"$ref":"#/components/schemas/MatchmakerJoinPortRange"},"is_tls":{"type":"boolean","description":"Whether or not this lobby port uses TLS. You cannot mix a non-TLS and TLS ports."}},"required":["hostname","is_tls"]},"MatchmakerJoinPortRange":{"type":"object","description":"Inclusive range of ports that can be connected to.","properties":{"min":{"type":"integer","description":"Minimum port that can be connected to. Inclusive range."},"max":{"type":"integer","description":"Maximum port that can be connected to. Inclusive range."}},"required":["min","max"]},"MatchmakerJoinPlayer":{"type":"object","description":"A matchmaker lobby player.","properties":{"token":{"$ref":"#/components/schemas/Jwt","description":"Pass this token through the socket to the lobby server. The lobby server will validate this token with `PlayerConnected.player_token`"}},"required":["token"]},"MatchmakerCustomLobbyPublicity":{"type":"string","enum":["public","private"]},"MatchmakerFindLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/MatchmakerJoinLobby"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"}},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer"}},"required":["lobby","ports","player"]},"MatchmakerJoinLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/MatchmakerJoinLobby"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"}},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer"}},"required":["lobby","ports","player"]},"MatchmakerCreateLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/MatchmakerJoinLobby"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"}},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer"}},"required":["lobby","ports","player"]},"MatchmakerListLobbiesResponse":{"type":"object","properties":{"game_modes":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerGameModeInfo"}},"regions":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerRegionInfo"}},"lobbies":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerLobbyInfo"}}},"required":["game_modes","regions","lobbies"]},"MatchmakerGetStatisticsResponse":{"type":"object","properties":{"player_count":{"type":"integer","format":"int64"},"game_modes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerGameModeStatistics"}}},"required":["player_count","game_modes"]},"MatchmakerGameModeStatistics":{"type":"object","properties":{"player_count":{"type":"integer","format":"int64"},"regions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerRegionStatistics"}}},"required":["player_count","regions"]},"MatchmakerRegionStatistics":{"type":"object","properties":{"player_count":{"type":"integer","format":"int64"}},"required":["player_count"]},"MatchmakerListRegionsResponse":{"type":"object","properties":{"regions":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerRegionInfo"}}},"required":["regions"]},"PortalNotificationRegisterService":{"type":"object","properties":{"firebase":{"$ref":"#/components/schemas/PortalNotificationRegisterFirebaseService"}}},"PortalNotificationRegisterFirebaseService":{"type":"object","properties":{"access_key":{"type":"string"}},"required":["access_key"]},"PortalNotificationUnregisterService":{"type":"string","enum":["firebase"]},"PortalGetSuggestedGamesResponse":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/GameGameSummary"},"description":"A list of game summaries."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["games","watch"]},"PortalGetGameProfileResponse":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/GameProfile"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["game","watch"]},"ProvisionPoolType":{"type":"string","enum":["job","gg","ats","pegboard","pegboard_isolate","fdb","worker","nats","guard"]},"ProvisionServer":{"type":"object","properties":{"server_id":{"type":"string","format":"uuid"},"datacenter_id":{"type":"string","format":"uuid"},"pool_type":{"$ref":"#/components/schemas/ProvisionPoolType"},"lan_ip":{"type":"string"},"wan_ip":{"type":"string"}},"required":["server_id","datacenter_id","pool_type"]},"RegionsRegion":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"RoutesRouteTargetActors":{"type":"object","description":"Configuration for targeting actors.","properties":{"selector_tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of actors to route requests to."}},"required":["selector_tags"]},"RoutesRouteTarget":{"type":"object","properties":{"actors":{"$ref":"#/components/schemas/RoutesRouteTargetActors","description":"Configuration for targeting actors."}}},"RoutesRoute":{"type":"object","properties":{"id":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"},"hostname":{"type":"string"},"path":{"type":"string"},"route_subpaths":{"type":"boolean","description":"Whether to route all subpaths of this path"},"strip_prefix":{"type":"boolean","description":"Whether to remove the path prefix before sending the request to the target."},"target":{"$ref":"#/components/schemas/RoutesRouteTarget"}},"required":["id","created_at","updated_at","hostname","path","route_subpaths","strip_prefix","target"]},"ServersGetBuildResponse":{"type":"object","properties":{"build":{"$ref":"#/components/schemas/ServersBuild"}},"required":["build"]},"ServersListBuildsResponse":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/ServersBuild"},"description":"A list of builds for the game associated with the token."}},"required":["builds"]},"ServersPatchBuildTagsRequest":{"type":"object","properties":{"tags":{},"exclusive_tags":{"type":"array","items":{"type":"string"},"description":"Removes the given tag keys from all other builds."}},"required":["tags"]},"ServersPatchBuildTagsResponse":{"type":"object","properties":{}},"ServersCreateBuildRequest":{"type":"object","properties":{"name":{"type":"string"},"image_tag":{"type":"string","description":"A tag given to the game build."},"image_file":{"$ref":"#/components/schemas/UploadPrepareFile"},"multipart_upload":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/ServersBuildKind"},"compression":{"$ref":"#/components/schemas/ServersBuildCompression"},"prewarm_datacenters":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["name","image_tag","image_file"]},"ServersCreateBuildResponse":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"image_presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"},"image_presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["build"]},"ServersBuildKind":{"type":"string","enum":["docker_image","oci_bundle"]},"ServersBuildCompression":{"type":"string","enum":["none","lz4"]},"ServersServer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"environment":{"type":"string","format":"uuid"},"datacenter":{"type":"string","format":"uuid"},"tags":{},"runtime":{"$ref":"#/components/schemas/ServersRuntime"},"network":{"$ref":"#/components/schemas/ServersNetwork"},"resources":{"$ref":"#/components/schemas/ServersResources"},"lifecycle":{"$ref":"#/components/schemas/ServersLifecycle"},"created_at":{"type":"integer","format":"int64"},"started_at":{"type":"integer","format":"int64"},"destroyed_at":{"type":"integer","format":"int64"}},"required":["id","environment","datacenter","tags","runtime","network","resources","lifecycle","created_at"]},"ServersRuntime":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"arguments":{"type":"array","items":{"type":"string"}},"environment":{"type":"object","additionalProperties":{"type":"string"}}},"required":["build"]},"ServersLifecycle":{"type":"object","properties":{"kill_timeout":{"type":"integer","format":"int64","description":"The duration to wait for in milliseconds before killing the server. This should be set to a safe default, and can be overridden during a DELETE request if needed."}}},"ServersResources":{"type":"object","properties":{"cpu":{"type":"integer","description":"The number of CPU cores in millicores, or 1/1000 of a core. For example,\n1/8 of a core would be 125 millicores, and 1 core would be 1000\nmillicores."},"memory":{"type":"integer","description":"The amount of memory in megabytes"}},"required":["cpu","memory"]},"ServersNetwork":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ServersNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ServersPort"}}},"required":["ports"]},"ServersNetworkMode":{"type":"string","enum":["bridge","host"]},"ServersPort":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ServersPortProtocol"},"internal_port":{"type":"integer"},"public_hostname":{"type":"string"},"public_port":{"type":"integer"},"routing":{"$ref":"#/components/schemas/ServersPortRouting"}},"required":["protocol","routing"]},"ServersPortProtocol":{"type":"string","enum":["http","https","tcp","tcp_tls","udp"]},"ServersPortRouting":{"type":"object","properties":{"game_guard":{"$ref":"#/components/schemas/ServersGameGuardRouting"},"host":{"$ref":"#/components/schemas/ServersHostRouting"}}},"ServersGameGuardRouting":{"type":"object","properties":{}},"ServersHostRouting":{"type":"object","properties":{}},"ServersBuild":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of this build"}},"required":["id","name","created_at","content_length","tags"]},"ServersDatacenter":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},"ServersListDatacentersResponse":{"type":"object","properties":{"datacenters":{"type":"array","items":{"$ref":"#/components/schemas/ServersDatacenter"}}},"required":["datacenters"]},"ServersGetServerLogsResponse":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"timestamps":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["lines","timestamps","watch"]},"ServersLogStream":{"type":"string","enum":["std_out","std_err"]},"UploadPresignedRequest":{"type":"object","description":"A presigned request used to upload files. Upload your file to the given URL via a PUT request.","properties":{"path":{"type":"string","description":"The name of the file to upload. This is the same as the one given in the upload prepare file."},"url":{"type":"string","description":"The URL of the presigned request for which to upload your file to."},"byte_offset":{"type":"integer","format":"int64","description":"The byte offset for this multipart chunk. Always 0 if not a multipart upload."},"content_length":{"type":"integer","format":"int64","description":"Expected size of this upload."}},"required":["path","url","byte_offset","content_length"]},"UploadPrepareFile":{"type":"object","description":"A file being prepared to upload.","properties":{"path":{"type":"string","description":"The path/filename of the file."},"content_type":{"type":"string","description":"The MIME type of the file."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]}}} \ No newline at end of file +{"definitions":{"ActorsGetActorResponse":{"type":"object","properties":{"actor":{"$ref":"#/components/schemas/ActorsActor"}},"required":["actor"]},"ActorsCreateActorRequest":{"type":"object","properties":{"region":{"type":"string"},"tags":{},"build":{"type":"string","format":"uuid"},"build_tags":{},"runtime":{"$ref":"#/components/schemas/ActorsCreateActorRuntimeRequest"},"network":{"$ref":"#/components/schemas/ActorsCreateActorNetworkRequest"},"resources":{"$ref":"#/components/schemas/ActorsResources"},"lifecycle":{"$ref":"#/components/schemas/ActorsLifecycle"}},"required":["tags"]},"ActorsCreateActorRuntimeRequest":{"type":"object","properties":{"environment":{"type":"object","additionalProperties":{"type":"string"}},"network":{"$ref":"#/components/schemas/ActorsCreateActorRuntimeNetworkRequest"}}},"ActorsCreateActorRuntimeNetworkRequest":{"type":"object","properties":{"endpoint_type":{"$ref":"#/components/schemas/ActorsEndpointType"}},"required":["endpoint_type"]},"ActorsCreateActorNetworkRequest":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ActorsNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ActorsCreateActorPortRequest"}},"wait_ready":{"type":"boolean"}}},"ActorsCreateActorPortRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ActorsPortProtocol"},"internal_port":{"type":"integer"},"routing":{"$ref":"#/components/schemas/ActorsPortRouting"}},"required":["protocol"]},"ActorsCreateActorResponse":{"type":"object","properties":{"actor":{"$ref":"#/components/schemas/ActorsActor","description":"The actor that was created"}},"required":["actor"]},"ActorsDestroyActorResponse":{"type":"object","properties":{}},"ActorsUpgradeActorRequest":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"build_tags":{}}},"ActorsUpgradeActorResponse":{"type":"object","properties":{}},"ActorsUpgradeAllActorsRequest":{"type":"object","properties":{"tags":{},"build":{"type":"string","format":"uuid"},"build_tags":{}},"required":["tags"]},"ActorsUpgradeAllActorsResponse":{"type":"object","properties":{"count":{"type":"integer","format":"int64"}},"required":["count"]},"ActorsListActorsResponse":{"type":"object","properties":{"actors":{"type":"array","items":{"$ref":"#/components/schemas/ActorsActor"},"description":"A list of actors for the project associated with the token."},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["actors","pagination"]},"BuildsGetBuildResponse":{"type":"object","properties":{"build":{"$ref":"#/components/schemas/BuildsBuild"}},"required":["build"]},"BuildsListBuildsResponse":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/BuildsBuild"},"description":"A list of builds for the project associated with the token."}},"required":["builds"]},"BuildsPatchBuildTagsRequest":{"type":"object","properties":{"tags":{},"exclusive_tags":{"type":"array","items":{"type":"string"},"description":"**Deprecated**\nRemoves the given tag keys from all other builds."}},"required":["tags"]},"BuildsPatchBuildTagsResponse":{"type":"object","properties":{}},"BuildsPrepareBuildRequest":{"type":"object","properties":{"image_tag":{"type":"string","description":"A tag given to the project build."},"image_file":{"$ref":"#/components/schemas/UploadPrepareFile"},"kind":{"$ref":"#/components/schemas/BuildsBuildKind"},"compression":{"$ref":"#/components/schemas/BuildsBuildCompression"}},"required":["image_file"]},"BuildsPrepareBuildResponse":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["build","presigned_requests"]},"BuildsBuildKind":{"type":"string","enum":["docker_image","oci_bundle","javascript"]},"BuildsBuildCompression":{"type":"string","enum":["none","lz4"]},"CloudBootstrapResponse":{"type":"object","properties":{"cluster":{"$ref":"#/components/schemas/CloudBootstrapCluster"},"access":{"$ref":"#/components/schemas/CloudBootstrapAccess"},"domains":{"$ref":"#/components/schemas/CloudBootstrapDomains"},"origins":{"$ref":"#/components/schemas/CloudBootstrapOrigins"},"captcha":{"$ref":"#/components/schemas/CloudBootstrapCaptcha"},"login_methods":{"$ref":"#/components/schemas/CloudBootstrapLoginMethods"},"deploy_hash":{"type":"string"}},"required":["cluster","access","domains","origins","captcha","login_methods","deploy_hash"]},"CloudBootstrapCluster":{"type":"string","enum":["enterprise","oss"],"description":"The type of cluster that the backend is currently running."},"CloudBootstrapAccess":{"type":"string","enum":["public","private","development"]},"CloudBootstrapDomains":{"type":"object","description":"Domains that host parts of Rivet","properties":{"cdn":{"type":"string"},"job":{"type":"string"},"main":{"type":"string"},"opengb":{"type":"string"}}},"CloudBootstrapOrigins":{"type":"object","description":"Origins used to build URLs from","properties":{"hub":{"type":"string"}},"required":["hub"]},"CloudBootstrapCaptcha":{"type":"object","properties":{"turnstile":{"$ref":"#/components/schemas/CloudBootstrapCaptchaTurnstile"}}},"CloudBootstrapCaptchaTurnstile":{"type":"object","properties":{"site_key":{"type":"string"}},"required":["site_key"]},"CloudBootstrapLoginMethods":{"type":"object","properties":{"email":{"type":"boolean"},"access_token":{"type":"boolean"}},"required":["email"]},"CloudGamesGetGamesResponse":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/GameGameSummary"},"description":"A list of game summaries."},"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"},"description":"A list of group summaries."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["games","groups","watch"]},"CloudGamesCreateGameRequest":{"type":"object","properties":{"name_id":{"$ref":"#/components/schemas/Identifier","description":"**Deprecated**"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"developer_group_id":{"type":"string","format":"uuid"}},"required":["display_name","developer_group_id"]},"CloudGamesCreateGameResponse":{"type":"object","properties":{"game_id":{"type":"string","format":"uuid"}},"required":["game_id"]},"CloudGamesValidateGameRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"name_id":{"$ref":"#/components/schemas/Identifier","description":"**Deprecated**"}},"required":["display_name"]},"CloudGamesValidateGameResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesGetGameByIdResponse":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/CloudGameFull"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["game","watch"]},"CloudGamesGameBannerUploadPrepareRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the game banner."},"mime":{"type":"string","description":"The MIME type of the game banner."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"CloudGamesGameBannerUploadPrepareResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"CloudGamesGameLogoUploadPrepareRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the game logo."},"mime":{"type":"string","description":"The MIME type of the game logo."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"CloudGamesGameLogoUploadPrepareResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"CloudGamesNamespacesInspectResponse":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/CloudAuthAgent"}},"required":["agent"]},"CloudGamesNamespacesCreateGameNamespaceRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"version_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."}},"required":["display_name","version_id","name_id"]},"CloudGamesNamespacesCreateGameNamespaceResponse":{"type":"object","properties":{"namespace_id":{"type":"string","format":"uuid"}},"required":["namespace_id"]},"CloudGamesNamespacesValidateGameNamespaceRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."}},"required":["display_name","name_id"]},"CloudGamesNamespacesValidateGameNamespaceResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesNamespacesGetGameNamespaceByIdResponse":{"type":"object","properties":{"namespace":{"$ref":"#/components/schemas/CloudNamespaceFull"}},"required":["namespace"]},"CloudGamesNamespacesUpdateNamespaceCdnAuthUserRequest":{"type":"object","properties":{"user":{"type":"string","description":"A user name."},"password":{"type":"string","description":"A bcrypt encrypted password. An error is returned if the given string is not properly encrypted."}},"required":["user","password"]},"CloudGamesNamespacesSetNamespaceCdnAuthTypeRequest":{"type":"object","properties":{"auth_type":{"$ref":"#/components/schemas/CloudCdnAuthType"}},"required":["auth_type"]},"CloudGamesNamespacesToggleNamespaceDomainPublicAuthRequest":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether or not to enable authentication based on domain."}},"required":["enabled"]},"CloudGamesNamespacesAddNamespaceDomainRequest":{"type":"object","properties":{"domain":{"type":"string","description":"A valid domain name (no protocol)."}},"required":["domain"]},"CloudGamesNamespacesUpdateGameNamespaceMatchmakerConfigRequest":{"type":"object","properties":{"lobby_count_max":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_count_max","max_players"]},"CloudGamesNamespacesGetGameNamespaceVersionHistoryResponse":{"type":"object","properties":{"versions":{"type":"array","items":{"$ref":"#/components/schemas/CloudNamespaceVersion"},"description":"A list of previously deployed namespace versions."}},"required":["versions"]},"CloudGamesNamespacesValidateGameNamespaceMatchmakerConfigRequest":{"type":"object","properties":{"lobby_count_max":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_count_max","max_players"]},"CloudGamesNamespacesValidateGameNamespaceMatchmakerConfigResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesNamespacesCreateGameNamespaceTokenDevelopmentRequest":{"type":"object","properties":{"hostname":{"type":"string","description":"The hostname used for the token."},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudMatchmakerDevelopmentPort"}},"lobby_ports":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerPort"},"description":"**Deprecated**\nA list of docker ports."}},"required":["hostname"]},"CloudGamesNamespacesCreateGameNamespaceTokenDevelopmentResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."}},"required":["token"]},"CloudGamesNamespacesValidateGameNamespaceTokenDevelopmentRequest":{"type":"object","properties":{"hostname":{"type":"string"},"lobby_ports":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerPort"},"description":"A list of docker ports."}},"required":["hostname","lobby_ports"]},"CloudGamesNamespacesValidateGameNamespaceTokenDevelopmentResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesNamespacesCreateGameNamespaceTokenPublicResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."}},"required":["token"]},"CloudGamesNamespacesUpdateGameNamespaceVersionRequest":{"type":"object","properties":{"version_id":{"type":"string","format":"uuid"}},"required":["version_id"]},"CloudVersionConfig":{"type":"object","description":"Cloud configuration for a given version.","properties":{"scripts":{"type":"object","additionalProperties":{"type":"string"}},"engine":{"$ref":"#/components/schemas/CloudVersionEngineEngineConfig"},"cdn":{"$ref":"#/components/schemas/CloudVersionCdnCdnConfig"},"matchmaker":{"$ref":"#/components/schemas/CloudVersionMatchmakerMatchmakerConfig"},"kv":{"$ref":"#/components/schemas/CloudVersionKvKvConfig"},"identity":{"$ref":"#/components/schemas/CloudVersionIdentityIdentityConfig"}}},"CloudVersionFull":{"type":"object","description":"A full version.","properties":{"version_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"config":{"$ref":"#/components/schemas/CloudVersionConfig"}},"required":["version_id","create_ts","display_name","config"]},"CloudVersionSummary":{"type":"object","description":"A version summary.","properties":{"version_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["version_id","create_ts","display_name"]},"CloudVersionCdnCdnConfig":{"type":"object","description":"CDN configuration for a given version.","properties":{"build_command":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"build_output":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"build_env":{"type":"object","additionalProperties":{"type":"string"},"description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"site_id":{"type":"string","format":"uuid"},"routes":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionCdnRoute"},"description":"Multiple CDN version routes."}}},"CloudVersionCdnRoute":{"type":"object","properties":{"glob":{"type":"string"},"priority":{"type":"integer","description":"Unsigned 32 bit integer."},"middlewares":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionCdnMiddleware"},"description":"Multiple CDN version middleware."}},"required":["glob","priority","middlewares"]},"CloudVersionCdnMiddleware":{"type":"object","properties":{"kind":{"$ref":"#/components/schemas/CloudVersionCdnMiddlewareKind"}},"required":["kind"]},"CloudVersionCdnMiddlewareKind":{"type":"object","properties":{"custom_headers":{"$ref":"#/components/schemas/CloudVersionCdnCustomHeadersMiddleware"}}},"CloudVersionCdnCustomHeadersMiddleware":{"type":"object","properties":{"headers":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionCdnHeader"}}},"required":["headers"]},"CloudVersionCdnHeader":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"CloudVersionEngineEngineConfig":{"type":"object","properties":{"unity":{"$ref":"#/components/schemas/CloudVersionEngineUnityConfig"},"unreal":{"$ref":"#/components/schemas/CloudVersionEngineUnrealConfig"},"godot":{"$ref":"#/components/schemas/CloudVersionEngineGodotConfig"},"html5":{"$ref":"#/components/schemas/CloudVersionEngineHtml5Config"},"custom":{"$ref":"#/components/schemas/CloudVersionEngineCustomConfig"}}},"CloudVersionIdentityIdentityConfig":{"type":"object","description":"**Deprecated**\nIdentity configuration for a given version.","properties":{"display_names":{"type":"array","items":{"type":"string"},"description":"**Deprecated**"},"avatars":{"type":"array","items":{"type":"string","format":"uuid"},"description":"**Deprecated**"},"custom_display_names":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionIdentityCustomDisplayName"},"description":"**Deprecated**"},"custom_avatars":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionIdentityCustomAvatar"},"description":"**Deprecated**"}}},"CloudVersionIdentityCustomDisplayName":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"CloudVersionIdentityCustomAvatar":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"}},"required":["upload_id"]},"CloudVersionKvKvConfig":{"type":"object","description":"KV configuration for a given version.","properties":{}},"CloudVersionMatchmakerMatchmakerConfig":{"type":"object","description":"Matchmaker configuration for a given version.","properties":{"game_modes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameMode"},"description":"A list of game modes."},"captcha":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptcha"},"dev_hostname":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"regions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRegion"}},"max_players":{"type":"integer"},"max_players_direct":{"type":"integer"},"max_players_party":{"type":"integer"},"docker":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker"},"tier":{"type":"string"},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig"},"lobby_groups":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroup"},"description":"**Deprecated: use `game_modes` instead**\nA list of game modes."}}},"CoreIntercomPegboardMarkClientRegisteredRequest":{"type":"object","properties":{"server_id":{"type":"string","format":"uuid"}},"required":["server_id"]},"EdgeIntercomPegboardPrewarmImageRequest":{"type":"object","properties":{}},"EdgeIntercomPegboardToggleClientDrainRequest":{"type":"object","properties":{"draining":{"type":"boolean"},"drain_complete_ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["draining"]},"GroupListSuggestedResponse":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"},"description":"A list of group summaries."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["groups","watch"]},"GroupCreateRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"GroupCreateResponse":{"type":"object","properties":{"group_id":{"type":"string","format":"uuid"}},"required":["group_id"]},"GroupPrepareAvatarUploadRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the group avatar."},"mime":{"type":"string","description":"The MIME type of the group avatar."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"GroupPrepareAvatarUploadResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"GroupValidateProfileRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"bio":{"$ref":"#/components/schemas/DisplayName"},"publicity":{"$ref":"#/components/schemas/GroupPublicity"}}},"GroupValidateProfileResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"GroupGetBansResponse":{"type":"object","properties":{"banned_identities":{"type":"array","items":{"$ref":"#/components/schemas/GroupBannedIdentity"},"description":"A list of banned group members."},"anchor":{"type":"string","description":"The pagination anchor."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["banned_identities","watch"]},"GroupGetJoinRequestsResponse":{"type":"object","properties":{"join_requests":{"type":"array","items":{"$ref":"#/components/schemas/GroupJoinRequest"},"description":"A list of group join requests."},"anchor":{"type":"string","description":"The pagination anchor."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["join_requests","watch"]},"GroupGetMembersResponse":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"},"description":"A list of group members."},"anchor":{"type":"string","description":"The pagination anchor."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["members","watch"]},"GroupGetProfileResponse":{"type":"object","properties":{"group":{"$ref":"#/components/schemas/GroupProfile"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["group","watch"]},"GroupUpdateProfileRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"bio":{"type":"string","description":"Detailed information about a profile."},"publicity":{"$ref":"#/components/schemas/GroupPublicity"}}},"GroupGetSummaryResponse":{"type":"object","properties":{"group":{"$ref":"#/components/schemas/GroupGroupSummary"}},"required":["group"]},"GroupTransferOwnershipRequest":{"type":"object","properties":{"new_owner_identity_id":{"type":"string","description":"Identity to transfer the group to.\nMust be a member of the group."}},"required":["new_owner_identity_id"]},"IdentitySetupResponse":{"type":"object","properties":{"identity_token":{"$ref":"#/components/schemas/Jwt","description":"Token used to authenticate the identity.\nShould be stored somewhere permanent.\nPass this to `rivet.api.identity#Setup$existing_identity_token` next time `rivet.api.identity#Setup` is called.\nToken has a 90 day TTL.\nThis means that if `rivet.api.identity#Setup` is not called again within 90 days, the token will no longer be valid.\nIf this happens, the user can recover their account through the linking process (see `rivet.api.identity#PrepareGameLink`).\nThis token should be stored locally and never sent to a server or another device.\nIf this token is compromised, anyone with access to this token has control of the identity."},"identity_token_expire_ts":{"$ref":"#/components/schemas/Timestamp"},"identity":{"$ref":"#/components/schemas/IdentityProfile","description":"Information about the identity that was just authenticated."},"game_id":{"type":"string","format":"uuid"}},"required":["identity_token","identity_token_expire_ts","identity","game_id"]},"IdentityGetProfileResponse":{"type":"object","properties":{"identity":{"$ref":"#/components/schemas/IdentityProfile"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identity","watch"]},"IdentityGetHandlesResponse":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/IdentityHandle"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identities","watch"]},"IdentityGetSummariesResponse":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/IdentitySummary"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identities","watch"]},"IdentityValidateProfileResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"}}},"required":["errors"]},"IdentityPrepareAvatarUploadResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"ProvisionDatacentersGetTlsResponse":{"type":"object","properties":{"job_cert_pem":{"type":"string"},"job_private_key_pem":{"type":"string"},"api_cert_pem":{"type":"string"},"api_private_key_pem":{"type":"string"}},"required":["job_cert_pem","job_private_key_pem","api_cert_pem","api_private_key_pem"]},"ProvisionDatacentersGetServersResponse":{"type":"object","properties":{"servers":{"type":"array","items":{"$ref":"#/components/schemas/ProvisionServer"}}},"required":["servers"]},"ProvisionServersGetInfoResponse":{"type":"object","properties":{"name":{"type":"string"},"server_id":{"type":"string","format":"uuid"},"datacenter_id":{"type":"string","format":"uuid"},"datacenter_name_id":{"type":"string"},"cluster_id":{"type":"string","format":"uuid"},"lan_ip":{"type":"string"},"wan_ip":{"type":"string"},"vlan_ip":{"type":"string","description":"**Deprecated**: Use lan_ip"},"public_ip":{"type":"string","description":"**Deprecated**: Use wan_ip"}},"required":["name","server_id","datacenter_id","datacenter_name_id","cluster_id","lan_ip","wan_ip","vlan_ip","public_ip"]},"ProvisionTunnelGetTlsResponse":{"type":"object","properties":{"cert_pem":{"type":"string"},"root_ca_cert_pem":{"type":"string"},"private_key_pem":{"type":"string"}},"required":["cert_pem","root_ca_cert_pem","private_key_pem"]},"RegionsListRegionsResponse":{"type":"object","properties":{"regions":{"type":"array","items":{"$ref":"#/components/schemas/RegionsRegion"}}},"required":["regions"]},"RegionsRecommendRegionResponse":{"type":"object","properties":{"region":{"$ref":"#/components/schemas/RegionsRegion"}},"required":["region"]},"RoutesListRoutesResponse":{"type":"object","properties":{"routes":{"type":"array","items":{"$ref":"#/components/schemas/RoutesRoute"}}},"required":["routes"]},"RoutesUpdateRouteBody":{"type":"object","properties":{"hostname":{"type":"string"},"path":{"type":"string"},"strip_prefix":{"type":"boolean","description":"Whether to remove the path prefix before sending the request to the actor."},"route_subpaths":{"type":"boolean","description":"Whether to route all subpaths of this path"},"target":{"$ref":"#/components/schemas/RoutesRouteTarget"}},"required":["hostname","path","strip_prefix","route_subpaths","target"]},"RoutesUpdateRouteResponse":{"type":"object","properties":{}},"RoutesDeleteRouteResponse":{"type":"object","properties":{}},"ServersGetServerResponse":{"type":"object","properties":{"server":{"$ref":"#/components/schemas/ServersServer"}},"required":["server"]},"ServersCreateServerRequest":{"type":"object","properties":{"datacenter":{"type":"string","format":"uuid"},"tags":{},"runtime":{"$ref":"#/components/schemas/ServersCreateServerRuntimeRequest"},"network":{"$ref":"#/components/schemas/ServersCreateServerNetworkRequest"},"resources":{"$ref":"#/components/schemas/ServersResources"},"lifecycle":{"$ref":"#/components/schemas/ServersLifecycle"}},"required":["datacenter","tags","runtime","network","resources"]},"ServersCreateServerRuntimeRequest":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"arguments":{"type":"array","items":{"type":"string"}},"environment":{"type":"object","additionalProperties":{"type":"string"}}},"required":["build"]},"ServersCreateServerNetworkRequest":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ServersNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ServersCreateServerPortRequest"}}},"required":["ports"]},"ServersCreateServerPortRequest":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ServersPortProtocol"},"internal_port":{"type":"integer"},"routing":{"$ref":"#/components/schemas/ServersPortRouting"}},"required":["protocol"]},"ServersCreateServerResponse":{"type":"object","properties":{"server":{"$ref":"#/components/schemas/ServersServer","description":"The server that was created"}},"required":["server"]},"ServersDestroyServerResponse":{"type":"object","properties":{}},"ServersListServersResponse":{"type":"object","properties":{"servers":{"type":"array","items":{"$ref":"#/components/schemas/ServersServer"},"description":"A list of servers for the game associated with the token."}},"required":["servers"]},"ActorsActor":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"region":{"type":"string"},"tags":{},"runtime":{"$ref":"#/components/schemas/ActorsRuntime"},"network":{"$ref":"#/components/schemas/ActorsNetwork"},"resources":{"$ref":"#/components/schemas/ActorsResources"},"lifecycle":{"$ref":"#/components/schemas/ActorsLifecycle"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"started_at":{"$ref":"#/components/schemas/Timestamp"},"destroyed_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","region","tags","runtime","network","resources","lifecycle","created_at"]},"ActorsRuntime":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"arguments":{"type":"array","items":{"type":"string"}},"environment":{"type":"object","additionalProperties":{"type":"string"}}},"required":["build"]},"ActorsLifecycle":{"type":"object","properties":{"kill_timeout":{"type":"integer","format":"int64","description":"The duration to wait for in milliseconds before killing the actor. This should be set to a safe default, and can be overridden during a DELETE request if needed."},"durable":{"type":"boolean","description":"If true, the actor will try to reschedule itself automatically in the event of a crash or a datacenter failover. The actor will not reschedule if it exits successfully."}}},"ActorsResources":{"type":"object","properties":{"cpu":{"type":"integer","description":"The number of CPU cores in millicores, or 1/1000 of a core. For example,\n1/8 of a core would be 125 millicores, and 1 core would be 1000\nmillicores."},"memory":{"type":"integer","description":"The amount of memory in megabytes"}},"required":["cpu","memory"]},"ActorsNetwork":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ActorsNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ActorsPort"}}},"required":["mode","ports"]},"ActorsNetworkMode":{"type":"string","enum":["bridge","host"]},"ActorsPort":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ActorsPortProtocol"},"internal_port":{"type":"integer"},"hostname":{"type":"string"},"port":{"type":"integer"},"path":{"type":"string"},"url":{"type":"string","description":"Fully formed connection URL including protocol, hostname, port, and path, if applicable."},"routing":{"$ref":"#/components/schemas/ActorsPortRouting"}},"required":["protocol","routing"]},"ActorsPortProtocol":{"type":"string","enum":["http","https","tcp","tcp_tls","udp"]},"ActorsPortRouting":{"type":"object","properties":{"guard":{"$ref":"#/components/schemas/ActorsGuardRouting"},"host":{"$ref":"#/components/schemas/ActorsHostRouting"}}},"ActorsGuardRouting":{"type":"object","properties":{}},"ActorsHostRouting":{"type":"object","properties":{}},"ActorsEndpointType":{"type":"string","enum":["hostname","path"]},"ActorsGetActorLogsResponse":{"type":"object","properties":{"actor_ids":{"type":"array","items":{"type":"string"},"description":"List of actor IDs in these logs. The order of these correspond to the index in the log entry."},"lines":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"timestamps":{"type":"array","items":{"$ref":"#/components/schemas/Timestamp"},"description":"Sorted old to new."},"streams":{"type":"array","items":{"type":"integer"},"description":"Streams the logs came from.\n\n0 = stdout\n1 = stderr"},"actor_indices":{"type":"array","items":{"type":"integer"},"description":"Index of the actor that this log was for. Use this index to look the full ID in `actor_ids`."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["actor_ids","lines","timestamps","streams","actor_indices","watch"]},"ActorsQueryLogStream":{"type":"string","enum":["std_out","std_err","all"]},"ActorsGetActorMetricsResponse":{"type":"object","properties":{"actor_ids":{"type":"array","items":{"type":"string"}},"metric_names":{"type":"array","items":{"type":"string"}},"metric_attributes":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},"metric_types":{"type":"array","items":{"type":"string"}},"metric_values":{"type":"array","items":{"type":"array","items":{"type":"number","format":"double"}}}},"required":["actor_ids","metric_names","metric_attributes","metric_types","metric_values"]},"AuthCompleteStatus":{"type":"string","enum":["switch_identity","linked_account_added","already_complete","expired","too_many_attempts","incorrect"],"description":"Represents the state of an external account linking process."},"AuthIdentityStartEmailVerificationRequest":{"type":"object","properties":{"email":{"type":"string"},"captcha":{"$ref":"#/components/schemas/CaptchaConfig"},"game_id":{"type":"string","format":"uuid"}},"required":["email"]},"AuthIdentityStartEmailVerificationResponse":{"type":"object","properties":{"verification_id":{"type":"string","format":"uuid"}},"required":["verification_id"]},"AuthIdentityCompleteEmailVerificationRequest":{"type":"object","properties":{"verification_id":{"type":"string","format":"uuid"},"code":{"type":"string","description":"The code sent to the requestee's email."}},"required":["verification_id","code"]},"AuthIdentityCompleteEmailVerificationResponse":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AuthCompleteStatus"}},"required":["status"]},"AuthRefreshIdentityTokenRequest":{"type":"object","properties":{"logout":{"type":"boolean","description":"When `true`, the current identity for the provided cookie will be logged out and a new identity will be returned."}}},"AuthRefreshIdentityTokenResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."},"exp":{"type":"string","description":"Token expiration time (in milliseconds)."},"identity_id":{"type":"string","format":"uuid"}},"required":["token","exp","identity_id"]},"BuildsBuild":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of this build"}},"required":["id","name","created_at","content_length","tags"]},"CaptchaConfig":{"type":"object","description":"Methods to verify a captcha","properties":{"hcaptcha":{"$ref":"#/components/schemas/CaptchaConfigHcaptcha"},"turnstile":{"$ref":"#/components/schemas/CaptchaConfigTurnstile"}}},"CaptchaConfigHcaptcha":{"type":"object","description":"Captcha configuration.","properties":{"client_response":{"type":"string"}},"required":["client_response"]},"CaptchaConfigTurnstile":{"type":"object","description":"Captcha configuration.","properties":{"client_response":{"type":"string"}},"required":["client_response"]},"CloudInspectResponse":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/CloudAuthAgent"}},"required":["agent"]},"CloudSvcPerf":{"type":"object","description":"A service performance summary.","properties":{"svc_name":{"type":"string","description":"The name of the service."},"ts":{"$ref":"#/components/schemas/Timestamp"},"duration":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"req_id":{"type":"string","format":"uuid"},"spans":{"type":"array","items":{"$ref":"#/components/schemas/CloudLogsPerfSpan"},"description":"A list of performance spans."},"marks":{"type":"array","items":{"$ref":"#/components/schemas/CloudLogsPerfMark"},"description":"A list of performance marks."}},"required":["svc_name","ts","duration","spans","marks"]},"CloudLogsPerfSpan":{"type":"object","description":"A performance span.","properties":{"label":{"type":"string","description":"The label given to this performance span."},"start_ts":{"$ref":"#/components/schemas/Timestamp"},"finish_ts":{"$ref":"#/components/schemas/Timestamp"},"req_id":{"type":"string","format":"uuid"}},"required":["label","start_ts"]},"CloudLogsPerfMark":{"type":"object","description":"A performance mark.","properties":{"label":{"type":"string","description":"The label given to this performance mark."},"ts":{"$ref":"#/components/schemas/Timestamp"},"ray_id":{"type":"string","format":"uuid"},"req_id":{"type":"string","format":"uuid"}},"required":["label","ts"]},"CloudLobbySummaryAnalytics":{"type":"object","description":"Analytical information about a lobby.","properties":{"lobby_id":{"type":"string","format":"uuid"},"lobby_group_id":{"type":"string","format":"uuid"},"lobby_group_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"region_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"is_ready":{"type":"boolean","description":"Whether or not this lobby is ready."},"is_idle":{"type":"boolean","description":"Whether or not this lobby is idle."},"is_closed":{"type":"boolean","description":"Whether or not this lobby is in a closed state."},"is_outdated":{"type":"boolean","description":"Whether or not this lobby is outdated."},"max_players_normal":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_direct":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_party":{"type":"integer","description":"Unsigned 32 bit integer."},"total_player_count":{"type":"integer","description":"Unsigned 32 bit integer."},"registered_player_count":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_id","lobby_group_id","lobby_group_name_id","region_id","create_ts","is_ready","is_idle","is_closed","is_outdated","max_players_normal","max_players_direct","max_players_party","total_player_count","registered_player_count"]},"CloudLogsLobbySummary":{"type":"object","description":"A logs summary for a lobby.","properties":{"lobby_id":{"type":"string","format":"uuid"},"namespace_id":{"type":"string","format":"uuid"},"lobby_group_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"region_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"start_ts":{"$ref":"#/components/schemas/Timestamp"},"ready_ts":{"$ref":"#/components/schemas/Timestamp"},"status":{"$ref":"#/components/schemas/CloudLogsLobbyStatus"}},"required":["lobby_id","namespace_id","lobby_group_name_id","region_id","create_ts","status"]},"CloudLogsLobbyStatus":{"type":"object","description":"A union representing the state of a lobby.","properties":{"running":{"$ref":"#/components/schemas/EmptyObject"},"stopped":{"$ref":"#/components/schemas/CloudLogsLobbyStatusStopped"}},"required":["running"]},"CloudLogsLobbyStatusStopped":{"type":"object","description":"The status of a stopped lobby.","properties":{"stop_ts":{"$ref":"#/components/schemas/Timestamp"},"failed":{"type":"boolean","description":"Whether or not the lobby failed or stopped successfully."},"exit_code":{"type":"integer","description":"The exit code returned by the lobby's main process when stopped."}},"required":["stop_ts","failed","exit_code"]},"CloudSvcMetrics":{"type":"object","description":"Metrics relating to a job service.","properties":{"job":{"type":"string","description":"The job name."},"cpu":{"type":"array","items":{"type":"number","format":"double"},"description":"CPU metrics."},"memory":{"type":"array","items":{"type":"number","format":"double"},"description":"Memory metrics."},"allocated_memory":{"type":"number","format":"double","description":"Total allocated memory (MB)."}},"required":["job","cpu","memory"]},"CloudAuthAgent":{"type":"object","description":"The current authenticated agent.","properties":{"identity":{"$ref":"#/components/schemas/CloudAuthAgentIdentity"},"game_cloud":{"$ref":"#/components/schemas/CloudAuthAgentGameCloud"}}},"CloudAuthAgentIdentity":{"type":"object","description":"The current authenticated identity.","properties":{"identity_id":{"type":"string","format":"uuid"}},"required":["identity_id"]},"CloudAuthAgentGameCloud":{"type":"object","description":"The current authenticated game cloud.","properties":{"game_id":{"type":"string","format":"uuid"}},"required":["game_id"]},"CloudCustomAvatarSummary":{"type":"object","description":"A custom avatar summary.","properties":{"upload_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"url":{"type":"string","description":"The URL of this custom avatar image. Only present if upload is complete."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"complete":{"type":"boolean","description":"Whether or not this custom avatar has completely been uploaded."}},"required":["upload_id","display_name","create_ts","content_length","complete"]},"CloudBuildSummary":{"type":"object","description":"A build summary.","properties":{"build_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"complete":{"type":"boolean","description":"Whether or not this build has completely been uploaded."},"tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of this build"}},"required":["build_id","upload_id","display_name","create_ts","content_length","complete","tags"]},"CloudCdnSiteSummary":{"type":"object","description":"A CDN site summary.","properties":{"site_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"complete":{"type":"boolean","description":"Whether or not this site has completely been uploaded."}},"required":["site_id","upload_id","display_name","create_ts","content_length","complete"]},"CloudGameFull":{"type":"object","description":"A full game.","properties":{"game_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"display_name":{"$ref":"#/components/schemas/DisplayName"},"developer_group_id":{"type":"string","format":"uuid"},"total_player_count":{"type":"integer","description":"Unsigned 32 bit integer."},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."},"namespaces":{"type":"array","items":{"$ref":"#/components/schemas/CloudNamespaceSummary"},"description":"A list of namespace summaries."},"versions":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionSummary"},"description":"A list of version summaries."},"available_regions":{"type":"array","items":{"$ref":"#/components/schemas/CloudRegionSummary"},"description":"A list of region summaries."}},"required":["game_id","create_ts","name_id","display_name","developer_group_id","total_player_count","namespaces","versions","available_regions"]},"CloudNamespaceSummary":{"type":"object","description":"A namespace summary.","properties":{"namespace_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"version_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."}},"required":["namespace_id","create_ts","display_name","version_id","name_id"]},"CloudRegionSummary":{"type":"object","description":"A region summary.","properties":{"region_id":{"type":"string","format":"uuid"},"region_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"provider":{"type":"string","description":"The server provider of this region."},"universal_region":{"$ref":"#/components/schemas/CloudUniversalRegion","description":"**Deprecated**\nA universal region label given to this region."},"provider_display_name":{"$ref":"#/components/schemas/DisplayName"},"region_display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["region_id","region_name_id","provider","universal_region","provider_display_name","region_display_name"]},"CloudGameLobbyExpenses":{"type":"object","description":"Game lobby expenses.","properties":{"game":{"$ref":"#/components/schemas/GameHandle"},"namespaces":{"type":"array","items":{"$ref":"#/components/schemas/CloudNamespaceSummary"},"description":"A list of namespace summaries."},"expenses":{"type":"array","items":{"$ref":"#/components/schemas/CloudRegionTierExpenses"},"description":"A list of multiple region tier expenses."}},"required":["game","namespaces","expenses"]},"CloudRegionTierExpenses":{"type":"object","description":"Region tier expenses.","properties":{"namespace_id":{"type":"string","format":"uuid"},"region_id":{"type":"string","format":"uuid"},"tier_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"lobby_group_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"uptime":{"type":"number","format":"double","description":"How long a region tier has been active (in milliseconds)."},"expenses":{"type":"number","format":"double","description":"Amount of expenses for this region tier (in hundred-thousandths USD, 100,000 = $1.00)."}},"required":["namespace_id","region_id","tier_name_id","lobby_group_name_id","uptime","expenses"]},"CloudGroupBankSource":{"type":"object","properties":{"account_number":{"type":"string","description":"The bank account number of this group's bank source."},"routing_number":{"type":"string","description":"The bank routing number of this group's bank source."}},"required":["account_number","routing_number"]},"CloudRegionTier":{"type":"object","description":"A region server tier.","properties":{"tier_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"rivet_cores_numerator":{"type":"integer","description":"Together with the denominator, denotes the portion of the CPU a given server uses."},"rivet_cores_denominator":{"type":"integer","description":"Together with the numerator, denotes the portion of the CPU a given server uses."},"cpu":{"type":"integer","description":"CPU frequency (MHz)."},"memory":{"type":"integer","description":"Allocated memory (MB)."},"disk":{"type":"integer","description":"Allocated disk space (MB)."},"bandwidth":{"type":"integer","description":"Internet bandwidth (MB)."},"price_per_second":{"type":"integer","description":"**Deprecated**\nPrice billed for every second this server is running (in quadrillionth USD, 1,000,000,000,000 = $1.00)."}},"required":["tier_name_id","rivet_cores_numerator","rivet_cores_denominator","cpu","memory","disk","bandwidth","price_per_second"]},"CloudUniversalRegion":{"type":"string","enum":["unknown","local","amsterdam","atlanta","bangalore","dallas","frankfurt","london","mumbai","newark","new_york_city","san_francisco","singapore","sydney","tokyo","toronto","washington_dc","chicago","paris","seattle","sao_paulo","stockholm","chennai","osaka","milan","miami","jakarta","los_angeles"],"description":"**Deprecated**"},"CloudNamespaceFull":{"type":"object","description":"A full namespace.","properties":{"namespace_id":{"type":"string","format":"uuid"},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"version_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"config":{"$ref":"#/components/schemas/CloudNamespaceConfig"}},"required":["namespace_id","create_ts","display_name","version_id","name_id","config"]},"CloudNamespaceConfig":{"type":"object","description":"Cloud configuration for a given namespace.","properties":{"cdn":{"$ref":"#/components/schemas/CloudCdnNamespaceConfig"},"matchmaker":{"$ref":"#/components/schemas/CloudMatchmakerNamespaceConfig"},"kv":{"$ref":"#/components/schemas/CloudKvNamespaceConfig"},"identity":{"$ref":"#/components/schemas/CloudIdentityNamespaceConfig"}},"required":["cdn","matchmaker","kv","identity"]},"CloudCdnNamespaceConfig":{"type":"object","description":"CDN configuration for a given namespace.","properties":{"enable_domain_public_auth":{"type":"boolean","description":"Whether or not to allow users to connect to the given namespace via domain name."},"domains":{"type":"array","items":{"$ref":"#/components/schemas/CloudCdnNamespaceDomain"},"description":"A list of CDN domains for a given namespace."},"auth_type":{"$ref":"#/components/schemas/CloudCdnAuthType"},"auth_user_list":{"type":"array","items":{"$ref":"#/components/schemas/CloudCdnNamespaceAuthUser"},"description":"A list of CDN authenticated users for a given namespace."}},"required":["enable_domain_public_auth","domains","auth_type","auth_user_list"]},"CloudMatchmakerNamespaceConfig":{"type":"object","description":"Matchmaker configuration for a given namespace.","properties":{"lobby_count_max":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_vpn":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_proxy":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_tor":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_per_client_hosting":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["lobby_count_max","max_players_per_client","max_players_per_client_vpn","max_players_per_client_proxy","max_players_per_client_tor","max_players_per_client_hosting"]},"CloudKvNamespaceConfig":{"type":"object","description":"KV configuration for a given namespace.","properties":{}},"CloudIdentityNamespaceConfig":{"type":"object","description":"Identity configuration for a given namespace.","properties":{}},"CloudCdnAuthType":{"type":"string","enum":["none","basic"],"description":"A value denoting what type of authentication to use for a game namespace's CDN."},"CloudCdnNamespaceDomain":{"type":"object","description":"A CDN domain for a given namespace.","properties":{"domain":{"type":"string","description":"A valid domain name (no protocol)."},"create_ts":{"$ref":"#/components/schemas/Timestamp"},"verification_status":{"$ref":"#/components/schemas/CloudCdnNamespaceDomainVerificationStatus"},"verification_method":{"$ref":"#/components/schemas/CloudCdnNamespaceDomainVerificationMethod"},"verification_errors":{"type":"array","items":{"type":"string"}}},"required":["domain","create_ts","verification_status","verification_method","verification_errors"]},"CloudCdnNamespaceDomainVerificationMethod":{"type":"object","description":"A union representing the verification method used for this CDN domain.","properties":{"invalid":{"$ref":"#/components/schemas/EmptyObject"},"http":{"$ref":"#/components/schemas/CloudCdnNamespaceDomainVerificationMethodHttp"}}},"CloudCdnNamespaceDomainVerificationMethodHttp":{"type":"object","properties":{"cname_record":{"type":"string"}},"required":["cname_record"]},"CloudCdnNamespaceDomainVerificationStatus":{"type":"string","enum":["active","pending","failed"],"description":"A value denoting the status of a CDN domain's verification status."},"CloudCdnNamespaceAuthUser":{"type":"object","description":"An authenticated CDN user for a given namespace.","properties":{"user":{"type":"string","description":"A user name."}},"required":["user"]},"CloudMatchmakerDevelopmentPort":{"type":"object","description":"A port configuration used to create development tokens.","properties":{"port":{"type":"integer"},"port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange"},"protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol"}},"required":["protocol"]},"CloudNamespaceVersion":{"type":"object","description":"A previously deployed namespace version.","properties":{"namespace_id":{"type":"string","description":"A universally unique identifier."},"version_id":{"type":"string","description":"A universally unique identifier."},"deploy_ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["namespace_id","version_id","deploy_ts"]},"CloudDevicesPrepareDeviceLinkResponse":{"type":"object","properties":{"device_link_id":{"type":"string","format":"uuid"},"device_link_token":{"type":"string"},"device_link_url":{"type":"string"}},"required":["device_link_id","device_link_token","device_link_url"]},"CloudDevicesGetDeviceLinkResponse":{"type":"object","properties":{"cloud_token":{"type":"string"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["watch"]},"CloudDevicesCompleteDeviceLinkRequest":{"type":"object","properties":{"device_link_token":{"$ref":"#/components/schemas/Jwt"},"game_id":{"type":"string","format":"uuid"}},"required":["device_link_token","game_id"]},"CloudGamesListGameCustomAvatarsResponse":{"type":"object","properties":{"custom_avatars":{"type":"array","items":{"$ref":"#/components/schemas/CloudCustomAvatarSummary"},"description":"A list of custom avatar summaries."}},"required":["custom_avatars"]},"CloudGamesPrepareCustomAvatarUploadRequest":{"type":"object","properties":{"path":{"type":"string","description":"The path/filename of the custom avatar."},"mime":{"type":"string","description":"The MIME type of the custom avatar."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]},"CloudGamesPrepareCustomAvatarUploadResponse":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid"},"presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"}},"required":["upload_id","presigned_request"]},"CloudGamesListGameBuildsResponse":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/CloudBuildSummary"},"description":"A list of build summaries."}},"required":["builds"]},"CloudGamesCreateGameBuildRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"image_tag":{"type":"string","description":"A tag given to the game build."},"image_file":{"$ref":"#/components/schemas/UploadPrepareFile"},"multipart_upload":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/CloudGamesBuildKind"},"compression":{"$ref":"#/components/schemas/CloudGamesBuildCompression"}},"required":["display_name","image_tag","image_file"]},"CloudGamesCreateGameBuildResponse":{"type":"object","properties":{"build_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"image_presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"},"image_presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["build_id","upload_id"]},"CloudGamesBuildKind":{"type":"string","enum":["docker_image","oci_bundle"]},"CloudGamesBuildCompression":{"type":"string","enum":["none","lz4"]},"CloudGamesListGameCdnSitesResponse":{"type":"object","properties":{"sites":{"type":"array","items":{"$ref":"#/components/schemas/CloudCdnSiteSummary"},"description":"A list of CDN site summaries."}},"required":["sites"]},"CloudGamesCreateGameCdnSiteRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"files":{"type":"array","items":{"$ref":"#/components/schemas/UploadPrepareFile"},"description":"A list of files preparing to upload."}},"required":["display_name","files"]},"CloudGamesCreateGameCdnSiteResponse":{"type":"object","properties":{"site_id":{"type":"string","format":"uuid"},"upload_id":{"type":"string","format":"uuid"},"presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["site_id","upload_id","presigned_requests"]},"CloudGamesExportMatchmakerLobbyHistoryRequest":{"type":"object","properties":{"query_start":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"query_end":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["query_start","query_end"]},"CloudGamesExportMatchmakerLobbyHistoryResponse":{"type":"object","properties":{"url":{"type":"string","description":"The URL to a CSV file for the given lobby history."}},"required":["url"]},"CloudGamesDeleteMatchmakerLobbyResponse":{"type":"object","properties":{"did_remove":{"type":"boolean","description":"Whether or not the lobby was successfully stopped."}},"required":["did_remove"]},"CloudGamesGetLobbyLogsResponse":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"timestamps":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["lines","timestamps","watch"]},"CloudGamesExportLobbyLogsRequest":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/CloudGamesLogStream"}},"required":["stream"]},"CloudGamesExportLobbyLogsResponse":{"type":"object","properties":{"url":{"type":"string","description":"The URL to a CSV file for the given lobby history."}},"required":["url"]},"CloudGamesLogStream":{"type":"string","enum":["std_out","std_err"]},"CloudGamesNamespacesGetAnalyticsMatchmakerLiveResponse":{"type":"object","properties":{"lobbies":{"type":"array","items":{"$ref":"#/components/schemas/CloudLobbySummaryAnalytics"},"description":"A list of analytics lobby summaries."}},"required":["lobbies"]},"CloudGamesNamespacesListNamespaceLobbiesResponse":{"type":"object","properties":{"lobbies":{"type":"array","items":{"$ref":"#/components/schemas/CloudLogsLobbySummary"},"description":"A list of lobby log summaries."}},"required":["lobbies"]},"CloudGamesNamespacesGetNamespaceLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/CloudLogsLobbySummary"},"metrics":{"$ref":"#/components/schemas/CloudSvcMetrics"},"stdout_presigned_urls":{"type":"array","items":{"type":"string"},"description":"**Deprecated**\nA list of URLs."},"stderr_presigned_urls":{"type":"array","items":{"type":"string"},"description":"**Deprecated**\nA list of URLs."},"perf_lists":{"type":"array","items":{"$ref":"#/components/schemas/CloudSvcPerf"},"description":"**Deprecated**\nA list of service performance summaries."}},"required":["lobby","stdout_presigned_urls","stderr_presigned_urls","perf_lists"]},"CloudGamesCreateCloudTokenResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token.\nSlightly modified to include a description prefix and use Protobufs of\nJSON."}},"required":["token"]},"CloudGamesCreateGameVersionRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"config":{"$ref":"#/components/schemas/CloudVersionConfig"}},"required":["display_name","config"]},"CloudGamesCreateGameVersionResponse":{"type":"object","properties":{"version_id":{"type":"string","format":"uuid"}},"required":["version_id"]},"CloudGamesReserveVersionNameResponse":{"type":"object","properties":{"version_display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["version_display_name"]},"CloudGamesValidateGameVersionRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"config":{"$ref":"#/components/schemas/CloudVersionConfig"}},"required":["display_name","config"]},"CloudGamesValidateGameVersionResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGamesGetGameVersionByIdResponse":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/CloudVersionFull"}},"required":["version"]},"CloudValidateGroupRequest":{"type":"object","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"CloudValidateGroupResponse":{"type":"object","properties":{"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"A list of validation errors."}},"required":["errors"]},"CloudGetRayPerfLogsResponse":{"type":"object","properties":{"perf_lists":{"type":"array","items":{"$ref":"#/components/schemas/CloudSvcPerf"},"description":"A list of service performance summaries."}},"required":["perf_lists"]},"CloudGetRegionTiersResponse":{"type":"object","properties":{"tiers":{"type":"array","items":{"$ref":"#/components/schemas/CloudRegionTier"},"description":"A list of region server tiers."}},"required":["tiers"]},"CloudVersionEngineCustomConfig":{"type":"object","properties":{}},"CloudVersionEngineGodotConfig":{"type":"object","properties":{}},"CloudVersionEngineHtml5Config":{"type":"object","properties":{}},"CloudVersionEngineUnityConfig":{"type":"object","properties":{}},"CloudVersionEngineUnrealConfig":{"type":"object","properties":{"game_module":{"type":"string","description":"Name of the Unreal module that holds the game code.\nThis is usually the value of `$.Modules[0].Name` in the file `MyProject.unproject`.\n_Configures Rivet CLI behavior. Has no effect on server behavior._"}},"required":["game_module"]},"CloudVersionMatchmakerPortRange":{"type":"object","description":"Range of ports that can be connected to.\nIf configured, `network_mode` must equal `host`.\nPort ranges may overlap between containers, it is the responsibility of the developer to ensure ports are available before using.\nRead more about host networking [here](https://rivet.gg/docs/dynamic-servers/concepts/host-bridge-networking).\nOnly available on Rivet Open Source & Enterprise.\n\n### Related\n\n- cloud.version.matchmaker.PortProtocol\n- cloud.version.matchmaker.ProxyKind","properties":{"min":{"type":"integer","description":"Unsigned 32 bit integer."},"max":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["min","max"]},"CloudVersionMatchmakerPortProtocol":{"type":"string","enum":["http","https","tcp","tcp_tls","udp"],"description":"Signifies the protocol of the port.\nNote that when proxying through GameGuard (via `ProxyKind`), the port number returned by `/find`, `/join`, and `/create` will not be the same as the port number configured in the config:\n\n- With HTTP, the port will always be 80. The hostname of the port correctly routes the incoming\n connection to the correct port being used by the game server.\n- With HTTPS, the port will always be 443. The hostname of the port correctly routes the incoming\n connection to the correct port being used by the game server.\n- Using TCP/UDP, the port will be a random number between 26000 and 31999. This gets automatically\n routed to the correct port being used by the game server.\n\n### Related - cloud.version.matchmaker.GameModeRuntimeDockerPort - cloud.version.matchmaker.ProxyKind - /docs/dynamic-servers/concepts/game-guard - matchmaker.lobbies.find"},"CloudVersionMatchmakerProxyKind":{"type":"string","enum":["none","game_guard"],"description":"Range of ports that can be connected to.\n`game_guard` (default) proxies all traffic through [Game Guard](https://rivet.gg/docs/dynamic-servers/concepts/game-guard) to mitigate DDoS attacks and provide TLS termination.\n`none` sends traffic directly to the game server. If configured, `network_mode` must equal `host`. Read more about host networking [here](https://rivet.gg/docs/dynamic-servers/concepts/host-bridge-networking). Only available on Rivet Open Source & Enterprise.\n\n### Related - /docs/dynamic-servers/concepts/game-guard - cloud.version.matchmaker.PortProtocol"},"CloudVersionMatchmakerCaptcha":{"type":"object","description":"Matchmaker captcha configuration.","properties":{"requests_before_reverify":{"type":"integer","description":"Denotes how many requests a connection can make before it is required to reverify a captcha."},"verification_ttl":{"type":"integer","format":"int64","description":"Denotes how long a connection can continue to reconnect without having to reverify a captcha (in milliseconds)."},"hcaptcha":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptchaHcaptcha"},"turnstile":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptchaTurnstile"}},"required":["requests_before_reverify","verification_ttl"]},"CloudVersionMatchmakerCaptchaHcaptcha":{"type":"object","description":"hCpatcha configuration.","properties":{"level":{"$ref":"#/components/schemas/CloudVersionMatchmakerCaptchaHcaptchaLevel","description":"**Deprecated**"},"site_key":{"type":"string","description":"Site key for your hCaptcha application. Must be set."},"secret_key":{"type":"string","description":"Secret key for your hCaptcha application. Must be set."}}},"CloudVersionMatchmakerCaptchaHcaptchaLevel":{"type":"string","enum":["easy","moderate","difficult","always_on"],"description":"**Deprecated**\nHow hard a captcha should be."},"CloudVersionMatchmakerCaptchaTurnstile":{"type":"object","description":"Turnstile captcha configuration.","properties":{"site_key":{"type":"string"},"secret_key":{"type":"string"}},"required":["site_key","secret_key"]},"CloudVersionMatchmakerNetworkMode":{"type":"string","enum":["bridge","host"],"description":"Configures how the container's network is isolated from the host.\n`bridge` (default) networking isolates the container's network from the host & other containers.\n`host` networking removes isolation between the container and the host. Only available in Rivet Open Source & Enterprise.\nRead more about bridge vs host networking [here](https://rivet.gg/docs/dynamic-servers/concepts/host-bridge-networking)."},"CloudVersionMatchmakerGameMode":{"type":"object","description":"A game mode.","properties":{"regions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRegion"}},"max_players":{"type":"integer"},"max_players_direct":{"type":"integer"},"max_players_party":{"type":"integer"},"docker":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDocker"},"listable":{"type":"boolean"},"taggable":{"type":"boolean"},"allow_dynamic_max_players":{"type":"boolean"},"actions":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeActions"},"tier":{"type":"string"},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig"}}},"CloudVersionMatchmakerGameModeRegion":{"type":"object","description":"A game mode region.","properties":{"tier":{"type":"string"},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdleLobbiesConfig"}}},"CloudVersionMatchmakerGameModeRuntimeDocker":{"type":"object","description":"A game mode runtime running through Docker.","properties":{"dockerfile":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"build_args":{"type":"object","additionalProperties":{"type":"string"},"description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"image":{"type":"string","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"image_id":{"type":"string","format":"uuid"},"args":{"type":"array","items":{"type":"string"}},"env":{"type":"object","additionalProperties":{"type":"string"}},"network_mode":{"$ref":"#/components/schemas/CloudVersionMatchmakerNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeRuntimeDockerPort"}}}},"CloudVersionMatchmakerGameModeRuntimeDockerPort":{"type":"object","description":"Port config for a docker build.","properties":{"port":{"type":"integer","description":"The port number to connect to.\n\n### Related - cloud.version.matchmaker.PortProtocol - cloud.version.matchmaker.ProxyKind"},"port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange"},"protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol"},"proxy":{"$ref":"#/components/schemas/CloudVersionMatchmakerProxyKind","description":"How this port should be proxied. Defaults to 'game-guard`."},"dev_port":{"type":"integer","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"dev_port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"},"dev_protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol","description":"_Configures Rivet CLI behavior. Has no effect on server behavior._"}}},"CloudVersionMatchmakerGameModeIdleLobbiesConfig":{"type":"object","description":"Configuration for how many idle lobbies a game version should have.","properties":{"min":{"type":"integer"},"max":{"type":"integer"}},"required":["min","max"]},"CloudVersionMatchmakerGameModeActions":{"type":"object","description":"Configuration for the connection types allowed for a game mode.","properties":{"find":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeFindConfig"},"join":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeJoinConfig"},"create":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeCreateConfig"}}},"CloudVersionMatchmakerGameModeIdentityRequirement":{"type":"string","enum":["none","guest","registered"],"description":"**Deprecated**\nThe registration requirement for a user when joining/finding/creating a lobby. \"None\" allows for connections without an identity."},"CloudVersionMatchmakerGameModeVerificationConfig":{"type":"object","description":"Configuration that tells Rivet where to send validation requests and with what headers. When set, Rivet will send the `verification_data` property (given by the user in the find/join/create endpoint) to the given url along with the headers provided and some information about the requested lobby. The response of this request will determine if the user can join that lobby or not.","properties":{"url":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}}},"required":["url","headers"]},"CloudVersionMatchmakerGameModeFindConfig":{"type":"object","description":"Configures the requirements and authentication for the /find endpoint. If this value is not set in the config, the /find endpoint is still enabled.","properties":{"enabled":{"type":"boolean","description":"Sets whether or not the /find endpoint is enabled."},"identity_requirement":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement"},"verification":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig"}},"required":["enabled"]},"CloudVersionMatchmakerGameModeJoinConfig":{"type":"object","description":"Configures the requirements and authentication for the /join endpoint. If this value is not set in the config, the /join endpoint is still enabled.","properties":{"enabled":{"type":"boolean","description":"Sets whether or not the /join endpoint is enabled."},"identity_requirement":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement"},"verification":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig"}},"required":["enabled"]},"CloudVersionMatchmakerGameModeCreateConfig":{"type":"object","description":"Configures the requirements and authentication for the /create endpoint. If this value is not set in the config, the /create endpoint is NOT enabled.","properties":{"enabled":{"type":"boolean","description":"Sets whether or not the /create endpoint is enabled."},"identity_requirement":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeIdentityRequirement"},"verification":{"$ref":"#/components/schemas/CloudVersionMatchmakerGameModeVerificationConfig"},"enable_public":{"type":"boolean","description":"Defaults to false when unset."},"enable_private":{"type":"boolean","description":"Defaults to true when unset."},"max_lobbies_per_identity":{"type":"integer","description":"**Deprecated**"}},"required":["enabled"]},"CloudVersionMatchmakerLobbyGroup":{"type":"object","description":"A game mode.","properties":{"name_id":{"type":"string","description":"**Deprecated: use GameMode instead**\nA human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"regions":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRegion"},"description":"A list of game mode regions."},"max_players_normal":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_direct":{"type":"integer","description":"Unsigned 32 bit integer."},"max_players_party":{"type":"integer","description":"Unsigned 32 bit integer."},"runtime":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntime"}},"required":["name_id","regions","max_players_normal","max_players_direct","max_players_party","runtime"]},"CloudVersionMatchmakerLobbyGroupRuntime":{"type":"object","description":"**Deprecated: use GameMode instead**\nA union representing the runtime a game mode runs on.","properties":{"docker":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDocker"}}},"CloudVersionMatchmakerLobbyGroupRegion":{"type":"object","description":"**Deprecated: use GameMode instead**\nA game mode region.","properties":{"region_id":{"type":"string","format":"uuid"},"tier_name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"idle_lobbies":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig"}},"required":["region_id","tier_name_id"]},"CloudVersionMatchmakerLobbyGroupRuntimeDocker":{"type":"object","description":"**Deprecated: use GameMode instead**\nA game mode runtime running through Docker.","properties":{"build_id":{"type":"string","format":"uuid"},"args":{"type":"array","items":{"type":"string"}},"env_vars":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerEnvVar"}},"network_mode":{"$ref":"#/components/schemas/CloudVersionMatchmakerNetworkMode"},"ports":{"type":"array","items":{"$ref":"#/components/schemas/CloudVersionMatchmakerLobbyGroupRuntimeDockerPort"}}},"required":["args","env_vars","ports"]},"CloudVersionMatchmakerLobbyGroupRuntimeDockerEnvVar":{"type":"object","description":"**Deprecated: use GameMode instead**\nA docker environment variable.","properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"]},"CloudVersionMatchmakerLobbyGroupRuntimeDockerPort":{"type":"object","description":"**Deprecated: use GameMode instead**\nA docker port.","properties":{"label":{"type":"string","description":"The label of this docker port."},"target_port":{"type":"integer","description":"The port number to connect to."},"port_range":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortRange"},"proxy_protocol":{"$ref":"#/components/schemas/CloudVersionMatchmakerPortProtocol"}},"required":["label","proxy_protocol"]},"CloudVersionMatchmakerLobbyGroupIdleLobbiesConfig":{"type":"object","description":"**Deprecated: use GameMode instead**\nConfiguration for how many idle lobbies a game version should have.","properties":{"min_idle_lobbies":{"type":"integer","description":"Unsigned 32 bit integer."},"max_idle_lobbies":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["min_idle_lobbies","max_idle_lobbies"]},"Identifier":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `uuid` because this is intended to be human readable. Different than `DisplayName` because this should not include special characters and be short."},"Bio":{"type":"string","description":"Follows regex ^(?:[^\\n\\r]+\\n?|\\n){1,5}$"},"Email":{"type":"string","description":"A valid email address"},"Jwt":{"type":"string","description":"Documentation at https://jwt.io/"},"WatchQuery":{"type":"string","description":"A query parameter denoting the requests watch index."},"WatchResponse":{"type":"object","description":"Provided by watchable endpoints used in blocking loops.","properties":{"index":{"type":"string","description":"Index indicating the version of the data responded.\nPass this to `WatchQuery` to block and wait for the next response."}},"required":["index"]},"DisplayName":{"type":"string","description":"Represent a resource's readable display name."},"AccountNumber":{"type":"integer"},"Timestamp":{"type":"string","format":"date-time","description":"RFC3339 timestamp"},"GlobalEventNotification":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"thumbnail_url":{"type":"string"},"url":{"type":"string"}},"required":["title","description","thumbnail_url","url"]},"ValidationError":{"type":"object","description":"An error given by failed content validation.","properties":{"path":{"type":"array","items":{"type":"string"},"description":"A list of strings denoting the origin of a validation error."}},"required":["path"]},"EmptyObject":{"type":"object","properties":{}},"ErrorMetadata":{"description":"Unstructured metadata relating to an error. Must be manually parsed."},"ErrorBody":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"ray_id":{"type":"string"},"documentation":{"type":"string"},"metadata":{"$ref":"#/components/schemas/ErrorMetadata"}},"required":["code","message","ray_id"]},"Pagination":{"type":"object","properties":{"cursor":{"type":"string"}}},"GameHandle":{"type":"object","properties":{"game_id":{"type":"string","format":"uuid"},"name_id":{"$ref":"#/components/schemas/Identifier"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."}},"required":["game_id","name_id","display_name"]},"GameGameSummary":{"type":"object","properties":{"game_id":{"type":"string","format":"uuid"},"name_id":{"$ref":"#/components/schemas/Identifier"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."},"url":{"type":"string"},"developer":{"$ref":"#/components/schemas/GroupHandle"},"total_player_count":{"type":"integer","description":"Unsigned 32 bit integer."}},"required":["game_id","name_id","display_name","url","developer","total_player_count"]},"GameProfile":{"type":"object","description":"A game profile.","properties":{"game_id":{"type":"string","format":"uuid"},"name_id":{"type":"string","description":"A human readable short identifier used to references resources. Different than a `rivet.common#Uuid` because this is intended to be human readable. Different than `rivet.common#DisplayName` because this should not include special characters and be short."},"display_name":{"$ref":"#/components/schemas/DisplayName"},"logo_url":{"type":"string","description":"The URL of this game's logo image."},"banner_url":{"type":"string","description":"The URL of this game's banner image."},"url":{"type":"string","description":"The URL to this game's website."},"developer":{"$ref":"#/components/schemas/GroupGroupSummary"},"tags":{"type":"array","items":{"type":"string"},"description":"A list of game tags."},"description":{"type":"string","description":"A description of the given game."},"platforms":{"type":"array","items":{"$ref":"#/components/schemas/GamePlatformLink"},"description":"A list of platform links."},"recommended_groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"},"description":"A list of group summaries."},"identity_leaderboard_categories":{"type":"array","items":{"$ref":"#/components/schemas/GameLeaderboardCategory"},"description":"A list of game leaderboard categories."},"group_leaderboard_categories":{"type":"array","items":{"$ref":"#/components/schemas/GameLeaderboardCategory"},"description":"A list of game leaderboard categories."}},"required":["game_id","name_id","display_name","url","developer","tags","description","platforms","recommended_groups","identity_leaderboard_categories","group_leaderboard_categories"]},"GamePlatformLink":{"type":"object","description":"A platform link denoting a supported platform.","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"url":{"type":"string","description":"The URL to the given game's method of distribution on this platform."}},"required":["display_name","url"]},"GameLeaderboardCategory":{"type":"object","description":"A game leaderboard category.","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["display_name"]},"GameStatSummary":{"type":"object","description":"A game statistic summary.","properties":{"game":{"$ref":"#/components/schemas/GameHandle"},"stats":{"type":"array","items":{"$ref":"#/components/schemas/GameStat"}}},"required":["game","stats"]},"GameStat":{"type":"object","description":"A game statistic.","properties":{"config":{"$ref":"#/components/schemas/GameStatConfig"},"overall_value":{"type":"number","format":"double","description":"A single overall value of the given statistic."}},"required":["config","overall_value"]},"GameStatConfig":{"type":"object","description":"A game statistic config.","properties":{"record_id":{"type":"string","format":"uuid"},"icon_id":{"type":"string","format":"uuid"},"format":{"$ref":"#/components/schemas/GameStatFormatMethod"},"aggregation":{"$ref":"#/components/schemas/GameStatAggregationMethod"},"sorting":{"$ref":"#/components/schemas/GameStatSortingMethod"},"priority":{"type":"integer"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"postfix_singular":{"type":"string","description":"A string appended to the end of a singular game statistic's value. Example: 1 **dollar**."},"postfix_plural":{"type":"string","description":"A string appended to the end of a game statistic's value that is not exactly 1. Example: 45 **dollars**."},"prefix_singular":{"type":"string","description":"A string appended to the beginning of a singular game statistic's value. Example: **value** 1."},"prefix_plural":{"type":"string","description":"A string prepended to the beginning of a game statistic's value that is not exactly 1. Example: **values** 45."}},"required":["record_id","icon_id","format","aggregation","sorting","priority","display_name"]},"GameStatFormatMethod":{"type":"string","enum":["integer","float_1","float_2","float_3","duration_minute","duration_second","duration_hundredth_second"],"description":"A value denoting the format method of a game statistic."},"GameStatAggregationMethod":{"type":"string","enum":["sum","average","min","max"],"description":"A value denoting the aggregation method of a game statistic."},"GameStatSortingMethod":{"type":"string","enum":["desc","asc"],"description":"A value denoting the sorting method of a game statistic."},"GamesEnvironmentsCreateServiceTokenResponse":{"type":"object","properties":{"token":{"type":"string","description":"A JSON Web Token."}},"required":["token"]},"GeoCoord":{"type":"object","description":"Geographical coordinates for a location on Planet Earth.","properties":{"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"}},"required":["latitude","longitude"]},"GeoDistance":{"type":"object","description":"Distance available in multiple units.","properties":{"kilometers":{"type":"number","format":"double"},"miles":{"type":"number","format":"double"}},"required":["kilometers","miles"]},"GroupGroupSummary":{"type":"object","properties":{"group_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"avatar_url":{"type":"string","description":"The URL of this group's avatar image."},"external":{"$ref":"#/components/schemas/GroupExternalLinks"},"is_developer":{"type":"boolean","description":"**Deprecated**\nWhether or not this group is a developer."},"bio":{"$ref":"#/components/schemas/Bio"},"is_current_identity_member":{"type":"boolean","description":"Whether or not the current identity is a member of this group."},"publicity":{"$ref":"#/components/schemas/GroupPublicity"},"member_count":{"type":"integer"},"owner_identity_id":{"type":"string","format":"uuid"}},"required":["group_id","display_name","external","is_developer","bio","is_current_identity_member","publicity","member_count","owner_identity_id"]},"GroupPublicity":{"type":"string","enum":["open","closed"],"description":"The current publicity value for the given group."},"GroupHandle":{"type":"object","description":"A group handle.","properties":{"group_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"avatar_url":{"type":"string","description":"The URL of this group's avatar image"},"external":{"$ref":"#/components/schemas/GroupExternalLinks"},"is_developer":{"type":"boolean","description":"Whether or not this group is a developer group."}},"required":["group_id","display_name","external"]},"GroupExternalLinks":{"type":"object","description":"External links for this group.","properties":{"profile":{"type":"string","description":"A link to this group's profile page."}},"required":["profile"]},"GroupJoinRequest":{"type":"object","description":"A group join request.","properties":{"identity":{"$ref":"#/components/schemas/IdentityHandle"},"ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["identity","ts"]},"GroupMember":{"type":"object","description":"A group member.","properties":{"identity":{"$ref":"#/components/schemas/IdentityHandle"}},"required":["identity"]},"GroupProfile":{"type":"object","description":"A list of group profiles.","properties":{"group_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"avatar_url":{"type":"string","description":"The URL of this group's avatar image."},"external":{"$ref":"#/components/schemas/GroupExternalLinks"},"is_developer":{"type":"boolean","description":"Whether or not this group is a developer."},"bio":{"type":"string","description":"Detailed information about a profile."},"is_current_identity_member":{"type":"boolean","description":"Whether or not the current identity is a member of this group."},"publicity":{"$ref":"#/components/schemas/GroupPublicity"},"member_count":{"type":"integer","description":"Unsigned 32 bit integer."},"members":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"},"description":"A list of group members."},"join_requests":{"type":"array","items":{"$ref":"#/components/schemas/GroupJoinRequest"},"description":"A list of group join requests."},"is_current_identity_requesting_join":{"type":"boolean","description":"Whether or not the current identity is currently requesting to join this group."},"owner_identity_id":{"type":"string","format":"uuid"}},"required":["group_id","display_name","external","bio","publicity","members","join_requests","owner_identity_id"]},"GroupBannedIdentity":{"type":"object","description":"A banned identity.","properties":{"identity":{"$ref":"#/components/schemas/IdentityHandle"},"ban_ts":{"$ref":"#/components/schemas/Timestamp"}},"required":["identity","ban_ts"]},"GroupGetInviteResponse":{"type":"object","properties":{"group":{"$ref":"#/components/schemas/GroupHandle"}},"required":["group"]},"GroupConsumeInviteResponse":{"type":"object","properties":{"group_id":{"type":"string","format":"uuid"}}},"GroupCreateInviteRequest":{"type":"object","properties":{"ttl":{"type":"number","format":"double","description":"How long until the group invite expires (in milliseconds)."},"use_count":{"type":"number","format":"double","description":"How many times the group invite can be used."}}},"GroupCreateInviteResponse":{"type":"object","properties":{"code":{"type":"string","description":"The code that will be passed to `rivet.api.group#ConsumeInvite` to join a group."}},"required":["code"]},"GroupResolveJoinRequestRequest":{"type":"object","properties":{"resolution":{"type":"boolean"}}},"IdentityListActivitiesResponse":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/IdentityHandle"}},"games":{"type":"array","items":{"$ref":"#/components/schemas/GameGameSummary"}},"suggested_groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupGroupSummary"}},"suggested_players":{"type":"array","items":{"$ref":"#/components/schemas/IdentityHandle"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["identities","games","suggested_groups","suggested_players","watch"]},"IdentityGlobalEvent":{"type":"object","description":"An event relevant to the current identity.","properties":{"ts":{"$ref":"#/components/schemas/Timestamp"},"kind":{"$ref":"#/components/schemas/IdentityGlobalEventKind"},"notification":{"$ref":"#/components/schemas/IdentityGlobalEventNotification"}},"required":["ts","kind"]},"IdentityGlobalEventKind":{"type":"object","properties":{"identity_update":{"$ref":"#/components/schemas/IdentityGlobalEventIdentityUpdate"}}},"IdentityGlobalEventNotification":{"type":"object","description":"Notifications represent information that should be presented to the user\nimmediately.\nAt the moment, only chat message events have associated notifications.\n\n# Display\n\nNotifications should be displayed in an unobtrusive manner throughout the\nentire game. Notifications should disappear after a few seconds if not\ninteracted with.\n\n# Interactions\n\nIf your platform supports it, notifications should be able to be clicked or\ntapped in order to open the relevant context for the event.\nFor a simple implementation of notification interactions, open `url` in a\nweb browser to present the relevant context. For example, a chat message\nnotification will open the thread the chat message was sent in.\nFor advanced implementations that implement a custom chat UI, use\n`GlobalEvent.kind` to determine what action to take when the notification is interacted with.\nFor example, if the global event kind is `GlobalEventChatMessage`, then open\nthe chat UI for the given thread.","properties":{"title":{"type":"string"},"description":{"type":"string"},"thumbnail_url":{"type":"string","description":"URL to an image thumbnail that should be shown for this notification."},"url":{"type":"string","description":"Rivet Hub URL that holds the relevant context for this notification."}},"required":["title","description","thumbnail_url","url"]},"IdentityGlobalEventIdentityUpdate":{"type":"object","properties":{"identity":{"$ref":"#/components/schemas/IdentityProfile"}},"required":["identity"]},"IdentityUpdateGameActivity":{"type":"object","description":"Information about the identity's current game. This is information that all other identities can see about what the current identity is doing.","properties":{"message":{"type":"string","description":"A short message about the current game activity."},"public_metadata":{"description":"JSON data seen by anyone."},"mutual_metadata":{"description":"JSON data seen only by the given identity and their mutual followers."}}},"IdentityHandle":{"type":"object","description":"An identity handle.","properties":{"identity_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"account_number":{"$ref":"#/components/schemas/AccountNumber"},"avatar_url":{"type":"string","description":"The URL of this identity's avatar image."},"is_registered":{"type":"boolean","description":"Whether or not this identity is registered with a linked account."},"external":{"$ref":"#/components/schemas/IdentityExternalLinks"}},"required":["identity_id","display_name","account_number","avatar_url","is_registered","external"]},"IdentitySummary":{"type":"object","description":"An identity summary.","properties":{"identity_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"account_number":{"$ref":"#/components/schemas/AccountNumber"},"avatar_url":{"type":"string","description":"The URL of this identity's avatar image."},"is_registered":{"type":"boolean","description":"Whether or not this identity is registered with a linked account."},"external":{"$ref":"#/components/schemas/IdentityExternalLinks"},"following":{"type":"boolean","description":"Whether or not the requestee's identity is following this identity."},"is_following_me":{"type":"boolean","description":"Whether or not this identity is both following and is followed by the requestee's identity."},"is_mutual_following":{"type":"boolean"}},"required":["identity_id","display_name","account_number","avatar_url","is_registered","external","following","is_following_me","is_mutual_following"]},"IdentityProfile":{"type":"object","description":"An identity profile.","properties":{"identity_id":{"type":"string","format":"uuid"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"account_number":{"$ref":"#/components/schemas/AccountNumber"},"avatar_url":{"type":"string","description":"The URL of this identity's avatar image."},"is_registered":{"type":"boolean","description":"Whether or not this identity is registered with a linked account."},"external":{"$ref":"#/components/schemas/IdentityExternalLinks"},"is_admin":{"type":"boolean","description":"Whether or not this identity is an admin."},"is_game_linked":{"type":"boolean","description":"Whether or not this game user has been linked through the Rivet dashboard."},"dev_state":{"$ref":"#/components/schemas/IdentityDevState","description":"**Deprecated**"},"follower_count":{"type":"integer","format":"int64"},"following_count":{"type":"integer","format":"int64"},"following":{"type":"boolean","description":"Whether or not the requestee's identity is following this identity."},"is_following_me":{"type":"boolean","description":"Whether or not this identity is both following and is followed by the requestee's identity."},"is_mutual_following":{"type":"boolean"},"join_ts":{"$ref":"#/components/schemas/Timestamp"},"bio":{"$ref":"#/components/schemas/Bio"},"linked_accounts":{"type":"array","items":{"$ref":"#/components/schemas/IdentityLinkedAccount"}},"groups":{"type":"array","items":{"$ref":"#/components/schemas/IdentityGroup"}},"games":{"type":"array","items":{"$ref":"#/components/schemas/GameStatSummary"}},"awaiting_deletion":{"type":"boolean","description":"Whether or not this identity is awaiting account deletion. Only visible to when the requestee is\nthis identity."}},"required":["identity_id","display_name","account_number","avatar_url","is_registered","external","is_admin","follower_count","following_count","following","is_following_me","is_mutual_following","join_ts","bio","linked_accounts","groups","games"]},"IdentityExternalLinks":{"type":"object","description":"External links for an identity.","properties":{"profile":{"type":"string","description":"A link to this identity's profile page."},"settings":{"type":"string","description":"A link to the Rivet settings page."}},"required":["profile"]},"IdentityStatus":{"type":"string","enum":["online","away","offline"],"description":"The current status of an identity. This helps players understand if another player is currently playing or has their game in the background."},"IdentityGameActivity":{"type":"object","description":"The game an identity is currently participating in.","properties":{"game":{"$ref":"#/components/schemas/GameHandle"},"message":{"type":"string","description":"A short activity message about the current game activity."},"public_metadata":{"description":"JSON data seen by anyone."},"mutual_metadata":{"description":"JSON data seen only by the given identity and their mutual followers."}},"required":["game","message"]},"IdentityGroup":{"type":"object","description":"A group that the given identity.","properties":{"group":{"$ref":"#/components/schemas/GroupHandle"}},"required":["group"]},"IdentityLinkedAccount":{"type":"object","description":"A union representing an identity's linked accounts.","properties":{"email":{"$ref":"#/components/schemas/IdentityEmailLinkedAccount"},"default_user":{"type":"boolean"}}},"IdentityEmailLinkedAccount":{"type":"object","description":"An identity's linked email.","properties":{"email":{"$ref":"#/components/schemas/Email"}},"required":["email"]},"IdentityDevState":{"type":"string","enum":["inactive","pending","accepted"],"description":"The state of the given identity's developer status."},"IdentityGameLinkStatus":{"type":"string","enum":["incomplete","complete","cancelled"]},"IdentityWatchEventsResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/IdentityGlobalEvent"}},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["events","watch"]},"MatchmakerLobbyInfo":{"type":"object","description":"A public lobby in the lobby list.","properties":{"region_id":{"type":"string"},"game_mode_id":{"type":"string"},"lobby_id":{"type":"string","format":"uuid"},"max_players_normal":{"type":"integer"},"max_players_direct":{"type":"integer"},"max_players_party":{"type":"integer"},"total_player_count":{"type":"integer"},"state":{}},"required":["region_id","game_mode_id","lobby_id","max_players_normal","max_players_direct","max_players_party","total_player_count"]},"MatchmakerGameModeInfo":{"type":"object","description":"A game mode that the player can join.","properties":{"game_mode_id":{"$ref":"#/components/schemas/Identifier"}},"required":["game_mode_id"]},"MatchmakerRegionInfo":{"type":"object","description":"A region that the player can connect to.","properties":{"region_id":{"$ref":"#/components/schemas/Identifier"},"provider_display_name":{"$ref":"#/components/schemas/DisplayName"},"region_display_name":{"$ref":"#/components/schemas/DisplayName"},"datacenter_coord":{"$ref":"#/components/schemas/GeoCoord"},"datacenter_distance_from_client":{"$ref":"#/components/schemas/GeoDistance"}},"required":["region_id","provider_display_name","region_display_name","datacenter_coord","datacenter_distance_from_client"]},"MatchmakerJoinLobby":{"type":"object","description":"A matchmaker lobby.","properties":{"lobby_id":{"type":"string","format":"uuid"},"region":{"$ref":"#/components/schemas/MatchmakerJoinRegion"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"},"description":"**Deprecated**"},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer","description":"**Deprecated**"}},"required":["lobby_id","region","ports","player"]},"MatchmakerJoinRegion":{"type":"object","description":"A matchmaker lobby region.","properties":{"region_id":{"$ref":"#/components/schemas/Identifier"},"display_name":{"$ref":"#/components/schemas/DisplayName"}},"required":["region_id","display_name"]},"MatchmakerJoinPort":{"type":"object","properties":{"host":{"type":"string","description":"The host for the given port. Will be null if using a port range."},"hostname":{"type":"string"},"port":{"type":"integer","description":"The port number for this lobby. Will be null if using a port range."},"port_range":{"$ref":"#/components/schemas/MatchmakerJoinPortRange"},"is_tls":{"type":"boolean","description":"Whether or not this lobby port uses TLS. You cannot mix a non-TLS and TLS ports."}},"required":["hostname","is_tls"]},"MatchmakerJoinPortRange":{"type":"object","description":"Inclusive range of ports that can be connected to.","properties":{"min":{"type":"integer","description":"Minimum port that can be connected to. Inclusive range."},"max":{"type":"integer","description":"Maximum port that can be connected to. Inclusive range."}},"required":["min","max"]},"MatchmakerJoinPlayer":{"type":"object","description":"A matchmaker lobby player.","properties":{"token":{"$ref":"#/components/schemas/Jwt","description":"Pass this token through the socket to the lobby server. The lobby server will validate this token with `PlayerConnected.player_token`"}},"required":["token"]},"MatchmakerCustomLobbyPublicity":{"type":"string","enum":["public","private"]},"MatchmakerFindLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/MatchmakerJoinLobby"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"}},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer"}},"required":["lobby","ports","player"]},"MatchmakerJoinLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/MatchmakerJoinLobby"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"}},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer"}},"required":["lobby","ports","player"]},"MatchmakerCreateLobbyResponse":{"type":"object","properties":{"lobby":{"$ref":"#/components/schemas/MatchmakerJoinLobby"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerJoinPort"}},"player":{"$ref":"#/components/schemas/MatchmakerJoinPlayer"}},"required":["lobby","ports","player"]},"MatchmakerListLobbiesResponse":{"type":"object","properties":{"game_modes":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerGameModeInfo"}},"regions":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerRegionInfo"}},"lobbies":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerLobbyInfo"}}},"required":["game_modes","regions","lobbies"]},"MatchmakerGetStatisticsResponse":{"type":"object","properties":{"player_count":{"type":"integer","format":"int64"},"game_modes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerGameModeStatistics"}}},"required":["player_count","game_modes"]},"MatchmakerGameModeStatistics":{"type":"object","properties":{"player_count":{"type":"integer","format":"int64"},"regions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MatchmakerRegionStatistics"}}},"required":["player_count","regions"]},"MatchmakerRegionStatistics":{"type":"object","properties":{"player_count":{"type":"integer","format":"int64"}},"required":["player_count"]},"MatchmakerListRegionsResponse":{"type":"object","properties":{"regions":{"type":"array","items":{"$ref":"#/components/schemas/MatchmakerRegionInfo"}}},"required":["regions"]},"PortalNotificationRegisterService":{"type":"object","properties":{"firebase":{"$ref":"#/components/schemas/PortalNotificationRegisterFirebaseService"}}},"PortalNotificationRegisterFirebaseService":{"type":"object","properties":{"access_key":{"type":"string"}},"required":["access_key"]},"PortalNotificationUnregisterService":{"type":"string","enum":["firebase"]},"PortalGetSuggestedGamesResponse":{"type":"object","properties":{"games":{"type":"array","items":{"$ref":"#/components/schemas/GameGameSummary"},"description":"A list of game summaries."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["games","watch"]},"PortalGetGameProfileResponse":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/GameProfile"},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["game","watch"]},"ProvisionPoolType":{"type":"string","enum":["job","gg","ats","pegboard","pegboard_isolate","fdb","worker","nats","guard"]},"ProvisionServer":{"type":"object","properties":{"server_id":{"type":"string","format":"uuid"},"datacenter_id":{"type":"string","format":"uuid"},"pool_type":{"$ref":"#/components/schemas/ProvisionPoolType"},"lan_ip":{"type":"string"},"wan_ip":{"type":"string"}},"required":["server_id","datacenter_id","pool_type"]},"RegionsRegion":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"RoutesRouteTargetActors":{"type":"object","description":"Configuration for targeting actors.","properties":{"selector_tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of actors to route requests to."}},"required":["selector_tags"]},"RoutesRouteTarget":{"type":"object","properties":{"actors":{"$ref":"#/components/schemas/RoutesRouteTargetActors","description":"Configuration for targeting actors."}}},"RoutesRoute":{"type":"object","properties":{"id":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"},"hostname":{"type":"string"},"path":{"type":"string"},"route_subpaths":{"type":"boolean","description":"Whether to route all subpaths of this path"},"strip_prefix":{"type":"boolean","description":"Whether to remove the path prefix before sending the request to the target."},"target":{"$ref":"#/components/schemas/RoutesRouteTarget"}},"required":["id","created_at","updated_at","hostname","path","route_subpaths","strip_prefix","target"]},"ServersGetBuildResponse":{"type":"object","properties":{"build":{"$ref":"#/components/schemas/ServersBuild"}},"required":["build"]},"ServersListBuildsResponse":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/ServersBuild"},"description":"A list of builds for the game associated with the token."}},"required":["builds"]},"ServersPatchBuildTagsRequest":{"type":"object","properties":{"tags":{},"exclusive_tags":{"type":"array","items":{"type":"string"},"description":"Removes the given tag keys from all other builds."}},"required":["tags"]},"ServersPatchBuildTagsResponse":{"type":"object","properties":{}},"ServersCreateBuildRequest":{"type":"object","properties":{"name":{"type":"string"},"image_tag":{"type":"string","description":"A tag given to the game build."},"image_file":{"$ref":"#/components/schemas/UploadPrepareFile"},"multipart_upload":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/ServersBuildKind"},"compression":{"$ref":"#/components/schemas/ServersBuildCompression"},"prewarm_datacenters":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["name","image_tag","image_file"]},"ServersCreateBuildResponse":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"image_presigned_request":{"$ref":"#/components/schemas/UploadPresignedRequest"},"image_presigned_requests":{"type":"array","items":{"$ref":"#/components/schemas/UploadPresignedRequest"}}},"required":["build"]},"ServersBuildKind":{"type":"string","enum":["docker_image","oci_bundle"]},"ServersBuildCompression":{"type":"string","enum":["none","lz4"]},"ServersServer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"environment":{"type":"string","format":"uuid"},"datacenter":{"type":"string","format":"uuid"},"tags":{},"runtime":{"$ref":"#/components/schemas/ServersRuntime"},"network":{"$ref":"#/components/schemas/ServersNetwork"},"resources":{"$ref":"#/components/schemas/ServersResources"},"lifecycle":{"$ref":"#/components/schemas/ServersLifecycle"},"created_at":{"type":"integer","format":"int64"},"started_at":{"type":"integer","format":"int64"},"destroyed_at":{"type":"integer","format":"int64"}},"required":["id","environment","datacenter","tags","runtime","network","resources","lifecycle","created_at"]},"ServersRuntime":{"type":"object","properties":{"build":{"type":"string","format":"uuid"},"arguments":{"type":"array","items":{"type":"string"}},"environment":{"type":"object","additionalProperties":{"type":"string"}}},"required":["build"]},"ServersLifecycle":{"type":"object","properties":{"kill_timeout":{"type":"integer","format":"int64","description":"The duration to wait for in milliseconds before killing the server. This should be set to a safe default, and can be overridden during a DELETE request if needed."}}},"ServersResources":{"type":"object","properties":{"cpu":{"type":"integer","description":"The number of CPU cores in millicores, or 1/1000 of a core. For example,\n1/8 of a core would be 125 millicores, and 1 core would be 1000\nmillicores."},"memory":{"type":"integer","description":"The amount of memory in megabytes"}},"required":["cpu","memory"]},"ServersNetwork":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/ServersNetworkMode"},"ports":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ServersPort"}}},"required":["ports"]},"ServersNetworkMode":{"type":"string","enum":["bridge","host"]},"ServersPort":{"type":"object","properties":{"protocol":{"$ref":"#/components/schemas/ServersPortProtocol"},"internal_port":{"type":"integer"},"public_hostname":{"type":"string"},"public_port":{"type":"integer"},"routing":{"$ref":"#/components/schemas/ServersPortRouting"}},"required":["protocol","routing"]},"ServersPortProtocol":{"type":"string","enum":["http","https","tcp","tcp_tls","udp"]},"ServersPortRouting":{"type":"object","properties":{"game_guard":{"$ref":"#/components/schemas/ServersGameGuardRouting"},"host":{"$ref":"#/components/schemas/ServersHostRouting"}}},"ServersGameGuardRouting":{"type":"object","properties":{}},"ServersHostRouting":{"type":"object","properties":{}},"ServersBuild":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."},"tags":{"type":"object","additionalProperties":{"type":"string"},"description":"Tags of this build"}},"required":["id","name","created_at","content_length","tags"]},"ServersDatacenter":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},"ServersListDatacentersResponse":{"type":"object","properties":{"datacenters":{"type":"array","items":{"$ref":"#/components/schemas/ServersDatacenter"}}},"required":["datacenters"]},"ServersGetServerLogsResponse":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"timestamps":{"type":"array","items":{"type":"string"},"description":"Sorted old to new."},"watch":{"$ref":"#/components/schemas/WatchResponse"}},"required":["lines","timestamps","watch"]},"ServersLogStream":{"type":"string","enum":["std_out","std_err"]},"UploadPresignedRequest":{"type":"object","description":"A presigned request used to upload files. Upload your file to the given URL via a PUT request.","properties":{"path":{"type":"string","description":"The name of the file to upload. This is the same as the one given in the upload prepare file."},"url":{"type":"string","description":"The URL of the presigned request for which to upload your file to."},"byte_offset":{"type":"integer","format":"int64","description":"The byte offset for this multipart chunk. Always 0 if not a multipart upload."},"content_length":{"type":"integer","format":"int64","description":"Expected size of this upload."}},"required":["path","url","byte_offset","content_length"]},"UploadPrepareFile":{"type":"object","description":"A file being prepared to upload.","properties":{"path":{"type":"string","description":"The path/filename of the file."},"content_type":{"type":"string","description":"The MIME type of the file."},"content_length":{"type":"integer","format":"int64","description":"Unsigned 64 bit integer."}},"required":["path","content_length"]}}} \ No newline at end of file diff --git a/site/src/generated/apiPages.json b/site/src/generated/apiPages.json index b0d2766768..4f99ac2c65 100644 --- a/site/src/generated/apiPages.json +++ b/site/src/generated/apiPages.json @@ -33,6 +33,11 @@ "href": "/docs/api/actors/get", "sortingKey": "/actors/{actor} get" }, + { + "title": "actors.metrics.get", + "href": "/docs/api/actors/metrics/get", + "sortingKey": "/actors/{actor}/metrics/history get" + }, { "title": "actors.upgrade", "href": "/docs/api/actors/upgrade",