# Configure Sdk Options

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-speakeasy-api-skills-configure-sdk-options`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [speakeasy-api](https://agentstack.voostack.com/s/speakeasy-api)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [speakeasy-api](https://github.com/speakeasy-api)
- **Source:** https://github.com/speakeasy-api/skills/tree/master/skills/configure-sdk-options
- **Website:** https://www.speakeasy.com/docs

## Install

```sh
agentstack add skill-speakeasy-api-skills-configure-sdk-options
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Configure SDK Options

Configure gen.yaml options for an existing Speakeasy SDK. Supports TypeScript, Python, Go, Java, C#, PHP, and Ruby.

> **For new SDK projects**: Use `start-new-sdk-project` skill instead. This skill is for configuring an existing SDK.

## Language-Specific Guides

For comprehensive configuration details, see the language-specific guides:

| Language | Guide | Key Features |
|----------|-------|--------------|
| TypeScript | [content/languages/typescript.md](content/languages/typescript.md) | Zod validation, React Query, standalone functions, dual module format |
| Python | [content/languages/python.md](content/languages/python.md) | Pydantic models, async modes (both/split), uv/poetry support |
| Go | [content/languages/go.md](content/languages/go.md) | Response formats, interface generation, K8s integration |
| Java | [content/languages/java.md](content/languages/java.md) | Builder pattern, Gradle customization, Maven Central publishing |
| C# | [content/languages/csharp.md](content/languages/csharp.md) | Async/await, cancellation tokens, DI integration, NuGet |
| PHP | [content/languages/php.md](content/languages/php.md) | Laravel integration, Guzzle config, Packagist publishing |
| Ruby | [content/languages/ruby.md](content/languages/ruby.md) | Sorbet typing, Rails integration, RubyGems publishing |

These guides include detailed configuration options, code examples, framework integrations, and publishing instructions.

## When to Use

- Configuring language-specific gen.yaml options on an existing SDK
- Setting up SDK hooks, async patterns, or publishing
- Configuring runtime behavior (retries, timeouts, server selection) in application code
- User says: "configure SDK", "gen.yaml options", "SDK config", "runtime override", "per-call config"
- User asks about: Zod, Pydantic, NuGet, PyPI, npm, Maven Central, Packagist, RubyGems

## Inputs

| Input | Required | Description |
|-------|----------|-------------|
| Existing SDK | Yes | SDK with `.speakeasy/workflow.yaml` already created |
| Target language | Yes | TypeScript, Python, Go, Java, C#, PHP, or Ruby |

## Outputs

| Output | Description |
|--------|-------------|
| Updated gen.yaml | Language-specific configuration |
| Hook files | Custom hooks if enabled |

## Prerequisites

You must have an existing SDK with `.speakeasy/workflow.yaml`. If not, run:

```bash
speakeasy quickstart --skip-interactive --output console \
  -s openapi.yaml -t  -n "MySDK" -p ""
```

## Common Configuration (All Languages)

These options apply to all SDK targets in gen.yaml:

```yaml
:
  version: 1.0.0
  packageName: "my-sdk"

  # Method signatures
  maxMethodParams: 4              # Params before request object
  flatteningOrder: parameters-first

  # Error handling
  responseFormat: flat            # or "envelope" (Go)
  clientServerStatusCodesAsErrors: true
```

## TypeScript Configuration

```yaml
typescript:
  version: 1.0.0
  packageName: "@myorg/my-sdk"
  moduleFormat: dual              # esm, commonjs, or dual
  zodVersion: v4-mini             # v3, v4, or v4-mini
  enableCustomCodeRegions: true   # For custom code
  enableReactQuery: true          # React Query hooks
```

| Feature | Notes |
|---------|-------|
| Zod validation | Automatic for all models |
| Tree-shaking | Use `moduleFormat: dual` + standalone functions |
| JSR publishing | Create `jsr.json`, run `deno publish` |
| npm publishing | Standard `npm publish` |

**Standalone functions for tree-shaking:**
```typescript
import { TodoCore } from "my-sdk/core.js";
import { todosCreate } from "my-sdk/funcs/todosCreate.js";
const sdk = new TodoCore({ apiKey: "..." });
```

## Python Configuration

```yaml
python:
  version: 1.0.0
  packageName: "my-sdk"
  asyncMode: both                 # both or split
  packageManager: uv              # uv or poetry
  envVarPrefix: ""                # Prefix for env config
```

| Feature | Notes |
|---------|-------|
| Pydantic models | Automatic for all models |
| Async mode `both` | `sdk.method()` and `sdk.method_async()` |
| Async mode `split` | `SDK()` and `AsyncSDK()` constructors |
| PyPI publishing | `uv publish` or `poetry publish` |

**Async patterns:**
```python
# asyncMode: both (default)
result = sdk.users.list()           # sync
result = await sdk.users.list_async() # async

# asyncMode: split
sdk = MySDK()                       # sync only
async_sdk = AsyncMySDK()            # async only
```

## Go Configuration

```yaml
go:
  version: 0.1.0
  packageName: github.com/myorg/my-sdk
  maxMethodParams: 2
  methodArguments: require-security-and-request
  responseFormat: envelope
  flattenGlobalSecurity: true
```

| Feature | Notes |
|---------|-------|
| Interfaces | Generate with ifacemaker |
| Mocks | Generate with mockery |
| K8s integration | Add kubebuilder markers, run controller-gen |

**Interface generation for testing:**
```bash
go install github.com/vburenin/ifacemaker@latest
go install github.com/vektra/mockery/v2@latest
ifacemaker --file consumers.go --struct Consumers --iface ConsumersSDK --output consumers_i.go
mockery
```

## Java Configuration

```yaml
java:
  version: 1.0.0
  groupID: com.myorg
  artifactID: my-sdk
  packageName: com.myorg.mysdk
  methodArguments: require-security-and-request
```

| Feature | Notes |
|---------|-------|
| Builder pattern | Automatic for all classes |
| Build customization | Use `build-extras.gradle` (preserved) |
| Maven Central | `./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository` |

**Client usage:**
```java
MySdk sdk = MySdk.builder()
    .security(Security.builder().apiKey("key").build())
    .build();
```

## C# Configuration

```yaml
csharp:
  version: 1.0.0
  packageName: MyOrg.MySDK
  dotnetVersion: "6.0"
  baseErrorName: MySDKException
```

| Feature | Notes |
|---------|-------|
| Async/await | All operations async by default |
| SSE streaming | `EventStream` support |
| NuGet publishing | `dotnet pack -c Release && dotnet nuget push` |

**Async with cancellation:**
```csharp
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = await sdk.Users.ListAsync(cancellationToken: cts.Token);
```

## PHP Configuration

```yaml
php:
  version: 1.0.0
  packageName: myorg/my-sdk
  namespace: MyOrg\MySDK
```

| Feature | Notes |
|---------|-------|
| PHP 8.2+ | Required minimum version |
| Guzzle | HTTP client (configurable timeout) |
| Packagist | Tag release, register on Packagist.org |

**Security callback for token refresh:**
```php
$sdk = MySDK\MySDK::builder()
    ->setSecuritySource(fn() => getTokenFromCache() ?? refreshToken())
    ->build();
```

## Ruby Configuration

```yaml
ruby:
  version: 1.0.0
  packageName: my-sdk
  module: MySdk
  typingStrategy: sorbet          # sorbet or none
```

| Feature | Notes |
|---------|-------|
| Sorbet typing | Optional, enable with `typingStrategy: sorbet` |
| Faraday | HTTP client |
| RubyGems | `gem build && gem push` |

## SDK Hooks (All Languages)

Enable custom hooks with `enableCustomCodeRegions: true`. Hook files are preserved across regeneration.

| Language | Hook Location |
|----------|---------------|
| TypeScript | `src/hooks/` |
| Python | `src//_hooks/` |
| Go | `internal/hooks/` |
| Java | `src/main/java/.../hooks/` |
| C# | `src/.../Hooks/` |
| PHP | `src/Hooks/` |
| Ruby | `lib/.../sdk_hooks/` |

See `customize-sdk-hooks` skill for detailed hook implementation.

## Runtime Overrides

Runtime behavior can be configured at SDK instantiation or per-call. These override gen.yaml defaults.

### Server Selection

Define server IDs in OpenAPI spec, then select at runtime:

```yaml
# OpenAPI spec
servers:
  - url: https://api.example.com
    x-speakeasy-server-id: production
  - url: https://sandbox.example.com
    x-speakeasy-server-id: sandbox
```

| Language | SDK Constructor | Custom URL |
|----------|-----------------|------------|
| TypeScript | `new SDK({ server: "sandbox" })` | `new SDK({ serverURL: "..." })` |
| Python | `SDK(server="sandbox")` | `SDK(server_url="...")` |
| Go | `SDK.New(SDK.WithServer("sandbox"))` | `SDK.WithServerURL("...")` |

### Retry Overrides

Override retry behavior per-call (spec defaults set via `x-speakeasy-retries`):

**TypeScript:**
```typescript
const res = await sdk.payments.create({ amount: 1000 }, {
  retries: {
    strategy: "backoff",
    backoff: { initialInterval: 1000, maxInterval: 30000, maxElapsedTime: 120000, exponent: 2.0 },
    retryConnectionErrors: true,
  },
});
```

**Python:**
```python
from sdk.utils import BackoffStrategy, RetryConfig
res = sdk.payments.create(amount=1000, retries=RetryConfig("backoff",
    backoff=BackoffStrategy(1000, 30000, 120000, 2.0), retry_connection_errors=True))
```

**Go:**
```go
res, err := sdk.Payments.Create(ctx, req, operations.WithRetries(retry.Config{
    Strategy: "backoff", Backoff: &retry.BackoffStrategy{
        InitialInterval: 1000, MaxInterval: 30000, MaxElapsedTime: 120000, Exponent: 2.0},
    RetryConnectionErrors: true}))
```

### Timeout Overrides

Set global timeout on SDK constructor, or per-call:

| Language | Global | Per-call |
|----------|--------|----------|
| TypeScript | `new SDK({ timeoutMs: 30000 })` | `sdk.op({}, { timeoutMs: 60000 })` |
| Python | `SDK(timeout_ms=30000)` | `sdk.op(timeout_ms=60000)` |
| Go | `SDK.WithTimeoutMs(30000)` | `operations.WithTimeoutMs(60000)` |

### Pagination Usage

SDK auto-generates pagination helpers when `x-speakeasy-pagination` is set in spec:

```typescript
// Auto-iterate all pages
for await (const user of await sdk.users.list({ limit: 50 })) {
  console.log(user.name);
}

// Manual pagination
let page = await sdk.users.list({ limit: 50 });
while (page) {
  for (const user of page.data) { console.log(user.name); }
  page = await page.next();
}
```

## Decision Framework

| Situation | Action |
|-----------|--------|
| Need tree-shaking (TS) | Set `moduleFormat: dual`, use standalone functions |
| Need async/sync (Python) | Set `asyncMode: both` (default) |
| Need separate async client | Set `asyncMode: split` (Python) |
| Need interfaces for testing (Go) | Use ifacemaker + mockery |
| Need custom build config (Java) | Edit `build-extras.gradle` |
| Need runtime retry override | Pass `retries` config in per-call options |
| Need runtime timeout override | Set `timeoutMs` on constructor or per-call |
| Need server switching | Use `x-speakeasy-server-id` in spec, select at runtime |

## What NOT to Do

- **Do NOT** use this skill for initial SDK generation - use `start-new-sdk-project`
- **Do NOT** edit generated files outside custom code regions
- **Do NOT** modify files in `src/` that aren't in preserved directories (hooks, extra)

## Troubleshooting

| Language | Issue | Solution |
|----------|-------|----------|
| TypeScript | Bundle too large | Use standalone functions |
| Python | Async pagination blocking | Enable `fixFlags.asyncPaginationSep2025: true` |
| Go | Interface not generated | Ensure struct is exported (capitalized) |
| Java | Gradle sync fails | Run `./gradlew --refresh-dependencies` |
| C# | Async deadlock | Use `await` not `.Result` |
| PHP | PHP version error | Requires PHP 8.2+ |
| Ruby | Sorbet errors | Run `bundle exec tapioca gems` |
| All | Retries not working | Ensure `x-speakeasy-retries` at document root or operation level |
| All | Server ID not recognized | Add `x-speakeasy-server-id` to each server entry |
| All | Pagination `next()` undefined | Add `x-speakeasy-pagination` to the list operation |

## After Making Changes

After modifying gen.yaml configuration, **prompt the user** to regenerate the SDK:

> **Configuration complete.** Would you like to regenerate the SDK now with `speakeasy run`?

If the user confirms, run:

```bash
speakeasy run --output console
```

Changes to gen.yaml only take effect after regeneration.

## Related Skills

- `start-new-sdk-project` - Initial SDK generation
- `customize-sdk-hooks` - Detailed hook implementation
- `manage-openapi-overlays` - Spec customization

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [speakeasy-api](https://github.com/speakeasy-api)
- **Source:** [speakeasy-api/skills](https://github.com/speakeasy-api/skills)
- **License:** Apache-2.0
- **Homepage:** https://www.speakeasy.com/docs

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-speakeasy-api-skills-configure-sdk-options
- Seller: https://agentstack.voostack.com/s/speakeasy-api
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
