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

# Search ProposalSchedules

> Search and list ProposalSchedule records with filtering, sorting, and pagination.

A ProposalSchedule is a future price change quoted on a proposal: a new unit price and the date it takes effect. Schedules are copied into the quoted contract at the moment the proposal is created, and become the customer contract's own scheduled price changes when the proposal is accepted, so a schedule added to a proposal that already has its quoted contract must be added to that contract instead.

## Authentication

<Note>
  This endpoint requires OAuth2 authentication. Include a valid bearer token in the `Authorization` header.
  The authenticated user must be a full unrestricted administrator or have the **`ProposalSchedule-List`** role.
</Note>

## Query Parameters

### Pagination & Sorting

<ParamField query="page" type="integer" default="1">
  The page number to retrieve.
</ParamField>

<ParamField query="size" type="integer" default="25">
  The number of records per page.
</ParamField>

<ParamField query="orderBy" type="string">
  The property name to sort results by (e.g. `Name`, `CreatedOn`).
</ParamField>

<ParamField query="dir" type="integer">
  Sort direction. `0` for ascending, `1` for descending.
</ParamField>

### Filters

<ParamField query="ProposalSchedule_Proposal" type="integer">
  Filter by iD of the proposal this price change belongs to; required, and the proposal's issuing location owns this record..
</ParamField>

<ParamField query="ProposalSchedule_Proposal_Quantity" type="integer">
  Filter by display value for Proposal.Quantity..
</ParamField>

<ParamField query="ProposalSchedule_Proposal_Tariff_Name" type="string">
  Filter by display value for Proposal.Tariff.Name..
</ParamField>

<ParamField query="ProposalSchedule_Proposal_Coworker_Id" type="integer">
  Filter by display value for Proposal.Coworker.Id..
</ParamField>

<ParamField query="ProposalSchedule_Proposal_Coworker_FullName" type="string">
  Filter by display value for Proposal.Coworker.FullName..
</ParamField>

<ParamField query="ProposalSchedule_Proposal_Coworker_BillingName" type="string">
  Filter by display value for Proposal.Coworker.BillingName..
</ParamField>

<ParamField query="ProposalSchedule_Notes" type="string">
  Filter by free-text note explaining the price change; it is copied onto the quoted contract's schedule..
</ParamField>

<ParamField query="ProposalSchedule_Price" type="number">
  Filter by new per-unit price that takes effect on ApplyOn, in the issuing location's currency..
</ParamField>

<ParamField query="ProposalSchedule_ApplyOn" type="string">
  Filter by date the new price takes effect; required, and each price change on the same proposal needs its own date..
</ParamField>

<ParamField query="ProposalSchedule_Applied" type="boolean">
  Filter by read-only flag recording whether this price change has already been applied; the billing run sets it and it is not changed through proposal administration..
</ParamField>

### Range Filters

<ParamField query="from_ProposalSchedule_ProposalQuantity" type="integer">
  Filter by display value for Proposal.Quantity. greater than or equal to this value.
</ParamField>

<ParamField query="to_ProposalSchedule_ProposalQuantity" type="integer">
  Filter by display value for Proposal.Quantity. less than or equal to this value.
</ParamField>

<ParamField query="from_ProposalSchedule_ProposalCoworkerId" type="integer">
  Filter by display value for Proposal.Coworker.Id. greater than or equal to this value.
</ParamField>

<ParamField query="to_ProposalSchedule_ProposalCoworkerId" type="integer">
  Filter by display value for Proposal.Coworker.Id. less than or equal to this value.
</ParamField>

<ParamField query="from_ProposalSchedule_Price" type="number">
  Filter by new per-unit price that takes effect on ApplyOn, in the issuing location's currency. greater than or equal to this value.
</ParamField>

<ParamField query="to_ProposalSchedule_Price" type="number">
  Filter by new per-unit price that takes effect on ApplyOn, in the issuing location's currency. less than or equal to this value.
</ParamField>

<ParamField query="from_ProposalSchedule_ApplyOn" type="string">
  Filter by date the new price takes effect; required, and each price change on the same proposal needs its own date. greater than or equal to this value. Format: `YYYY-MM-DDTHH:mm`.
</ParamField>

<ParamField query="to_ProposalSchedule_ApplyOn" type="string">
  Filter by date the new price takes effect; required, and each price change on the same proposal needs its own date. less than or equal to this value. Format: `YYYY-MM-DDTHH:mm`.
</ParamField>

<ParamField query="from_ProposalSchedule_CreatedOn" type="string">
  Filter records created on or after this date. Format: `YYYY-MM-DDTHH:mm`.
</ParamField>

<ParamField query="to_ProposalSchedule_CreatedOn" type="string">
  Filter records created on or before this date. Format: `YYYY-MM-DDTHH:mm`.
</ParamField>

<ParamField query="from_ProposalSchedule_UpdatedOn" type="string">
  Filter records updated on or after this date. Format: `YYYY-MM-DDTHH:mm`.
</ParamField>

<ParamField query="to_ProposalSchedule_UpdatedOn" type="string">
  Filter records updated on or before this date. Format: `YYYY-MM-DDTHH:mm`.
</ParamField>

## Code Examples

### Simple listing

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    "https://spaces.nexudus.com/api/billing/proposalschedules?page=1&size=15&orderBy=CreatedOn&dir=0" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://spaces.nexudus.com/api/billing/proposalschedules?' + new URLSearchParams({
      page: 1,
      size: 15,
      orderBy: 'CreatedOn',
      dir: 1 // Ascending
    }),
    {
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN'
      }
    }
  );

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

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

  response = requests.get(
      'https://spaces.nexudus.com/api/billing/proposalschedules',
      params={
          'page': 1,
          'size': 15,
          'orderBy': 'CreatedOn',
          'dir': 0 // Ascending
      },
      headers={
          'Authorization': 'Bearer YOUR_TOKEN'
      }
  )

  data = response.json()
  ```
</CodeGroup>

### Filtering by CreatedOn

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    "https://spaces.nexudus.com/api/billing/proposalschedules?ProposalSchedule_CreatedOn=example-value&orderBy=CreatedOn&dir=0" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://spaces.nexudus.com/api/billing/proposalschedules?' + new URLSearchParams({
      ProposalSchedule_CreatedOn: 'example-value',
      orderBy: 'CreatedOn',
      dir: 1
    }),
    {
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN'
      }
    }
  );

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

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

  response = requests.get(
      'https://spaces.nexudus.com/api/billing/proposalschedules',
      params={
          'ProposalSchedule_CreatedOn': 'example-value',
          'orderBy': 'CreatedOn',
          'dir': 0 // Ascending
      },
      headers={
          'Authorization': 'Bearer YOUR_TOKEN'
      }
  )

  data = response.json()
  ```
</CodeGroup>

### Range filters

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    "https://spaces.nexudus.com/api/billing/proposalschedules?from_ProposalSchedule_UpdatedOn=2025-01-01T00:00&to_ProposalSchedule_UpdatedOn=2025-12-31T23:59&orderBy=UpdatedOn&dir=0" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://spaces.nexudus.com/api/billing/proposalschedules?' + new URLSearchParams({
      from_ProposalSchedule_UpdatedOn: '2025-01-01T00:00',
      to_ProposalSchedule_UpdatedOn: '2025-12-31T23:59',
      orderBy: 'UpdatedOn',
      dir: 1 // Descending
     }),
    {
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN'
      }
    }
  );

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

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

  response = requests.get(
      'https://spaces.nexudus.com/api/billing/proposalschedules',
      params={
          'from_ProposalSchedule_UpdatedOn': '2025-01-01T00:00',
          'to_ProposalSchedule_UpdatedOn': '2025-12-31T23:59',
          'orderBy': 'UpdatedOn',
          'dir': 1 // Descending
      },
      headers={
          'Authorization': 'Bearer YOUR_TOKEN'
      }
  )

  data = response.json()
  ```
</CodeGroup>

## Response

### 200

<ResponseField name="Records" type="ProposalSchedule[]">
  The list of ProposalSchedule records matching the query. See the [Get one ProposalSchedule](/rest-api/billing/get-proposalschedules-by-id) endpoint for the full list of properties returned for each record.
</ResponseField>

<Warning>
  **Partial records** — The listing endpoint returns a summary representation of each ProposalSchedule. The following fields are **not populated** in the `Records[]` response: `Notes`.

  To get all fields, fetch the full record using the [Get one ProposalSchedule](/rest-api/billing/get-proposalschedules-by-id) endpoint.

  **Important for updates:** When updating a record via `PUT`, always retrieve the full record with a `GET` request first, apply your changes to that complete data, and then send the updated record. Do not use data from a listing response as the base for a `PUT` request, as missing fields may be unintentionally cleared.
</Warning>

<ResponseField name="CurrentPage" type="integer">
  Current page number.
</ResponseField>

<ResponseField name="CurrentPageSize" type="integer">
  Number of records per page.
</ResponseField>

<ResponseField name="CurrentOrderField" type="string">
  The field used for sorting.
</ResponseField>

<ResponseField name="CurrentSortDirection" type="integer">
  The sort direction (`0` = ascending, `1` = descending).
</ResponseField>

<ResponseField name="FirstItem" type="integer">
  Index of the first item on the current page.
</ResponseField>

<ResponseField name="LastItem" type="integer">
  Index of the last item on the current page.
</ResponseField>

<ResponseField name="TotalItems" type="integer">
  Total number of matching records across all pages.
</ResponseField>

<ResponseField name="TotalPages" type="integer">
  Total number of pages.
</ResponseField>

<ResponseField name="HasNextPage" type="boolean">
  Whether there is a next page of results.
</ResponseField>

<ResponseField name="HasPreviousPage" type="boolean">
  Whether there is a previous page of results.
</ResponseField>

```json Example Response theme={null}
{
  "Records": [
    {
      "ProposalId": 0,
      "ProposalQuantity": null,
      "ProposalTariffName": null,
      "ProposalCoworkerId": null,
      "ProposalCoworkerFullName": null,
      "ProposalCoworkerBillingName": null,
      "Price": null,
      "ApplyOn": "2025-01-15T10:30:00Z",
      "Applied": false,
      "Id": 87654321,
      "UpdatedOn": "2025-01-15T10:30:00Z",
      "CreatedOn": "2025-01-10T08:00:00Z",
      "UniqueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "UpdatedBy": "admin@example.com",
      "IsNew": false,
      "SystemId": null,
      "ToStringText": "ProposalSchedule Example",
      "LocalizationDetails": null,
      "CustomFields": null
    }
  ],
  "CurrentPageSize": 15,
  "CurrentPage": 1,
  "CurrentOrderField": "CreatedOn",
  "CurrentSortDirection": 1,
  "FirstItem": 1,
  "HasNextPage": false,
  "HasPreviousPage": false,
  "LastItem": 1,
  "PageNumber": 1,
  "PageSize": 15,
  "TotalItems": 1,
  "TotalPages": 1
}
```
