# `Immich.API`

Public facade for the most common Immich API workflows.

This module combines:

- OAuth bootstrap (`authorize/2`, `callback/3`)
- Authenticated user lookup (`current_user/2`)
- Sync stream consumption (`sync_stream/3`)
- Sync acknowledgement posting (`sync_ack/3`)

Most request functions accept `shared_opts` so callers can inject a custom
client implementation (for example in tests) while keeping the same API.

## Typical usage

1. Call `authorize/2` and open the returned login URL.
2. After redirect, call `callback/3` to build an authenticated `Session`.
3. Use that `Session` with `current_user/2`, `sync_stream/3`, and `sync_ack/3`.

# `api_error`

```elixir
@type api_error() :: Immich.API.Client.api_error()
```

Standard API error shape returned by the configured client.

This includes transport failures, authentication/authorization failures,
and non-success HTTP responses mapped by `Immich.API.Client`.

# `shared_opts`

```elixir
@type shared_opts() :: [{:client, Immich.API.Client.t()}]
```

Options shared by authenticated API functions.

Supported options:

- `:client` - module implementing `Immich.API.Client.Behaviour`
  (defaults to `Immich.API.Client`)

# `sync_ack`

```elixir
@type sync_ack() :: String.t()
```

Sync acknowledgement identifier sent back to the server.

Each acknowledgement corresponds to an event previously received from
`sync_stream/3`.

# `sync_stream_opts`

```elixir
@type sync_stream_opts() :: [reset?: boolean(), client: Immich.API.Client.t()]
```

Options for `sync_stream/3`.

Supported options:

- all `shared_opts`
- `:reset?` - when `true`, requests a reset sync from the server
  (defaults to `false`)

# `sync_type`

```elixir
@type sync_type() :: String.t()
```

Sync type identifier sent to Immich sync APIs.

Values are expected to match server-recognized type names (for example
`"AssetsV1"`, `"StacksV1"`).

# `authorize`

```elixir
@spec authorize(Immich.API.OAuth.redirect_uri(), Immich.API.OAuth.shared_opts()) ::
  {:ok, Immich.API.OAuth.login_url(), Immich.API.OAuth.oauth_context()}
  | {:error, Immich.API.OAuth.oauth_error()}
```

Initiates the OAuth flow by requesting PKCE parameters and an authorization URL.

Returns the login URL and OAuth context required by `callback/3`.

This delegates to `Immich.API.OAuth.authorize/2`.

See `Immich.API.OAuth.authorize/2` for details.

# `callback`

```elixir
@spec callback(
  Immich.API.OAuth.callback_uri(),
  Immich.API.OAuth.oauth_context(),
  Immich.API.OAuth.shared_opts()
) :: {:ok, Immich.API.Session.t()} | {:error, Immich.API.OAuth.oauth_error()}
```

Completes OAuth callback exchange and returns an authenticated session.

The provided `oauth_context` must be the exact context returned by `authorize/2`.

This delegates to `Immich.API.OAuth.callback/3`.

See `Immich.API.OAuth.callback/3` for details.

# `current_user`

```elixir
@spec current_user(Immich.API.Session.t(), shared_opts()) ::
  {:ok, map()} | {:error, api_error()}
```

Fetches the currently authenticated user for a session.

Uses `session.base_url` to build `/api/users/me` and attaches a bearer token
from `session.access_token`.

# `sync_ack`

```elixir
@spec sync_ack(Immich.API.Session.t(), [sync_ack()], shared_opts()) ::
  {:ok, map() | term()} | {:error, api_error()}
```

Posts sync acknowledgements.

Sends acknowledgements to `/api/sync/ack` using the authenticated session.

# `sync_stream`

```elixir
@spec sync_stream(Immich.API.Session.t(), [sync_type()], sync_stream_opts()) ::
  {:ok, Enumerable.t(map())} | {:error, api_error()}
```

Opens the Immich sync stream and returns decoded NDJSON events.

The request payload is forwarded as:

- `"types"` from `sync_types`
- `"reset"` from `opts[:reset?]` (defaults to `false`)

Returned events are yielded as a lazy enumerable of decoded maps.

---

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