# `DocuSign.Connection`
[🔗](https://github.com/neilberkman/docusign_elixir/blob/v3.4.0/lib/docusign/connection.ex#L1)

The module is intended to be used to establish a connection with
DocuSign eSignature API and then perform requests to it.

## JWT Impersonation Example

    iex> user_id = "74830914-547328-5432-5432543"
    iex> account_id = "61ac4bd1-c83c-4aa6-8654-ddf3tg5"
    iex> {:ok, conn} = DocuSign.Connection.get(user_id)
    iex> {:ok, users} = DocuSign.Api.Users.users_get_users(conn, account_id)
    {:ok, %DocuSign.Model.UserInformationList{...}}

## OAuth2 Authorization Code Flow Example

    # Using the OAuth2 Authorization Code Strategy
    iex> oauth_client = DocuSign.OAuth.AuthorizationCodeStrategy.client(
    ...>   redirect_uri: "https://yourapp.com/auth/callback"
    ...> )
    ...> |> DocuSign.OAuth.AuthorizationCodeStrategy.get_token!(code: "auth_code")
    iex> user_info = DocuSign.OAuth.AuthorizationCodeStrategy.get_user_info!(oauth_client)
    iex> account = Enum.find(user_info["accounts"], &(&1["is_default"] == "true"))
    iex> {:ok, conn} = DocuSign.Connection.from_oauth_client(
    ...>   oauth_client,
    ...>   account_id: account["account_id"],
    ...>   base_uri: account["base_uri"] <> "/restapi"
    ...> )
    iex> {:ok, users} = DocuSign.Api.Users.users_get_users(conn, account["account_id"])
    {:ok, %DocuSign.Model.UserInformationList{...}}

# `oauth_error`

```elixir
@type oauth_error() :: OAuth2.Response.t() | OAuth2.Error.t()
```

# `t`

```elixir
@type t() :: %DocuSign.Connection{
  app_account: map() | nil,
  client: OAuth2.Client.t() | nil,
  req: Req.Request.t()
}
```

# `detect_environment`

```elixir
@spec detect_environment(String.t()) :: :sandbox | :production
```

Detects the environment type based on the API base URI.

## Parameters

- `base_uri` - The DocuSign API base URI

## Returns

- `:sandbox` for sandbox/demo environments
- `:production` for production environments

## Examples

    iex> DocuSign.Connection.detect_environment("https://demo.docusign.net")
    :sandbox

    iex> DocuSign.Connection.detect_environment("https://na3.docusign.net")
    :production

# `determine_hostname`

```elixir
@spec determine_hostname(String.t()) :: String.t()
```

Automatically determines the appropriate OAuth hostname based on a base URI.

This function provides a convenient way to automatically configure the correct
OAuth hostname by analyzing the provided base URI for sandbox/demo patterns.
This is useful when creating connections with different environments.

## Parameters

- `base_uri` - The DocuSign API base URI (e.g., "https://demo.docusign.net/restapi")

## Returns

- `"account-d.docusign.com"` for sandbox/demo environments
- `"account.docusign.com"` for production environments

## Examples

    # Automatically detect sandbox environment
    iex> DocuSign.Connection.determine_hostname("https://demo.docusign.net/restapi")
    "account-d.docusign.com"

    # Automatically detect production environment
    iex> DocuSign.Connection.determine_hostname("https://na3.docusign.net/restapi")
    "account.docusign.com"

## Usage with OAuth2 Configuration

    # Use automatic detection for OAuth2 setup
    base_uri = "https://demo.docusign.net/restapi"
    hostname = DocuSign.Connection.determine_hostname(base_uri)

    Application.put_env(:docusign, :hostname, hostname)

# `download_file`

```elixir
@spec download_file(t(), String.t(), DocuSign.FileDownloader.download_options()) ::
  DocuSign.FileDownloader.download_result()
```

Downloads a file from the DocuSign API.

This is a convenience function that wraps `DocuSign.FileDownloader.download/3`.
It provides an easy way to download documents, attachments, and other files
from DocuSign APIs with automatic filename extraction and flexible storage options.

## Options

See `DocuSign.FileDownloader.download/3` for all available options.

## Examples

    # Download envelope document to temporary file
    {:ok, temp_path} = DocuSign.Connection.download_file(conn,
      "/v2.1/accounts/123/envelopes/456/documents/1")

    # Download to memory
    {:ok, {content, filename, content_type}} = DocuSign.Connection.download_file(conn, url,
      strategy: :memory)

    # Download with custom temp options
    {:ok, path} = DocuSign.Connection.download_file(conn, url,
      temp_options: [prefix: "contract", suffix: ".pdf"])

# `from_oauth_client`

```elixir
@spec from_oauth_client(
  OAuth2.Client.t(),
  keyword()
) :: {:ok, t()} | {:error, atom()}
```

Create new connection from OAuth2 client with tokens.

This function creates a connection using an OAuth2.Client obtained through the
authorization code flow with `DocuSign.OAuth.AuthorizationCodeStrategy`.

## Parameters

- `oauth_client` - OAuth2.Client with valid access token
- `opts` - Keyword list of options:
  - `:account_id` - DocuSign account ID (required)
  - `:base_uri` - API base URI (required)

## Examples

    # Using OAuth2 Authorization Code Strategy
    oauth_client = DocuSign.OAuth.AuthorizationCodeStrategy.client(
      redirect_uri: "https://yourapp.com/callback"
    )
    |> DocuSign.OAuth.AuthorizationCodeStrategy.get_token!(code: auth_code)

    # Get user info to find account details
    user_info = DocuSign.OAuth.AuthorizationCodeStrategy.get_user_info!(oauth_client)
    account = Enum.find(user_info["accounts"], &(&1["is_default"] == "true"))

    # Create connection
    {:ok, conn} = from_oauth_client(
      oauth_client,
      account_id: account["account_id"],
      base_uri: account["base_uri"] <> "/restapi"
    )

## Returns

- `{:ok, connection}` - Success with connection struct
- `{:error, reason}` - Failure with error reason

## Notes

- The `base_uri` should be the full API endpoint (e.g., "https://demo.docusign.net/restapi")
- Use the account information from the user info endpoint to get correct base_uri
- The connection can be used immediately with DocuSign API functions

# `from_oauth_client_with_detection`

```elixir
@spec from_oauth_client_with_detection(
  OAuth2.Client.t(),
  keyword()
) :: {:ok, t()} | {:error, atom()}
```

Creates a connection with automatic environment detection from OAuth client.

This is an enhanced version of `from_oauth_client/2` that can automatically
determine the OAuth hostname from the base_uri if not already configured.

## Parameters

- `oauth_client` - The OAuth2.Client with valid tokens
- `opts` - Options including:
  - `:account_id` (required) - The DocuSign account ID
  - `:base_uri` (required) - The API base URI
  - `:auto_detect_hostname` (optional) - Whether to automatically set hostname config

## Options

- `:auto_detect_hostname` - If `true`, automatically configures the application
  hostname based on the base_uri environment detection. Default: `false`

## Examples

    # Create connection with automatic hostname detection
    {:ok, conn} = DocuSign.Connection.from_oauth_client_with_detection(
      oauth_client,
      account_id: "12345",
      base_uri: "https://demo.docusign.net/restapi",
      auto_detect_hostname: true
    )

# `get`

```elixir
@spec get(String.t()) :: {:ok, t()} | {:error, oauth_error()}
```

Create new connection for provided user ID using JWT impersonation.

# `request`

```elixir
@spec request(t(), Keyword.t()) :: {:ok, Req.Response.t()} | {:error, any()}
```

Makes a request.

## Options

* `:ssl_options` - Override SSL options for this specific request
* `:telemetry_metadata` - Additional metadata to include in telemetry events
* All other options are passed through to Req

## Examples

    # Use custom CA certificate for this request
    DocuSign.Connection.request(conn,
      method: :get,
      url: "/accounts",
      ssl_options: [cacertfile: "/custom/ca.pem"]
    )

    # With telemetry metadata
    DocuSign.Connection.request(conn,
      method: :get,
      url: "/accounts",
      telemetry_metadata: %{operation: "list_accounts"}
    )

---

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