> This page is for SDKs, version Legacy.
> 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.

# Ruby configuration

> Configuration options for the Fern Ruby SDK.

> **You're viewing the legacy SDK docs**
>
> These pages cover SDK generation configured with `generators.yml`. New projects use `sdk-config.yml`, so see [the Current version of this page](/learn/sdks/generators/ruby/configuration) for up-to-date guidance. To move an existing project, follow the [SDK Config migration guide](/learn/sdks/legacy/generators/migration-guides/sdk-config), which walks through `fern sdk migrate`, and review the [`sdk-config.yml` reference](/learn/sdks/reference/sdk-config).

You can customize the behavior of the Ruby SDK generator in `generators.yml`:

**`generators.yml`**

```yaml {6-14} title="generators.yml"
groups:
  ruby-sdk:
    generators:
      - name: fern-ruby-sdk
        version: 1.39.2
        config:
          moduleName: YourModuleName
          enableWireTests: true
          extraDependencies:
            faraday: "~> 2.0"
            oj: "~> 3.0"
          extraDevDependencies:
            rspec: "~> 3.0"
            webmock: "~> 3.0"
```

**`auto-generate-idempotency-key`** `boolean | object` — default: false

Overrides the API-wide [`api.settings.auto-generate-idempotency-key`](/learn/sdks/legacy/reference/generators-yml#settings) for this SDK. Set `true` to attach an [idempotency-key header](/learn/sdks/legacy/deep-dives/idempotency#auto-generate-idempotency-keys) to eligible requests (`POST` and `PUT` by default) unless the caller provides one, or `false` to opt this SDK out when auto-generation is enabled API-wide. Pass an object to customize `header-name` and `methods`.

---

**`clientModuleName`** `string`

Custom name for the client module. This allows you to customize the module name that wraps the generated client class.

---

**`customPagerName`** `string`

Custom name for the pager class used in paginated endpoints. By default, the generator creates a standard pager class, but you can customize its name to match your SDK's naming conventions.

---

**`customReadmeSections`** `array of objects`

Add custom sections to the generated README file. Each section requires a title and content.

```yaml
config:
  customReadmeSections:
    - title: "Custom integration"
      content: "Instructions for custom integration..."
    - title: "Advanced usage"
      content: "Advanced usage examples for {{ packageName }}"
```

The content supports template variables like `{{ packageName }}` that are replaced with actual values during generation.

---

**`enableWireTests`** `boolean` — default: false

When enabled, generates [mock server (wire) tests](/learn/sdks/legacy/deep-dives/testing#mock-server-tests) to verify that the SDK sends and receives HTTP requests as expected.

---

**`extraDependencies`** `object`

> **Enterprise feature**
>
> This feature is available only for the [Enterprise plan](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com).

Specify additional dependencies to include in the generated SDK's gemspec. This is useful when you need to add custom gems that your SDK depends on.

---

**`extraDevDependencies`** `object`

> **Enterprise feature**
>
> This feature is available only for the [Enterprise plan](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com).

Specify additional development dependencies to include in the generated SDK's Gemfile. These are dependencies used for development and testing but not required by end users.

---

**`maxRetries`** `number`

The default number of retries for failed requests. When not set, the generated SDK uses its own built-in default. SDK users can still override this per-request via request options.

---

**`moduleName`** `string`

Custom module name for the generated SDK. This sets the top-level Ruby module that wraps all generated code. By default, the module name is derived from the package name in your publish configuration or your organization name.

```yaml
config:
  moduleName: MyCustomModule
```

This generates code like:

```ruby
module MyCustomModule
  class Client
    # ...
  end
end
```

---

**`offsetSemantics`** `'item-index' | 'page-index'`

Controls how the offset parameter is interpreted for [auto-paginated](/learn/sdks/legacy/deep-dives/auto-pagination) endpoints.

* `item-index`: The offset counts individual items (e.g., offset 20 skips the first 20 items).
* `page-index`: The offset counts pages (e.g., offset 3 skips to page 3).

---

**`omitFernHeaders`** `boolean` — default: false

When enabled, the generated SDK omits the `X-Fern-Language`, `X-Fern-SDK-Name`, and `X-Fern-SDK-Version` headers from HTTP requests.

---

**`includePlatformHeaders`** `boolean` — default: false

When enabled, the generated SDK sends a single structured `User-Agent` header of the form `{sdkName}/{version} ({os}; {arch}) {runtime}/{runtimeVersion}` (for example, `my-sdk/0.0.1 (linux; x86_64) Ruby/3.2.0`), carrying SDK, operating system, architecture, and runtime information in place of the default `User-Agent` and discrete platform headers. A configured [`user-agent`](#user-agent) template supplies the leading product token. If `omitFernHeaders` is enabled, no `User-Agent` or platform headers are sent and this option has no effect.

---

**`allowUserAgentAppInfo`** `boolean` — default: false

When enabled, the generated client accepts an optional `app_info` keyword of the shape `{ name:, version:, comment: }`, which appends a `{name}/{version} ({comment})` [product token](https://www.rfc-editor.org/rfc/rfc9110#name-user-agent) to the `User-Agent` header so an application built on the SDK can identify itself to the API. The application passes a required `name` plus an optional `version` and `comment`; omitted or blank values are dropped from the token. An explicit `User-Agent` header takes precedence, and [`omitFernHeaders`](#omitfernheaders) suppresses the header entirely.

```ruby
app_info: { name: "partner-app", version: "3.1.0", comment: "+https://partner.example" }
# User-Agent: my-sdk/0.0.1 (linux; x86_64) Ruby/3.2.0 partner-app/3.1.0 (+https://partner.example)
```

---

**`allowCustomHttpClient`** `boolean` — default: false

When enabled, the generated client accepts an optional `http_client:` keyword that replaces the SDK's built-in `Net::HTTP` connection. Use it to route requests through a proxy, configure custom TLS, reuse connections, or add request and response interceptors for logging, signing, or header injection.

The object must respond to `request(url, http_request)`, where `url` is a `URI` and `http_request` is a `Net::HTTPGenericRequest`, and return a `Net::HTTPResponse`. The client passes it to every request, including OAuth and inferred-auth token requests. The SDK's retry loop still wraps each attempt, but the custom client owns its connection settings, including timeouts.

**`generators.yml`**

```yaml title="generators.yml"
config:
  allowCustomHttpClient: true
```

```ruby
class LoggingTransport
  def request(url, http_request)
    puts "#{http_request.method} #{url}"
    Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == "https") do |http|
      http.request(http_request)
    end
  end
end

client = Acme::Client.new(token: "...", http_client: LoggingTransport.new)
```

---

**`requirePaths`** `array of strings`

> **Enterprise feature**
>
> This feature is available only for the [Enterprise plan](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com).

Paths to files that will be auto-loaded when the gem is required. This is useful for including custom integrations or extensions that should be loaded automatically.

```yaml
config:
  requirePaths:
    - custom_integration
    - sentry_integration
```

This will load `lib/<gem>/custom_integration.rb` and `lib/<gem>/sentry_integration.rb` when the gem is required.

---

**`user-agent`** `string` — default: \{packageName}/\{version}

Sets a custom `User-Agent` header template for requests sent by the generated SDK. The template is resolved at generation time and supports the `{packageName}`, `{version}`, `{language}`, `{generatorVersion}`, `{organization}`, and `{apiName}` placeholders.

**`generators.yml`**

```yaml title="generators.yml"
config:
  user-agent: "plantstore-ruby-sdk/{version}"
```

This sends `User-Agent: plantstore-ruby-sdk/0.1.0`. With [`includePlatformHeaders`](#includeplatformheaders) enabled, the resolved value leads the structured header: `User-Agent: plantstore-ruby-sdk/0.1.0 (linux; x86_64) Ruby/3.2.0`. A value that doesn't end in a version, such as `plantstore/sdk-ruby`, is used as-is. The [`allowUserAgentAppInfo`](#allowuseragentappinfo) token is appended after either form.

---

**`respectAuthSchemeNames`** `boolean` — default: false

Names the client's credential keyword arguments after the auth schemes in your API definition. For example, `token: { name: apiKey }` produces `Client.new(api_key:)` instead of `Client.new(token:)`. Enabling it renames the keyword argument for existing callers of a published gem.

---

**`requireAuthCredentials`** `boolean` — default: false

When enabled, the client constructor raises `ArgumentError` if a bearer token or header-auth credential is empty, whether it's passed as an argument or read from its environment variable. Without this option, the client is constructed and sends an empty auth header on every request.

```ruby
Acme::Client.new
# ArgumentError: secret is required; pass secret: or set the ACME_SECRET environment variable
```

The check is skipped for endpoint-level security and for `any`-composed auth with multiple schemes, where each credential is independently optional.

---

**`respectOptionalRequestBody`** `boolean` — default: false

Lets callers omit the request body on endpoints with an optional request body. A call that omits it sends no body and no `Content-Type` header, instead of an empty JSON object (`{}`). Enable this when your API treats a missing body differently from an empty one.

Only applies to request bodies declared as a single named type. Required bodies, inlined request properties, and form-urlencoded bodies are unaffected.

---

**`wrapInvalidJsonResponses`** `boolean` — default: false

When enabled, a 2xx response whose body isn't valid JSON raises `Errors::ResponseError`, carrying the raw body and status code, instead of letting `JSON::ParserError` escape to the caller.

---