> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pazy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Request List API

> List payment requests (vendor advances) by review, active, or history view with cursor pagination

## Authentication

All requests require an API key in the request headers.

**Headers:**

```
Authorization: Api-Key YOUR_API_KEY
```

The permission required on your API key is **Payment Request** with the **Read** action enabled.

<Warning>
  In addition to the API key permission, the user the API key belongs to must have an **admin** or **bookkeeper** role in the organization. Any other role gets a `403 ACCESS_DENIED` — see [Error Responses](#error-responses).
</Warning>

## Request

### Query Parameters

| Parameter | Type    | Required | Description                                                                                |
| --------- | ------- | -------- | ------------------------------------------------------------------------------------------ |
| `type`    | string  | Yes      | Payment request type to list. Only `VENDOR_ADVANCE` is currently supported                 |
| `status`  | string  | Yes      | Which list view to return: `review`, `active`, or `history`. See [List Views](#list-views) |
| `limit`   | integer | No       | Rows per page. Min 1, Max 100, Default 15                                                  |
| `cursor`  | string  | No       | Pagination cursor. Pass the `nextCursor` from the previous page (1–20 characters)          |

<Warning>
  Unknown query parameters are rejected rather than ignored — sending anything other than the four parameters above returns a `400 VALIDATION_ERROR`.
</Warning>

### List Views

| `status`  | Contains                                                   |
| --------- | ---------------------------------------------------------- |
| `review`  | Requests that need review/approval action                  |
| `active`  | Requests in progress — approved and moving towards payment |
| `history` | Completed requests                                         |

Results are scoped **organization-wide** — every matching request in the organization is returned, not just those the API key's user created.

### Pagination

`cursor` is an opaque offset token. Request the first page without a cursor, then pass the returned `context.nextCursor` on each subsequent call until `context.hasMore` is `false` (at which point `nextCursor` is `null`).

<Info>
  Keep `limit` **stable across pages** of the same traversal. The cursor is interpreted relative to the page size, so changing `limit` mid-traversal can skip or repeat rows.
</Info>

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.pazy.io/v1.0/payment/requests?type=VENDOR_ADVANCE&status=active&limit=15" \
    -H "Authorization: Api-Key YOUR_API_KEY"
  ```

  ```javascript JavaScript (Fetch API) theme={null}
  const params = new URLSearchParams({
    type: 'VENDOR_ADVANCE',
    status: 'active',
    limit: '15'
  });

  const response = await fetch(
    `https://api.pazy.io/v1.0/payment/requests?${params}`,
    {
      method: 'GET',
      headers: {
        Authorization: 'Api-Key YOUR_API_KEY'
      }
    }
  );

  const result = await response.json();
  ```

  ```python Python (requests) theme={null}
  import requests

  url = "https://api.pazy.io/v1.0/payment/requests"
  headers = {
      "Authorization": "Api-Key YOUR_API_KEY"
  }
  params = {
      "type": "VENDOR_ADVANCE",
      "status": "active",
      "limit": 15
  }

  response = requests.get(url, headers=headers, params=params)
  result = response.json()
  ```
</CodeGroup>

### Paginating Through All Pages

```javascript JavaScript (Fetch API) theme={null}
const all = [];
let cursor = null;

do {
  const params = new URLSearchParams({
    type: 'VENDOR_ADVANCE',
    status: 'active',
    limit: '100'
  });
  if (cursor) params.set('cursor', cursor);

  const response = await fetch(
    `https://api.pazy.io/v1.0/payment/requests?${params}`,
    { headers: { Authorization: 'Api-Key YOUR_API_KEY' } }
  );
  const { data } = await response.json();

  all.push(...data.paymentRequests);
  cursor = data.context.hasMore ? data.context.nextCursor : null;
} while (cursor);
```

## Success Response

**HTTP Status:** `200 OK`

**Response Fields:**

| Field                                   | Type    | Description                                                                                           |
| --------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------- |
| `ok`                                    | boolean | Indicates whether the request was successful                                                          |
| `data.paymentRequests`                  | array   | Payment requests on this page                                                                         |
| `data.paymentRequests[].id`             | string  | Payment request identifier — pass to the [Payment Request Details](/apis/payment-request-details) API |
| `data.paymentRequests[].sequenceNo`     | string  | Human-readable running number assigned within the organization                                        |
| `data.paymentRequests[].amount`         | number  | Net payable amount of the request                                                                     |
| `data.paymentRequests[].currency`       | string  | ISO currency code e.g. `INR`                                                                          |
| `data.paymentRequests[].state`          | string  | Approval lifecycle state e.g. `PENDING`, `APPROVED`, `REJECTED`                                       |
| `data.paymentRequests[].paymentState`   | string  | Payment lifecycle state e.g. `AWAITING`, `PAID`                                                       |
| `data.paymentRequests[].approvalState`  | string  | Payer's approval state e.g. `PENDING`, `APPROVED`                                                     |
| `data.paymentRequests[].requestDate`    | string  | ISO 8601 timestamp of when the request was created                                                    |
| `data.paymentRequests[].createdBy`      | object  | User who created the request. `null` if the user could not be resolved                                |
| `data.paymentRequests[].createdBy.id`   | string  | Identifier of the creating user                                                                       |
| `data.paymentRequests[].createdBy.name` | string  | Name of the creating user                                                                             |
| `data.paymentRequests[].vendor`         | object  | Vendor the advance was raised for. `null` when unresolved                                             |
| `data.paymentRequests[].vendor.id`      | string  | Vendor identifier — usable with the [Vendor Details](/apis/vendor-details) API                        |
| `data.paymentRequests[].vendor.name`    | string  | Vendor display name                                                                                   |
| `data.context.totalCount`               | number  | Total matching requests across all pages                                                              |
| `data.context.count`                    | number  | Number of requests in this page                                                                       |
| `data.context.hasMore`                  | boolean | Whether more pages remain                                                                             |
| `data.context.nextCursor`               | string  | Cursor for the next page. `null` when `hasMore` is `false`                                            |

### Response Example

```json theme={null}
{
  "ok": true,
  "data": {
    "paymentRequests": [
      {
        "id": "<paymentRequestId>",
        "sequenceNo": "615",
        "amount": 106200,
        "currency": "INR",
        "state": "APPROVED",
        "paymentState": "AWAITING",
        "approvalState": "APPROVED",
        "requestDate": "2026-06-19T13:17:51.749Z",
        "createdBy": {
          "id": "<userId>",
          "name": "John Doe"
        },
        "vendor": {
          "id": "<vendorId>",
          "name": "MDP Coffee House"
        }
      },
      {
        "id": "<paymentRequestId>",
        "sequenceNo": "614",
        "amount": 25000,
        "currency": "INR",
        "state": "APPROVED",
        "paymentState": "AWAITING",
        "approvalState": "PENDING",
        "requestDate": "2026-06-18T09:04:12.115Z",
        "createdBy": {
          "id": "<userId>",
          "name": "Jane Smith"
        },
        "vendor": {
          "id": "<vendorId>",
          "name": "Acme Packaging"
        }
      }
    ],
    "context": {
      "totalCount": 42,
      "count": 2,
      "hasMore": true,
      "nextCursor": "2"
    }
  }
}
```

### Empty Result

A view with no matching requests returns `200` with an empty array, not an error:

```json theme={null}
{
  "ok": true,
  "data": {
    "paymentRequests": [],
    "context": {
      "totalCount": 0,
      "count": 0,
      "hasMore": false,
      "nextCursor": null
    }
  }
}
```

## Error Responses

### Validation Errors

**HTTP Status:** `400 Bad Request`

Missing a required query parameter:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: type: must have required property 'type'"
  }
}
```

Unsupported `type` or `status` value:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: /status: must be equal to one of the allowed values"
  }
}
```

`limit` outside the allowed range:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: /limit: must be <= 100"
  }
}
```

An unrecognised query parameter:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: vendorId: must NOT have additional properties"
  }
}
```

### Access Denied

**HTTP Status:** `403 Forbidden`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "ACCESS_DENIED",
    "message": "Access denied: only admins and bookkeepers can list payment requests"
  }
}
```

### Authentication Errors

**HTTP Status:** `401 Unauthorized`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "MISSING_CREDENTIALS",
    "message": "Missing Credentials"
  }
}
```

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API Key"
  }
}
```

### Permission Errors

**HTTP Status:** `403 Forbidden`

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "Permission check failed - PERMISSION_CHECK_FAILED"
  }
}
```

## Best Practices

* Send `limit=100` when syncing in bulk to minimise round trips, and keep it constant for every page of that traversal
* Drive pagination off `context.hasMore` rather than comparing `count` to `limit` — a short page is not proof that the traversal is finished
* This list returns summary rows only; call [Payment Request Details](/apis/payment-request-details) for tax breakdown, narration, tags, and the linked purchase order
* Poll the `review` view to find requests awaiting action, and `history` for reconciliation of completed ones
