Skip to content

Organised Smallholders (OSH)

OSH Portal

Overview

Property Value
Endpoint GET https://api.mspots.org.my/api/osh/all-smallholder
Portal URL https://emspo.org.my/public/osh
Total Records ~47,500
Update Frequency Daily
Authentication None (public)

Parameters

Parameter Type Required Default Description
state integer No - Filter by state ID (ignored - returns all)
page integer No 1 Page number (ignored - returns all)
pageSize integer No 10 Records per page (ignored - returns all)

Note: Like other public endpoints, this returns ALL records (~47.5k) in a single response regardless of parameters.

Response Structure

Important: OSH uses .data.data instead of .data.results like other endpoints.

{
  "data": {
    "page_size": 10,
    "data": [
      {
        "entity_smallholder_id": 474748,
        "entity_code": "ORS15721",
        "entity_name": "FELDA LOK HENG BARAT",
        "mpob_no": null,
        "planted_area": "3.9520",
        "certified_area": "3.9520",
        "gps_coordinate_lat": "1.70941",
        "gps_coordinate_long": "104.08802",
        "name": "A.LATIF BIN BENU",
        "stateId": 1,
        "state": "Johor",
        "daerahId": 4,
        "daerah": "KOTA TINGGI",
        "lot_no": "5722",
        "cert_status": "EXPIRED",
        "cert_no": "MYMS12195673",
        "created_at": "2025-10-29T03:15:10.612Z",
        "updated_at": "2024-07-24T01:17:06.101Z",
        "track_id": "MTS0000014"
      }
    ]
  }
}

Response Fields

Field Type Description
entity_smallholder_id integer Unique smallholder plot ID
entity_code string Entity code (e.g., "ORS15721")
entity_name string Organisation/scheme name (FELDA, FELCRA, etc)
mpob_no string/null MPOB registration number (often null for OSH)
planted_area string Total planted area in hectares
certified_area string MSPO certified area in hectares
gps_coordinate_lat string GPS latitude
gps_coordinate_long string GPS longitude
name string Smallholder name
stateId integer Malaysian state ID
state string Malaysian state name
daerahId integer/null District ID
daerah string/null District name
lot_no string Land lot number
cert_status string Certification status (ACTIVE/EXPIRED/DELAYED)
cert_no string MSPO certificate number
created_at string Record creation timestamp (ISO 8601)
updated_at string Last update timestamp (ISO 8601)
track_id string Tracking ID

Key Differences from Other Smallholder Endpoints

Aspect SPOC (Independent) Group Manager OSH (Organised)
Records ~306k ~2.3k ~47.5k
Identifier spoc_code gm_code entity_code
Management SPOC clusters Private companies FELDA/FELCRA/etc
Response Key .data.results .data.results .data.data
Has mpob_no Yes Yes Often null

Organisation Types (entity_name)

Common organisations managing OSH smallholders:

Organisation Description
FELDA Federal Land Development Authority
FELCRA Federal Land Consolidation and Rehabilitation Authority
RISDA Rubber Industry Smallholders Development Authority
KESEDAR South Kelantan Development Authority
KEJORA Johor Regional Development Authority
KETENGAH Terengganu Tengah Development Authority
KEDA Kedah Regional Development Authority

GCS Storage

gs://calee_data/raw/mspo/api/smallholders/osh/all-smallholder/
└── YYYYMMDD/
    └── all-smallholder.parquet    # ~2-3MB compressed (zstd)

Example Code

Python

import requests
import polars as pl

def fetch_osh_smallholders():
    """Fetch all Organised Smallholders."""
    url = "https://api.mspots.org.my/api/osh/all-smallholder"

    response = requests.get(url, params={"page": 1, "pageSize": 10}, verify=False)
    response.raise_for_status()

    # Note: OSH uses .data.data instead of .data.results
    results = response.json()["data"]["data"]
    print(f"Fetched {len(results):,} records")

    return results

# Fetch and analyze
records = fetch_osh_smallholders()
df = pl.DataFrame(records, infer_schema_length=10000)

# Summary by organisation
print(df.group_by("entity_name").agg([
    pl.count().alias("smallholders"),
    pl.col("certified_area").cast(pl.Float64).sum().alias("total_ha")
]).sort("total_ha", descending=True).head(10))

DuckDB Query

-- Query Organised Smallholders by scheme
SELECT
    entity_name as organisation,
    state,
    COUNT(*) as smallholders,
    SUM(CAST(certified_area AS DOUBLE)) as total_ha
FROM read_parquet('gs://calee_data/raw/mspo/api/smallholders/osh/all-smallholder/*/*.parquet')
GROUP BY entity_name, state
ORDER BY total_ha DESC;

Data Quality Notes

  1. MPOB number often null: Unlike SPOC/GM, OSH records frequently have null mpob_no
  2. Entity code format: Prefix "ORS" followed by numbers (e.g., "ORS15721")
  3. Response key difference: Uses .data.data instead of .data.results
  4. Scheme-managed: All entries are managed by government-linked organisations