What to Do When API Has Multiple Parameter Structures — Use oneOf/anyOf/allOf in Apidog

Learn how to use JSON Schema's oneOf, anyOf, and allOf features in Apidog to create precise API documentation for complex parameter structures. Master combination modes for better API design and clearer developer communication.

Ashley Innocent

Ashley Innocent

6 November 2025

What to Do When API Has Multiple Parameter Structures — Use oneOf/anyOf/allOf in Apidog

API parameters often have complex structures, with a single endpoint supporting multiple different parameter combinations. For example, a login endpoint might support username-password authentication, email-password authentication, or phone number verification codes. Payment endpoints can offer various methods like credit cards, or Alipay, each requiring different fields.

api parameters

Traditional API documentation approaches often simply list all possible fields and use text descriptions like "choose different fields based on different scenarios." This approach is neither precise nor developer-friendly, often leading to confusion. Apidog supports JSON Schema's oneOf, anyOf, and allOf features, allowing you to accurately describe these complex composite data structures in your API documentation.

Understanding the Three Combination Modes

In JSON Schema, oneOf, anyOf, and allOf are used to combine multiple sub-schemas, but they have different logical meanings:

Setting Up Combination Modes in Apidog

Apidog provides two ways to use these combination modes:

Visual Editor Approach

The first method uses the visual editing panel. In your project, click "Data Models" to create a new model, then find "Combination Modes" in the type selection. Choose the needed oneOf, anyOf, or allOf mode, then define specific data structures for each sub-schema.

JSON Schema Code Editor

The second approach involves directly editing JSON Schema code. In the data model editing panel, you can switch to code mode and write JSON Schema directly to define these logical combination patterns. This method is more direct for developers familiar with JSON Schema.

Applying These Patterns in API Endpoints

Once you've defined your data models, you can use them in your API documentation. When editing interface request parameters, select Body type as JSON, then in the data structure section, you can reference the "Data Models" you just created, or directly select "Combination Modes" to define complex parameter structures.

apply the patterns in api endpoints

The same principle applies to response data definitions. When adding response examples in the return response section, you can use combination modes to describe response formats for different scenarios. This way, developers can clearly understand what data structure will be returned in different situations.

Real-World Use Cases

allOf: Combining Multiple Structures

allOf combines multiple structures together - it's not about selection, but about stacking. allOf doesn't change field hierarchy; all fields end up in the same object. It simply stacks multiple rules on the same data. Think of it as "logical AND" - all sub-structure constraints must be satisfied.

For example, this JSON Schema:

{
  "allOf": [
    {
      "description": "Basic user information",
      "type": "object",
      "properties": {
        "id": { "type": "integer" },
        "name": { "type": "string" }
      },
      "required": ["id", "name"]
    },
    {
      "description": "Contact information", 
      "type": "object",
      "properties": {
        "email": { "type": "string", "format": "email" },
        "phone": { "type": "string" }
      },
      "required": ["email"]
    }
  ]
}

This schema means: the final data must simultaneously satisfy both "basic user information" and "contact information" structures.

In other words, the request body must include id, name, and email, while phone is optional.

Valid data:

{
  "id": 1001,
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "1-800-000-0000"
}

Invalid data:

{
  "id": 1001,
  "name": "John Doe"
}

This lacks the required email field and doesn't satisfy the second structure.

This approach is suitable for splitting complex objects. User information, order details, configuration items, etc., can all be divided into independent structures by functional modules, then combined using allOf. Other interfaces that need part of these structures can reference them directly without redundant definitions.

anyOf: Satisfying At Least One Condition

anyOf lists multiple possible structures, and data is considered valid as long as it conforms to at least one of them. It doesn't care whether multiple conditions are satisfied, nor does it require unique matching.

For example, an identifier field might be an email or a phone number. These two formats are distinctly different, but both belong to the category of "user login credentials."

You can use anyOf to clearly express this "can be A or B" intention:

{
  "type": "object",
  "properties": {
    "identifier": {
      "description": "User identifier: can be email or phone number",
      "anyOf": [
        {
          "title": "Email format",
          "description": "Must be a valid email address",
          "type": "string",
          "format": "email"
        },
        {
          "title": "Phone format",
          "description": "Must be a valid international phone number",
          "type": "string",
          "pattern": "^\\+?[1-9]\\d{1,14}$"
        }
      ]
    },
    "password": {
      "type": "string",
      "minLength": 6,
      "description": "Login password, at least 6 characters"
    }
  },
  "required": ["identifier", "password"],
  "description": "User login request parameters"
}

This structure means: identifier is a string that's considered valid as long as it satisfies either email format or phone number format.

Valid data:

{
  "identifier": "test@example.com",
  "password": "123456"
}
{
  "identifier": "+1-800-000-0000",
  "password": "123456"
}

Invalid data:

{
  "identifier": "abc",
  "password": "123456"
}

"abc" is neither an email nor a valid phone number format, satisfying none of the conditions.

oneOf: Choose Exactly One Option

oneOf lists multiple possible structures, and data must conform to exactly one of them. It emphasizes exclusivity - you can only choose one, not more, not less.

For example, payment methods: to complete a payment, users must choose one of credit card, WeChat Pay, or Alipay, but cannot use two methods simultaneously, nor can they choose none. You can define this "single-choice" logic using oneOf:

{
  "properties": {
    "paymentMethod": {
      "description": "Payment method, must choose exactly one",
      "oneOf": [
        {
          "title": "Credit Card Payment",
          "description": "Pay with credit card, requires card number and expiry date",
          "type": "object",
          "properties": {
            "type": { "const": "credit_card" },
            "cardNumber": { "type": "string" },
            "expiryDate": { "type": "string" }
          },
          "required": ["type", "cardNumber", "expiryDate"],
          "additionalProperties": false
        },
        {
          "title": "WeChat Pay",
          "description": "Pay through WeChat, requires user's openid",
          "type": "object",
          "properties": {
            "type": { "const": "wechat" },
            "openid": { "type": "string" }
          },
          "required": ["type", "openid"],
          "additionalProperties": false
        },
        {
          "title": "Alipay Payment",
          "description": "Pay through Alipay, requires account ID",
          "type": "object",
          "properties": {
            "type": { "const": "alipay" },
            "accountId": { "type": "string" }
          },
          "required": ["type", "accountId"],
          "additionalProperties": false
        }
      ]
    }
  }
}

This definition means: paymentMethod is an object that can only match one of the three sub-structures.

Valid examples:

{
  "paymentMethod": {
    "type": "wechat",
    "openid": "wx_123456"
  }
}
{
  "paymentMethod": {
    "type": "credit_card",
    "cardNumber": "4111111111111111",
    "expiryDate": "12/25"
  }
}

Invalid example:

{
  "paymentMethod": {
    "type": "wechat",
    "openid": "wx_123",
    "accountId": "2088102"
  }
}

Even though type is "wechat", the presence of accountId might cause it to match multiple structures, causing oneOf to fail. Adding "additionalProperties": false prevents this confusion (meaning no additional fields are allowed), ensuring each structure only allows its own defined fields. Apidog supports visual configuration for additionalProperties.

When you need to make exclusive choices between multiple distinct types, oneOf is the most direct and reliable way to express this.

Choosing the Right Combination Mode

The choice of combination mode mainly depends on your business logic:

Understanding their respective roles allows your API documentation to accurately describe complex data structures, making it immediately clear to interface users how to pass parameters.

Conclusion

Apidog's comprehensive JSON Schema support empowers developers to create precise, clear API documentation for even the most complex parameter structures. By leveraging oneOf, anyOf, and allOf combinations, you can eliminate ambiguity and provide crystal-clear guidance to API consumers.

Ready to experience the power of advanced API documentation? Try Apidog today and see how easy it becomes to manage complex API parameters with precision and clarity.

button

Explore more

How to Use Discriminator to Match Different Parameter Structures by Type When Designing APIs in Apidog

How to Use Discriminator to Match Different Parameter Structures by Type When Designing APIs in Apidog

When an API has multiple parameter structures, oneOf or anyOf can define them—but the relationships aren’t always clear. By adding a discriminator, you can use a shared field to automatically switch between schemas, making your documentation in Apidog more intuitive and easier to read.

6 November 2025

How to Claim Free Claude Code Credits: $250 for Pro, $1000 for Max Subscribers

How to Claim Free Claude Code Credits: $250 for Pro, $1000 for Max Subscribers

Claude Pro and Max subscribers gain free credits for Claude Code on web and mobile – $250 for Pro, $1000 for Max. This technical guide covers features, claiming process, integration with Apidog, and developer benefits.

6 November 2025

What Is a JSON Validator: The Complete Guide to Clean And Error-Free JSON

What Is a JSON Validator: The Complete Guide to Clean And Error-Free JSON

Discover what a JSON validator is, why it matters for API development, and how Apidog’s powerful API mocking and validation tools streamline your workflow. Try Apidog for free today!

5 November 2025

Practice API Design-first in Apidog

Discover an easier way to build and use APIs