# View Functions — Move REST API on Movement

## Overview

View functions let you call read-only Move functions on-chain without submitting a transaction or paying gas. They are the primary way to query computed state from Move modules: token balances, pool prices, governance parameters, NFT metadata, and any other data exposed through `#[view]` functions. The response contains the return values of the function, serialized as JSON.

This is one of the most frequently used endpoints for dApp frontends and backend services that need to read on-chain state.

## Endpoint

```
POST /v1/view
```

**Base URL:** `https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1`

## Request Parameters

- `ledger_version` (`string, optional`): Query parameter: Specific ledger version to execute against. Defaults to the latest version. Useful for querying historical state.
- `function` (`string, required`): Body Schema: Fully qualified function identifier: `{address}::{module}::{function_name}`
- `type_arguments` (`array of strings, required`): Body Schema: Generic type parameters. Pass `[]` if the function has no type parameters.
- `arguments` (`array, required`): Body Schema: Function arguments as JSON-encoded strings. Pass `[]` if the function takes no arguments.

## Request Example

```json
{
  "function": "0x1::coin::balance",
  "type_arguments": ["0x1::aptos_coin::AptosCoin"],
  "arguments": ["0xYOUR_ADDRESS"]
}
```

## Response Fields

- `result` (`OBJECT, required`): ### Success Response (200) Returns an array of return values, JSON-encoded. The number of elements matches the number of return values in the Move function signature. ```json ["1000000"] ``` For functions that return multiple values: ```json ["1000000", "500000", true] ``` For functions that return structs: ```json [{ "coin": { "value": "1000000" }, "frozen": false }] ``` ### Error Responses | Status | Description | Common Cause | |---|---|---| | `400` | Bad request | Invalid function name, wrong number of arguments, type mismatch | | `404` | Module or function not found | Module does not exist at the specified address, or function is not a view function | | `500` | Internal server error / VM error | Function execution failed (e.g., abort in the Move code) | ```json { "message": "Function not found: 0x1::coin::nonexistent", "error_code": "function_not_found", "vm_error_code": null } ```

## Successful Response

```json
["1000000"]
```

## Code Examples

### Query Token Balance

cURL
Python
TypeScript

```bash
# Get MOVE token balance for an account
curl -s -X POST "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1/view" \
  -H "Content-Type: application/json" \
  -d '{
    "function": "0x1::coin::balance",
    "type_arguments": ["0x1::aptos_coin::AptosCoin"],
    "arguments": ["0xYOUR_ADDRESS"]
  }'
# Response: ["1000000"] (in smallest unit, 8 decimals)
```

```python
from aptos_sdk.client import RestClient

client = RestClient("https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1")

# Query MOVE token balance
result = client.view_function(
    "0x1::coin::balance",
    ["0x1::aptos_coin::AptosCoin"],
    ["0xYOUR_ADDRESS"],
)
balance = int(result[0])
print(f"Balance: {balance / 1e8:.8f} MOVE")
```

```typescript
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

const config = new AptosConfig({
  network: Network.CUSTOM,
  fullnode: "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1",
});
const aptos = new Aptos(config);

// Query MOVE token balance
const [balance] = await aptos.view<[string]>({
  payload: {
    function: "0x1::coin::balance",
    typeArguments: ["0x1::aptos_coin::AptosCoin"],
    functionArguments: ["0xYOUR_ADDRESS"],
  },
});

console.log(`Balance: ${Number(balance) / 1e8} MOVE`);
```

### Get Chain ID

cURL
Python
TypeScript

```bash
# Get the chain ID (no arguments needed)
curl -s -X POST "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1/view" \
  -H "Content-Type: application/json" \
  -d '{
    "function": "0x1::chain_id::get",
    "type_arguments": [],
    "arguments": []
  }'
# Response: [126]
```

```python
from aptos_sdk.client import RestClient

client = RestClient("https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1")

result = client.view_function("0x1::chain_id::get", [], [])
chain_id = int(result[0])
print(f"Chain ID: {chain_id}")
```

```typescript
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

const config = new AptosConfig({
  network: Network.CUSTOM,
  fullnode: "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1",
});
const aptos = new Aptos(config);

const [chainId] = await aptos.view<[string]>({
  payload: {
    function: "0x1::chain_id::get",
    typeArguments: [],
    functionArguments: [],
  },
});

console.log(`Chain ID: ${chainId}`);
```

### Query DEX Pool Price

cURL
Python
TypeScript

```bash
# Example: query a DEX pool's reserves (function signature varies by DEX)
curl -s -X POST "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1/view" \
  -H "Content-Type: application/json" \
  -d '{
    "function": "0xDEX_ADDRESS::pool::get_reserves",
    "type_arguments": [
      "0x1::aptos_coin::AptosCoin",
      "0xUSDC_ADDRESS::coin::USDC"
    ],
    "arguments": []
  }'
# Response: ["50000000000", "125000000000"] (reserve_a, reserve_b)
```

```python
from aptos_sdk.client import RestClient

client = RestClient("https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1")

# Query pool reserves (adjust function/address for your DEX)
result = client.view_function(
    "0xDEX_ADDRESS::pool::get_reserves",
    [
        "0x1::aptos_coin::AptosCoin",
        "0xUSDC_ADDRESS::coin::USDC",
    ],
    [],
)

reserve_a = int(result[0])
reserve_b = int(result[1])
price = reserve_b / reserve_a  # Simplified price calculation
print(f"Reserves: {reserve_a} / {reserve_b}")
print(f"Price: {price:.4f}")
```

```typescript
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

const config = new AptosConfig({
  network: Network.CUSTOM,
  fullnode: "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1",
});
const aptos = new Aptos(config);

// Query pool reserves
const [reserveA, reserveB] = await aptos.view<[string, string]>({
  payload: {
    function: "0xDEX_ADDRESS::pool::get_reserves",
    typeArguments: [
      "0x1::aptos_coin::AptosCoin",
      "0xUSDC_ADDRESS::coin::USDC",
    ],
    functionArguments: [],
  },
});

const price = Number(reserveB) / Number(reserveA);
console.log(`Reserves: ${reserveA} / ${reserveB}`);
console.log(`Price: ${price.toFixed(4)}`);
```

### Query Historical State

cURL
TypeScript

```bash
# Query balance at a specific ledger version (historical state)
curl -s -X POST "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1/view?ledger_version=100000000" \
  -H "Content-Type: application/json" \
  -d '{
    "function": "0x1::coin::balance",
    "type_arguments": ["0x1::aptos_coin::AptosCoin"],
    "arguments": ["0xYOUR_ADDRESS"]
  }'
```

```typescript
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

const config = new AptosConfig({
  network: Network.CUSTOM,
  fullnode: "https://api-movement-mainnet.n.dwellir.com/YOUR_API_KEY/v1",
});
const aptos = new Aptos(config);

// Query balance at a specific historical ledger version
const [historicalBalance] = await aptos.view<[string]>({
  payload: {
    function: "0x1::coin::balance",
    typeArguments: ["0x1::aptos_coin::AptosCoin"],
    functionArguments: ["0xYOUR_ADDRESS"],
  },
  options: {
    ledgerVersion: "100000000",
  },
});

console.log(`Historical balance: ${Number(historicalBalance) / 1e8} MOVE`);
```

## Common Use Cases

### DApp Frontend State Queries

View functions are the backbone of dApp frontends. Use them to display token balances, NFT ownership, pool prices, staking positions, and governance states without requiring the user to submit transactions.

### Price Oracles and Aggregators

Query multiple DEX pools to compute aggregated prices and find optimal swap routes. View functions are free and fast, making them ideal for real-time price feeds.

### Smart Contract Testing

Call view functions during development to verify your module's read-only functions return expected values. This is faster than submitting a full transaction for every state query during testing.

## Movement-Specific Notes

- The function identifier must be fully qualified: `{address}::{module}::{function_name}`. For framework functions, the address is `0x1`.
- Only functions marked with `#[view]` in the Move source can be called through this endpoint. Attempting to call a non-view function returns a 404 error.
- View function execution is free (no gas cost) but is still subject to computational limits. Extremely complex view functions may time out.
- All argument values must be passed as strings, even numeric types. The node handles deserialization.

## Related Endpoints

- [`GET /v1/accounts/{address}/modules`](https://www.dwellir.com/docs/movement/account_modules) -- List modules to discover available view functions.
- [`GET /v1/accounts/{address}/resources`](https://www.dwellir.com/docs/movement/account_resources) -- Read raw resource data (alternative to view functions for simple reads).
- [`POST /v1/transactions/simulate`](https://www.dwellir.com/docs/movement/transaction_simulate) -- Simulate a transaction to preview state changes (for write operations).
- [`POST /v1/tables/{handle}/item`](https://www.dwellir.com/docs/movement/tables) -- Query table data directly.
