OpenAPI (especially v3.1) does support conditional request/response schemas based on parameters in the payload — using oneOf, anyOf, discriminator, or JSON Schema if / then / else (in v3.1 only).
Example Scenarios
Let’s say your request body has a field like "type": "email" or "type": "sms", and the shape of the rest of the payload depends on it.
Solution 1: discriminator (Best for mutually exclusive types)
This is clean and well-supported in tools like Swagger UI:
requestBody:
required: true
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/EmailRequest'
- $ref: '#/components/schemas/SmsRequest'
discriminator:
propertyName: type
mapping:
email: '#/components/schemas/EmailRequest'
sms: '#/components/schemas/SmsRequest'
components:
schemas:
EmailRequest:
type: object
required: [type, email]
properties:
type:
type: string
enum: [email]
email:
type: string
format: email
SmsRequest:
type: object
required: [type, phone]
properties:
type:
type: string
enum: [sms]
phone:
type: string
🎯 This is good when the payload changes entirely depending on a
type.
Solution 2: if/then/else (Only in OpenAPI 3.1)
If you’re using OpenAPI 3.1, which supports full JSON Schema, you can do this:
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
type:
type: string
allOf:
- if:
properties:
type:
const: email
then:
required: [email]
properties:
email:
type: string
format: email
- if:
properties:
type:
const: sms
then:
required: [phone]
properties:
phone:
type: string
⚠️ This is powerful but not widely supported in Swagger UI yet.
Solution 3: oneOf without discriminator
If you can’t use discriminator, you can still use oneOf:
requestBody:
content:
application/json:
schema:
oneOf:
- type: object
required: [type, email]
properties:
type:
type: string
enum: [email]
email:
type: string
- type: object
required: [type, phone]
properties:
type:
type: string
enum: [sms]
phone:
type: string
Downside: Swagger UI can’t infer which schema to use unless you also give a discriminator.
Conditional Response Schema?
You can also vary the response based on a request parameter (like type) using:
oneOfinresponses.[status].content.application/json.schema- Or just define multiple response examples, if it’s not programmatically deducible.
🔚 Summary
| Approach | Best For | OpenAPI Version | UI Support |
|---|---|---|---|
discriminator + oneOf |
Polymorphic request bodies | 3.0+ | ✅ Swagger UI |
if/then/else |
Complex conditional logic | 3.1 only | ⚠️ Partial |
oneOf without discriminator |
Simpler cases | 3.0+ | ⚠️ Limited |
Multiple examples |
Optional clarity | 3.0+ | ✅ |