# `Fivetrex.Client`
[🔗](https://github.com/lostbean/fivetrex/blob/v0.2.3/lib/fivetrex/client.ex#L1)

Low-level HTTP client for the Fivetran REST API.

This module handles authentication, request building, and response parsing.
It is used internally by the API modules (`Fivetrex.Groups`, `Fivetrex.Connectors`,
etc.) and is not typically used directly.

## Authentication

The client uses HTTP Basic Authentication with your Fivetran API key and secret.
Credentials are Base64-encoded and sent in the `Authorization` header with each request.

## Creating a Client

Use `Fivetrex.client/1` to create a new client instance:

    client = Fivetrex.client(
      api_key: "your_api_key",
      api_secret: "your_api_secret"
    )

## Request Methods

The client provides methods for each HTTP verb:

  * `get/3` - GET requests with optional query parameters
  * `post/3` - POST requests with JSON body
  * `patch/3` - PATCH requests with JSON body
  * `delete/2` - DELETE requests

## Response Handling

All request methods return `{:ok, body}` on success (2xx status) or
`{:error, %Fivetrex.Error{}}` on failure. The response body is automatically
decoded from JSON.

## Error Mapping

HTTP errors are mapped to structured `Fivetrex.Error` types:

  * 401 → `:unauthorized`
  * 404 → `:not_found`
  * 429 → `:rate_limited` (includes `retry_after` from header)
  * 5xx → `:server_error`
  * Other → `:unknown`

# `t`

```elixir
@type t() :: %Fivetrex.Client{req: Req.Request.t()}
```

A Fivetrex client struct containing the configured Req request.

This struct is opaque and should be created using `Fivetrex.client/1`.

# `delete`

```elixir
@spec delete(t(), String.t()) :: {:ok, map()} | {:error, Fivetrex.Error.t()}
```

Performs a DELETE request to the specified path.

## Parameters

  * `client` - The Fivetrex client
  * `path` - The API path

## Examples

    {:ok, _} = Fivetrex.Client.delete(client, "/groups/abc")

## Returns

  * `{:ok, map()}` - The decoded JSON response body (usually empty)
  * `{:error, Fivetrex.Error.t()}` - A structured error

# `get`

```elixir
@spec get(t(), String.t(), keyword()) :: {:ok, map()} | {:error, Fivetrex.Error.t()}
```

Performs a GET request to the specified path.

## Parameters

  * `client` - The Fivetrex client
  * `path` - The API path (e.g., "/groups" or "/connectors/abc123")
  * `opts` - Optional keyword list:
    * `:params` - Query parameters as a keyword list or map

## Examples

    # Simple GET
    {:ok, body} = Fivetrex.Client.get(client, "/groups")

    # GET with query parameters
    {:ok, body} = Fivetrex.Client.get(client, "/groups", params: [limit: 10])

## Returns

  * `{:ok, map()}` - The decoded JSON response body
  * `{:error, Fivetrex.Error.t()}` - A structured error

# `new`

```elixir
@spec new(keyword()) :: t()
```

Creates a new client with the given options.

This function is called internally by `Fivetrex.client/1`. Prefer using
that function for creating clients.

## Options

  * `:api_key` - Required. Your Fivetran API key.
  * `:api_secret` - Required. Your Fivetran API secret.
  * `:base_url` - Optional. Override the API base URL. Defaults to
    `https://api.fivetran.com/v1`.

## Examples

    client = Fivetrex.Client.new(
      api_key: "key",
      api_secret: "secret"
    )

# `patch`

```elixir
@spec patch(t(), String.t(), map()) :: {:ok, map()} | {:error, Fivetrex.Error.t()}
```

Performs a PATCH request to the specified path with a JSON body.

## Parameters

  * `client` - The Fivetrex client
  * `path` - The API path
  * `body` - The request body (will be JSON-encoded)

## Examples

    {:ok, body} = Fivetrex.Client.patch(client, "/groups/abc", %{name: "New Name"})

## Returns

  * `{:ok, map()}` - The decoded JSON response body
  * `{:error, Fivetrex.Error.t()}` - A structured error

# `post`

```elixir
@spec post(t(), String.t(), map()) :: {:ok, map()} | {:error, Fivetrex.Error.t()}
```

Performs a POST request to the specified path with a JSON body.

## Parameters

  * `client` - The Fivetrex client
  * `path` - The API path
  * `body` - The request body (will be JSON-encoded)

## Examples

    {:ok, body} = Fivetrex.Client.post(client, "/groups", %{name: "My Group"})

## Returns

  * `{:ok, map()}` - The decoded JSON response body
  * `{:error, Fivetrex.Error.t()}` - A structured error

---

*Consult [api-reference.md](api-reference.md) for complete listing*
