# Intro

> The Rust SDK, the primary and most complete Iggy client, and where its source lives.

Rendered page: https://iggy.apache.org/docs/sdk/rust/intro/

Source: https://github.com/apache/iggy-website/blob/main/content/docs/sdk/rust/intro.mdx

Docs version: server 0.9.0, Rust SDK 0.11.0, CLI 0.14.0, Node.js SDK 0.10.0, and the Python, Java, Go and C# SDKs at 0.9.0

The Rust SDK is the primary and most feature-complete client for Iggy. It is available on [crates.io](https://crates.io/crates/iggy) and the source code is part of the [core repository](https://github.com/apache/iggy/tree/master/core/sdk).

Run from your application crate to add the published SDK:

```bash
cargo add iggy
```

Use an SDK release compatible with your server. For unreleased changes, build both from the same checkout; the [Getting Started](https://iggy.apache.org/docs/introduction/getting-started) guide shows the source dependency setup.

## Prerequisites

The examples below log in with `iggy`/`iggy`. For a new local development instance, with no `IGGY_ROOT_USERNAME` or `IGGY_ROOT_PASSWORD` overrides, use:

```bash
cargo run --bin iggy-server -- --fresh --with-default-root-credentials
```

`--fresh` **wipes this replica's local data directory**. Environment credentials take precedence over the flag, and bootstrap settings do not replace recovered credentials. In a cluster, a fresh replica can recover credentials from peers. Use disposable development data. A new standalone server without explicit credentials generates a root password; a new cluster requires explicit credentials.

## High-level vs low-level API

The SDK provides two layers. The snippets below assume an async Tokio context with a `Result` return type.

**High-level API (recommended)** - the easiest way to get started. It handles connection management, auto-batching, consumer group lifecycle, offset commits, retry logic, and reconnection out of the box. Use `IggyClient`, `IggyProducer`, and `IggyConsumer` for the best developer experience.

```rust
use iggy::prelude::*;

// Connect with a connection string
let client = IggyClient::from_connection_string("iggy://iggy:iggy@127.0.0.1:8090")?;
client.connect().await?;

// Or use the builder
let client = IggyClientBuilder::new()
    .with_tcp()
    .with_server_address("127.0.0.1:8090".to_string())
    .build()?;
client.connect().await?;
client.login_user("iggy", "iggy").await?;
```

**Low-level API** - direct access to individual protocol operations. Useful when you need fine-grained control over every request, or when building custom abstractions on top.

The high-level API is built on top of the low-level one, so you can always drop down when needed.

## Connection string

The connection string is the simplest way to configure the client. It supports all four transport protocols:

```text
iggy://user:pass@host:port              (TCP, default)
iggy+tcp://user:pass@host:port          (TCP, explicit)
iggy+quic://user:pass@host:port         (QUIC)
iggy+http://user:pass@host:port         (HTTP)
iggy+ws://user:pass@host:port           (WebSocket)
```

TCP, QUIC, and WebSocket apply connection-string credentials on `connect()`. HTTP requires an explicit login and supports ordinary consumers only.

Options can be appended as query parameters:

```text
iggy://iggy:iggy@127.0.0.1:8090?nodelay=true&heartbeat_interval=5s
iggy://iggy:iggy@127.0.0.1:8090?reconnection_retries=unlimited&heartbeat_interval=5s
```

Personal Access Tokens are also supported. Any credential without a colon is treated as a PAT. Paste the token exactly as the server returned it, with **no prefix**:

```text
iggy://<personal-access-token>@127.0.0.1:8090
```

See [Connection Strings](https://iggy.apache.org/docs/sdk/connection-strings) for the full per-transport option tables and defaults.

## Quick example

```rust
use iggy::prelude::*;
use std::str::FromStr;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = IggyClient::from_connection_string("iggy://iggy:iggy@127.0.0.1:8090")?;
    client.connect().await?;

    // Re-running this example is fine: an existing stream or topic is not an error.
    match client.create_stream("my-stream").await {
        Ok(_) | Err(IggyError::StreamNameAlreadyExists(_)) => {}
        Err(e) => return Err(e.into()),
    }
    // Every topic knob rides `TopicCreateOptions`; fields left as `None`
    // resolve against the server's defaults at admission.
    match client
        .create_topic(
            &"my-stream".try_into()?,
            "my-topic",
            &TopicCreateOptions {
                partitions_count: Some(1),
                message_expiry: Some(IggyExpiry::NeverExpire),
                ..TopicCreateOptions::default()
            },
        )
        .await
    {
        Ok(_) | Err(IggyError::TopicNameAlreadyExists(_, _)) => {}
        Err(e) => return Err(e.into()),
    }

    let msg = IggyMessage::from_str("hello world")?;
    client
        .send_messages(
            &"my-stream".try_into()?,
            &"my-topic".try_into()?,
            &Partitioning::partition_id(0),
            &mut [msg],
        )
        .await?;
    println!("Message sent");

    let polled = client
        .poll_messages(
            &"my-stream".try_into()?,
            &"my-topic".try_into()?,
            Some(0),
            &Consumer::default(),
            &PollingStrategy::next(),
            10,
            true,
        )
        .await?;

    for message in &polled.messages {
        let payload = std::str::from_utf8(&message.payload)?;
        println!("Offset: {}, Payload: {}", message.header.offset, payload);
    }

    Ok(())
}
```

Partition IDs are **0-based**: the first partition of a topic is partition `0`. The consumer uses the default consumer identity and requests auto-commit; its offset can advance before application processing finishes. Use explicit offset storage after successful processing when that distinction matters.

For the full getting started tutorial, see [Getting Started](https://iggy.apache.org/docs/introduction/getting-started). For the high-level producer/consumer builders, see [High-level SDK](https://iggy.apache.org/docs/sdk/rust/high-level-sdk) and [Stream Builder](https://iggy.apache.org/docs/sdk/rust/stream-builder).
