Wassenger Funnel API
The Funnel API from Wassenger — 1 operation(s) for funnel.
The Funnel API from Wassenger — 1 operation(s) for funnel.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/wassenger:wassenger-funnel-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Wassenger Funnel API
version: 1.0.0
description: '**API documentation for Wassenger**
> 🔥 🆕 **Introducing Flows**: No-Code Automation Solution to create AI agents and automate anything on WhatsApp! Learn more
## Introduction
This API documentation provides detailed information about the API endpoints and request/response API contracts. You can easily browse all the API resources, request/response the with code examples in 15+ programming languages, including JavaScript/Node.js, Python, PHP, Ruby, Java, C#, Go, Swift, Kotlin, ObjectiveC, C/C++, cURL, Powershell and more. This is a web based API, therefore is only required to send HTTPS requests in order to communicate with the API, making it very easy to use and integrate with any third-party software, programming language, CMS, CRM or CLI tools. The API does not require any SDK and has no strict software dependencies, it can be easily used with no friction by simply sending HTTPS requests to the desired API endpoint. > 🤩 🤖 **Ask the Wassenger AI Assistant to write code for you** 👉
## Security
This API is intended for use exclusively in server-side applications. Attempting to use them in a client-side application will result in Cross-Origin Resource Sharing (CORS) errors. This restriction is intentional and ensures the security and integrity of the service. ## Tutorials
Learn how to use the API exploring our handy tutorials with detailed code examples and live API testing:
- 💬 Send messages to phone numbers
- 💬 Send messages to group chats
- 💬 Send messages to channel 🆕
- 💬 Send messages from a CSV file 🆕
- 💬 Send messages from a Google Sheets document 🆕
- 📁 Send multimedia messages (images, videos, documents, files or audios)
- 💬 Include emojis in text messages
- 💬 Send location messages
- 💬 Send contacts
- 💬 Send URL links in text messages
- 💬 Send auto-expiring messages
- 💬 Send messages in real-time without queueing
- 💬 Send messages through a specific WhatsApp number/device
- 💬 Send messages on behalf of a chat agent
- 💬 Send messages replying to a specific message
- 💬 Send dynamic buttons message
- 💬 Send dynamic list message
- 📝 How to use template variables
- 📝 How to format text with styling in messages
- ✅ Check if a phone number exists in WhatsApp and can receive messages
## Chatbots 🔥
- 🤖 Create a custom chat bot using the API + Webhooks 🆕
- 🤖 Create a ChatGPT-powered AI chatbot assistant for your business 🆕
## MCP 🆕
MCP (acronym of Model Context Protocol) connector lets you connect your Wassenger WhatsApp numbers into modern AI LLMs and chat with your WhatsApp data, analyze conversation, send messages, or perform any other WhatsApp action directly from your favorite AI chat or code tool. - 🤖 **Learn how to use MCP with your AI tool**
## Integrations
- n8n: integrate with 600+ third-party apps
- Zapier: integrate with 6000+ third-party apps
- Make (formerly Integromat): integrate with 2000+ third-party apps
- Integrately: integrate with 1200+ third-party apps
- Google Sheets
- Hubspot
- Shopify
- Zoho CRM
- Salesforce
- Microsoft Dynamics
- Pipedrive
- Bitrix24
- Airtable
- Notion
- Nimble CRM
- Monday.com
## Live API testing
Explore the live API testing using real use cases with dozens of ready-to-use examples:
- **Go to the API client live tester**
- **Explore, test and debug the API using Postman graphical HTTP client**
### API examples
Explore the many API use cases in the API tester ready-to-use code examples available in 15+ programming languages. > 🤩 🤖 **Ask the Wassenger AI Assistant to write code for you** 👉
Find below each relevant API endpoint documentation with more ready-to-use code examples. ## How to use the API
Search or browse the API endpoint by name or action to perform in the left bar. Then click on the API endpoint and browse the details of the request/response, including query or body required/optional parameters and possible valid responses.'
x-traitTag: true
x-logo:
url: https://api.wassenger.com/v1/static/accounts/waplatform/fenix/logo.png
backgroundColor: '#FFFFFF'
altText: Wassenger
servers:
- url: https://api.wassenger.com/v1
tags:
- name: Funnel
paths:
/pipelines/{pipelineId}/summary:
parameters: []
get:
summary: Get pipeline summary
description: 'Per-stage counters and open amount totals for the board columns, plus the won and lost totals. Each stage row also carries `closed` (`{count, amount, mixedCurrency, currency}`): the deals that finished in that stage over the whole life of the pipeline. A won or lost stage holds no open deals by construction, so its `count`/`amount` pair is always zero and `closed` is the only figure that describes it. `closedOffStage` carries the same shape for the closed deals whose stage is no longer part of the pipeline, which a stage deleted after deals were decided in it leaves behind. The per-stage `closed` figures plus `closedOffStage` always add up to `won` plus `lost`; without the second term they would silently stop doing so. Those totals come in two windows: `won` and `lost` cover the whole life of the pipeline, `won30d` and `lost30d` the last 30 days, measured from the `since` date in the response. An archived pipeline is read by the lifetime pair: a funnel retired more than a month ago has an empty 30-day window, and its history is exactly what archiving keeps. `wonPrev30d` and `lostPrev30d` carry the same pair for the window immediately BEFORE that one, `previousSince, since)`, which is what a variation is measured against. The two windows are half-open and meet at `since`, so no deal is counted by both. A period in which nothing closed is returned as a zero rather than omitted, because "nothing closed then" and "this was not measured" are different answers: there is no percentage between no deals and five, so a caller reading a zero here should omit the variation rather than divide by it. Also returns `lostReasonStats`: the reasons the lost deals were lost, one entry per reason with its lifetime `count` and `amount` plus the `count30d` / `amount30d` of those that closed inside the window, ranked by count and then by amount. Deals closed without a reason are grouped into a single entry whose `reason` is `null`, and that entry is always returned. A reason is free text, so at most 20 named reasons are ranked and returned, and everything left over is summed into `lostReasonStatsOther` (`{reasons, count, amount, count30d, amount30d, mixedCurrency, currency, mixedCurrency30d, currency30d}`, or `null` when nothing was left over). The remainder is worked out by subtracting the listed entries from the lost totals rather than by reading the tail, so the two always add up to `lost`, and their 30-day halves to `lost30d`, exactly. `mixedCurrency` carries one flag per figure (`open`, `won`, `lost`, `won30d`, `lost30d`, `wonPrev30d`, `lostPrev30d`), and each stage row and each loss reason carries its own (a loss reason carries `mixedCurrency30d` for its windowed half too). A true flag means the deals behind that amount do not all share one currency: `deal.currency` is seeded from the pipeline currency but can be set per deal, and no exchange rate is applied anywhere, so the amount is a sum of different units and should not be printed as a single figure. A deal that states no currency of its own is not a second currency. The remainder entry answers this question conservatively: it is subtracted rather than read, so it reports one unit only when every lost deal in the funnel shares it. `currencies` mirrors it with the unit each figure IS in, and every stage row and loss reason carries its own `currency` (and `currency30d`) too. It is `null` exactly when the matching flag is true. This is not the same answer as `currency`, the pipeline''s own unit: a pipeline priced in EUR whose deals were all stored in USD mixes nothing, and pricing its totals in the pipeline currency would print dollars with a euro sign. Restricted agents only see figures for their own deals, and `scope` says which of the two the response is: `account` for the whole funnel, `agent` when every figure has been narrowed to the reader.'
operationId: getPipelineSummary
security:
- apiKey: []
tags:
- Funnel
responses:
'200':
description: Pipeline summary
'400':
description: Invalid query or body request data
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'401':
description: Unauthorized - Invalid or missing API token
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'403':
description: Missing required permissions
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'404':
description: Pipeline not found
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'409':
description: Conflict
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'429':
description: Too many requests - Try again later
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'500':
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'501':
description: Not implemented
content:
application/json:
schema:
$ref: '#/components/schemas/error'
'503':
description: Service temporarily unavailable - Try again later
content:
application/json:
schema:
$ref: '#/components/schemas/error'
x-codeSamples:
- lang: cURL
source: "// This code example requires you to have installed curl package\n// Installation instructions here: https://curl.haxx.se/download.html\n\n// Get the pipeline board summary\ncurl --request GET \\\n --url https://api.wassenger.com/v1/pipelines/{pipelineId}/summary \\\n --header 'Token: <api token goes here>'"
- lang: HTTPie
source: "// This code example requires to have installed httpie package, an powerful alternative to curl and wget\n// Installation instructions here: https://httpie.org/docs#installation\n\n// Get the pipeline board summary\nhttp GET https://api.wassenger.com/v1/pipelines/{pipelineId}/summary \\\n Token:'<api token goes here>'"
- lang: Node
source: "// This code example requires you to have installed node-fetch Node.js package.\n// Install it by running: npm install --save node-fetch or yarn add node-fetch\n\n// Get the pipeline board summary\nconst fetch = require('node-fetch');\n\nconst url = 'https://api.wassenger.com/v1/pipelines/{pipelineId}/summary';\nconst options = {method: 'GET', headers: {Token: '<api token goes here>'}};\n\ntry {\n const response = await fetch(url, options);\n const data = await response.json();\n console.log(data);\n} catch (error) {\n console.error(error);\n}"
- lang: Node (axios)
source: "// Get the pipeline board summary\nconst axios = require('axios').default;\n\nconst options = {\n method: 'GET',\n url: 'https://api.wassenger.com/v1/pipelines/{pipelineId}/summary',\n headers: {Token: '<api token goes here>'}\n};\n\ntry {\n const { data } = await axios.request(options);\n console.log(data);\n} catch (error) {\n console.error(error);\n}"
- lang: Node (unirest)
source: "// This code example requires you to have installed unirest Node.js package.\n// Install it by running: npm install --save unirest or yarn add unirest\n\n// Get the pipeline board summary\nconst unirest = require('unirest');\n\nconst req = unirest('GET', 'https://api.wassenger.com/v1/pipelines/{pipelineId}/summary');\n\nreq.headers({\n Token: '<api token goes here>'\n});\n\nreq.end(function (res) {\n if (res.error) throw new Error(res.error);\n\n console.log(res.body);\n});"
- lang: PHP (Guzzle)
source: "// This code example requires to have installed Guzzle package, a flexible and elegant HTTP client for PHP.\n// Install it first following these instructions:\n// https://docs.guzzlephp.org/en/stable/overview.html#installation\n\n// Get the pipeline board summary\n<?php\n\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', 'https://api.wassenger.com/v1/pipelines/{pipelineId}/summary', [\n 'headers' => [\n 'Token' => '<api token goes here>',\n ],\n]);\n\necho $response->getBody();"
- lang: PHP (http2)
source: "// This code example requires to have installed pecl_http package, a simple and elegant HTTP client for PHP.\n// Install it by running: pecl install pecl_http\n// More information: https://mdref.m6w6.name/http\n\n// Get the pipeline board summary\n<?php\n\n$client = new http\\Client;\n$request = new http\\Client\\Request;\n\n$request->setRequestUrl('https://api.wassenger.com/v1/pipelines/{pipelineId}/summary');\n$request->setRequestMethod('GET');\n$request->setHeaders([\n 'Token' => '<api token goes here>'\n]);\n\n$client->enqueue($request)->send();\n$response = $client->getResponse();\n\necho $response->getBody();"
- lang: PHP (curl)
source: "// Get the pipeline board summary\n<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"GET\",\n CURLOPT_HTTPHEADER => [\n \"Token: <api token goes here>\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
- lang: Python
source: '# Examples requires to have installed requests Python package.
# Install it by running: pip install requests
# Get the pipeline board summary
import requests
url = "https://api.wassenger.com/v1/pipelines/{pipelineId}/summary"
headers = {"Token": "<api token goes here>"}
response = requests.get(url, headers=headers)
print(response.json())'
- lang: JavaScript
source: "// IMPORTANT NOTICE:\n// Performing HTTPS requests to the API from a JavaScript in a web browser is\n// forbidden by default due to cross-origin security policies (CORS).\n// More information here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\n//\n// Communicating directly from JavaScript in a web browser with the API\n// is considered security bad practice and completely discouraged\n// as this will expose your API secret key, enabling a third-party user\n// to easily steal your key and have full privilege access to your account via API.\n//\n// We strongly recommend to do not expose the API key in the web browser JavaScript code.\n// Always use your server to communicate with the API without exposing the API key.\n\n// Get the pipeline board summary\nconst url = 'https://api.wassenger.com/v1/pipelines/{pipelineId}/summary';\nconst options = {method: 'GET', headers: {Token: '<api token goes here>'}};\n\ntry {\n const response = await fetch(url, options);\n const data = await response.json();\n console.log(data);\n} catch (error) {\n console.error(error);\n}"
- lang: jQuery
source: "// IMPORTANT NOTICE:\n// Performing HTTPS requests to the API from a JavaScript in a web browser is\n// forbidden by default due to cross-origin security policies (CORS).\n// More information here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\n//\n// Communicating directly from JavaScript in a web browser with the API\n// is considered security bad practice and completely discouraged\n// as this will expose your API secret key, enabling a third-party user\n// to easily steal your key and have full privilege access to your account via API.\n//\n// We strongly recommend to do not expose the API key in the web browser JavaScript code.\n// Always use your server to communicate with the API without exposing the API key.\n\n// Get the pipeline board summary\nconst settings = {\n async: true,\n crossDomain: true,\n url: 'https://api.wassenger.com/v1/pipelines/{pipelineId}/summary',\n method: 'GET',\n headers: {\n Token: '<api token goes here>'\n }\n};\n\n$.ajax(settings).done(function (response) {\n console.log(response);\n});"
- lang: Ruby
source: '# Get the pipeline board summary
require ''uri''
require ''net/http''
url = URI("https://api.wassenger.com/v1/pipelines/{pipelineId}/summary")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Token"] = ''<api token goes here>''
response = http.request(request)
puts response.read_body'
- lang: Go
source: "// Get the pipeline board summary\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io\"\n)\n\nfunc main() {\n\n\turl := \"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\treq.Header.Add(\"Token\", \"<api token goes here>\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := io.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
- lang: C# (RestClient)
source: '// This code requires you to have installed RestSharp package.
// Documentation: https://restsharp.dev
// Installation: https://www.nuget.org/packages/RestSharp
// Get the pipeline board summary
var client = new RestClient("https://api.wassenger.com/v1/pipelines/{pipelineId}/summary");
var request = new RestRequest(Method.GET);
request.AddHeader("Token", "<api token goes here>");
IRestResponse response = client.Execute(request);'
- lang: C# (HttpClient)
source: "// This code uses the built-in HttpClient package in the .NET framework.\n// Documentation: https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0\n\n// Get the pipeline board summary\nusing System.Net.Http.Headers;\nvar client = new HttpClient();\nvar request = new HttpRequestMessage\n{\n Method = HttpMethod.Get,\n RequestUri = new Uri(\"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\"),\n Headers =\n {\n { \"Token\", \"<api token goes here>\" },\n },\n};\nusing (var response = await client.SendAsync(request))\n{\n response.EnsureSuccessStatusCode();\n var body = await response.Content.ReadAsStringAsync();\n Console.WriteLine(body);\n}"
- lang: Java
source: "// This code requires you to have installed Unirest package.\n// Documentation: https://kong.github.io/unirest-java/#requests\n// Installation: http://kong.github.io/unirest-java/\n\n// Get the pipeline board summary\nHttpResponse<String> response = Unirest.get(\"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\")\n .header(\"Token\", \"<api token goes here>\")\n .asString();"
- lang: Kotlin
source: "// This code requires to have installed okhttp package.\n// Documentation: https://square.github.io/okhttp/recipes/\n// Installation via Maven: https://square.github.io/okhttp/#releases\n\n// Get the pipeline board summary\nval client = OkHttpClient()\n\nval request = Request.Builder()\n .url(\"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\")\n .get()\n .addHeader(\"Token\", \"<api token goes here>\")\n .build()\n\nval response = client.newCall(request).execute()"
- lang: C
source: '// Get the pipeline board summary
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.wassenger.com/v1/pipelines/{pipelineId}/summary");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Token: <api token goes here>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);'
- lang: Powershell
source: '# Get the pipeline board summary
$headers=@{}
$headers.Add("Token", "<api token goes here>")
$response = Invoke-WebRequest -Uri ''https://api.wassenger.com/v1/pipelines/{pipelineId}/summary'' -Method GET -Headers $headers'
- lang: ObjC
source: "// Get the pipeline board summary\n#import <Foundation/Foundation.h>\n\nNSDictionary *headers = @{ @\"Token\": @\"<api token goes here>\" };\n\nNSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@\"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\"]\n cachePolicy:NSURLRequestUseProtocolCachePolicy\n timeoutInterval:10.0];\n[request setHTTPMethod:@\"GET\"];\n[request setAllHTTPHeaderFields:headers];\n\nNSURLSession *session = [NSURLSession sharedSession];\nNSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request\n completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {\n if (error) {\n NSLog(@\"%@\", error);\n } else {\n NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;\n NSLog(@\"%@\", httpResponse);\n }\n }];\n[dataTask resume];"
- lang: Swift
source: "// Get the pipeline board summary\nimport Foundation\n\nlet headers = [\"Token\": \"<api token goes here>\"]\n\nlet request = NSMutableURLRequest(url: NSURL(string: \"https://api.wassenger.com/v1/pipelines/{pipelineId}/summary\")! as URL,\n cachePolicy: .useProtocolCachePolicy,\n timeoutInterval: 10.0)\nrequest.httpMethod = \"GET\"\nrequest.allHTTPHeaderFields = headers\n\nlet session = URLSession.shared\nlet dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in\n if (error != nil) {\n print(error as Any)\n } else {\n let httpResponse = response as? HTTPURLResponse\n print(httpResponse)\n }\n})\n\ndataTask.resume()"
components:
schemas:
error:
type: object
properties:
status:
type: number
default: 400
description: HTTP status code of the error. Same as HTTP protocol response status
enum:
- 400
- 401
- 402
- 403
- 404
- 405
- 409
- 410
- 413
- 415
- 429
- 451
- 500
- 501
- 502
- 503
- 504
- 505
message:
type: string
description: Error message
errorCode:
type: string
enum:
- error:generic
- error:*
description: Application specific error code. Not always present.
errors:
type: array
description: Additional data validation errors, if present
items:
type: object
properties:
code:
type: string
description: Optional error code identifier
reason:
type: string
description: Reason of the validation error
message:
type: string
description: Error detailed description
meta:
type: object
description: Optional error metadata key-value pairs.
securitySchemes:
apiKey:
type: apiKey
name: Token
in: header
description: 'User API key token needs to be used on every API request that requires authentication.
You can define it via "token" URL query param or via "Token" HTTP request header.
Get or create your API key from the [Web Console](https://console.wassenger.com/apikeys).
**Note**: chat agents and supervisors have no access to the API.
#### Example as request header:
```
GET /v1/messages HTTP/1.1
Host: api.wassenger.com:443
Token: 5f2296349b12abf18c3e4a072cfceb47f51bde312477d048a0baf7cccf4af17861e28f80739d3a3f
```
#### Example as URL query param:
```
GET /v1/messages?token=5f2296349b12abf18c3e4a072cfceb47f51bde312477d048a0baf7cccf4af17861e28f80739d3a3f HTTP/1.1
Host: api.wassenger.com:443
```'
keypassToken:
type: apiKey
name: Authorization
in: header
description: Account-wide keypass token in the Authorization header (issued via the extension download).
externalDocs:
description: Website
url: https://app.wassenger.com
x-tagGroups:
- name: Messages (outbound)
tags:
- Messages
- name: Numbers Management
tags:
- Devices
- Session
- Groups
- Channels
- Queue
- Settings
- Profile
- Contacts
- Team Members
- Departments
- Labels
- Automatic Replies
- Automatic Assignment
- Automatic Resolution
- Quick Replies
- Meeting Links
- Business catalog
- Billing
- name: Chat
tags:
- Chats
- Chat Messages
- Chat Contacts
- Chat Files
- User Status
- Analytics
- name: Sales Funnel
tags:
- Pipeline
- Deals
- name: Campaigns
tags:
- Campaigns
- name: WhatsApp Business API
tags:
- Templates
- Templates Pricing
- Catalog
- Flows
- name: Files Storage
tags:
- Files
- name: Notifications
tags:
- Webhooks
- name: Utilities
tags:
- Verify
x-mcp:
protocolVersion: '2025-11-25'
capabilities:
tools: {}
prompts: {}
logging: {}
completions: {}
servers:
- url: https://api.wassenger.com/mcp
description: 'MCP server (beta). Authenticate with an Authorization Bearer header holding your API key. Setup guide: /help/mcp'
x-express-openapi-disable-response-validation-middleware: true
x-express-openapi-additional-middleware:
- null
x-express-openapi-schema-extension:
definitions:
schema:
properties:
oneOf:
type: array
minItems: 1
items: {}