+ );
+}
diff --git a/apps/web/src/lib/settings-api.ts b/apps/web/src/lib/settings-api.ts
new file mode 100644
index 0000000..5056aa1
--- /dev/null
+++ b/apps/web/src/lib/settings-api.ts
@@ -0,0 +1,89 @@
+/**
+ * Settings API client — SMTP configuration.
+ * Consumes the SettingsController built in 07-03.
+ * All calls use credentials: 'include' for cookie-based auth.
+ *
+ * T-07-17: SmtpConfig exposes only hasPassword, never the secret.
+ * The password field is never pre-filled from server data.
+ */
+
+const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
+
+// --- Types mirroring the 07-03 backend contract ---
+
+/**
+ * SMTP configuration as returned by GET /settings/smtp.
+ * encryptedPassword is NEVER returned (T-07-17).
+ */
+export interface SmtpConfig {
+ host: string;
+ port: number;
+ encryption: 'none' | 'starttls' | 'ssl-tls';
+ username?: string;
+ fromAddress: string;
+ /** True when an encrypted password is stored; the password value is never exposed. */
+ hasPassword: boolean;
+}
+
+/**
+ * Payload for PUT /settings/smtp and POST /settings/smtp/test.
+ * password is optional — omit to preserve the existing stored password.
+ */
+export interface SaveSmtpPayload {
+ host: string;
+ port: number;
+ encryption: 'none' | 'starttls' | 'ssl-tls';
+ username?: string;
+ /** Only include when the user has typed a new password. */
+ password?: string;
+ fromAddress: string;
+}
+
+// --- API functions ---
+
+/**
+ * Fetch the SMTP configuration for the current tenant.
+ * GET /settings/smtp
+ * Returns null when no configuration has been saved yet (404).
+ */
+export async function fetchSmtp(): Promise