When aiming for the most realistic scenario, we sometimes need our mock API to respond differently based on the parameters we send. This can be easily achieved with Mockfly, and we also support conditional API responses based on:
An endpoint can have multiple responses, each with a different status code. To create a new response, click on the "+" button next to the status code, and a new response with a status code of 200 and a body of will be created:

Now you will see that in the response selector, you have two available responses. The first one is the default response created when you first set up the endpoint, and the second one is the one we just created.

An endpoint always serves a default response. To change the default response, click on the "Mark as default response" button next to the "+" and delete response buttons. The default response is served when no condition is specified or when no condition is met.

It's essential to note that rules apply per response, and each response has its own set of rules. This means that if we have two responses, each one can have its own rules. For example, we can have a response served by default and another served when a specific condition is met. In this case, if the condition is met, the response that fulfills the condition will be served instead of the default one.
To start serving responses conditionally, we simply need to create what we've termed "custom rules". You can find this under the "rules" tab on any endpoint. In this tab, you'll find a button to create a rule for serving a response conditionally.
Consider the following scenario: we have an endpoint with two responses created at the URL: /responses/:responseId.
{
"response": "this is my first response"
}{
"response": "this is my SECOND response"
}Our goal is for the API to return the second response when the :responseId parameter is "2", i.e., when the request is to /responses/2. In any other case, it should return the first response. To achieve this, we must select the response we want our rule to apply to (response 2) and then create a rule by clicking the "Create rule" button in the "rules" tab.
Upon clicking the button, a modal will appear asking for:
As you fill the modal in, it shows a live sentence — "This response is returned when…" — describing exactly what the rule will do. The Match toggle and the "Add condition" and "Add group" buttons let you combine several conditions in one rule; they are covered in AND/OR groups.
In our case, we'll specify that it should be taken from the URL parameter, that the property is "responseId", and that the value must be equal to 2.
Once we create it, any requests made when responseId is 2 will serve response 2, i.e.,
{
"response": "this is my SECOND response"
}and in any other case, response 1.
This allows us to have more realistic data and for our mock API to be more lifelike. For instance, we could specify that if a request doesn't include the Authorization header, it should return a 403, and other such behaviors to mimic a real API as closely as possible.
These are all the comparators a rule can use, grouped by family. They apply to every source except XML tag and XPath, which only accept equal and distinct.
| Comparator | What it does | Example |
|---|---|---|
contains | The extracted value includes the rule value as a substring | value gmail.com matches [email protected] |
notContains | The extracted value does not include the rule value | value gmail.com matches [email protected] |
startsWith | The extracted value begins with the rule value | value ES- matches ES-1042 |
endsWith | The extracted value ends with the rule value | value .pdf matches invoice.pdf |
regex | The rule value is a regular expression tested against the extracted value | value ^[A-Z]{2}-\d+$ matches ES-1042 |
Both sides are read as numbers; if either one is not numeric, the rule simply doesn't match. The rule value itself must be a number, or the rule is rejected when you save it.
| Comparator | What it does | Example |
|---|---|---|
greaterThan | The extracted value is strictly greater than the rule value | value 10 matches 10.5 |
greaterOrEqual | Greater than or equal to the rule value | value 10 matches 10 |
lessThan | Strictly less than the rule value | value 10 matches 9.99 |
lessOrEqual | Less than or equal to the rule value | value 10 matches 10 |
These four don't compare against anything, so they take no value — leave the value field empty.
| Comparator | What it does | Example |
|---|---|---|
exists | The property is present in the request, whatever its value | matches when the Authorization header is sent |
notExists | The property is missing | matches when the Authorization header is not sent |
isEmpty | The property is missing or empty — "", [] and {} all count as empty | matches a body where items is [] |
isNotEmpty | The property has a non-empty value | matches a body where items has at least one element |
| Comparator | What it does | Example |
|---|---|---|
equal | The extracted value is the rule value (types are not strict: the number 2 matches the string "2") | value active matches active |
distinct | Anything but the rule value | value active matches archived |
includes | The rule value is a comma-separated list, and the extracted value must equal one of its items | value ES, FR, PT matches FR |
A few validation details worth knowing, because the API rejects the rule with a 400 otherwise:
equal and distinct.exists, notExists, isEmpty and isNotEmpty take no value.regex requires a pattern that compiles.To return a conditional response based on the query params, the process is quite similar to what we've discussed with URL params. However, this time you'll need to select "Query string". For instance, if you wish to return the second response when the query param page is set to two, you'll select "Query string", input "page", set the condition to "equal", and the value to "2". Consequently, when a request is made with ?page=2, the second response will be returned.
Responses can also be conditionally returned based on the presence of an XML tag in the received body. Let's consider we have two XML responses:
//respnse 1
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
//response 2
<note>
<to>Zam</to>
<from>Angela</from>
<heading>Reminder</heading>
<body>Test</body>
</note>
If you want the mock API to return the second response when the body of the incoming request contains a specific XML tag, say "testtagname", you'll need to choose the "XML tag" option. This will change the input options since when adding an XML rule, you can only verify the existence of that tag. Select "has" and specify the XML tag name, in this case, "testtagname". If the body sent to the mock API contains a <testtagname> tag, the API will return the second response. An example request could be:
//body request
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<testtagname>test</testtagname>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
If you need something more sophisticated, you can use XPath to find what you need in your XML. For example, you can create a rule with the following XPath:
//person[role='admin']Then, send the following XML in the body. If the XPath finds any node in the body, it will return that response.
<root>
<people>
<person id="1">
<name>Laura</name>
<age>28</age>
<role>guest</role>
</person>
<person id="2">
<name>Mario</name>
<age>35</age>
<role>admin</role>
</person>
</people>
</root>
If you need more information about using XPath, check the official documentation.
Using headers in rules is straightforward. Simply go to the rules button, click to create a new rule, and in the modal, you will need to select something like the following:

If we look at the example in the image, it is specifying that this response will be served when the request includes an Authorization header with the value "Bearer testbearer". If this condition is not met, the default response will be served.
You can also use the body you send, for example, in a POST request to mock different responses. For instance, if you want to always serve a response when the body contains a dog object with a name property equal to "India," you can do the following:
Select the body and specify that dog.name should be equal to India, as shown in the following image:

Next, to test it, we will use Postman and make a POST request to the endpoint with a body that matches the rule. The expected response should be {"response": "2"}:

It also works with arrays; you just have to keep in mind that it starts at 0, and you can use it like this: users.1.name, which refers to users[1].name. For example, a rule where users.1.name should be equal to "zam" matches the following request, because the second user is called that:

Keep in mind that dot notation can only point at one exact position of the array. If what you need is "any item of the array", or a filter like "any item with a price above 10", use a JSONPath rule instead.
The JSON path source evaluates a JSONPath expression against the JSON body of the request, which makes it the most flexible way to inspect the body: it can address any item of an array or filter items by the values inside them, which plain dot notation can't do. When you select it, the property field becomes an Expression field (through the Public API, the expression travels in the property attribute — unlike XPath, where the expression goes in the value). The value field keeps its usual meaning: it's what the extracted result is compared against, and you can use any of the comparators:

The leading $. (the root of the body) is optional, so users[0].name and $.users[0].name are equivalent. Some example expressions:
$.items[0].sku — the sku of the first item$.items[*].sku — the sku of every item$.items[?(@.price>10)].sku — the sku of the items with a price above 10When the expression selects more than one value, the rule matches if any of them satisfies the comparator. For example, a rule with source JSON path, expression $.items[*].sku, comparator startsWith and value ES- matches the following body, because the second item's sku starts with "ES-":
{
"items": [
{ "sku": "FR-0001", "price": 5 },
{ "sku": "ES-1042", "price": 12 }
]
}If you need more information about the supported syntax, check the JSONPath Plus documentation.
A rule doesn't have to be a single condition. In the rule modal:
Through the Public API, a group is an object with an operator and a conditions array whose entries are plain rules or nested groups. For example, this group matches when the request carries the header x-country: ES, or when the sku of some item in the body starts with "ES-":
{
"operator": "or",
"conditions": [
{ "source": "header", "property": "x-country", "comparator": "equal", "value": "ES" },
{ "source": "jsonPath", "property": "$.items[*].sku", "comparator": "startsWith", "value": "ES-" }
]
}Groups can nest up to 3 levels deep, enough for conditions like "(A and B) or (C and D)". As always, when no rule matches, the default response is served.

Sometimes you need the API to return a random response from the ones you've already created. To do that, simply click the "Random response" button, and the API will randomly return one of the defined responses. Keep in mind that this button will only be available if you have more than one response created and the rules will be ignored.
Create a project