---
title: "Better Auth 1.3"
description: "SSO with SAML, Multi Team Support, Additional Fields for Organization, Performance and more."
date: 2025-07-19
author:
  name: "Bereket Engida"
  avatar: "/avatars/beka.jpg"
  twitter: "iambereket"
image: "/release-og/1-3.png"
tags: ["1.3", "authentication", "oidc", "mcp", "sso", "organization"]
---

## Better Auth 1.3 Release

We're excited to announce the release of Better Auth 1.3. This release includes a lot of new features and improvements.

To upgrade, run:

```package-install
npm install better-auth@1.3
```

---

## 🚀 Highlights

### **SSO Plugin**

The SSO plugin has been moved to its own package and now supports both **OIDC** and **SAML 2.0**.

👉 [Read the SSO docs](/docs/plugins/sso)

```ts title="auth.ts"
import { betterAuth } from "better-auth";
import { sso } from "@better-auth/sso";

export const auth = betterAuth({
  plugins: [
    sso({
      oidc: {
        clientId: process.env.OIDC_CLIENT_ID!,
        clientSecret: process.env.OIDC_CLIENT_SECRET!,
      },
      saml: {
        entryPoint: "https://example.com/saml",
        issuer: "better-auth-example",
        certificate: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
      },
      providersLimit: async (user) => {
        const plan = await getUserPlan(user);
        return plan.name === "pro" ? 10 : 1;
      },
    }),
  ],
});
```

---

### **OIDC & MCP Plugins – Now Stable**

Both OIDC and MCP plugins are production‑ready.

✅ Features:

* Refresh token support in discovery & token endpoints
* JWKs and PKCE for public clients
* Trusted clients
* Encrypted & hashed client secrets

👉 [Read OIDC docs](/docs/plugins/oidc-provider)
👉 [Read MCP docs](/docs/plugins/mcp)

```ts title="auth.ts"
import { mcp } from "better-auth/plugins";

export const auth = betterAuth({
  plugins: [
    mcp({
      loginPage: "/login",
    }),
  ],
});
```

---

### **Stripe Plugin is now production ready**

The Stripe plugin is now stable and usage based pricing is coming very soon.

👉 [Read Stripe docs](/docs/plugins/stripe)


```ts title="auth.ts"
import { betterAuth } from "better-auth";
import { stripe } from "@better-auth/stripe";

export const auth = betterAuth({
  plugins: [
    stripe({
      // ...
    }),
  ],
});
```

### **SIWE Plugin**

Native support for **Sign‑In with Ethereum**.

👉 [Read SIWE docs](/docs/plugins/siwe)

```ts title="auth.ts"
import { siwe } from "better-auth/plugins";

export const auth = betterAuth({
  plugins: [
    siwe(),
  ],
});
```

---

### **New Social Providers**

We’ve added providers for **Notion, Slack, Linear, and Faceit**.

```ts title="auth.ts"
import { betterAuth } from "better-auth";

export const auth = betterAuth({
  socialProviders: {
    notion: { /* ... */ },
    slack: { /* ... */ },
    linear: { /* ... */ },
    faceit: { /* ... */ },
  },
});
```

---

### **SvelteKit Cookie Helper Plugin**

Utilities for handling cookies in SvelteKit server actions.

<Callout type="warn">
  Breaking change: `building` and `getRequestEvent` must now be passed in as props.
</Callout>

```ts title="auth.ts"
import { betterAuth } from "better-auth";
import { sveltekitCookies } from "better-auth/svelte-kit";
import { getRequestEvent } from "$app/server";

export const auth = betterAuth({
  plugins: [sveltekitCookies(getRequestEvent)],
});
```

---

### **Email Verification on Sign‑In**

```ts title="auth.ts"
export const auth = betterAuth({
  emailVerification: {
    sendOnSignIn: true, // sends a verification email on sign‑in if the user isn’t verified
  },
});
```

---

### **Multi‑Team Support**

The organization plugin now supports members belonging to multiple teams.

**Breaking change:**
`teamId` has been removed from the `member` table. A new `teamMembers` table is required.

```ts title="auth.ts"
export const auth = betterAuth({
  plugins: [
    organization({
      // ...
    }),
  ],
});
```

```ts title="auth-client.ts"
import { createAuthClient } from "better-auth/client";
import { organizationClient } from "better-auth/client/plugins";
import { auth } from "./auth";

export const authClient = createAuthClient({
  // pass your auth instance to infer additional fields
  plugins: [organizationClient({ $inferAuth: {} as typeof auth })], // [!code highlight]
});
```

---

### **Additional Organization Fields**

Add custom fields to `organization`, `member`, and `invitation` models.

```ts title="auth.ts"
export const auth = betterAuth({
  plugins: [
    organization({
      schema: {
        organization: { additionalFields: { /* ... */ } },
        member: { additionalFields: { /* ... */ } },
        invitation: { additionalFields: { /* ... */ } },
      },
    }),
  ],
});
```

Other new options:

* `maximumMembersPerTeam` – set team member limits
* `listUserInvitations` – list all invitations for a user

---

### **Generic OAuth Improvements**

* Added support for extra token URL params
* OAuth token encryption options

```ts title="auth.ts"
export const auth = betterAuth({
  plugins: [
    genericOAuth({
      // ...
    }),
  ],
});
```

---

### **API Keys**

* `requireName` option for key creation
* `verifyKey` now supports async functions

---

### **Username**

* Availability checks
* Custom normalization

---

### ✨ More Features

* Migrated to **Zod 4** for better type safety and performance
* CLI supports custom adapter `createSchema`
* `inferAuth` utility to infer types from the client
* Improved docs with `auth` and `authClient` examples
* `rememberMe` support in `signUp`
* `afterEmailVerification` hook
* `freshAge` and custom `errorURL` respected properly
* OAuth2 tokens now include `refresh_token_expires_in`

---

### 🐛 Bug Fixes & Improvements

#### Plugins

* Expo: Fixed type path import
* SSO: Fixed SAML redirection & type checks
* Dropbox: Token access type support
* Stripe:

  * Prevent duplicate customers
  * Allow upgrading incomplete subscriptions
* Admin:

  * Fixed missing `ctx` in hooks
  * Proper error when removing invalid user IDs

#### OAuth & Providers

* Fixed duplicate OAuth registration
* Improved Google/Microsoft scope handling
* Fixed malformed error URLs in generic OAuth
* Facebook: Better detection for limited token JWT
* Twitter: Improved email verification logic

#### Core Authentication

* Exclude current user from username uniqueness check
* Support `callbackURL` in `signInUsername`
* Allow account linking without email
* Fixed missing `null` type in `/get-session` response
* Global `onSuccess` hook now works
* JWT: Alternate algorithms supported in JWKS
* `origin-check`: Wildcard trusted origins supported

#### CLI, DB, and Adapters

* CLI: Improved Drizzle schema formatting
* MongoAdapter: Works with `create-adapter`
* Schema generation respects `useNumberId`
* Postgres: Better varchar normalization and type comparison
* Drizzle CLI: Uses `serial` as PK if `useNumberId` is enabled

#### Email & OTP

* OTPs now encrypted
* Fixed `onEmailVerification` not firing
* Proper error when sign‑up is disabled
* Phone number: Reset clears verification values

#### Two-Factor Auth

* Default OTP period fix
* URI generation doesn’t require enabling 2FA
* Fixed OTP URI separator mismatch

#### Miscellaneous

* Delete organization if member not found
* Correct error codes for API key rate limits
* Additional fields now show in OpenAPI
* Fixed FK constraint generation for MySQL
* Various improvements to account linking
* OIDC `offline_access` no longer requires `prompt=consent`
* Fixed malformed base64 encoding for token validation

---

A lot of refinements to make everything smoother, faster, and more reliable.
👉 [Check the full changelog](https://github.com/better-auth/better-auth/releases/tag/v1.3.0)

---
