Skip to main content

Vobiz SDKs — Free, self-managed pipeline with Fern

Why this exists: Stainless (the original plan in ../stainless/) was acquired by Anthropic and is closed to new users. This is the replacement: Fern’s open-source, Apache-2.0 generators produce idiomatic SDKs from the same openapi.yaml, and our own GitHub Actions publish them to registries. Total tooling cost: $0/mo.
Cost honesty. Fern’s managed pipeline (auto-publishing, managed repos) is ~250/moperSDK— 250/mo **per SDK** — ~1,750/mo for 7 languages. We do not use it. We use only the free local generators + our own CI. The trade-off: we own the publish wiring (this folder already scaffolds it) and the package manifests (see §4).

1. What’s in this folder

fern/
├── fern.config.json            # org + pinned CLI version
├── generators.yml              # all 7 languages → local-file-system output
└── openapi/
    ├── openapi.yml             # Fern reads this; auto-synced from root openapi.yaml
    └── overrides.yml           # SDK-only patches (auth is auto; mostly empty)

.github/workflows/              # INSTALLED & LIVE in this repo (no longer under fern/)
├── generate-sdks.yml           # sync spec → regenerate → commit SDKs on spec change
├── publish-typescript.yml      # → npm        (OIDC, free)
├── publish-python.yml          # → PyPI       (OIDC, free)
├── publish-go.yml              # → mirror to vobiz-ai/vobiz-go + git tag
├── publish-java.yml            # → Maven Central (Sonatype Central Portal, vanniktech)
├── publish-ruby.yml            # → RubyGems
├── publish-csharp.yml          # → NuGet
└── publish-php.yml             # → mirror to vobiz-ai/vobiz-php → Packagist

sdks/<lang>/                    # generated SDK source (committed). Java build.gradle +
                                # settings.gradle + gradle.properties are HAND-AUTHORED.
Languages: TypeScript, Python, Go, Java, Ruby, C#, PHP. (Kotlin dropped per scope; Fern supports Swift/Rust too if wanted later.)

2. How the free pipeline works end-to-end

edit fern/openapi/openapi.yml  →  push to main


generate-sdks.yml (GitHub Action)
  • npm i -g fern-api
  • fern generate --local            ← Apache-2.0 generators run in Docker, FREE
  • writes idiomatic source to sdks/<lang>/
  • commits sdks/ back to the repo


tag a release  (e.g. `git tag python-v1.2.0 && git push --tags`)


publish-<lang>.yml (GitHub Action)
  • builds the package in sdks/<lang>/
  • publishes to npm / PyPI / Maven / RubyGems / NuGet / Packagist


package live on the registry      ← all on free GitHub Actions minutes
Two human actions: edit the spec and tag a release. Everything between is automated, and nothing bills you (GitHub Actions public-repo minutes are free).

3. One-time setup runbook

A. Spec repo

  1. Create vobiz-ai/vobiz-api-spec. Move this fern/ folder to its root, move fern/workflows/* to .github/workflows/, and keep openapi.yml as the source of truth. (Or run it all from this Mintlify docs repo — the spec already lives here.)

B. Fern token — NOT NEEDED ✅ (verified)

  1. npm install -g fern-api. No token or login is required for fern generate --local — tested empirically: the command runs the open-source generator Docker images straight away, with no auth prompt. There is no FERN_TOKEN secret anywhere in the pipeline. (Use --force in CI to skip the interactive “overwrite existing files?” confirmation.)

C. First generation (verify package manifests — see §4)

  1. Locally: fern generate --local --force (Docker must be running — no token needed). Inspect each sdks/<lang>/ for a package manifest (package.json, pyproject.toml, go.mod, *.csproj, composer.json, *.gemspec). If missing → §4.

D. Architecture: mirror-into-each-repo

Each language has its own public repo under the vobiz-ai org. This docs repo generates + commits sdks/<lang>/; on a <lang>-v* tag the publish workflow injects the version, publishes to the registry, and mirrors sdks/<lang>/ into that repo + tags it. The per-language repos are source mirrors (and the actual release channel for Go + PHP). One shared SDK_PUSH_TOKEN (a vobiz-ai member/bot PAT with Contents write) powers all seven mirrors.
LanguageMirror repo (vobiz-ai/…)RegistryOne-time setupRegistry secret
TypeScriptVobiz-Node-SDKnpmTrusted Publisher for @vobiz/sdk → repo devlume-in/Mintlyfy-Docs + publish-typescript.ymlnone (OIDC)
PythonVobiz-Python-SDKPyPIPending publisher for vobiz → same repo + publish-python.ymlnone (OIDC)
GoVobiz-Go-SDK— (git tag)Module path must equal repo URL github.com/vobiz-ai/Vobiz-Go-SDK (set ✔). Consider a lowercase vobiz-go repo for a clean go get.
JavaVobiz-Java-SDK ⚠️ createMaven CentralVerify ai.vobiz namespace (DNS TXT) + GPG keySONATYPE_*, GPG_*
RubyVobiz-Ruby-SDKRubyGemsAPI key, “Push” scopeGEM_HOST_API_KEY
C#Vobiz-Csharp-sdkNuGetAPI key, “Push” scopeNUGET_API_KEY
PHPVobiz-PHP-SDK ⚠️ createPackagistSubmit vobiz-ai/Vobiz-PHP-SDK, enable GitHub hook (version comes from tag)
Plus, for every language: the single SDK_PUSH_TOKEN secret. Optional — AI READMEs: set GEMINI_API_KEY (repo secret on devlume-in/Mintlyfy-Docs). generate-sdks.yml then runs fern/scripts/generate-readme.mjs after every generation to overwrite each Fern-template README with a detailed, source-grounded one (Gemini gemini-2.5-flash by default; set GEMINI_MODEL=gemini-2.5-pro for max quality). If the key is unset the step no-ops and keeps the existing README, so it never blocks the build. This also makes the good READMEs durable — they’re rewritten on each regen instead of reverting to Fern’s template.

E. Go!

  1. Push a spec change → generate-sdks.yml commits SDKs → tag python-v0.1.0 etc. → publish-*.yml ships each package.

4. The package-manifest caveat (the one real catch)

Fern’s free --local generation reliably emits SDK source code. Package-metadata files (package.json, pyproject.toml, go.mod, README) are documented as added when Fern “completes the SDK” — and the Python quickstart explicitly says pyproject.toml and README.md are generated only on paid plans. So on the free tier some manifests may be missing. This does not block the free path. If a manifest is missing, commit a thin hand-authored one into sdks/<lang>/ (you control name/version/deps). The publish workflows already assume the manifest lives in the SDK folder. You write each manifest once; regeneration only rewrites the source, not your manifest. Status (verified empirically): 6/7 manifests were emitted on the free tier — TS package.json, Python pyproject.toml, Go go.mod, PHP composer.json, Ruby vobiz.gemspec, C# Vobiz.csproj+Vobiz.slnx. Only Java had no build file, exactly as predicted — now hand-authored at sdks/java/build.gradle (+ settings.gradle, gradle.properties), using the vanniktech maven-publish plugin → Sonatype Central Portal. ⚠️ Its dependency versions weren’t compile-verified (no local JDK); run gradle build in sdks/java/ once before the first java-v* tag.

5. Auth (handled automatically)

The dual-header scheme is read straight from the spec’s securitySchemes (X-Auth-ID = AuthId, X-Auth-Token = AuthToken, combined with AND in one security requirement). Both surface as client constructor options:
const client = new Vobiz({ authId: "…", authToken: "…" });
No extra config needed. To rename the params, add x-fern-header in overrides.yml.

6. Honest assessment vs. the old Stainless plan

Stainless (dead)Fern managed ($1,750/mo)Fern free (this)
Costn/a (closed)~$250/mo × 7$0
SDK qualityexcellentexcellentidiomatic (same generators)
Generation automationfullfullfull (our CI)
Publish automationfullfullfull (our CI, we wired it)
Package manifestsprovidedprovidedwe author missing ones once (§4)
Mintlify code samplesbuilt-inbuilt-innot free — see §7
Vendor lock / disappear risk(gone)low (Postman-backed)none (Apache-2.0)
What we give up vs. paid: the auto-injected Mintlify x-codeSamples loop and Fern’s managed release PRs. Both are replaceable (see §7) or simply nice-to-haves.

7. Optional follow-ups

  • Mintlify code samples: Fern’s auto-x-codeSamples is a paid feature. Free alternative: keep Mintlify’s built-in examples.languages (curl/python/javascript) that docs.json already enables, or hand-add a few x-codeSamples for hero endpoints.
  • Separate per-language repos: this scaffold is a monorepo (all SDKs in sdks/). Go and PHP already mirror out to their own repos (registry requirement). If you want every SDK in its own vobiz-ai/vobiz-<lang> repo, extend the mirror pattern in publish-go.yml/publish-php.yml to the others.
  • Spec hardening (carried over): complete the make-call/record/play/speak request schemas, fix /account//Account/ casing, name reused inline schemas. Fern reads schemas, not examples — same Phase-1 work as the Stainless plan. Do it in openapi.yml (or surgically in overrides.yml).

8. Verify-before-trust list (flagged from research)

  1. Package manifests on free tier (§4) — confirm empirically per language.
  2. Whether --local needs FERN_TOKEN RESOLVED: no token/login needed. Verified empirically — fern generate --local runs the open-source generators with zero auth.
  3. Generator image versions in generators.yml — bump to latest tags at setup (pinned values were current at authoring).
  4. Java/Ruby/C#/PHP config keys (group-id, clientClassName, namespace, packageName) — verify exact names on each generator’s …/configuration page.
  5. Go/PHP own-repo mirroring — the module path / Packagist registration require the SDK to live in its own repo; the mirror workflows assume vobiz-ai/vobiz-go and vobiz-ai/vobiz-php exist.
Sources: buildwithfern.com/learn/sdks/* (quickstarts, configuration, publishing, self-hosted, how-it-works), hub.docker.com/u/fernapi, buildwithfern.com/pricing.