# Graana Property Search API Documentation

Scrappa's `GET /api/graana/search` returns Graana property for sale and rent in Pakistan as structured JSON, with city, area, price, bedroom, bathroom, size and type filters, sort and paging.

## What you get

One request returns one page of listings, Graana's own match count in `total`, the real `page` and `per_page`, `total_pages` and `has_more`. Each listing has `id`, `url`, `title`, `purpose` (`sale` or `rent`), `type`, `subtype`, `price` (`amount` as a number and `currency` PKR), `area` (`size` and `unit`), `bedrooms`, `bathrooms`, `location`, `agency_id`, `poster_name`, `status`, `verified`, `total_images`, `cover_image`, `images` and `created_at`. A missing bedroom or bathroom count is `null`, never 0, for example on plots. Address, coordinates and description are in the listing endpoint.

## A city is required

Graana searches one city at a time. Pass `purpose` and `city_id`; take the id from `/api/graana/cities`. Take area ids from `/api/graana/autocomplete`, whose `search_params` can be passed as they are.

## Filters are honoured

Graana applies every filter itself, so `total` and the paging describe the real result set. Bedroom and bathroom counts are exact, not "or more". Prices are in PKR; for rent the price is monthly. A size filter needs `area_unit` and matches only listings measured in that unit, because Graana keeps the unit the poster chose (`marla`, `kanal`, `sqft` or `sqyd`). Unknown parameters and unknown values return `422` instead of being ignored. `applied_filters` echoes what was sent.

## Sorting

`sort` is `newest` (default), `price_asc` or `price_desc`. No other value is accepted.

## Pagination

`page` is 1-based and `per_page` is 1 to 50 (default 25). A page past the last one returns an empty `listings` list with the requested `page`. Graana sends no count there, so `total` and `total_pages` are `null`. An empty first page means no match and has `total` 0. It never returns another page's listings.

## Agency listings

Set `agency_id` (with `city_id` and `purpose`) to list the properties of one agency. Take the id from a listing or from the agency endpoints.

## Not available

Graana publishes no fees, no agent profile, no reviews and no price history. These fields are not in the response.

- **Documentation:** [https://scrappa.co/docs/graana-api/graana_search](https://scrappa.co/docs/graana-api/graana_search)
- **API group:** Graana API
- **Endpoint:** `GET https://scrappa.co/api/graana/search`

## Authentication

Send your Scrappa API key in the `X-API-KEY` request header. Paid endpoints also support accountless x402 payments when called without an API key.

## Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `purpose` | string | Yes | sale or rent. |
| `city_id` | integer | Yes | City id from the cities endpoint, for example 2 for Lahore. Graana searches one city at a time. |
| `area_id` | string | No | Area ids from the autocomplete endpoint. Comma-separated, for example 830,829. |
| `type` | string | No | residential, plot or commercial. |
| `subtype` | string | No | house, flat, upper_portion, lower_portion, pent_house, room, basement, guest_house, residential_plot, commercial_plot, agricultural_land, farmhouse_plot, plot_file, office, shop, warehouse, factory, building, plaza, hall or land. Comma-separated. |
| `bedrooms` | string | No | Exact bedroom counts, for example 3 or 2,3. Comma-separated. |
| `bathrooms` | string | No | Exact bathroom counts, for example 2. Comma-separated. |
| `price_min` | number | No | Minimum price in PKR. For rent this is the monthly rent. |
| `price_max` | number | No | Maximum price in PKR. For rent this is the monthly rent. |
| `area_min` | number | No | Minimum size in the unit of area_unit. |
| `area_max` | number | No | Maximum size in the unit of area_unit. |
| `area_unit` | string | No | marla, kanal, sqft or sqyd. Required with area_min or area_max. Only listings measured in this unit match. |
| `agency_id` | string | No | Only listings of these agencies. Comma-separated agency ids. |
| `verified` | boolean | No | true for listings that carry a verified property record. |
| `sort` | string | No | newest (default), price_asc or price_desc. |
| `page` | integer | No | Result page, 1-based. |
| `per_page` | integer | No | Listings per page, 1 to 50. Default 25. |

## Example request

```bash
#!/bin/bash

curl -X GET \
    -H "x-api-key: YOUR_API_KEY_HERE" \
    "https://scrappa.co/api/graana/search?purpose=sale&city_id=2&bedrooms=3&sort=price_asc&per_page=25"
```

## Example response

```json
{
    "success": true,
    "page": 1,
    "per_page": 25,
    "total": 1473,
    "total_pages": 59,
    "has_more": true,
    "applied_filters": {
        "purpose": "sale",
        "city_id": 2,
        "sort": "price_asc",
        "bedrooms": [
            3
        ]
    },
    "listings": [
        {
            "id": 1559223,
            "url": "https://www.graana.com/property/1559223",
            "title": "5 Marla House for Sale",
            "purpose": "sale",
            "type": "residential",
            "subtype": "house",
            "price": {
                "amount": 29500000,
                "currency": "PKR"
            },
            "area": {
                "size": 5,
                "unit": "marla"
            },
            "bedrooms": 5,
            "bathrooms": 5,
            "location": {
                "area_id": 9580,
                "area": "Wapda Town",
                "city_id": 2,
                "city": "Lahore"
            },
            "agency_id": 2344,
            "poster_name": "M Qaisar",
            "status": "published",
            "verified": false,
            "total_images": 3,
            "cover_image": "https://images.graana.com/images/original/cc517755497c782be011d5fefbb0d8d0",
            "images": [
                {
                    "url": "https://images.graana.com/images/original/8fe6eb3dd4661ca841ecce8dadd750f4",
                    "type": "image"
                },
                {
                    "url": "https://images.graana.com/images/original/cc517755497c782be011d5fefbb0d8d0",
                    "type": "cover"
                }
            ],
            "created_at": "2026-10-24T09:32:45.278Z"
        }
    ],
    "meta": {
        "endpoint_family": "search",
        "billable": true,
        "attempts": 1
    }
}
```

## Errors

| Status | Error | Description |
| --- | --- | --- |
| 422 | Filters Rejected | Graana refused the filter combination (`upstream_rejected`). Non-billable. |
| 422 | Validation Error | A query parameter is missing, unknown or unusable. Unknown parameters and unknown values are rejected, never ignored. Non-billable. |
| 503 | Upstream Unavailable | Graana could not be reached after retries, answered with an error or changed its format (`upstream_unavailable`, `upstream_blocked`, `parser_drift`). Retryable and never billed. Clients are never rate limited. |

## More Scrappa resources

- [API documentation](https://scrappa.co/docs)
- [Full LLM-readable API reference](https://scrappa.co/llms-full.txt)
- [OpenAPI specification](https://scrappa.co/docs/api.json)
- [Pricing](https://scrappa.co/pricing)
