> For the complete documentation index, see [llms.txt](https://docs.idrx.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.idrx.co/api/transaction-api/post-api-transaction-mint-request.md).

# POST /api/transaction/mint-request

{% hint style="info" %}
Check out [this page](https://docs.idrx.co/introduction/supported-chain-and-contract-address) to see the list of chains where IDRX is available and [this page](broken://pages/KhKvK6yEuxrJBWASD8c7) to see the list of supported other stablecoins.
{% endhint %}

{% hint style="info" %}

* The balance will be processed and credited to \`**`` destinationWalletAddress` ``** max 24 hours after your request is submitted.
* Minimum transaction:
  * Minting IDRX is Rp20,000 IDR
  * Minting other stablecoins are $2 USD
* Maximum transaction:&#x20;
  * Minting IDRX is 1,000,000,000 IDR.
  * Minting other stablecoins are 5,555 USD
* For transactions more than the maximum limit, please send your request to <support@idrx.co> to be processed.
* The transaction will be automatically canceled if you have not made a payment within 24 hours.
* IDRX is not responsible for deposit errors from incorrect Virtual Account numbers. Refunds for payments made to Virtual Account numbers under a different name will be processed within 14 business days.
  {% endhint %}

```
POST https://idrx.co/api/transaction/mint-request
```

### Quick start

```bash
curl -X POST 'https://idrx.co/api/transaction/mint-request' \
  -H 'idrx-api-key: <API_KEY>' \
  -H 'idrx-api-sig: <SIGNATURE>' \
  -H 'idrx-api-ts: <TIMESTAMP>' \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: my-app/1.0' \
  -d '{
    "toBeMinted": "20000",
    "destinationWalletAddress": "0x7D1398C397C64368B7079bD5b3EE904aaaf8A495",
    "networkChainId": "8453",
    "returnUrl": "https://your-app.example.com/callback",
    "requestType": "idrx"
  }'
```

Redirect the user to `data.paymentUrl` from the response. After payment, IDRX is delivered to the wallet — usually within minutes.

> For end-to-end integration including status tracking and reconciliation, see [Processing Mint IDRX Requests](/integration/processing-mint-idrx-requests.md#overview).

***

### Authentication

Every request needs four headers:

| Header         | Value                                     |
| -------------- | ----------------------------------------- |
| `idrx-api-key` | Your API key                              |
| `idrx-api-sig` | HMAC-SHA256 signature (see formula below) |
| `idrx-api-ts`  | Unix timestamp in milliseconds            |
| `User-Agent`   | Custom string like `my-app/1.0` (why)     |

#### Signature formula

```
HMAC-SHA256(secret, METHOD + ":" + PATH + ":" + SHA256(body) + ":" + timestamp)
```

For GET requests with no body, use `SHA256("")`.

Full guide: [Generating a Signature](/api/generating-a-signature.md)

API keys are issued via:

```http
POST /api/auth/generate-api-key
```

{% hint style="warning" %}
**Custom `User-Agent` required.** Defaults from `curl`, `Python-urllib`, or generic SDK strings are blocked at the edge with HTTP `403` (Cloudflare error 1010).
{% endhint %}

***

### Parameters

| Parameter                  | Type   | Required | Description                                                                  |
| -------------------------- | ------ | -------- | ---------------------------------------------------------------------------- |
| `toBeMinted`               | string | ✓        | Amount to mint. Min 20,000 IDR or 2 USD. Max 1,000,000,000 IDR or 5,555 USD. |
| `destinationWalletAddress` | string | ✓        | Recipient wallet on the target chain.                                        |
| `networkChainId`           | string | ✓        | Target chain ID. Supported chains →                                          |
| `returnUrl`                | string | ✓        | HTTPS URL the user returns to after checkout.                                |
| `requestType`              | string | —        | `"idrx"` (default) or `"usdt"`. Other tokens →                               |
| `expiryPeriod`             | number | —        | Payment window in minutes. Default `120`.                                    |
| `productDetails`           | string | —        | Custom note on payment page. Max 255 chars.                                  |
| `customerDetail`           | object | —        | `{ firstName, lastName, email }`. Each max 50 chars.                         |

***

### Hosted checkout

#### Request

```json
{
  "toBeMinted": "20000",
  "destinationWalletAddress": "0x7D1398C397C64368B7079bD5b3EE904aaaf8A495",
  "networkChainId": "8453",
  "returnUrl": "https://your-app.example.com/callback",
  "expiryPeriod": 60,
  "requestType": "idrx"
}
```

#### Response

```json
{
  "statusCode": 200,
  "message": "success",
  "data": {
    "id": "85",
    "merchantOrderId": "20230321091546",
    "merchantCode": "DS15079",
    "reference": "DS1507923DW1N5088J6LW6TO",
    "paymentUrl": "https://app.duitku.com/redirect_checkout?reference=DS1507923DW1N5088J6LW6TO",
    "amount": "19500.00",
    "statusCode": "00",
    "statusMessage": "SUCCESS"
  }
}
```

1. Redirect the user to `paymentUrl`.
2. User picks a payment method and pays.
3. User is redirected to your `returnUrl`.
4. You receive a callback on settlement.

{% hint style="info" %}
**Fee handling depends on the payment method the user picks.** For VA and e-wallet, the fee is added on top of `toBeMinted` (the user pays slightly more). For QRIS, the fee is deducted from the minted IDRX. See [Fee structure by payment method](/api/callback.md#fee-structure-by-payment-method) for the full matrix.
{% endhint %}

{% hint style="warning" %}
Don't rely on the `returnUrl` redirect to confirm payment. Users close browsers. Always confirm via [callback](/api/callback.md) or [Transaction History](/api/transaction-api/get-api-transaction-user-transaction-history.md).
{% endhint %}

***

### Confirming payment

A transaction has two status fields you must track together:

| Field            | Tracks                                  |
| ---------------- | --------------------------------------- |
| `paymentStatus`  | The fiat payment (VA / QRIS / checkout) |
| `userMintStatus` | The on-chain token delivery             |

#### Success state

```
paymentStatus: PAID
userMintStatus: MINTED
```

#### Terminal states

* `MINTED`
* `REFUND`
* `REJECTED`
* `paymentStatus: EXPIRED`

Confirm via [callback](/api/callback.md), or poll [Transaction History](/api/transaction-api/get-api-transaction-user-transaction-history.md) by `merchantOrderId` and stop on a terminal state.

> Full state machine, reconciliation pattern, and edge cases: [Processing Mint IDRX Requests](/integration/processing-mint-idrx-requests.md#step-2-track-the-status)

{% hint style="warning" %}
**Callbacks are sent once and not retried.** If your endpoint is down, you must reconcile by polling the Transaction History API. Always re-fetch the transaction before crediting users — treat the callback body as untrusted input.
{% endhint %}

***

### Errors

| Status | Cause                                | Fix                                                                        |
| ------ | ------------------------------------ | -------------------------------------------------------------------------- |
| `400`  | Invalid parameter                    | Check param types and limits                                               |
| `401`  | Bad signature or timestamp drift     | Recompute signature; sync server clock (NTP)                               |
| `403`  | Blocked `User-Agent`                 | Set custom `User-Agent` like `my-app/1.0`                                  |
| `422`  | Unsupported `channelId` for merchant | Contact <support@idrx.co> to enable                                        |
| `429`  | Rate limit                           | Back off and retry                                                         |
| `5xx`  | Server error                         | Retry with backoff. Don't create a new order — recover the payload instead |

***

### See also

* [Callback](/api/callback.md) — webhook payload structure, fee breakdown per payment method, and reconciliation tips.
* [Processing Mint IDRX Requests](/integration/processing-mint-idrx-requests.md) — end-to-end mint workflow with status state machine and edge cases.
* [Transaction History API](/api/transaction-api/get-api-transaction-user-transaction-history.md) — query transaction state by `merchantOrderId`.
* [Generating a Signature](/api/generating-a-signature.md) — HMAC-SHA256 signature reference with code examples.

***

The returned `amount` value will be different from the request in `toBeMinted` parameter. This is the amount after fees and will be the amount that the user are going to pay.

Use the payment page in `paymentUrl` to pay the amount required. Shortly after the payment is done, IDRX tokens will be minted and sent to the specified destination wallet address. In the case of "usdt" `requestType`, USDT tokens will be sent to the wallet address.

To check the status of the transaction, you can use the [Transaction History API](/api/transaction-api/get-api-transaction-user-transaction-history.md).
