> ## Documentation Index
> Fetch the complete documentation index at: https://docs.limitless.exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# Go SDK

> Official Go SDK for the Limitless Exchange API

## Overview

The Limitless Exchange Go SDK (`limitless-exchange-go-sdk`) is a fully typed Go client for interacting with both **CLOB** and **NegRisk** prediction markets. It provides:

* Strongly typed structs for all API requests and responses
* Automatic venue caching for EIP-712 order signing
* Built-in retry logic with exponential backoff (using Go generics)
* WebSocket streaming with auto-reconnect
* Functional options pattern for flexible configuration

<Note>
  The SDK requires **Go 1.22+**. All I/O methods accept a `context.Context` as the first parameter and return `error` as the last return value, following standard Go conventions.
</Note>

## Installation

```bash theme={null}
go get github.com/limitless-labs-group/limitless-exchange-go-sdk@latest
```

## Quick Start

<Steps>
  <Step title="Initialize the HTTP client">
    ```go theme={null}
    package main

    import (
        "context"
        "fmt"

        limitless "github.com/limitless-labs-group/limitless-exchange-go-sdk/limitless"
    )

    func main() {
        client := limitless.NewHttpClient() // loads LIMITLESS_API_KEY from env
    }
    ```
  </Step>

  <Step title="Fetch active markets">
    ```go theme={null}
    func main() {
        client := limitless.NewHttpClient()
        marketFetcher := limitless.NewMarketFetcher(client)

        ctx := context.Background()
        result, err := marketFetcher.GetActiveMarkets(ctx, &limitless.ActiveMarketsParams{
            Limit: 10,
            Page:  1,
        })
        if err != nil {
            panic(err)
        }

        for _, m := range result.Data {
            fmt.Println(m.Title, m.Slug)
        }
    }
    ```
  </Step>

  <Step title="Check your positions">
    ```go theme={null}
    func main() {
        client := limitless.NewHttpClient()
        portfolio := limitless.NewPortfolioFetcher(client)

        ctx := context.Background()
        positions, err := portfolio.GetPositions(ctx)
        if err != nil {
            panic(err)
        }

        for _, pos := range positions.CLOB {
            fmt.Println(pos.Market.Title)
        }
    }
    ```
  </Step>
</Steps>

## Authentication

Authentication uses scoped API tokens with HMAC-SHA256 request signing:

* HMAC headers `lmts-api-key`, `lmts-timestamp`, `lmts-signature` — the SDK builds and signs them for you when you pass HMAC credentials

<Tabs>
  <Tab title="Environment variable (recommended)">
    Set the `LIMITLESS_API_KEY` environment variable. The `HttpClient` loads it automatically:

    ```bash theme={null}
    export LIMITLESS_API_KEY="lmts_your_key_here"
    ```

    ```go theme={null}
    client := limitless.NewHttpClient() // auto-loads LIMITLESS_API_KEY
    ```
  </Tab>

  <Tab title="HMAC (partner/programmatic)">
    Use the root client with scoped token credentials:

    ```go theme={null}
    client := limitless.NewClient(
        limitless.WithHMACCredentials(limitless.HMACCredentials{
            TokenID: "your-token-id",
            Secret:  "your-base64-secret",
        }),
    )
    ```
  </Tab>

  <Tab title="Explicit option">
    Pass `WithAPIKey` directly to the constructor:

    ```go theme={null}
    client := limitless.NewHttpClient(
        limitless.WithAPIKey("lmts_your_key_here"),
    )
    ```
  </Tab>
</Tabs>

<Info>
  With `WithHMACCredentials(...)` set, the SDK automatically generates and sends `lmts-api-key`, `lmts-timestamp`, and `lmts-signature`. Do not manually build HMAC headers when using the SDK client.
</Info>

<Warning>
  Never hardcode API keys in source code or commit them to version control. Use environment variables or a secrets manager.
</Warning>

## Root Client

The recommended entrypoint is the root `Client`, which composes all domain services (markets, portfolio, orders, API tokens, partner accounts, delegated orders):

```go theme={null}
client := limitless.NewClient(
    limitless.WithAPIKey("lmts_your_key_here"),
)

// client.Markets, client.Portfolio, client.Pages,
// client.ApiTokens, client.PartnerAccounts, client.DelegatedOrders
```

For partner integrations using HMAC authentication:

```go theme={null}
client := limitless.NewClient(
    limitless.WithHMACCredentials(limitless.HMACCredentials{
        TokenID: "your-token-id",
        Secret:  "your-base64-secret",
    }),
)
```

## HttpClient Options

The `HttpClient` uses the functional options pattern. Pass any combination of options to `NewHttpClient()` or `NewClient()`:

| Option                       | Type                | Default                          | Description                                                                                       |
| ---------------------------- | ------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------- |
| `WithBaseURL(url)`           | `string`            | `https://api.limitless.exchange` | API base URL                                                                                      |
| `WithAPIKey(key)`            | `string`            | Reads `LIMITLESS_API_KEY` env    | Legacy API key authentication                                                                     |
| `WithHMACCredentials(creds)` | `HMACCredentials`   | --                               | HMAC credentials for scoped API token auth (see [Programmatic API](/developers/programmatic-api)) |
| `WithTimeout(d)`             | `time.Duration`     | `30s`                            | HTTP request timeout                                                                              |
| `WithMaxIdleConns(n)`        | `int`               | `50`                             | Maximum idle connections in the pool                                                              |
| `WithIdleConnTimeout(d)`     | `time.Duration`     | `60s`                            | How long idle connections remain in the pool                                                      |
| `WithTransport(t)`           | `http.RoundTripper` | Default transport                | Custom HTTP transport                                                                             |
| `WithAdditionalHeaders(h)`   | `map[string]string` | `nil`                            | Extra headers merged into every request                                                           |
| `WithLogger(l)`              | `Logger`            | `NoOpLogger`                     | Logger for request/response tracing                                                               |

```go theme={null}
client := limitless.NewHttpClient(
    limitless.WithAPIKey("lmts_your_key_here"),
    limitless.WithTimeout(15 * time.Second),
    limitless.WithLogger(limitless.NewConsoleLogger(limitless.LogLevelDebug)),
)
```

## Logging

The SDK provides a pluggable `Logger` interface with a built-in `ConsoleLogger`:

```go theme={null}
logger := limitless.NewConsoleLogger(limitless.LogLevelDebug)
client := limitless.NewHttpClient(limitless.WithLogger(logger))
```

| Level           | Description                                                                |
| --------------- | -------------------------------------------------------------------------- |
| `LogLevelDebug` | Verbose output including headers, venue cache operations, and raw payloads |
| `LogLevelInfo`  | General operational messages                                               |
| `LogLevelWarn`  | Warnings about potential issues                                            |
| `LogLevelError` | Errors only                                                                |

<Tip>
  Set `LogLevelDebug` during development to see request headers, venue cache hits/misses, and full API responses. Switch to `LogLevelInfo` or `LogLevelWarn` in production.
</Tip>

## Source Code

The SDK is open source. Contributions and issue reports are welcome.

<Card title="GitHub Repository" icon="github" href="https://github.com/limitless-labs-group/limitless-exchange-go-sdk">
  Browse the source, report issues, and contribute at github.com/limitless-labs-group/limitless-exchange-go-sdk
</Card>

## Disclaimer

<Warning>
  **USE AT YOUR OWN RISK.** This SDK is provided as-is with no guarantees. You are solely responsible for any trading activity conducted through this software. Limitless Exchange is not available to users in the United States or other restricted jurisdictions. By using this SDK, you confirm compliance with all applicable local laws and regulations.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Markets" icon="chart-bar" href="/developers/sdk/go/markets">
    Discover markets, fetch orderbooks, and understand venue caching.
  </Card>

  <Card title="Market Pages" icon="compass" href="/developers/sdk/go/market-pages">
    Browse markets by category with navigation, filters, and pagination.
  </Card>

  <Card title="Trading & Orders" icon="arrow-right-arrow-left" href="/developers/sdk/go/orders">
    Place GTC and FOK orders, cancel orders, and manage token approvals.
  </Card>

  <Card title="Portfolio & Positions" icon="wallet" href="/developers/sdk/go/portfolio">
    Track your open positions and trading history.
  </Card>

  <Card title="API Tokens" icon="shield-halved" href="/developers/sdk/go/api-tokens">
    Derive, list, and revoke scoped HMAC tokens for partner integrations.
  </Card>

  <Card title="Partner Accounts" icon="users" href="/developers/sdk/go/partner-accounts">
    Create sub-accounts with server wallets or EOA verification.
  </Card>

  <Card title="Delegated Orders" icon="user-check" href="/developers/sdk/go/delegated-orders">
    Place orders on behalf of sub-accounts with server-side signing.
  </Card>

  <Card title="WebSocket Streaming" icon="bolt" href="/developers/sdk/go/websocket">
    Subscribe to real-time orderbook and price updates.
  </Card>

  <Card title="Error Handling & Retry" icon="rotate" href="/developers/sdk/go/error-handling">
    Retry logic, error types, and debugging strategies.
  </Card>
</CardGroup>

## Server Wallet Redemption and Withdrawal

For partner server-wallet sub-accounts, the SDK provides helper methods for payout settlement and treasury movement:

* [`POST /portfolio/redeem`](/api-reference/portfolio/redeem) — claim resolved positions
* [`POST /portfolio/withdraw`](/api-reference/portfolio/withdraw) — transfer ERC20 funds from managed sub-accounts
* [`POST /portfolio/withdrawal-addresses`](/api-reference/portfolio/add-withdrawal-address) — allowlist an explicit treasury destination with Privy identity auth
* [`DELETE /portfolio/withdrawal-addresses/:address`](/api-reference/portfolio/delete-withdrawal-address) — remove an allowlisted destination with Privy identity auth

Required scopes for `apiToken` auth: `trading` for redeem and `withdrawal` for withdraw. Allowlist add/delete calls use a Privy identity token instead of API-token/HMAC auth.

```go theme={null}
identityToken := os.Getenv("PRIVY_IDENTITY_TOKEN")
treasuryAddress := "0x0F3262730c909408042F9Da345a916dc0e1F9787"

_, err := client.PartnerAccounts.AddWithdrawalAddress(ctx, identityToken, limitless.PartnerWithdrawalAddressInput{
    Address: treasuryAddress,
    Label:   "treasury",
})
if err != nil {
    log.Fatal(err)
}

withdraw, err := client.ServerWallets.Withdraw(ctx, limitless.WithdrawServerWalletParams{
    Amount:      "1000000",
    OnBehalfOf:  childProfileID,
    Destination: treasuryAddress,
})
if err != nil {
    log.Fatal(err)
}

fmt.Println(withdraw.Destination)
```

Set `OnBehalfOf` when withdrawing from a child server-wallet profile. `Destination` is optional for child withdrawals; when omitted, the API defaults to the authenticated partner smart wallet when present, otherwise the authenticated partner account. Leave `OnBehalfOf` as zero only when withdrawing the authenticated caller's own server wallet to an explicit `Destination`.

See the full flow and scope guidance in [Programmatic API](/developers/programmatic-api).
