Is this suited for github?
Reproduction
Description
The emailOTP plugin generates OpenAPI metadata (responses, operationId, description)
for all its endpoints, but none of them include a requestBody definition.
The body schemas are defined internally in the plugin (the Zod schemas exist and are used for
validation), but they are not serialized into the OpenAPI spec output.
Affected endpoints
All endpoints in the emailOTP plugin, including:
POST /api/auth/email-otp/send-verification-otp
POST /api/auth/sign-in/email-otp
POST /api/auth/email-otp/verify-email
POST /api/auth/email-otp/check-verification-otp
POST /api/auth/email-otp/reset-password
- (and others)
Expected behavior
Each endpoint's OpenAPI spec should include a requestBody with the correct schema.
For example, POST /api/auth/sign-in/email-otp should produce:
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["email", "otp"],
"properties": {
"email": { "type": "string" },
"otp": { "type": "string" },
"name": { "type": "string" },
"image": { "type": "string" }
}
}
}
}
}
### Current vs. Expected behavior
Actual behavior
The requestBody field is absent. The /api/auth/reference Scalar UI shows the endpoint with no body schema, making it impossible to test directly from the docs.
Root cause (observed)
Inspecting the plugin at runtime confirms the body Zod schemas exist and are used for validation, but the openapi metadata object does not include them:
const { emailOTP } = require('better-auth/plugins');
const plugin = emailOTP({ sendVerificationOTP: async () => {} });
// Body schema exists:
console.log(plugin.endpoints.signInEmailOTP.options.body);
// → ZodIntersection { email, otp, name?, image?, ...Record<string, any> }
// OpenAPI metadata has no requestBody:
console.log(plugin.endpoints.signInEmailOTP.options.metadata.openapi);
// → { operationId: 'signInWithEmailOTP', description: '...', responses: { ... } }
// no requestBody field
The openapi metadata object is manually authored per-endpoint and does not derive requestBody from the Zod body schema automatically. This is consistent across all emailOTP endpoints.
### What version of Better Auth are you using?
1.6.4
### System info
```bash
{
"system": {
"platform": "darwin",
"arch": "arm64",
"version": "Darwin Kernel Version 25.4.0: Thu Mar 19 19:30:44 PDT 2026; root:xnu-12377.101.15~1/RELEASE_ARM64_T6000",
"release": "25.4.0",
"cpuCount": 8,
"cpuModel": "Apple M1 Pro",
"totalMemory": "16.00 GB",
"freeMemory": "0.12 GB"
},
"node": {
"version": "v22.20.0",
"env": "development"
},
"packageManager": {
"name": "npm",
"version": "10.9.3"
},
"frameworks": [
{
"name": "fastify",
"version": "^5.8.5"
}
],
"databases": [
{
"name": "pg",
"version": "^8.20.0"
},
{
"name": "@prisma/client",
"version": "^7.7.0"
}
],
"betterAuth": {
"version": "^1.6.4",
"config": null
}
}
Which area(s) are affected? (Select all that apply)
Backend
Auth config (if applicable)
import { betterAuth } from "better-auth"
export const auth = betterAuth({
emailAndPassword: {
enabled: true
},
});
Additional context
No response
Is this suited for github?
Reproduction
Description
The
emailOTPplugin generates OpenAPI metadata (responses,operationId,description)for all its endpoints, but none of them include a
requestBodydefinition.The body schemas are defined internally in the plugin (the Zod schemas exist and are used for
validation), but they are not serialized into the OpenAPI spec output.
Affected endpoints
All endpoints in the
emailOTPplugin, including:POST /api/auth/email-otp/send-verification-otpPOST /api/auth/sign-in/email-otpPOST /api/auth/email-otp/verify-emailPOST /api/auth/email-otp/check-verification-otpPOST /api/auth/email-otp/reset-passwordExpected behavior
Each endpoint's OpenAPI spec should include a
requestBodywith the correct schema.For example,
POST /api/auth/sign-in/email-otpshould produce:Which area(s) are affected? (Select all that apply)
Backend
Auth config (if applicable)
Additional context
No response