POST/ipos/orders
Apply IPO Beta
API to submit an IPO application. Each application contains one to three bids and is backed by a UPI mandate that blocks the required amount in the applicant's bank account. Here's how the process works in detail:
Step 1: Discovering open IPOs
Call Get IPOs to list the IPOs currently in the market. Only those with status set to open accept applications — upcoming ones have not started bidding, and closed or listed ones are past it.
Step 2: Reading the IPO's bidding rules
Pass that id to Get IPO Details. Every IPO sets its own bidding rules, and an application that violates any of them is rejected, so read these fields before building the payload:
- lot_size and minimum_quantity: Bid quantities must be a multiple of lot size and at least minimum quantity.
- minimum_price, maximum_price and cut_off_price: The bid price must fall inside the price band or match the cut-off price exactly. Retail applicants commonly bid at cut off price, which means accepting whatever price the IPO is finally allotted at.
- investors[].category: The categories this IPO accepts. Applying under a category the IPO does not offer fails validation.
Step 3: Submitting the application
Call apply IPO API with id, the applicant's UPI ID, the investor category, and one to three bids that satisfy the rules from the previous step. Multiple bids let the applicant spread the application across different price points within the same IPO.
A successful response returns an order_id. This confirms the application reached the exchange; it does not mean the money has been blocked yet.
Step 4: Approving the mandate and tracking the application
Submission raises a UPI mandate request in the applicant's bank. Until the applicant approves it in their UPI app, the application remains unfunded and carries payment_status: pending.
- Checking status: Pass the
order_idto Get IPO Order Details for a single application, or use Get IPO Orders to list all applications for the user. - Withdrawing: Pass the
order_idto Cancel IPO Order to withdraw the application while the IPO is still open.
Request Body
| Name | Required | Type | Description |
|---|---|---|---|
| id | Required | string | IPO identifier. Obtain from the id field in Get IPOs or Get IPO Details. |
| upi | Required | string | UPI ID against which the mandate is raised and the application amount is blocked. |
| category | Required | string | Investor category to apply under. Possible values: IND (individual), HNI. Must be a category the IPO accepts — see investors[].category in Get IPO Details. |
| bids | Required | array | Bids submitted with the application. One to three bids are allowed. |
| bids[].quantity | Required | integer | Number of shares bid for. Must be a multiple of lot_size and at least minimum_quantity. |
| bids[].price | Required | number | Bid price per share (in INR). Must fall within the minimum_price–maximum_price band, or equal cut_off_price. |
Bid validation
Both bid fields are validated against the IPO's own parameters, so read them from Get IPO Details before building the payload.
| Constraint | Rule |
|---|---|
| Quantity | A multiple of lot_size, and greater than or equal to minimum_quantity. |
| Price | Within the minimum_price–maximum_price band, or exactly cut_off_price. |
| Bid count | One to three bids per application. |
For an IPO with lot size 20, minimum quantity 20, a price band of ₹366–₹385, and a cut off price of ₹385:
| Bid | Valid | Reason |
|---|---|---|
| quantity: 20, price: 385 | Yes | One lot at the cut-off price. |
| quantity: 40, price: 370 | Yes | Two lots at a price inside the band. |
| quantity: 30, price: 380 | No | 30 is not a multiple of lot_size 20. |
| quantity: 20, price: 350 | No | 350 is below minimum_price. |
A successful response means the application reached the exchange, not that it is funded. The applicant must approve the mandate request in their UPI app before timeline.mandate_end_date from Get IPO Details. Until then the application stays at payment_status: pending. Track it with Get IPO Orders.
Request
curl --location 'https://api.upstox.com/v2/ipos/orders' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {your_access_token}' \
--data '{
"id": "mandb-engineering-limited-ipo",
"upi": "91xxxxxxxx@ybl",
"category": "IND",
"bids": [
{
"quantity": 20,
"price": 385
}
]
}'
For additional samples in various languages, please refer to the Sample code section on this page.
Responses
- 200
- 4XX
Response Body
{
"status": "success",
"data": {
"order_id": "UPCHK500000020"
}
}
| Name | Type | Description |
|---|---|---|
| status | string | Outcome of the request. Possible values: success, error, partial_success. |
| data.order_id | string | Application ID created for this IPO application. Pass it as the order_id path parameter to Get IPO Order Details and Cancel IPO Order. |
Error codes
| Error code | Description |
|---|---|
| UDAPI1226 | id is required - Provide the IPO identifier in the id field. Obtain it from Get IPOs or Get IPO Details. |
| UDAPI1227 | upi is required - Provide the UPI ID against which the mandate is raised. |
| UDAPI1228 | category is required - Provide the investor category to apply under. |
| UDAPI1229 | Invalid category. Allowed values: IND, HNI - The supplied category is not recognized. |
| UDAPI1231 | At least one bid is required - The bids array must contain at least one bid. |
| UDAPI1232 | Bid quantity is required - Each bid must specify a quantity. |
| UDAPI1233 | Bid price is required - Each bid must specify a price. |
| UDAPI1235 | A maximum of three bids is allowed - The bids array contains more than three bids. |
| UDAPI1236 | Invalid UPI id - The supplied upi is not a valid UPI ID. |
Sample Code
- Python
- Node.js
- Java
- PHP
import requests
url = 'https://api.upstox.com/v2/ipos/orders'
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer {your_access_token}'
}
payload = {
'id': 'mandb-engineering-limited-ipo',
'upi': '91xxxxxxxx@ybl',
'category': 'IND',
'bids': [
{'quantity': 20, 'price': 385}
]
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const axios = require('axios');
const payload = {
id: 'mandb-engineering-limited-ipo',
upi: '91xxxxxxxx@ybl',
category: 'IND',
bids: [
{ quantity: 20, price: 385 }
]
};
axios.post('https://api.upstox.com/v2/ipos/orders', payload, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer {your_access_token}'
}
}).then(response => console.log(response.data))
.catch(error => console.error('Error:', error));
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ApplyForIpo {
public static void main(String[] args) throws Exception {
String payload = "{"
+ "\"id\": \"mandb-engineering-limited-ipo\","
+ "\"upi\": \"91xxxxxxxx@ybl\","
+ "\"category\": \"IND\","
+ "\"bids\": [{\"quantity\": 20, \"price\": 385}]"
+ "}";
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://api.upstox.com/v2/ipos/orders"))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer {your_access_token}")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$url = 'https://api.upstox.com/v2/ipos/orders';
$headers = [
'Accept: application/json',
'Content-Type: application/json',
'Authorization: Bearer {your_access_token}'
];
$payload = [
'id' => 'mandb-engineering-limited-ipo',
'upi' => '91xxxxxxxx@ybl',
'category' => 'IND',
'bids' => [
['quantity' => 20, 'price' => 385]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_errno($ch) ? print('Error: ' . curl_error($ch)) : print($response);
curl_close($ch);
?>