@molecule/api-model-hosting-runpod
Provider bond · model-hosting · API (Node) · v1.0.0 · Apache-2.0
RunPod Serverless model hosting for molecule.dev — run a model server container on a load-balancing GPU endpoint that scales to zero
npm install @molecule/api-model-hosting-runpodnpm · Source on GitHub · Implements @molecule/api-model-hosting
How it works
@molecule/api-model-hosting-runpod is a provider bond on the API (Node) side: it implements the model-hosting core interface (@molecule/api-model-hosting) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setProvider, requireProvider } from '@molecule/api-model-hosting'
import { provider } from '@molecule/api-model-hosting-runpod'
setProvider(provider) // reads RUNPOD_API_KEY on first use
const endpoint = await requireProvider().deploy({
name: 'jeff',
image: 'ghcr.io/acme/jeff-serve:0.8b',
port: 8000,
healthPath: '/ping',
accelerator: { kind: 'gpu', minVramGb: 16 },
region: 'us',
scaling: { minInstances: 0, maxInstances: 2, idleTimeoutSeconds: 60 },
access: 'private',
})
const headers = await requireProvider().authHeaders(endpoint.id) // { authorization: 'Bearer <RUNPOD_API_KEY>' }Works with: @molecule/api-bond, @molecule/api-i18n, @molecule/api-model-hosting, @molecule/api-secrets
Secrets: RUNPOD_API_KEY
Reference
RunPod Serverless model hosting for molecule.dev — run a model server
container on a load-balancing GPU endpoint (16 GB class and up) that scales
to zero, called at https://<endpoint-id>.api.runpod.ai with your RunPod
API key.
Load-balancing endpoints run YOUR HTTP server (no RunPod handler code), so
laya-serve, jeff-serve or any /v1/systemone server works unchanged.
Quick Start
import { setProvider, requireProvider } from '@molecule/api-model-hosting'
import { provider } from '@molecule/api-model-hosting-runpod'
setProvider(provider) // reads RUNPOD_API_KEY on first use
const endpoint = await requireProvider().deploy({
name: 'jeff',
image: 'ghcr.io/acme/jeff-serve:0.8b',
port: 8000,
healthPath: '/ping',
accelerator: { kind: 'gpu', minVramGb: 16 },
region: 'us',
scaling: { minInstances: 0, maxInstances: 2, idleTimeoutSeconds: 60 },
access: 'private',
})
const headers = await requireProvider().authHeaders(endpoint.id) // { authorization: 'Bearer <RUNPOD_API_KEY>' }
Type
provider
Installation
npm install @molecule/api-model-hosting-runpod @molecule/api-bond @molecule/api-i18n @molecule/api-model-hosting @molecule/api-secrets
API
Interfaces
RunPodConfig
Configuration for the RunPod model hosting provider.
interface RunPodConfig {
/** API key. Defaults to `RUNPOD_API_KEY`. */
apiKey?: string
/** GraphQL `locations` for `'us'`. Default `'US'`. */
usLocations?: string
/** GraphQL `locations` for `'eu'`. Default `'CZ,FR,GB,NO,RO'`. */
euLocations?: string
/** Container disk per worker, in GB. Default 20. */
containerDiskGb?: number
/** REST base URL (tests). Default `https://rest.runpod.io/v1`. */
restBaseUrl?: string
/** GraphQL URL (tests). Default `https://api.runpod.io/graphql`. */
graphqlUrl?: string
/** Endpoint URL template (tests); `{id}` is replaced. Default `https://{id}.api.runpod.ai`. */
endpointUrlTemplate?: string
/** How often `deploy` probes the health path while workers start, in ms. Default 5000. */
pollIntervalMs?: number
}
RunPodEndpoint
A RunPod serverless endpoint (only the fields read here).
interface RunPodEndpoint {
id: string
name: string
templateId?: string
workersMin?: number
workersMax?: number
idleTimeout?: number
gpuTypeIds?: string[]
dataCenterIds?: string[]
createdAt?: string
workers?: unknown[]
}
RunPodTemplate
A RunPod template (only the fields read here).
interface RunPodTemplate {
id: string
name: string
}
Classes
RunPodApiError
A RunPod API error, carrying the HTTP status.
RunPodClient
Thin RunPod client.
Functions
createProvider(config)
Creates a RunPod model hosting provider.
function createProvider(config?: RunPodConfig): ModelHostingProvider
config— API key, locations, disk size.
Returns: A ModelHostingProvider backed by RunPod Serverless.
gpuIdsFor(spec)
The GPU pools a spec may land on: the named pool, or every pool with enough memory.
function gpuIdsFor(spec: ModelEndpointSpec): string
spec— The endpoint spec.
Returns: Comma-separated gpuIds.
toGraphQLLiteral(value)
Serializes a plain object as a GraphQL input literal (unquoted keys,
type values that are enums stay quoted strings — RunPod takes strings).
function toGraphQLLiteral(value: unknown): string
value— The value.
Returns: The GraphQL literal.
toTemplate(spec, diskGb)
The serverless template body for a spec.
function toTemplate(spec: ModelEndpointSpec, diskGb: number): Record<string, unknown>
spec— The endpoint spec.diskGb— Container disk.
Returns: TemplateCreateInput.
Constants
modelHostingRunPodSecretDefinitions
Secret definitions used by the RunPod model hosting bond.
const modelHostingRunPodSecretDefinitions: SecretDefinition[]
provider
The provider implementation — lazy, so env vars are read on first use.
const provider: ModelHostingProvider
RUNPOD_CAPABILITIES
What RunPod Serverless load-balancing endpoints offer here (GPU only).
const RUNPOD_CAPABILITIES: ProviderCapabilities
RUNPOD_GPU_POOLS
GPU pools by memory, smallest first (docs.runpod.io/sdks/graphql/manage-endpoints, 2026-09-30).
const RUNPOD_GPU_POOLS: readonly { id: string; vramGb: number }[]
RUNPOD_GRAPHQL
Default GraphQL URL.
const RUNPOD_GRAPHQL: 'https://api.runpod.io/graphql'
RUNPOD_REST
Default REST base URL.
const RUNPOD_REST: 'https://rest.runpod.io/v1'
Core Interface
Implements @molecule/api-model-hosting interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-model-hosting'
import { provider } from '@molecule/api-model-hosting-runpod'
export function setupModelHostingRunpod(): void {
setProvider(provider)
}
Injection Notes
Requirements
Peer dependencies:
@molecule/api-bond^1.0.1@molecule/api-i18n^1.0.1@molecule/api-model-hosting^1.0.0@molecule/api-secrets^1.0.1
Environment Variables
RUNPOD_API_KEY(required) — runpod api key- Setup: RunPod API key — Manages templates and serverless endpoints, and authorizes calls to them (Settings → API Keys). Workers stop when the account balance reaches $0.
- Get it here: https://www.console.runpod.io/user/settings
- Example:
rpa_XXXXXXXXXXXXXXXXXXXXXXXX
Runtime Dependencies
-
@molecule/api-bond -
@molecule/api-i18n -
@molecule/api-model-hosting -
@molecule/api-secrets -
Serve
/pingon your port. RunPod's load balancer health-polls/ping(theHEALTH_CHECK_PATHoverride is documented but reported ignored — runpod/docs#853) and expects200healthy /204still loading. A server with only/healthnever becomes healthy; add/ping(or proxy it). The bond setsPORT,PORT_HEALTHandHEALTH_CHECK_PATHfrom the spec anyway, anddeploywaits on YOURhealthPaththrough the public URL. -
Cold starts return "no workers available" until a worker is up; retry 3 times 5–10 s apart (RunPod's own guidance), or keep
minInstances: 1. -
GPU only.
minVramGbpicks the smallest pool class that fits (AMPERE_16→ 16 GB; 24 GB →AMPERE_24,ADA_24; …); name one or a comma-separated set inaccelerator.model.'us'→US,'eu'→CZ,FR,GB,NO,RO, or pass RunPod location codes. -
The endpoint is created with the GraphQL
saveEndpointmutation (type: "LB"), because the REST API cannot create load-balancing endpoints; updates, reads and deletes use REST.removedrains workers to 0 before deleting, then deletes the template. -
Anyone with your RunPod API key can call every endpoint — the key is both the admin credential and the endpoint credential. Keep it server-side.
-
Workers stop when the account balance reaches $0 — a silent outage.
-
list()returns every serverless endpoint on the account (RunPod does not say which are load-balancing). -
API errors throw
RunPodApiErrorwith the HTTPstatus.