> This page is for SDKs, version Current (default).
> For other versions, use one of these documentation indexes:
> - Current (default): https://buildwithfern.com/learn/sdks/current/llms.txt
> - Legacy: https://buildwithfern.com/learn/sdks/legacy/llms.txt

> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt.

# sdk-config.yml configuration schema

> Complete sdk-config.yml reference for Fern SDK generation. Configure API sources, client behavior, package metadata, output, publishing, and language targets.

> **Meet your new SDK generator**
>
> Describe the SDK you want, not the generators that build it. You only have to declare shared settings like auth, retries and package details once, and every language target inherits them. Add an SDK in a single line: a new language target. Targets run the newest SDK generators unless you pin `generatorVersion`.
>
> Already using `generators.yml`? Follow the [SDK Config migration guide](/learn/sdks/legacy/generators/migration-guides/sdk-config) to migrate.

The `sdk-config.yml` file configures SDK generation. It declares the API source, the settings shared by every SDK, and one target per language. Settings at the top level apply to every target; each target can override them.

Projects that still generate from `generators.yml` can move to `sdk-config.yml` with `fern sdk migrate`. The [legacy `generators.yml` reference](/learn/sdks/legacy/reference/generators-yml) documents the previous format.

**`sdk-config.yml`**

```yaml title="sdk-config.yml" maxLines=10
schemaVersion: sdk-config/v1
sdkName: Plant Store
sdkVersion: 1.0.0

source:
  specs:
    - id: plant-store
      type: openapi
      path: ./openapi.yml

api:
  auth:
    schemes:
      - id: bearer
        type: bearer
        environmentVariable: PLANT_STORE_API_KEY

client:
  retry:
    maxAttempts: 3
  timeoutMs: 60000

package:
  description: Official SDK for the Plant Store API
  authors:
    - name: SDK Team
      email: sdk@example.com

targets:
  - language: typescript
    package:
      packageName: "@plant-store/sdk"
    output:
      delivery: github
      github:
        repository: your-organization/plant-store-typescript
      publish:
        registry: npm
        token: ${NPM_TOKEN}

  - language: python
    package:
      packageName: plant-store
    output:
      delivery: files
      path: ../sdks/python
```

## Credentials

Credential fields such as `output.publish.token` and `output.github.credentials` don't accept literal secrets. Use an environment expression such as `${NPM_TOKEN}`, which Fern resolves when it generates the SDK.

## Paths

Paths in `sdk-config.yml` are relative to the file. Absolute paths and paths that contain `..` segments are rejected.

## Override settings per target

A target inherits the top-level `sdkName`, `sdkVersion`, `client`, `docs`, `package`, and `generation` settings and overrides only the fields it sets. A target's `output` replaces the top-level `output` entirely. Every target needs an effective `output`, either from the top level or from its own block.

**`sdk-config.yml`**

```yaml title="sdk-config.yml"
client:
  timeoutMs: 60000

targets:
  - language: typescript
    output:
      delivery: files
      path: ../sdks/typescript
  - language: python
    client:
      timeoutMs: 30000 # overrides the top-level value for Python only
    output:
      delivery: files
      path: ../sdks/python
```

## `schemaVersion`

**`schemaVersion`** `"sdk-config/v1"` — required

The version of the SDK Config schema. Set to `sdk-config/v1`.

---

## `sdkName`, `sdkVersion`, and `apiVersion`

**`sdkName`** `string`

The default name used for generated SDKs.

---

**`sdkVersion`** `string` — default: 1.0.0

The default version assigned to generated SDKs.

---

**`apiVersion`** `string`

The version of the API represented by the generated SDKs.

---

## `source`

The API descriptions used to generate the SDKs. Each entry in `specs` sets exactly one of `path` (a local file) or `url` (an HTTP(S) resource).

**`sdk-config.yml`**

```yaml title="sdk-config.yml"
source:
  specs:
    - id: plant-store
      type: openapi
      path: ./openapi.yml
      overrides:
        - ./openapi-overrides.yml
```

**`source.specs[].id`** `string` — required

A unique identifier for this API source.

---

**`source.specs[].type`** `"openapi" | "swagger" | "postman" | "asyncapi" | "graphql"` — required

The API description format of this source.

---

**`source.specs[].name`** `string`

A human-readable name for this API source.

---

**`source.specs[].namespace`** `string`

A namespace used to isolate this source in a multi-source SDK.

---

**`source.specs[].apiImportSettings`** `object`

Import behavior that overrides the source-level defaults for this spec.

---

**`source.specs[].overlays`** `list<string>`

Relative paths to overlays applied to this source in order.

---

**`source.specs[].overrides`** `list<string>`

Relative paths to source override files applied in order.

---

**`source.specs[].path`** `string`

The relative path to the API source file.

---

**`source.specs[].url`** `string`

The HTTP or HTTPS URL of the API source file.

---

**`source.apiImportSettings`** `object`

API import settings applied to every spec. A spec's own `apiImportSettings` override these values.

---

## `api`

**`api.baseUrl`** `string`

The default base URL used by the generated client.

---

**`api.environments`** `list<object>`

Named API environments and their base URLs.

---

**`api.environmentVariables`** `list<object>`

Environment variables exposed through generated client configuration.

---

**`api.defaultEnvironment`** `string`

The environment selected when a caller doesn't choose one.

---

**`api.auth`** `object`

Authentication supported by the API.

---

**`api.headers`** `list<object>`

Headers added to generated API requests.

---

**`api.audiences`** `list<string>`

Named API audiences included in the generated SDK.

---

**`api.webhookSignature`** `object`

How generated helpers verify webhook signatures from the API.

---

## `client`

**`client.retry`** `object`

Retry behavior for generated API requests.

---

**`client.responseHeaders`** `boolean` — default: false

Whether generated operations expose HTTP response headers.

---

**`client.responseValidation`** `boolean`

Whether the client validates API responses against the schema.

---

**`client.multiTenant`** `boolean` — default: false

Whether the client exposes configuration for tenant-specific API access.

---

**`client.additionalConstructorParameters`** `list<object>`

Additional parameters added to the generated client constructor.

---

**`client.timeoutMs`** `union`

The default request timeout in milliseconds, or "infinity" for no timeout.

---

**`client.requestParameterStyle`** `"wrapped" | "inline" | "language-default"`

Whether generated operation parameters are wrapped or passed inline.

---

**`client.pathParameterStyle`** `"wrapped" | "inline" | "language-default"`

Whether generated path parameters are wrapped or passed inline.

---

**`client.filePropertyStyle`** `"wrapped" | "inline" | "language-default"`

Whether generated file properties are wrapped or passed inline.

---

**`client.useDefaultRequestParameterValues`** `boolean`

Whether schema defaults are applied to omitted request parameters.

---

**`client.respectOptionalRequestBody`** `boolean`

Whether an optional request body remains optional in generated methods.

---

**`client.tokenRefresh`** `object`

Refresh-token behavior for the generated client.

---

**`client.idempotencyKeyGeneration`** `object`

Automatic idempotency keys on eligible requests.

---

**`client.userAgent`** `object`

The User-Agent header the generated client sends.

---

**`client.offsetSemantics`** `"item-index" | "page-index"`

How an offset-paginated endpoint advances: by the number of items returned, or by one page.

---

## `package`

Package metadata inherited by every target. Package identity fields such as `packageName` usually belong on each target.

**`package.packageName`** `string`

The package name used by the target language registry.

---

**`package.moduleName`** `string`

The generated module or import name when it differs from the package name.

---

**`package.modulePath`** `string`

The Go module path used for imports and publishing.

---

**`package.namespace`** `string`

The namespace or package prefix for generated code.

---

**`package.groupId`** `string`

The Maven group identifier.

---

**`package.artifactId`** `string`

The Maven artifact identifier.

---

**`package.description`** `string`

The package description used in generated metadata.

---

**`package.repository`** `string`

The source repository for the generated SDK.

---

**`package.homepage`** `string`

The package homepage URL.

---

**`package.documentationUrl`** `string`

The package documentation URL.

---

**`package.authors`** `list<object>`

Authors credited in package metadata.

---

**`package.developers`** `list<object>`

Developers credited in package metadata.

---

**`package.license`** `object`

License metadata for the generated package.

---

**`package.keywords`** `list<string>`

Search keywords for package metadata.

---

**`package.classifiers`** `list<string>`

Package classifiers used by registries such as PyPI.

---

**`package.projectUrls`** `list<object>`

Labeled project links for package metadata.

---

**`package.extraDependencies`** `list<object>`

Additional runtime dependencies added to the generated package.

---

**`package.extraDevDependencies`** `list<object>`

Additional development dependencies added to the generated package.

---

**`package.extraPeerDependencies`** `list<object>`

Additional peer dependencies added to the generated package.

---

**`package.extraPeerDependenciesMeta`** `object`

npm peerDependenciesMeta entries keyed by peer dependency name, such as \{ optional: true }.

---

## `output`

The default output delivery and publication configuration. A target's `output` replaces this block for that target.

**`sdk-config.yml`**

```yaml title="sdk-config.yml"
targets:
  - language: typescript
    output:
      delivery: github
      github:
        repository: your-organization/plant-store-typescript
        mode: pull-request
      publish:
        registry: npm
        trustedPublishing: true
```

**`output.delivery`** `"files" | "zip" | "github"` — required

Where Fern delivers the generated SDK. `files` writes it to a directory, `zip` packages it as a ZIP archive, and `github` delivers it to a GitHub repository.

---

**`output.path`** `string`

The destination directory for generated files. Applies to `delivery: files`.

---

**`output.fileName`** `string`

The generated ZIP archive file name. Applies to `delivery: zip`.

---

**`output.github`** `object`

GitHub repository delivery settings. Required for `delivery: github`.

---

### `github`

**`output.github.repository`** `string` — required

The GitHub repository that receives generated files.

---

**`output.github.host`** `string`

The GitHub host for enterprise installations.

---

**`output.github.branch`** `string`

The target branch for generated changes.

---

**`output.github.mode`** `"release" | "pull-request" | "push" | "commit" | "commit-and-release"`

How generated changes are delivered to the repository.

---

**`output.github.reviewers`** `object`

Reviewers requested for generated pull requests.

---

**`output.github.credentials`** `object`

Credentials used to authenticate GitHub delivery.

---

**`output.github.privateRepository`** `boolean`

Whether the destination repository is private.

---

### `publish`

Optional package registry publication. `registry` selects the registry, and the remaining fields depend on it.

**`output.publish.registry`** `"npm" | "pypi" | "maven" | "nuget" | "rubygems" | "crates" | "go" | "composer"` — required

The package registry to publish to.

---

**`output.publish.token`** `string`

The registry token, or an environment expression that resolves to it. Applies to `npm` and `crates`.

---

**`output.publish.trustedPublishing`** `boolean`

Whether npm publication uses trusted publishing (OIDC) instead of a token. Applies to `npm`.

---

**`output.publish.username`** `string`

The registry username, or an environment expression that resolves to it. Applies to `pypi` and `maven`.

---

**`output.publish.password`** `string`

The registry password or token, or an environment expression that resolves to it. Applies to `pypi` and `maven`.

---

**`output.publish.signature`** `object`

Credentials used to sign Maven artifacts. Applies to `maven`.

---

**`output.publish.url`** `string`

A custom package registry URL.

---

**`output.publish.releaseBranch`** `string`

The branch used by generated package release workflows.

---

**`output.publish.tolerateRepublish`** `boolean`

Whether an already-published package version is treated as non-fatal.

---

## `replay`

**`replay.enabled`** `boolean` — required

Whether regeneration reapplies customer-authored repository changes.

---

## `docs`

**`docs.readme`** `object`

README content and example configuration.

---

**`docs.snippets`** `object`

Standalone usage snippet generation.

---

**`docs.referenceBaseUrl`** `string`

The base URL used for links to generated API Reference files.

---

**`docs.includeApiReference`** `boolean`

Whether API Reference documentation is included in the SDK output.

---

## `generation`

Generation settings inherited by every target. Each target's `generation` block also accepts language-specific settings, documented on each language's configuration page.

**`generation.includeOptionalSnippetParameters`** `boolean`

Whether usage snippets include optional request parameters.

---

**`generation.buildAllModels`** `boolean` — default: false

Whether models not referenced by operations are also generated.

---

**`generation.inferServiceNames`** `boolean` — default: false

Whether service names are inferred from API structure.

---

**`generation.includeDeprecatedOperations`** `boolean` — default: true

Whether deprecated API operations are generated.

---

**`generation.multipleResponses`** `boolean` — default: false

Whether operations model multiple successful response types.

---

**`generation.devContainer`** `boolean` — default: false

Whether development-container configuration is generated.

---

**`generation.allowMockClient`** `boolean` — default: false

Whether a mock API client is included in the generated SDK.

---

**`generation.ignoreFiles`** `list of string`

Generated paths excluded from the final output.

---

**`generation.reservedKeywords`** `list of string`

Additional identifiers treated as reserved words.

---

**`generation.customCode`** `object`

Customer-authored code merge configuration.

---

**`generation.customCode.enabled`** `boolean` — required

Whether customer-authored code is merged into generated output.

---

**`generation.customCode.source`** `object`

The source containing customer-authored code.

---

\<ParamField path="generation.customCode.source.type" type=""path"" required= toc=>
Loads the generation asset from a relative path.
\</ParamField>

**`generation.customCode.source.location`** `string`

The relative path to the generation asset.

---

\<ParamField path="generation.customCode.conflictStrategy" type=""mark" | "ours" | "theirs"" required= toc=>
How merge conflicts between generated and custom code are handled.
\</ParamField>

**`generation.customCode.trackChanges`** `boolean`

Whether custom-code changes are tracked between builds.

---

**`generation.customCode.protectedFiles`** `list of string`

Generated file paths that custom-code merging must not overwrite.

---

**`generation.customQueryPaths`** `list of string`

Relative paths to custom query definitions.

---

**`generation.analytics`** `object`

Generated client telemetry configuration.

---

**`generation.analytics.enabled`** `boolean` — required

Whether generated clients export usage telemetry.

---

**`generation.analytics.endpoint`** `string`

The telemetry export endpoint.

---

\<ParamField path="generation.analytics.exporter" type=""otlp-http" | "console"" required= toc=>
The telemetry exporter implementation.
\</ParamField>

**`generation.analytics.headers`** `list of object`

Headers sent by the telemetry exporter.

---

**`generation.analytics.batchSize`** `number`

The maximum spans in each export batch.

---

**`generation.analytics.scheduledDelayMs`** `number`

The delay between scheduled exports, in milliseconds.

---

**`generation.analytics.exportTimeoutMs`** `number`

The maximum time allowed for an export, in milliseconds.

---

**`generation.wireTests`** `object`

Wire-level request and response test generation.

---

**`generation.wireTests.enabled`** `boolean` — required

Whether wire-level request and response tests are generated.

---

**`generation.wireTests.exclusions`** `list of string`

Operations excluded from wire tests.

---

**`generation.wireTests.fallbackToGeneratedErrorExamples`** `boolean`

Whether missing error fixtures are synthesized from generated examples.

---

\<ParamField path="generation.wireTests.fixtureSource" type=""synthetic" | "recorded" | "auto"" required= toc=>
Where wire-test fixtures are obtained.
\</ParamField>

**`generation.unitTests`** `object`

SDK unit-test generation.

---

**`generation.unitTests.enabled`** `boolean` — required

Whether SDK unit tests are generated.

---

**`generation.unitTests.exclusions`** `list of string`

Operations excluded from unit tests.

---

**`generation.webSockets`** `boolean`

Whether WebSocket clients are generated for supported channels.

---

**`generation.streams`** `object`

Streaming response generation behavior.

---

**`generation.streams.enabled`** `boolean` — required

Whether generated clients expose streaming response APIs.

---

\<ParamField path="generation.streams.responseType" type=""wrapper" | "native" | "web"" required= toc=>
The streaming response abstraction exposed by generated clients.
\</ParamField>

\<ParamField path="generation.streams.fileResponseType" type=""stream" | "binary-response"" required= toc=>
The response type used for file downloads.
\</ParamField>

**`generation.streams.defaultChunkSizeBytes`** `number`

The default number of bytes yielded by streaming iterators.

---

**`generation.naming`** `object`

Names and casing used by generated code.

---

**`generation.naming.clientName`** `string`

The generated client class name.

---

**`generation.naming.exportedClientName`** `string`

The client name exported from the generated package.

---

**`generation.naming.environmentTypeName`** `string`

The generated type name for API environments.

---

**`generation.naming.apiErrorName`** `string`

The generated API error class name.

---

**`generation.naming.baseErrorName`** `string`

The generated base error class name.

---

**`generation.naming.pagerName`** `string`

The generated pagination helper name.

---

**`generation.naming.smartCasing`** `boolean`

Whether generated identifiers use initialism-aware casing.

---

**`generation.naming.smartCasingDigitWordBoundary`** `boolean`

Whether smart casing preserves a word boundary after digits.

---

**`generation.layout`** `object`

Generated project and source layout.

---

\<ParamField path="generation.layout.outputDirectory" type=""project-root" | "source-root"" required= toc=>
Whether generated source is rooted at the project or its source directory.
\</ParamField>

**`generation.layout.packagePath`** `string`

The package-relative path for generated source files.

---

**`generation.serialization`** `object`

Generated model serialization behavior.

---

\<ParamField path="generation.serialization.enumRepresentation" type=""enum" | "union" | "literal" | "forward-compatible-enum" | "language-default"" required= toc=>
How schema enums are represented in generated code.
\</ParamField>

\<ParamField path="generation.serialization.additionalProperties" type=""allow" | "forbid" | "ignore" | "language-default"" required= toc=>
How undeclared object properties are handled.
\</ParamField>

**`generation.serialization.inlineTypes`** `boolean`

Whether inline schemas remain nested under their parent types.

---

**`generation.serialization.omitUndefined`** `boolean`

Whether undefined properties are omitted during serialization.

---

## `targets`

Language targets to generate. Each language may appear once per file. Generate a single target with `fern generate --target <language>`.

**`targets[].language`** `"typescript" | "python" | "java" | "kotlin" | "go" | "csharp" | "php" | "ruby" | "rust" | "swift" | "cli" | "mcp" | "terraform"` — required

The language to generate. The value determines which language-specific settings `generation` accepts.

---

**`targets[].generation`** `object`

Common and TypeScript-specific generation settings for this target.

---

**`targets[].generatorVersion`** `string`

The exact generator version used for this target.

---

**`targets[].sdkName`** `string`

An SDK name that overrides the root value for this target.

---

**`targets[].sdkVersion`** `string`

An SDK version that overrides the root value for this target.

---

**`targets[].client`** `object`

Client settings that override root client configuration for this target.

---

**`targets[].docs`** `object`

Documentation settings that override root documentation for this target.

---

**`targets[].package`** `object`

Package metadata that overrides root package configuration for this target.

---

**`targets[].output`** `object`

Output configuration that replaces the root output for this target.

---