# Send Your First Message (/sdks/elixir/tutorials/first-message)



This is your first hands-on lesson with the Elixir SDK: create a client, send an event, and receive it. Make sure you have the SDK installed (see the [Elixir SDK overview](/sdks/elixir)).

## Create a Client [#create-a-client]

```elixir title="main.exs"
{:ok, client} = KubeMQ.Client.start_link(
  address: "localhost:50000",
  client_id: "my-app"
)

IO.puts("Connected: #{KubeMQ.Client.connected?(client)}")
KubeMQ.Client.close(client)
```

## Send Your First Event [#send-your-first-event]

```elixir title="send_event.exs"
{:ok, client} = KubeMQ.Client.start_link(
  address: "localhost:50000",
  client_id: "my-app"
)

event = KubeMQ.Event.new(
  channel: "notifications",
  body: "hello kubemq",
  metadata: "greeting"
)

case KubeMQ.Client.send_event(client, event) do
  :ok -> IO.puts("Event sent successfully")
  {:error, err} -> IO.puts("Send failed: #{err.message}")
end

KubeMQ.Client.close(client)
```

## Receive Events [#receive-events]

```elixir title="receive_events.exs"
{:ok, client} = KubeMQ.Client.start_link(
  address: "localhost:50000",
  client_id: "my-app"
)

{:ok, sub} = KubeMQ.Client.subscribe_to_events(client, "notifications",
  on_event: fn event ->
    IO.puts("Received: #{event.body}")
  end
)

Process.sleep(30_000)

KubeMQ.Subscription.cancel(sub)
KubeMQ.Client.close(client)
```

## Configuration Options [#configuration-options]

| Option              | Default                               | Description                             |
| ------------------- | ------------------------------------- | --------------------------------------- |
| `address`           | `"localhost:50000"`                   | KubeMQ server gRPC address              |
| `client_id`         | **Required** (no default)             | Unique client identifier                |
| `auth_token`        | `nil`                                 | Authentication token                    |
| `tls`               | `nil` (plaintext)                     | TLS/mTLS SSL options keyword list       |
| `rpc_timeout`       | `10_000`                              | Default RPC timeout in milliseconds     |
| `reconnect_policy`  | Infinite retries, exponential backoff | Reconnection behavior                   |
| `default_cache_ttl` | `900_000`                             | Default query cache TTL in milliseconds |

## Error Handling [#error-handling]

All SDK operations return tagged tuples with `%KubeMQ.Error{}` structs:

```elixir title="error_handling.exs"
case KubeMQ.Client.send_event(client, event) do
  :ok ->
    IO.puts("Sent!")

  {:error, %KubeMQ.Error{code: code, message: msg, retryable?: retryable}} ->
    IO.puts("Error [#{code}]: #{msg} (retryable: #{retryable})")

    case code do
      :timeout -> IO.puts("Retry with longer timeout")
      :authentication -> IO.puts("Check credentials")
      :transient -> IO.puts("Transient failure, retry")
      _ -> IO.puts("Unhandled error")
    end
end
```

## Supervision Tree [#supervision-tree]

Add the client to your application supervision tree for automatic lifecycle management:

```elixir title="lib/my_app/application.ex"
defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      {KubeMQ.Client,
        address: "localhost:50000",
        client_id: "my-app",
        name: MyApp.KubeMQ}
    ]

    Supervisor.start_link(children, strategy: :one_for_one)
  end
end
```

## Next Steps [#next-steps]

* [Elixir SDK Reference](/sdks/elixir/reference) — full API documentation
* [Elixir SDK Examples](/sdks/elixir/how-to) — complete examples for all patterns
* [GitHub Repository](https://github.com/kubemq-io/kubemq-elixir) — source code and issues
