---
schema_version: "1"
id: 614e6249c0bb4b84450943758d6fde344aa8f818410fb6b3a5ebd1ecb8b21f6b
title: External Services OpenAPI 3.0 Schema
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/platform/264-0-0/external_services_examples_openapi_3_0.md
canonical_url: https://help.salesforce.com/s/articleView?id=platform.external_services_examples_openapi_3_0.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: c0d963db9ee8cf3863323bd0e18be92caf87334f38a3c1c188629ebccd750ea2
description: This section features External Services OpenAPI 3.0 schema examples.
products:
  - Salesforce Platform
  - Security
release: "264"
---
# External Services OpenAPI 3.0 Schema

This section features External Services OpenAPI 3.0 schema examples.

### Required Editions

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small edition"><colgroup><col></colgroup><tbody><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: Lightning Experience</td></tr><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: <strong>Enterprise</strong>, <strong>Performance</strong>, <strong>Unlimited</strong>, and <strong>Developer</strong> Editions</td></tr></tbody></table>

## Example 1: Basic OpenAPI Spec with Request and Response (OAS 3.0)

Here’s an example of an API spec that contains a supported JSON schema for OpenAPI 3.0. The parameters contain the definition for the `accountId` input. The responses contain the definition for the output, which is `creditRating`. Parameters, requests, and responses translate to inputs and outputs, respectively, for your flow actions.

`{   "openapi": "3.0.0",   "info": {     "description": "A service for checking credit for an account.",     "version": "1.0.0",     "title": "Credit Decision",     "termsOfService": "http://swagger.io/terms/",     "contact": {       "email": "apiteam@swagger.io"     },     "license": {       "name": "Apache 2.0",       "url": "http://www.apache.org/licenses/LICENSE-2.0.html"     }   },   "servers": [     {       "url": "https://<YourHostName>"     }   ],   "paths": {     "/account/lastCreditRating": {       "get": {         "summary": "Evaluates credit rating and decides what payment terms to offer.",         "description": "",         **"requestBody": {           "content": {             "application/json": {               "schema": {                 "$ref": "#/components/schemas/accountId"               }             },             "application/xml": {               "schema": {                 "$ref": "#/components/schemas/accountId"               }             }           },           "description": "Specifies input parameters to calculate payment term",           "required": true         },         "responses": {           "200": {             "description": "success",             "content": {               "application/xml": {                 "schema": {                   "$ref": "#/components/schemas/creditRating"                 }               },               "application/json": {                 "schema": {                   "$ref": "#/components/schemas/creditRating"                 }               }             }           },           "405": {             "description": "Invalid input"           }         }**       }     }   },   "components": {     "schemas": {       "accountId": {         "type": "object",         "properties": {           "accountIdString": {             "type": "string"           }         },         "xml": {           "name": "accountId"         }       },       "creditRating": {         "type": "object",         "properties": {           "creditRatingString": {             "type": "string"           }         },         "xml": {           "name": "creditRating"         }       }     }   } }`

## Example 2: Named Object Schema Reference (OAS 3.0)

Basic Setup

- For the named credential that your org uses to access the banking system, assign the Bank label and a placeholder URL, such as https://api.example.com. Use example.com because you _paste in_ the schema at registration time, instead of by using a URL to point to an API spec.
- Register the employee banking system’s external service. Use the Bank name and the Bank named credential, and then copy and paste in the schema.
- The banking system's external service shows two ways to define parameters with object types: a named object type under a "components/schema" block or an anonymously declared object type inline.
    
    ![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-platform-extend_click-264-0-0-production-enus/5f7d9219-b7b1-4552-8891-f1aba9b289fc/images/icon_note.png)
    
    Note The defined or derived parameter object type name, or a property with an object type, must be fewer than 255 characters to be used in Apex or Flow Builder.

Here’s a schema with the named object type defined under the "components/schema" block. The phone object type's name is ExternalService\_\_Bank\_Phone in Apex or Flow Builder.

`{   "openapi": "3.0.0",   "info": {     "title": "bankService",     "description": "API description in Markdown.",     "version": "1.0.0"   },   "servers": [     {       "url": "**https://api.example.com**/v1"     }   ],  "**components**": {     "**schemas**": {       **"User": {**         "properties": {           "id": {             "type": "integer"           },           "name": {             "type": "string"           },           "phones": {             "type": "array",             "items": {               **"$ref": "#/components/schemas/Phone"**             }           }         }       },       **"Phone": {**         "properties": {           "typeofphone": {             "type": "string"           },           "phone": {             "type": "string"           }         }       }     }   }   "paths": {     "/users/{userId}": {       "get": {         "summary": "Returns a user by ID.",         "parameters": [           {             "in": "path",             "name": "userId",             "required": true,             "schema": {               "type": "integer"             }           }         ],         "responses": {           "200": {             "description": "OK",             "content": {               "application/json": {                 "schema": {                   **"$ref": "#/components/schemas/User"**                 }               }             }           }         }       }     },     "/users": {       "post": {         "summary": "Creates a new user.",         "requestBody": {           "content": {             "application/json": {               "schema": {                 **"$ref": "#/components/schemas/User"**               }             }           }         },         "responses": {           "200": {             "description": "OK"           }         }       }     }   } }`

## Example 3: Nested Anonymous Object Schema (OAS 3.0)

Here’s an API spec with a JSON schema with anonymous object types defined inline. The derived phone object type's name is ExternalService\_\_Bank\_getUsers\_OUT\_200\_phones.

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-platform-extend_click-264-0-0-production-enus/5f7d9219-b7b1-4552-8891-f1aba9b289fc/images/icon_note.png)

Note For anonymous object types, Salesforce automatically derives object type names. The derived names are based on the external service, parent operation, operation parameter, parent object, and object property names. Each derived name must be fewer than 255 characters. For more information, see [Schema Definition Support](https://help.salesforce.com/s/articleView?id=platform.external_services_intro_schema_definitions.htm&release=264.0.0&type=5 "Learn about External Services' schema limits and other considerations.").

`{   "openapi": "3.0.0",   "info": {     "title": "bankService",     "description": "API description in Markdown.",     "version": "1.0.0"   },   "servers": [     {       "url": "**https://api.example.com**/v1"     }   ],   "paths": {     "/users/{userId}": {       "get": {         "summary": "Returns a user by ID.",         "parameters": [           {             "in": "path",             "name": "userId",             "required": true,             "schema": {               "type": "integer"             }           }         ],         "responses": {           "**200**": {             "description": "OK",             "content": {               "application/json": {                 **"schema": {                   "type": "object",**                   "properties": {                     "id": {                       "type": "integer"                     },                     "name": {                       "type": "string"                     },                     "phones": {                       "type": "array",                       "items": {                         **"type": "object",**                         "properties": {                           "typeofphone": {                             "type": "string"                           },                           "phone": {                             "type": "string"                           }                         }                       }                     }                   }                 }               }             }           }         }       }     },     "/users": {       "post": {         "summary": "Creates a new user.",         "requestBody": {           "content": {             "application/json": {               **"schema": {                 "type": "object",**                 "properties": {                   "id": {                     "type": "integer"                   },                   "name": {                     "type": "string"                   },                   "phones": {                     "type": "array",                     "items": {                       **"type": "object",**                       "properties": {                         "typeofphone": {                           "type": "string"                         },                         "phone": {                           "type": "string"                         }                       }                     }                   }                 }               }             }           }         },         "responses": {           "200": {             "description": "OK"           }         }       }     }   } }`

## Example 4: Apex Object Class Naming (OAS 3.0)

Here's an API spec registered with the external service name BankingAutomaticTellerMachine. However, the derived object names must be no longer than 255 characters.

- `ExternalService__BankingAutomaticTellerMachine_VeryImportantCustomer_phone`
- `ExternalService__BankingAutomaticTellerMachine_getBalanceAccountTypeChecking_OUT_200`

To use Apex or Flow Builder, you must shorten the external service schema name and the schema (shown in Example 5).

![Tip](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-platform-extend_click-264-0-0-production-enus/5f7d9219-b7b1-4552-8891-f1aba9b289fc/images/icon_tip.png)

Tip If the derived object name is longer than 255 characters, try one of these methods to resolve the issue.

- Shorten the external service name.
- If the object is declared inline under an operation parameter, shorten the operation name by adding an operationId to the schema.
- If the object is declared inline under a parent object property, shorten the parent object name in the schema.
- Declare the nested object as a top-level object under schema "components/schemas".

`{   "openapi": "3.0.0",   ...   "paths": {     "/balance/account/{accountId}/type/checking": {       "get": {         "parameters": [           {             "in": "path",             "name": "accountId",             "required": true,             "schema": {               "type": "integer"             }           }         ],         "responses": {           "200": {             "description": "",             "content": {               "*/*": {                 "schema": {                   "type": "object",                   "properties": {                     "balance": {                       "type": "integer"                     },                     "owner": {                       "$ref": "#/components/schemas/VeryImportantCustomer"                     }                   }                 }               }             }           }         }       }     }   },   "components": {     "schemas": {       "VeryImportantCustomer": {         "type": "object",         "properties": {           "name": {             "type": "string"           },           "phone": {             "type": "object",             "properties": {               "number": {                 "type": "string"               }             }           }         }       }     }   } }`

## Example 5: Shortening Apex Object Class Names (OAS 3.0)

Here's an example of an API spec with a schema that results in shortened names. It's registered with the shortened name BankAtm.

Shorten the external service schema name to `BankAtm`, the schema object name to `VIP` and add `operationId` as `getBalance`:

- `ExternalService__BankAtm_VIP_phone`
- `ExternalService__BankAtm_getBalance_200`

`{   "openapi": "3.0.0",   ...   "paths": {     "/balance/account/{accountId}/type/checking": {       "get": {         **"operationId": "getBalance",**         "parameters": [           {             "in": "path",             "name": "accountId",             "required": true,             "schema": {               "type": "integer"             }           }         ],         "responses": {           "200": {             "description": "",             "content": {               "application/json": {                 "schema": {                   "type": "object",                   "properties": {                     "balance": {                       "type": "integer"                     },                     "owner": {                       "$ref": "#/components/schemas/VIP"                     }                   }                 }               }             }           }         }       }     }   },   "components": {     "schemas": {       "**VIP**": {         "type": "object",         "properties": {           "name": {             "type": "string"           },           "phone": {             "type": "object",             "properties": {               "number": {                 "type": "string"               }             }           }         }       }     }   } }`

## Example 6: Inline Arrays (OAS 3.0)

Here's an example with an inline array definition.

`{   "openapi": "3.0.0",   ...   "paths": {     "/employees/{employeeId}": {       "get": {         "operationId": "getEmployee",         "parameters": [           {             "in": "path",             "name": "employeeId",             "required": true,             "schema": {               "type": "string"             }           }         ],         "responses": {           "200": {             "description": "",             "content": {               "application/json": {                 "schema": {                   "type": "object",                   "properties": {                     "employee": {                       "$ref": "#/components/schemas/Employee"                     },                     "manager": {                       "$ref": "#/components/schemas/Employee"                     },                     "team": {                       **"type": "array",                       "items": {                         "$ref": "#/components/schemas/Employee"**                       }                     }                   }                 }               }             }           }         }       }     }   },   "components": {     "schemas": {       "Employee": {         "type": "object",         "properties": {           "employeeId": {"type": "string"},           "firstName": {"type": "string"},           "middleName": {"type": "string"},           "lastName": {"type": "string"},           "dateOfHire": {"type": "date"}         }       }     }   } }`

## Example 7: HTTP Header Parameters (OAS 3.0)

Here’s how a header parameter is declared in an OpenAPI schema. In Apex or Flow, the name “`apiKey`” shows up as a string parameter. Now when you set any string value in Apex or a flow to `apiKey`, it functions as an HTTP parameter when making a callout request.

`{   "openapi": "3.0.0",   "info": {     "description": "A service for checking credit for an account.",     "version": "1.0.0",     "title": "Credit Decision",     "termsOfService": "http://swagger.io/terms/",     "contact": {       "email": "apiteam@swagger.io"     },     "license": {       "name": "Apache 2.0",       "url": "http://www.apache.org/licenses/LICENSE-2.0.html"     }   },  "servers": [     {       "url": "https://<YourHostName>"     }   ],   "paths": {     "/account/lastCreditRating": {       "get": {         "summary": "Evaluates credit rating and decides what payment terms to offer.",         "description": "",         "parameters": [           {             **"name": "apiKey",             "description": "Your API Key for calling the credit rating service",             "in": "header",             "schema": {               "type": "string"             }**           }         ],         "requestBody": {           "content": {             "application/json": {               "schema": {                 "$ref": "#/components/schemas/accountId"               }             },             "application/xml": {               "schema": {                 "$ref": "#/components/schemas/accountId"               }             }           },           "description": "Specifies input parameters to calculate payment term",           "required": true         },         "responses": {           "200": {             "description": "success",             "content": {               "application/xml": {                 "schema": {                   "$ref": "#/components/schemas/creditRating"                 }               },               "application/json": {                 "schema": {                   "$ref": "#/components/schemas/creditRating"                 }               }             }           },           "405": {             "description": "Invalid input"           }         }       }     }   },   "components": {     "schemas": {       "accountId": {         "type": "object",         "properties": {           "accountIdString": {             "type": "string"           }         },         "xml": {           "name": "accountId"         }       },       "creditRating": {         "type": "object",         "properties": {           "creditRatingString": {             "type": "string"           }         },         "xml": {           "name": "creditRating"         }       }     }   } }`

## Example 8: URL Encoded Form Media Type (OAS 3.0)

Request and response form data is declared with media type `application/x-www-form-urlencoded`.

```java
{
  "openapi": "3.0.0",
  "info": {
    "description": "Apply here for your next mortgage",
    "version": "1.0.0",
    "title": "My Mortgage Buddy",
    "contact": {
      "email": "apiteam@swagger.io"
    }
  },
  "servers": [
    {
      "url": "https://MyMortgageBuddy.org/mortgages"
    }
  ],
  "paths": {
    "/apply": {
      "post": {
        "operationId": "applyMortgage",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded; charset=utf-8": {
              "schema": {
                "type": "object",
                "properties": {
                  "terms": {
                    "description": "Desired mortgage terms",
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  },
                  "fullName": {
                    "description": "Full Name",
                    "type": "string"
                  },
                  "loanAmount": {
                    "description": "Loan amount",
                    "type": "number"
                  }
                },
                "required": [
                  "terms",
                  "fullName",
                  "loanAmount"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "200",
            "content": {
              "application/x-www-form-urlencoded; charset=utf-8": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "formApplicationId": {
                      "type": "string"
                    },
                    "loanOfficerFullName": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```

## Example 9: allOf and additionalProperties Schema Directives (OAS 3.0)

This JSON schema definition highlights the constructs `allOf` for schema object composition and `additionalProperties` for dictionary values. The sample schema is registered as external service `MyBank` with named credential `MyBank`.

The schema defines a banking service that gets customer details for a customer ID.

- The `Customer` schema object has dictionary properties of type schema object `CreditRating`. In Apex, the class `ExternalService.MyBank_Customer` has property `properties` of type `Map<String, ExternalService_CreditRating>` with the customer’s credit ratings.
- `Phones` and `Emails` compose their own properties together with the common `allOf` properties from the schema object `Contact.`

```
{
  "openapi": "3.0.0",
  "info": {
    "title": "myBank",
    "description": "Sample Banking Service with allOf and additionalProperties",
    "version": "1.0.0"
  },
 "servers": [
    {
      "url": "https://api.mybank.com/v1"
    }
  ],
  "paths": {
    "/customers/{customerId}": {
      "get": {
        "summary": "Get the customer by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "customerId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "phones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            }
          },
          "emails": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            }
          }
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/CreditRating"
        },
        "required": [
          "id",
          "name"
        ]
      },
      "Contact": {
        "type": "object",
        "properties": {
          "primary": {
            "type": "boolean"
          },
          "timeOfDay": {
            "type": "string"
          }
        },
        "required": [
          "primary"
        ]
      },
      "Phone": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Contact"
          },
          {
            "type": "object",
            "properties": {
              "typeOfPhone": {
                "type": "string"
              },
              "phoneNumber": {
                "type": "string"
              }
            }
          }
        ]
      },
      "Email": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Contact"
          },
          {
            "type": "object",
            "properties": {
              "email": {
                "type": "string"
              }
            }
          }
        ]
      },
      "CreditRating": {
        "type": "object",
        "properties": {
          "rating": {
            "type": "string"
          },
          "score": {
            "type": "number",
            "format": "double"
          }
        }
      }
    }
  }
}
```

To use `allOf` composition and `additionalProperties`, see [For Examples 9: allOf Composition and additionalProperties Use in Flow with Apex Unit Tests](https://help.salesforce.com/s/articleView?id=platform.external_services_examples_using.htm&release=264.0.0&type=5).

## Example 10: allOf and Discriminator Directives (OAS 3.0)

To specify a general extensible list of contacts for a customer, the `discriminator` directive can be combined with `allOf` to declare whether a contact is an email or a phone number:

```
{
  "openapi": "3.0.0",
  "info": {
    "title": "myBank",
    "description": "Sample Banking Service with allOf and discriminator",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.mybank.com/v1"
    }
  ],
  "paths": {
    "/customers/{customerId}": {
      "get": {
        "summary": "Get the customer by ID.",
        "parameters": [
          {
            "in": "path",
            "name": "customerId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Contact"
            }
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "Contact": {
        "type": "object",
        "discriminator": {
          "propertyName": "contactType"
        },
        "properties": {
          "contactType": {
            "type": "string"
          },
          "primary": {
            "type": "boolean"
          },
          "timeOfDay": {
            "type": "string"
          }
        },
        "required": [
          "contactType",
          "primary"
        ]
      },
      "Phone": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Contact"
          },
          {
            "type": "object",
            "properties": {
              "typeOfPhone": {
                "type": "string"
              },
              "phoneNumber": {
                "type": "string"
              }
            }
          }
        ]
      },
      "Email": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Contact"
          },
          {
            "type": "object",
            "properties": {
              "email": {
                "type": "string"
              }
            }
          }
        ]
      }
    }
  }
}
```

To use composition and polymorphic OpenAPI schema constructs, see [For Examples 10: Polymorphism with allOf and Discriminator](https://help.salesforce.com/s/articleView?id=platform.external_services_examples_using.htm&release=264.0.0&type=5).

## Example 11: anyOf, oneOf, and Discriminator Directives (OAS 3.0)

`anyOf` and `oneOf` directives model types with parts of a common schema type. `anyOf` and `oneOf` can be combined with the schema construct `discriminator` for polymorphic types.

- Social security number
- The driver's license number
- The customer's first _and_ last name with optional middle name

In the example, a customer can be identified by one or more of the following allowed identifiers.

The schema mandates both the customer's first and last name, or to choose any other allowed identification.

This example also highlights a variation of the Contact type polymorphism with `oneOf` and `discriminator` from Example 10 with `allOf`.

`{   "openapi": "3.0.0",   "info": {     "title": "myBank",     "description": "Sample Banking Service with oneOf, anyOf and discriminator",     "version": "1.0.0"   },   "servers": [     {       "url": "https://api.mybank.com/v1"     }   ],   "paths": {     "/customers/{customerId}": {       "get": {         "summary": "Get the customer by ID.",         "parameters": [           {             "in": "path",             "name": "customerId",             "required": true,             "schema": {               "type": "integer"             }           }         ],         "responses": {           "200": {             "description": "OK",             "content": {               "application/json": {                 "schema": {                   "$ref": "#/components/schemas/Customer"                 }               }             }           }         }       }     }   },    "components": {     "schemas": {       "Customer": {         "type": "object",         "properties": {           "id": {             **"anyOf": [               {                 "$ref": "#/components/schemas/SSN"               },               {                 "$ref": "#/components/schemas/DriversLicense"               },               {                 "$ref": "#/components/schemas/FullName"               }             ]**           },           "contacts": {             "type": "array",             "items": {               "$ref": "#/components/schemas/Contact"             }           }         },         "required": [           "id"         ]       },       "SSN": {         "type": "object",         "properties": {           "ssn": {             "type": "string"           }         },         "required": [           "ssn"         ]       },       "DriversLicense": {         "type": "object",         "properties": {           "dl": {             "type": "string"           }         },         "required": [           "dl"         ]       },       "FullName": {         "type": "object",         "properties": {           "firstName": {             "type": "string"           },           "middleName": {             "type": "string"           },           "lastName": {             "type": "string"           }         },         "required": [           "firstName",           "lastName"         ]       },        "Contact": {         **"oneOf": [           {             "$ref": "#/components/schemas/Phone"           },           {             "$ref": "#/components/schemas/Email"           }         ],         "discriminator": {           "propertyName": "contactType"         }**       },       "Phone": {         "type": "object",         "properties": {           **"contactType": {             "type": "string"           },**           "typeOfPhone": {             "type": "string"           },           "phoneNumber": {             "type": "string"           }         }       },       "Email": {         "type": "object",         "properties": {           **"contactType": {             "type": "string"           },**           "email": {             "type": "string"           }         }       }     }   } }`

To use composition and polymorphic OpenAPI schema constructs, see [For Example 11 (Open API 3.0): AnyOf, OneOf, and Discriminator](https://help.salesforce.com/s/articleView?id=platform.external_services_examples_using.htm&release=264.0.0&type=5).

## Example 12: Callbacks (OAS3.0)

External Services specify callback options through the OpenAPI 3.0 schema’s `callbacks` object.

This is an example of a callback for a mortgage application process for the fictitious company Acme Mortgages.

```
openapi: 3.0.0

info:
  version: '1.0'
  title: Acme Mortgages
  description: Acme Mortgages
  
paths:
  # Example of synchronous operation GetApplication
  /applications/{applicationNumber}:
    get:
      operationId: GetApplication
      description: Get the mortgage application status and details
      parameters:
        - name: applicationNumber
          in: path
          required: true
          description: Mortgage Application Number
          schema:
            type: string
        - name: referenceId
          in: query
          description: Reference ID if applicable. Either as query or header
          schema:
            type: string
        - name: referenceId
          in: header
          description: Reference ID if applicable. Either as query or header
          schema:
            type: string
      responses:
        200:
          description: Mortgage application status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MortgageApplication'
                
  /applications:
    # Example of asynchronous operation with callback SubmitApplication
    post:
      operationId: SubmitApplication
      description: Submit a new mortgage application
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                applicant:
                  $ref: '#/components/schemas/Contact'
                object:
                  $ref: '#/components/schemas/Contact'
                statusUpdateRequest:
                  $ref: '#/components/schemas/ApplicationStatusUpdateRequest'
                callbackUrl:
                  type: object
                  properties:
                    outcome:
                      type: object
                      properties:
                        approved:
                          type: string
                        rejected:
                          type: string
                    documentation:
                      type: string
                    outcomeError:
                      type: string
      responses:
        200:
          description: Mortgage loan application submission response
          content:
            application/json:
              schema:
                type: object
                properties:
                  applicationNumber:
                    type: string
        400:
          description: Mortgage application error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MortgageApplicationError'
      callbacks:
        applicationOutcome:
          '{$request.body#/callbackUrl/outcome/approved}':
            post:
              operationId: ApplicationApproved
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/MortgageApplication'
              responses:
                200:
                  description: Approved mortgage application callback accepted
          '{$request.body#/callbackUrl/outcome/rejected}':
            post:
              operationId: ApplicationRejected
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/MortgageApplication'
              responses:
                200:
                  description: Rejected mortgage application callback accepted
        applicationDocumentation:
          '{$request.body#/callbackUrl/documentation}':
            post:
              parameters:
                - in: query
                  name: applicationNumber
                  schema:
                    type: string
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/MortgageApplicationDocumentation'
              responses:
                200:
                  description: Mortgage application documentation callback accepted
        applicationStatus_Update:
            $ref: '#/components/callbacks/ApplicationStatus_Update'
        applicationOutcomeError:
            $ref: '#/components/callbacks/applicationOutcomeError'

servers:
  - url: '/'
  
components:
  schemas:
    MortgageApplication:
      required:
        - applicationNumber
        - status
      properties:
        applicationNumber:
          type: string
        status:
          description: One of pending, approved, rejected
          type: string
        requestedAmount:
          type: number
        approvedAmount:
          type: number
        appliedOn:
          type: string
          format: date-time
        updatedOn:
          type: string
          format: date-time          
        applicant:
          $ref: '#/components/schemas/Contact'
        object:
          $ref: '#/components/schemas/Contact'

    ApplicationStatusUpdateRequest:
      description: Mortgage application status update request
      type: object
      properties:
        sendStatusUpdates:
          type: boolean
        statusUpdateCallbackUrl:
          type: string

    MortgageApplicationDocumentation:
        description: Required mortgage documentation
        type: array
        items:
          type: object
          properties:
              documentType:
                  type: string
              uploadUrl:
                  type: string
              instructions:
                  type: string 
                              
    Contact:
      type: object
      properties:
        name:
          type: string
        address:
          type: string
          
    MortgageApplicationError:
      properties:
        errorMessage:
          type: string
        applicationNumber:
          type: string

  callbacks:
    ApplicationStatus_Update:
      '{$request.body#/statusUpdateRequest/statusUpdateCallbackUrl}':
        post:
          requestBody:
            required: true
            content: 
              application/json:
                schema:
                  type: object
                  properties:
                    applicationNumber:
                      type: string
                    status:
                      type: string
                    updateMessage:
                      type: string
          responses:
            200:
                description: Mortgage application status update callback accepted
    applicationOutcomeError:
      '{$request.body#/callbackUrl/outcomeError}':
        post:
          requestBody:
            required: true
            content:
                application/json:
                  schema:
                      $ref: '#/components/schemas/MortgageApplicationError'
          responses:
            200:
                description: Mortgage application callback error accepted
```

## Example 13: File Upload and Download (OAS 3.0)

This spec contains these examples:

- A PUT operation for file upload—the PUT operation takes a `key` parameter with the location/file name of the file to upload and specifies the `content-type` header. The `requestBody` is defined as a binary string, and contains the contents of the file being uploaded.
- A GET operation for file download—the GET operation takes a `key` parameter with the file name of the file to download. The 200 response returns a `content` object defined as a binary string, and contains the contents of the file being downloaded.

This spec references uploading a file to Amazon S3, but the spec can be used to upload files to any system for which you have a named credential configured.

```javascript
openapi: 3.0.0
info:
  title: S3 PutObject and GetObject API
  version: 1.1.0
  description: Example API for uploading and downloading files to Amazon S3 (without auth headers)

paths:
  /{key}:
    put:
      summary: Upload an object to S3 at the specified key
      description: Upload a file to the given bucket and key using HTTP PUT.
      operationId: putObject
      parameters:
        - name: key
          in: path
          required: true
          description: The key (path) of the S3 object
          schema:
            type: string
        - name: Content-Type
          in: header
          description: MIME type of the uploaded file
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
            description: Binary content of the file to upload
      responses:
        '200':
          description: Upload successful
          headers:
            ETag:
              description: The ETag of the uploaded object
              schema:
                type: string
        '400':
          description: Bad request
        '404':
          description: Bucket or key not found
        '500':
          description: Internal server error

    get:
      summary: Download an object from S3 at the specified key
      description: Download the file content from the given bucket and key using HTTP GET.
      operationId: getObject
      parameters:
        - name: key
          in: path
          required: true
          description: The key (path) of the S3 object
          schema:
            type: string
      responses:
        '200':
          description: File content returned
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '403':
          description: Access denied
        '404':
          description: Object not found
        '500':
          description: Internal server error
```

To use this functionality, see [For Example 13 (Open API 3.0): Binary File Upload](https://help.salesforce.com/s/articleView?id=platform.external_services_examples_using.htm&release=264.0.0&type=5) and [For Example 13 (Open API 3.0): Binary File Download](https://help.salesforce.com/s/articleView?id=platform.external_services_examples_using.htm&release=264.0.0&type=5).

## Example 14: Enum Parameters in Queries and Responses (OAS 3.0)

This spec contains a GET operation that takes two enum values as parameters:

- An `ItemStatus` parameter that contains a value from the ItemStatus enum.
- An `ItemPriority` parameter that contains a value from the ItemPriority enum.

The 200 response returns an object that contains the item id, status, priority, and description.

```json
{
  "openapi": "3.0.3",
  "info": {
    "title": "Enum Examples API",
    "version": "1.0.0",
    "description": "Example API demonstrating enum parameters in queries and responses."
  },
  "servers": [
    {
      "url": "https://abc-mock-api-123456789123.herokuapp.com/"
    }
  ],
  "paths": {
    "/items": {
      "get": {
        "operationId": "getItemList",
        "summary": "Retrieve a list of items filtered by enum parameters",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ItemStatus"
            },
            "description": "Filter items by their status"
          },
          {
            "name": "priority",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ItemPriority"
            },
            "description": "Optional filter for item priority"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response with list of items",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ItemStatus": {
        "type": "string",
        "enum": [
          "active",
          "inactive",
          "pending",
          "archived"
        ]
      },
      "ItemPriority": {
        "type": "integer",
        "enum": [
          1,
          2,
          3,
          4,
          5
        ]
      },
      "ItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "$ref": "#/components/schemas/ItemStatus"
          },
          "priority": {
            "$ref": "#/components/schemas/ItemPriority"
          },
          "message": {
            "type": "string",
            "description": "Additional information about the item"
          }
        },
        "required": [
          "id",
          "status"
        ]
      }
    }
  }
}
```

## Example 15: Any Type Support by Using schema: {} (OAS 3.0)

This spec contains a POST method that takes any JSON string. Any type support is only available for orgs that have Data 360 provisioned.

You can also use a mixed structure in your spec that combines typed parameters with an any type body. For example, define typed query parameters, path parameters, or headers for event metadata while keeping the request body as any type.

```json
openapi: 3.0.1
info:
  title: Flow Any Type Test Service
  description: |
    Minimal OAS3 spec for any type support 
  version: 1.0.0

servers:
  - url: https://sample.com

paths:
  /test:
    post:
      operationId: sendTestPayload
      summary: Accepts any JSON payload (anytype body)
      requestBody:
        required: false
        content:
          application/json:
            schema: {}
      responses:
        '200':
          description: Payload accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
```

#### See Also

- [Schema Examples](https://help.salesforce.com/s/articleView?id=platform.external_services_examples.htm&release=264.0.0&type=5 "Explore various scenarios with OpenAPI 2.0 and OpenAPI 3.0 compliant JSON or YAML schemas supported by External Services. The examples cover schema elements like HTTP header as input parameters, and include example usage in Apex. Understanding the examples helps with proper syntax and code placement.")
- [Using the Schema Examples](https://help.salesforce.com/s/articleView?id=platform.external_services_examples_using.htm&release=264.0.0&type=5 "See how the respective Open API 2.0 and 3.0 examples are implemented with Apex.")