@molecule/api-model-hosting-koyeb

Provider bond · model-hosting · API (Node) · v1.0.0 · Apache-2.0

Koyeb model hosting for molecule.dev — run a model server container on CPU or an RTX 4000 / L4 GPU in the EU or US, with sleep when idle

npm install @molecule/api-model-hosting-koyeb

npm · Source on GitHub · Implements @molecule/api-model-hosting

How it works

@molecule/api-model-hosting-koyeb 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-koyeb'

setProvider(provider) // reads KOYEB_API_TOKEN on first use

const endpoint = await requireProvider().deploy({
  name: 'laya',
  image: 'ghcr.io/acme/laya-serve:0.3.1',
  port: 8000,
  healthPath: '/health',
  secretEnv: { LAYA_API_KEY: process.env.LAYA_API_KEY ?? '' },
  accelerator: { kind: 'cpu' },
  region: 'eu',
  scaling: { minInstances: 0, maxInstances: 2, idleTimeoutSeconds: 600 },
  access: 'private',
  serverEnforcesAuth: true,
})
endpoint.url // https://laya-acme.koyeb.app

Works with: @molecule/api-bond, @molecule/api-i18n, @molecule/api-model-hosting, @molecule/api-secrets

Secrets: KOYEB_API_TOKEN

Reference

Koyeb model hosting for molecule.dev — run a model server container on a CPU instance or an NVIDIA GPU (L4, A100, H100, H200) in the EU or US, with sleep-when-idle and per-second billing.

Each endpoint is one Koyeb app holding one WEB service, reachable at the app's *.koyeb.app domain.

Quick Start

import { setProvider, requireProvider } from '@molecule/api-model-hosting'
import { provider } from '@molecule/api-model-hosting-koyeb'

setProvider(provider) // reads KOYEB_API_TOKEN on first use

const endpoint = await requireProvider().deploy({
  name: 'laya',
  image: 'ghcr.io/acme/laya-serve:0.3.1',
  port: 8000,
  healthPath: '/health',
  secretEnv: { LAYA_API_KEY: process.env.LAYA_API_KEY ?? '' },
  accelerator: { kind: 'cpu' },
  region: 'eu',
  scaling: { minInstances: 0, maxInstances: 2, idleTimeoutSeconds: 600 },
  access: 'private',
  serverEnforcesAuth: true,
})
endpoint.url // https://laya-acme.koyeb.app

Type

provider

Installation

npm install @molecule/api-model-hosting-koyeb @molecule/api-bond @molecule/api-i18n @molecule/api-model-hosting @molecule/api-secrets

API

Interfaces

KoyebApp

A Koyeb app (only the fields read here).

interface KoyebApp {
  id: string
  name: string
  domains?: Array<{ name?: string }>
}

KoyebConfig

Configuration for the Koyeb model hosting provider.

interface KoyebConfig {
  /** API token. Defaults to `KOYEB_API_TOKEN`. */
  apiToken?: string
  /** Region for `'us'`. Default `'was'` (Washington D.C.). */
  usRegion?: string
  /** Region for `'eu'`. Default `'fra'` (Frankfurt). */
  euRegion?: string
  /** CPU instance type when `accelerator` is CPU. Default `'large'` (4 vCPU / 4 GB). */
  cpuInstanceType?: string
  /** API base URL (tests, proxies). Default `https://app.koyeb.com`. */
  apiBaseUrl?: string
  /** How often `deploy` polls the service while it rolls out, in ms. Default 5000. */
  pollIntervalMs?: number
}

KoyebDefinition

A Koyeb deployment definition (only the fields written here).

interface KoyebDefinition {
  name: string
  type: 'WEB'
  docker: { image: string; entrypoint?: string[]; args?: string[] }
  env: Array<{ key: string; value: string }>
  ports: Array<{ port: number; protocol: 'http' }>
  routes: Array<{ port: number; path: string }>
  regions: string[]
  instance_types: Array<{ type: string }>
  scalings: Array<{
    min: number
    max: number
    targets?: Array<{
      sleep_idle_delay?: { value?: number }
      concurrent_requests?: { value?: number }
    }>
  }>
  health_checks: Array<{ grace_period?: number; http: { port: number; path: string } }>
}

KoyebService

A Koyeb service (only the fields read here).

interface KoyebService {
  id: string
  name: string
  app_id: string
  created_at?: string
  status?:
    | 'STARTING'
    | 'HEALTHY'
    | 'DEGRADED'
    | 'UNHEALTHY'
    | 'DELETING'
    | 'DELETED'
    | 'PAUSING'
    | 'PAUSED'
    | 'RESUMING'
  messages?: string[]
  latest_deployment_id?: string
}

Classes

KoyebApiError

A Koyeb API error, carrying the HTTP status and Koyeb's error code.

KoyebClient

Thin Koyeb API client.

Functions

createProvider(config)

Creates a Koyeb model hosting provider.

function createProvider(config?: KoyebConfig): ModelHostingProvider
  • config — API token, region mapping, CPU instance type.

Returns: A ModelHostingProvider backed by Koyeb.

instanceTypeFor(spec, cpuType)

Picks the Koyeb instance type for a spec.

function instanceTypeFor(spec: ModelEndpointSpec, cpuType: string): string
  • spec — The endpoint spec.
  • cpuType — The CPU instance type to use for CPU specs.

Returns: A Koyeb instance type id.

statusOf(status)

Maps a Koyeb service status to an endpoint status.

function statusOf(
  status:
    | 'STARTING'
    | 'HEALTHY'
    | 'DEGRADED'
    | 'UNHEALTHY'
    | 'DELETING'
    | 'DELETED'
    | 'PAUSING'
    | 'PAUSED'
    | 'RESUMING'
    | undefined,
): EndpointStatus
  • status — Koyeb Service.status.

Returns: The endpoint status.

toDefinition(spec, region, cpuType)

Builds the Koyeb deployment definition for a spec.

function toDefinition(spec: ModelEndpointSpec, region: string, cpuType: string): KoyebDefinition
  • spec — The endpoint spec.
  • region — Koyeb region id.
  • cpuType — CPU instance type for CPU specs.

Returns: The definition.

Constants

KOYEB_API

Default API base URL.

const KOYEB_API: 'https://app.koyeb.com'

KOYEB_CAPABILITIES

What Koyeb offers here.

const KOYEB_CAPABILITIES: ProviderCapabilities

KOYEB_GPUS

GPU instance ids by memory, smallest first (koyeb.com/docs/reference/instances, 2026-09-30).

const KOYEB_GPUS: readonly { id: string; vramGb: number }[]

modelHostingKoyebSecretDefinitions

Secret definitions used by the Koyeb model hosting bond.

const modelHostingKoyebSecretDefinitions: SecretDefinition[]

provider

The provider implementation — lazy, so env vars are read on first use.

const provider: ModelHostingProvider

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-koyeb'

export function setupModelHostingKoyeb(): 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

  • KOYEB_API_TOKEN (required) — koyeb api token
    • Setup: Koyeb API token — An organization API token (Settings → API). GPU instances need a paid plan and a card on file.
    • Get it here: https://app.koyeb.com/user/settings/api
    • Example: koyeb-api-token

Runtime Dependencies

  • @molecule/api-bond

  • @molecule/api-i18n

  • @molecule/api-model-hosting

  • @molecule/api-secrets

  • No endpoint auth of its own. A Koyeb URL is public. For access: 'private' you must set serverEnforcesAuth: true, pass the server's key in secretEnv (e.g. LAYA_API_KEY), and give the consumer the same key (apiKey). authHeaders() always returns {}.

  • secretEnv is stored as plain service env, visible in the Koyeb console to anyone in the organization. Use Koyeb secrets yourself for anything stricter.

  • Instance types: CPU uses large (4 vCPU / 4 GB — enough for a ~400M encoder; medium has too little memory) unless cpuInstanceType is set. GPUs are picked by minVramGb from gpu-nvidia-l4 (24 GB) up; pass accelerator.model to name one exactly (e.g. an RTX 4000 SFF Ada id from Koyeb's catalog). Which regions carry which GPUs is not documented on the regions page — a GPU in a region without it fails the deploy.

  • Sleep: minInstances: 0 sleeps after idleTimeoutSeconds (300–43,200 s; the upper end depends on your plan) and wakes in 1–5 s plus the model load. 'us' → was, 'eu' → fra.

  • GPU instances need a paid plan and a card on file (Koyeb holds a pre-authorization); the deploy fails with Koyeb's message otherwise.

  • remove() deletes the whole app. list() returns services whose app has the same name — the shape this bond creates.

  • API errors throw KoyebApiError with the HTTP status and Koyeb's code.