# Configure servers

## Default Behavior

The OpenAPI specification allows you to define an array of servers that can be used to make requests to the API. These servers are generally used to define different environments (for example, production, development, and testing) available for the API.

```yaml
openapi: 3.0.3
info:
  title: Example
  version: 0.0.1
servers:
  - url: https://prod.example.com # Used as the default URL by the SDK
    description: Our production environment
  - url: https://sandbox.example.com
    description: Our sandbox environment
```

The Speakeasy SDK Generator automatically selects the first server URL from the OpenAPI document's servers list as the default endpoint. While this default is commonly set to the production server, it's flexible to accommodate application development cycles by reordering or modifying the server list.

## Declare Base Server URL

Speakeasy SDKs are battery-included, meaning they are designed to work out of the box with minimal configuration from end users.

If the OpenAPI document lacks server definitions (both at the global level and for individual operations) or relies on relative paths for server URLs, it's essential to set a default server endpoint. Set the default server endpoint by specifying a `baseServerUrl` in the SDK Generator configuration file (`gen.yaml`). This ensures the SDK always has a primary server to connect to for its operations.

```yaml
# ...
generation:
  baseServerUrl: "https://prod.example.com"
```

## Use Templated URLs

[Templated](https://spec.openapis.org/oas/v3.0.3#server-object) URLs provide a dynamic method to customize server endpoints based on runtime parameters, making them ideal for applications that serve multiple clients or operate in varied environments.

```yaml
servers:
  - url: https://{customer}.yourdomain.com
    variables:
      customer:
        default: api
        description: The name of the customer sending API requests.
```

These placeholders can then be replaced with specific values at runtime, allowing for customer-specific or environment-specific configurations without altering the SDK.

<Callout title="Note" type="info">
The templating feature is only supported for global server URLs and is not yet supported for per-operation server URLs.
</Callout>

## Managing Multiple Servers With IDs

For a better developer experience, define an ID for each server using the `x-speakeasy-server-id` extension. This simplifies the process of selecting between servers at SDK initialization.

```yaml
openapi: 3.0.3
info:
  title: Example
  version: 0.0.1
servers:
  - url: https://prod.example.com # Used as the default URL by the SDK
    description: Our production environment
    x-speakeasy-server-id: prod
  - url: https://sandbox.example.com
    description: Our sandbox environment
    x-speakeasy-server-id: sandbox
```

## Dynamic Server Declaration at Runtime

Dynamic server selection allows developers to switch between multiple predefined servers at runtime, offering flexibility across different deployment environments or client configurations.

<Callout title="Note" type="info">
The Speakeasy README file accompanying the generated SDK includes SDK-specific examples to guide through the process of dynamically selecting servers.
</Callout>

### Methods

#### Server Selection by Index

Specify a server from the predefined list based on its index.

<CodeWithTabs
  tabs={[
    {
      label: "Go",
      language: "go",
      code: `s := sdk.New(
		sdk.WithServerIndex(1)
)`,
    },
    {
      label: "Python",
      language: "python",
      code: `s = sdk.SDK(
    server_idx=1,
)`,
    },
    {
      label: "TypeScript",
      language: "typescript",
      code: `const sdk = new SDK({
    serverIdx: 1,
});`,
    },
    {
      label: "C#",
      language: "csharp",
      code: `const sdk = new SDK(serverIndex: 1);`,
    },
    {
      label: "PHP",
      language: "php",
      code: `$sdk = OpenAPI\\SDK::builder()->withServerIndex(1)->build();`,
    },
    {
      label: "Ruby",
      language: "ruby",
      code: `sdk = ::OpenApiSDK::SDK.new(server_idx: 1)`,
    },
  ]}
/>

#### Global URL Override

Set a global server URL at SDK initialization, overriding the base URL.

<CodeWithTabs
  tabs={[
    {
      label: "Go",
      language: "go",
      code: `s := sdk.New(
      // if the x-speakeasy-server-id extension is not used
      sdk.WithServerURL("https://sandbox.example.com")

      // with x-speakeasy-server-id extension
      sdk.WithServer("sandbox"),
  )`,
    },
    {
      label: "Python",
      language: "python",
      code: `s = sdk.SDK(
    # if the x-speakeasy-server-id extension is not used
    server_url="https://sandbox.example.com"

    # with x-speakeasy-server-id extension
    server="sandbox"

  )`,
    },
    {
      label: "TypeScript",
      language: "typescript",
      code: `const sdk = new SDK({
      // if the x-speakeasy-server-id extension is not used
      serverURL: "https://sandbox.example.com",

      // with x-speakeasy-server-id extension
      server: "sandbox",
  });`,
    },
    {
      label: "C#",
      language: "csharp",
      code: `const sdk = new SDK(
      // if the x-speakeasy-server-id extension is not used
      serverURL: "https://sandbox.example.com",

      // with x-speakeasy-server-id extension
      server: "sandbox",
  );`,
    },
    {
      label: "PHP",
      language: "php",
      code: `$sdk = OpenAPI\\SDK::builder()->
  // if the x-speakeasy-server-id extension is not used
  withServerUrl("https://sandbox.example.com")
  // with x-speakeasy-server-id extension
  withServer("sandbox")->build();`,
    },
    {
      label: "Ruby",
      language: "ruby",
      code: `sdk = OpenApiSDK::SDK.new(
    server_url: "https://sandbox.example.com",
    server: "sandbox"
  )`,
},
]}
/>

#### Per-Client or Per-Operation Override

Override the server URL for specific instances or API calls.

<Callout title="Caution" type="warning">
  If you choose to configure the SDK URL at runtime and relative paths were used
  in the OpenAPI document, make sure that you account for the `baseURL` when
  initializing the SDK server configuration.
</Callout>
