# `Unicom360`
[🔗](https://github.com/TechRode-Solution-Limited/unicom360-elixir/blob/v0.1.0/lib/unicom360.ex#L1)

The official Elixir client for the [Unicom360](https://unicom360.com) API: SMS, email and
WhatsApp over one JSON API.

    {:ok, client} = Unicom360.client()  # reads UNICOM360_API_KEY

    {:ok, result} =
      Unicom360.SMS.send(client, %{
        from: "Unicom360",
        to: "260971234567",
        message: "Your order ZM4821 is ready."
      })

Every operation takes the client first and returns `{:ok, result}` or
`{:error, %Unicom360.Error{}}`; each has a `!` variant that returns the result or raises.

| Operation | Function | Returns |
|---|---|---|
| Send an SMS | `Unicom360.SMS.send/3` | `Unicom360.SMS.SendResult` |
| Send an email | `Unicom360.Email.send/3` | `Unicom360.Email.SendResult` |
| Send a WhatsApp template | `Unicom360.WhatsApp.send_template/3` | `Unicom360.WhatsApp.TemplateSendResult` |
| Send a WhatsApp session message | `Unicom360.WhatsApp.send_session/3` | `Unicom360.WhatsApp.SessionSendResult` |
| WhatsApp message status | `Unicom360.WhatsApp.status/3` | `Unicom360.WhatsApp.StatusResult` |
| WhatsApp templates | `Unicom360.WhatsApp.templates/2` | `Unicom360.WhatsApp.TemplateList` |
| One balance | `Unicom360.Balance.get/2` | `Unicom360.Balance` |
| Every balance | `Unicom360.Balance.all/2` | `Unicom360.Balances` |
| Health | `health/2` | `Unicom360.Health` |

Webhooks and delivery reports are in `Unicom360.Webhook`, the opt-in GSM-7 helpers in
`Unicom360.GSM`. There is no sandbox: every accepted send is real and billed.

# `client`

```elixir
@spec client([Unicom360.Client.option()]) ::
  {:ok, Unicom360.Client.t()} | {:error, Unicom360.Error.t()}
```

Builds a client. See `Unicom360.Client` for every option.

    {:ok, client} = Unicom360.client()
    {:ok, client} = Unicom360.client(api_key: "...", max_retries: 4)

Returns `{:error, %Unicom360.Error{type: :configuration_error}}` when no API key is found or an
option is unusable.

# `client!`

```elixir
@spec client!([Unicom360.Client.option()]) :: Unicom360.Client.t()
```

Like `client/1`, but returns the client or raises `Unicom360.Error`.

# `contract_version`

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

The version of the Unicom360 API contract (`openapi.yaml` and its conformance suite) this SDK
targets.

# `health`

```elixir
@spec health(Unicom360.Client.t(), keyword()) ::
  {:ok, Unicom360.Health.t()} | {:error, Unicom360.Error.t()}
```

Checks that the API is up (`GET /health`). Sends no API key.

Options: `:timeout` (ms per attempt) and `:max_retries`.

# `health!`

```elixir
@spec health!(Unicom360.Client.t(), keyword()) :: Unicom360.Health.t()
```

Like `health/2`, but returns the result or raises `Unicom360.Error`.

# `version`

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

The SDK's version.

---

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