Migration guides

Migrating from Stainless to Sourced without losing the SDK experience

If you have a Stainless project, the files that matter already exist on your machine: an OpenAPI spec, a stainless.yml, two or three SDK repos, a docs repo, and the publishing settings that point at npm and PyPI. A migration to Sourced does not rewrite any of that. It reads what you own, generates a replacement plan, and asks you to approve before anything reaches a customer.

This post is the short version of the migration page. It walks the four steps the way the dashboard does them, and is honest about what changes and what doesn't.

What stays the same

  • Package names. Sourced reads stainless.yml, so the TypeScript package name, the Python package name, the MCP host package, and the production repos stay exactly as configured.
  • Auth env vars. Whatever your customers set in their shell stays the same. Sourced derives the env-var prefix from your client class name; if Stainless emitted ACME_API_API_KEY, so does Sourced.
  • Method names and resource shapes. Sourced maps your configured resources to OpenAPI operations, so client.messages.send(...) keeps working.
  • README examples. The example endpoint and parameters defined in stainless.yml are used to render a runnable snippet in the generated README.
  • Custom domains and redirects. Your docs domain and existing URLs are mapped before cutover.

What does change

  • Where things run. Generation moves from Stainless's hosted workers to Sourced's. The output is yours either way.
  • The report layer. Sourced emits a compatibility report that diffs the generated SDK against your live Stainless SDK. Stainless does not.
  • Docs hosting. If you used the Stainless Docs Platform, Sourced generates a private docs preview plus a DNS, redirect, sitemap, and llms.txt cutover plan. The docs migration scanner finds the dependencies to swap before you cut over.

The four-step path

1. Upload OpenAPI and stainless.yml

Sourced reads both files. The stainless.yml parser captures package names, production repos, auth env vars, README examples, MCP host settings, and the full resource tree. The OpenAPI spec drives the actual method generation.

If you don't have a current stainless.yml, you can paste your OpenAPI and Sourced will generate a starter config. Most teams prefer to keep the existing config so package names and auth conventions stay stable.

2. Read the compatibility report

This is the part Stainless doesn't offer. Sourced generates a TypeScript and Python SDK preview and then diffs the public surface — methods, error classes, pagination helpers, README examples — against your live Stainless package.

A typical report says something like:

0 missing TypeScript methods. 0 missing Python methods. 42 Python method shapes marked for human review (signature differences, mostly safe). 1 method in stainless.yml not present in the source OpenAPI (retrieve_opt_out_status).

Anything flagged "review" is a human decision, not a blocker. Anything red is a blocker.

3. Preview docs and SDK output

Both outputs are downloadable before publishing:

  • TypeScript SDK preview with package.json, tsconfig.json, src/index.ts, and the README.
  • Python SDK preview with pyproject.toml, package files, sync and async clients, errors, and models.
  • Docs previews preview at a private URL, including llms.txt and a sitemap.

Nothing reaches a customer yet. The docs preview lives on a *.sourced.sh subdomain that you share with your team.

4. Publish on your timeline

When the report is clean, Sourced shows release readiness for SDK repo sync, registry readiness, and docs-domain cutover; external writes stay behind explicit approval. The cutover is reversible: keep the old packages on the latest minor until the new ones have run for a release cycle.

What to do this week

If you spot something missing — your team's deploy convention, a niche Python pagination pattern, anything that should be in the parity table — tell us and we'll add it.