# `Lather.Soap.Envelope`
[🔗](https://github.com/awksedgreep/lather/blob/v1.1.0/lib/lather/soap/envelope.ex#L1)

SOAP envelope builder and parser.

Handles creation and parsing of SOAP 1.1 envelopes with support for
headers, namespaces, and fault detection.

# `build`

```elixir
@spec build(atom() | String.t(), map(), keyword()) ::
  {:ok, String.t()} | {:error, any()}
```

Builds a SOAP envelope for the given operation and parameters.

## Parameters

* `operation` - The operation name (atom or string)
* `params` - Parameters for the operation (map)
* `options` - Envelope options

## Options

* `:version` - SOAP version (`:v1_1` or `:v1_2`, default: `:v1_1`)
* `:headers` - SOAP headers to include
* `:namespace` - Target namespace for the operation
* `:namespace_prefix` - Optional namespace prefix for the operation element (e.g. `"ns0"`).
  When set the element is rendered as `<ns0:Op xmlns:ns0="...">` instead of the default
  `<Op xmlns="...">`. When omitted, the existing default-namespace behaviour is preserved.

## Examples

    iex> Envelope.build(:get_user, %{id: 123})
    {:ok, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..."}

# `parse_response`

```elixir
@spec parse_response(map()) :: {:ok, any()} | {:error, any()}
```

Parses a SOAP response and extracts the result or fault.

## Parameters

* `response` - HTTP response map with `:body` key containing XML

## Returns

* `{:ok, result}` - Successful response with parsed body. An empty
  `<Body/>` yields `{:ok, %{}}`.
* `{:error, {:soap_fault, fault}}` - The body carried a SOAP fault
* `{:error, :invalid_soap_response}` - No Envelope/Body found
* `{:error, {:parse_error, reason}}` - The body was not valid XML
* `{:error, {:http_error, status, body}}` - Non-2xx status without a fault

Envelope, Body and Fault elements are matched by local name, so any
namespace prefix (`soap:`, `soapenv:`, `SOAP-ENV:`, `s:`, none, ...) is
accepted.

---

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