> ## Documentation Index
> Fetch the complete documentation index at: https://razorpay-881012b3.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Bill Request | BBPS API | Razorpay

> Initiate an asynchronous request to retrieve a customer's outstanding bill from a BBPS biller using Razorpay's Bill Payments API. Poll Fetch Bill Request for results.

<div style={{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"0.35rem 0.9rem",border:"1px solid rgba(128,128,128,0.28)",borderRadius:"0.5rem",padding:"0.45rem 0.75rem",margin:"0 0 1.25rem",fontSize:"0.875rem"}}>
  <span style={{fontWeight:600}}>Available in</span>
  <span>🇮🇳 India</span>
</div>

Use this endpoint to either retrieve the outstanding bill amount for a customer from a biller or validate the customer's account details when the biller does not support bill retrieval. This is an asynchronous API. The response immediately returns a bill request in `processing` status. Poll the [Fetch Bill Request](/docs/api/bills/bill-payments/fetch-bill-request) API with the returned `id` until the status reaches `success` or `failed`.

<Info>
  **When to use this API**

  * When the biller's `bill_request_config.bill_request_required` is `mandatory` - call this API to retrieve the bill before payment.
  * When `bill_request_required` is `optional` - call this API to validate the customer's account or skip and use Direct Pay.
  * When `bill_request_required` is `not_supported` - skip this step and call [Create a Bill Payment](/docs/api/bills/bill-payments/create-bill-payment) directly.
</Info>

<Info>
  **Polling URL**

  Poll for the final state using `GET /v1/bill_payments/bill_requests/{id}` with the `id` from the response.
</Info>

<RequestExample>
  ```bash Curl theme={null}
  curl -u [YOUR_KEY_ID]:[YOUR_KEY_SECRET] \
  -X POST https://api.razorpay.com/v1/bill_payments/bill_requests \
  -H "Content-Type: application/json" \
  -d '{
    "biller_id": "biller_001",
    "gateway_biller_id": "TPOW00000MUM01",
    "customer": {
      "id": "rzp_cust_123",
      "name": "Gaurav Kumar",
      "mobile": "919000090000",
      "email": "gaurav.kumar@example.com"
    },
    "device": {
      "initiating_channel": "mobile",
      "mobile": "9999999999",
      "geocode": "12.9667,77.5667",
      "ip": "198.1.1.1",
      "mac": "00-0D-60-07-2A-F0",
      "os": "android",
      "imei": "490154203237518",
      "app": "amazon_pay"
    },
    "biller_data": {
      "account_holder": {
        "account_number": "XXXXXXX",
        "KEY": "VALUE",
        "KEY2": "VALUE2"
      }
    }
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json Success (state=processing) theme={null}
  {
    "id": "billreq_ERNEungCtXpZqM",
    "entity": "bill_payment.bill_request",
    "status": "processing",
    "customer": {
      "id": "rzp_cust_123",
      "name": "Gaurav Kumar",
      "mobile": "919000090000",
      "email": "gaurav.kumar@example.com"
    },
    "biller_id": "biller_001",
    "gateway_biller_id": "TPOW00000MUM01",
    "gateway": "bbps",
    "created_at": 1609459200
  }
  ```

  ```json Failure (state=failed) theme={null}
  {
    "error": {
      "code": "BAD_REQUEST_ERROR",
      "description": "The biller id provided does not correspond to a valid or active biller. Verify the biller_id and retry with a valid biller.",
      "source": "business",
      "step": "bill_request",
      "reason": "biller_not_found"
    }
  }
  ```
</ResponseExample>

## Request Parameters

<ParamField body="biller_id" type="string">
  Razorpay's internal biller id sent in biller info. One of `biller_id` or `gateway_biller_id` is mandatory.
</ParamField>

<ParamField body="gateway_biller_id" type="string">
  NPCI biller id (for example, `TPOW00000MUM01`). One of `biller_id` or `gateway_biller_id` is mandatory.
</ParamField>

<ParamField body="customer" type="object">
  Customer information passed as dynamic key-value pairs. Free-form metadata for your own tracking and reconciliation. Razorpay echoes these back on responses and webhooks without validation.
</ParamField>

<ParamField body="customer.id" type="string">
  Dynamic key-value pair holding your customer reference. Not validated by Razorpay.
</ParamField>

<ParamField body="customer.name" type="string">
  Dynamic key-value pair holding the customer name. Not validated by Razorpay.
</ParamField>

<ParamField body="customer.mobile" type="string" required>
  Customer mobile number provided at payment create on PA.
</ParamField>

<ParamField body="customer.email" type="string">
  Dynamic key-value pair holding the customer email. Not validated by Razorpay.
</ParamField>

<ParamField body="device" type="object" required>
  Info about the bill payment initiating device.
</ParamField>

<ParamField body="device.initiating_channel" type="enum" required>
  Channel from which the bill request is initiated. Values:

  * `internet` - Web
  * `mobile` - Mobile App
  * `pos` - Point of Sale
  * `mpos` - Mobile Point of Sale
</ParamField>

<ParamField body="device.app" type="string">
  Application name (for example, `amazon_pay`). Required for `mobile`, `mpos` initiating channels.
</ParamField>

<ParamField body="device.mobile" type="string">
  NPCI channel requirements - End agent's mobile number for offline channels. Required for `pos`, `mpos` initiating channels.
</ParamField>

<ParamField body="device.geocode" type="string">
  NPCI channel requirements - Latitude, Longitude (for example, `12.9667,77.5667`). Required for `internet`, `mobile`, `pos`, `mpos` channels.
</ParamField>

<ParamField body="device.ip" type="string">
  NPCI channel requirements - IP address (IPv4 or IPv6). Required for `internet`, `mobile` initiating channels.
</ParamField>

<ParamField body="device.mac" type="string">
  MAC address. Required for `internet` channels.
</ParamField>

<ParamField body="device.os" type="string">
  Operating system. Required for `mobile`, `mpos` channels. For example, `android`, `iOS`.
</ParamField>

<ParamField body="device.imei" type="string">
  Device IMEI number. Required for the `mobile` initiating channel.
</ParamField>

<ParamField body="biller_data" type="object" required>
  Bill account holder details. Required for every bill request irrespective of the pay flow.
</ParamField>

<ParamField body="biller_data.account_holder" type="object" required>
  Dynamic key-value pairs that identify the customer's account at the biller. Razorpay does not control the keys nor the values. Pass them exactly as defined in the biller's `account_holder_config` returned by the [Fetch Billers](/docs/api/bills/bill-payments/fetch-billers) API.
</ParamField>

## Response Parameters

<ResponseField name="id" type="string">
  Razorpay's bill request id created. Store for reference and reconciliation. For example, `billreq_ERNEungCtXpZqM`.
</ResponseField>

<ResponseField name="entity" type="string">
  Entity type. Always `bill_payment.bill_request`.
</ResponseField>

<ResponseField name="status" type="string">
  Request status. Possible values: `processing`, `success`, `failed`. To take next action if the status is not terminal (`success` or `failed`), continue polling.
</ResponseField>

<ResponseField name="customer" type="object">
  Customer reference details echoed from the request as dynamic key-value pairs. Returned only when sent in the request. Free-form metadata that you can use for your own tracking and reconciliation.
</ResponseField>

<ResponseField name="customer.id" type="string">
  Dynamic key-value pair holding your customer reference. Echoed back exactly as sent in the request. Not validated by Razorpay.
</ResponseField>

<ResponseField name="customer.name" type="string">
  Dynamic key-value pair holding the customer name. Echoed back exactly as sent in the request. Not validated by Razorpay.
</ResponseField>

<ResponseField name="customer.mobile" type="string" required>
  Customer mobile number provided at payment create on PA.
</ResponseField>

<ResponseField name="customer.email" type="string">
  Dynamic key-value pair holding the customer email. Echoed back exactly as sent in the request. Not validated by Razorpay.
</ResponseField>

<ResponseField name="biller_id" type="string">
  Razorpay's internal biller id, same as sent in request. Use for reference and reconciliation.
</ResponseField>

<ResponseField name="gateway_biller_id" type="string">
  NPCI biller id sent in request. Use for reference and reconciliation.
</ResponseField>

<ResponseField name="gateway" type="string">
  Bill payment gateway used. Default value is `bbps`.
</ResponseField>

<ResponseField name="created_at" type="integer">
  Request created timestamp at Razorpay (Unix seconds). Audit trail.
</ResponseField>

## Errors

<AccordionGroup>
  <Accordion title="The `biller_id` is missing or invalid.">
    **Code:** `400`

    The biller id provided does not correspond to a valid or active biller.

    **Solution:** Verify the `biller_id` and retry with a valid biller from the Fetch Billers API.
  </Accordion>

  <Accordion title="The `gateway_biller_id` is missing.">
    **Code:** `400`

    `biller_id` is required.

    **Solution:** Pass either a valid `biller_id` or `gateway_biller_id` in the request.
  </Accordion>

  <Accordion title="The `biller_data.account_holder` values are invalid.">
    **Code:** `400`

    Invalid customer parameter format for `{param_name}`.

    **Solution:** Pass values matching the biller's `account_holder_config.params` validation rules (`data_type`, `min_length`, `max_length`, `regex`).
  </Accordion>

  <Accordion title="Device information is incomplete.">
    **Code:** `400`

    Device information is incomplete. Missing required field for the initiating channel.

    **Solution:** Pass all device fields required for the chosen `initiating_channel`.
  </Accordion>

  <Accordion title="No bill found for the provided customer parameters.">
    **Code:** `502`

    No bill found at the biller for the customer details provided.

    **Solution:** Confirm the customer details with the user and retry.
  </Accordion>

  <Accordion title="Unable to fetch bill from NPCI.">
    **Code:** `502`

    NPCI did not respond within the timeout window.

    **Solution:** Retry the request after a short interval.
  </Accordion>

  <Accordion title="Invalid or missing customer account holder data.">
    **Code:** `502`

    The biller rejected the account holder data as invalid or incomplete.

    **Solution:** Verify `biller_data.account_holder` keys match the biller's `account_holder_config`.
  </Accordion>

  <Accordion title="Biller system temporarily unavailable.">
    **Code:** `502`

    The biller is temporarily unavailable to retrieve the bill.

    **Solution:** Retry the request after a short interval.
  </Accordion>

  <Accordion title="Bill retrieval is not valid for this biller.">
    **Code:** `400`

    The biller does not support bill retrieval.

    **Solution:** Use Direct Pay via the Create a Bill Payment API. Check the biller's `bill_request_config.bill_request_required` before calling this API.
  </Accordion>

  <Accordion
    title="The API `<key/secret>
` provided is invalid."
  >
    **Code:** `401`

    The API credentials passed in the request differ from the ones generated on the Dashboard.

    **Solution:** Ensure your API key and secret are correct and active.
  </Accordion>
</AccordionGroup>
