Live · Rwanda Agriculture Board

Inzira API

Open API layer on Rwanda's national soil information system. Query soil carbon, pH, erosion risk, and fertilizer recommendations for every district in Rwanda — programmatically.

BASE URL https://rwasis.rab.gov.rw/api/v1
6 Crops in system
30 Districts covered
3 Live endpoints
$0 Current access cost

Live Endpoints

GET /crops Returns all crops in the system

Parameters

NameTypeDescription
No parameters required. Returns the full crop list.

Response

json · /crops
[
  { "id": 1, "name": "Bean" },
  { "id": 2, "name": "Cassava" },
  { "id": 3, "name": "Rice" },
  { "id": 4, "name": "Potato" },
  { "id": 5, "name": "Maize" },
  { "id": 6, "name": "Wheat" }
]

Authentication

EndpointHeader
GET /cropsAuthorization: Bearer <key>
GET /boundariesX-Api-Key: <key>
GET /boundaries/location/X-Api-Key: <key>

Using Bearer on /boundaries returns 401. This is a wrong-header issue, not an access restriction.

Note: Only Potato and Rice have fertilizer recommendations populated in the current RwaSIS release. Maize, Bean, Cassava, and Wheat recommendations are in development.

GET /boundaries Returns soil data by location
Use province + district, not ?name= The ?name= parameter exists but returns empty soil arrays. Always use province + district for real data. Auth: X-Api-Key header (not Bearer — Bearer returns 401 on this endpoint).

Parameters

NameTypeDescription
province string Province name. Example: Kigali, Northern, Southern
district string District name within the province. Example: Gasabo, Musanze
sectoroptional string Sector within the district for more granular data. Example: Rusororo

Response fields

carbon calcium potassium phValues erosionRisk erosionRecommendation potatoFertilizerRecommendation riceFertilizerRecommendation boundary

Example: GET /boundaries?province=Kigali&district=Gasabo

json · province=Kigali&district=Gasabo
{
  "name": "Gasabo",
  "carbon": 2.34,
  "calcium": 1820,
  "potassium": 187,
  "phValues": 5.8,
  "erosionRisk": "Moderate",
  "erosionRecommendation": "Maintain ground cover year-round. Use contour ridges on slopes >15%. Incorporate crop residues into soil.",
  "potatoFertilizerRecommendation": "Apply 60 kg/ha DAP at planting. Top-dress with 50 kg/ha urea at 6 weeks. Supplement with 100 kg/ha potassium sulphate.",
  "riceFertilizerRecommendation": "Apply 45 kg/ha DAP pre-transplant. Top-dress with 60 kg/ha urea in two equal splits at 3 and 6 weeks.",
  "boundary": {
    "type": "Polygon",
    "coordinates": [[ 30.12, -1.86 ], [ 30.18, -1.86 ], ...]
  }
}
GET /boundaries/location/ Search by UPI or location name
Fully working externally — confirmed April 2026 This endpoint works with X-Api-Key authentication (not Bearer). The API uses two different auth schemes: /crops uses Authorization: Bearer <key>, while /boundaries and /boundaries/location/ use X-Api-Key: <key>. UPI parcel queries return real fertilizer data. Note: /boundaries?name= currently returns empty soil arrays — data not yet populated by RAB.

Two modes

Modekeyword valueReturns
Name lookup Gasabo Matching districts, sectors, cells, villages grouped by type. Use this to resolve a name to province/district/sector before calling /boundaries.
UPI lookup 1/03/08/04/2148 Resolved location hierarchy (province, district, sector, cell, village) + fertilizer recommendations.

Two-step usage pattern

Step 1
Call /boundaries/location/?keyword=<name> to resolve the name to province/district/sector
Step 2
Call /boundaries?province=X&district=Y&sector=Z with the resolved values to get soil data

Parameters

NameTypeDescription
keyword string Location name (leaf name only — e.g. Rusororo, not "Kigali Gasabo Rusororo")
or UPI parcel ID (e.g. 1/03/08/04/2148)

UPI format decoded

1 / 03 / 08 / 04 / 2148
Province    District    Sector     Cell      Parcel ID

Example: GET /boundaries/location/?keyword=1/03/08/04/2148

Province

Kigali City

District

Kicukiro

Sector

Masaka

Cell

Gitaraga

Village

Kabeza

Data returned

Soil · Erosion · Fertilizer

Name search — confirmed behavior

✓ Works
keyword=Rusororo

Leaf name only — village, cell, sector, or district. Returns full location hierarchy + soil data.

✗ Fails
keyword=Kigali+Gasabo+Rusororo

Full path returns "No Location Found". The portal dropdown label is display-only — never send it as-is.

The portal autocomplete shows the full path Kigali Gasabo Rusororo to help disambiguate between multiple locations with the same name (there are 8 villages named Rusororo across Rwanda). When a result is clicked, the portal extracts only the last term and sends keyword=Rusororo to the API. The response then tells you which province, district, sector, cell, and village it matched.

District Explorer

Select any of Rwanda's 30 districts to query soil data directly from the RwaSIS API. Results reflect live data from Rwanda Agriculture Board.

Code Examples

Query the RwaSIS API directly from your application. The API key is publicly readable from the RwaSIS frontend bundle.

python
import requests

BASE_URL = "https://rwasis.rab.gov.rw/api/v1"
API_KEY  = "95856365-2a3f-4faa-82bc-ab9aca985b4a"

headers = {"Authorization": f"Bearer {API_KEY}"}

# --- Fetch all crops ---
crops = requests.get(f"{BASE_URL}/crops", headers=headers)
print(crops.json())
# [{'id': 1, 'name': 'Bean'}, {'id': 2, 'name': 'Cassava'}, ...]

# --- Fetch soil data by district name ---
def get_soil(district: str) -> dict:
    resp = requests.get(
        f"{BASE_URL}/boundaries",
        params={"name": district},
        headers=headers,
    )
    resp.raise_for_status()
    return resp.json()

data = get_soil("Gasabo")
print(f"pH: {data['phValues']}, Carbon: {data['carbon']}%")
print(data['potatoFertilizerRecommendation'])

# --- Fetch soil data by UPI (land parcel ID) ---
# NOTE: /boundaries/location/ uses X-Api-Key auth (confirmed working externally)
# from the RwaSIS portal login flow — not the public Bearer key.
# This is a known limitation; RAB has been asked to unify auth.
# The endpoint URL for reference:
#
# GET /boundaries/location/?keyword=1/03/08/04/2148
#
# UPI format: Province/District/Sector/Cell/ParcelID
# Returns: Province, District, Sector, Cell, Village
#          + soil data, erosion risk, fertilizer recommendations
javascript
const BASE_URL = "https://rwasis.rab.gov.rw/api/v1";
const API_KEY  = "95856365-2a3f-4faa-82bc-ab9aca985b4a";

const headers = { "Authorization": `Bearer ${API_KEY}` };

// --- Fetch all crops ---
const cropsRes = await fetch(`${BASE_URL}/crops`, { headers });
const crops = await cropsRes.json();
console.log(crops);
// [{ id: 1, name: 'Bean' }, { id: 2, name: 'Cassava' }, ...]

// --- Fetch soil data by district name ---
async function getSoil(district) {
  const url = new URL(`${BASE_URL}/boundaries`);
  url.searchParams.set("name", district);
  const res = await fetch(url, { headers });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

const data = await getSoil("Gasabo");
console.log(`pH: ${data.phValues}, Carbon: ${data.carbon}%`);
console.log(data.potatoFertilizerRecommendation);

// --- Fetch by UPI (land parcel ID) ---
// NOTE: /boundaries/location/ uses X-Api-Key auth (confirmed working externally)
// from the RwaSIS portal — not the public Bearer key.
// Endpoint for reference (pending auth fix from RAB):
//
// GET /boundaries/location/?keyword=1/03/08/04/2148
//
// UPI format: Province/District/Sector/Cell/ParcelID
// Returns parcel location + full soil + fertilizer data
shell
# All crops
curl https://rwasis.rab.gov.rw/api/v1/crops \
  -H "Authorization: Bearer 95856365-2a3f-4faa-82bc-ab9aca985b4a"

# Soil data — Gasabo district (works with Bearer key)
curl "https://rwasis.rab.gov.rw/api/v1/boundaries?name=Gasabo" \
  -H "Authorization: Bearer 95856365-2a3f-4faa-82bc-ab9aca985b4a"

# Soil data — Musanze district
curl "https://rwasis.rab.gov.rw/api/v1/boundaries?name=Musanze" \
  -H "Authorization: Bearer 95856365-2a3f-4faa-82bc-ab9aca985b4a"

# UPI search — parcel-level query (X-Api-Key auth — fully working externally)
# Format: Province/District/Sector/Cell/ParcelID
# Format: Province/District/Sector/Cell/ParcelID
curl "https://rwasis.rab.gov.rw/api/v1/boundaries/location/?keyword=1/03/08/04/2148" \
  -H "X-Api-Key: 95856365-2a3f-4faa-82bc-ab9aca985b4a"

# Name-based location search (leaf name only — e.g. Rusororo not "Kigali Gasabo Rusororo")
curl "https://rwasis.rab.gov.rw/api/v1/boundaries/location/?keyword=Rusororo" \
  -H "X-Api-Key: 95856365-2a3f-4faa-82bc-ab9aca985b4a"

MCP Server

rwasis-mcp is a Model Context Protocol server that wraps this API, letting AI assistants like Claude query Rwanda soil data through natural conversation — in English, French, or Kinyarwanda.

rwasis-mcp v0.1.7 · PyPI
shell
pip install rwasis-mcp
📦
PyPI
pypi.org/project/rwasis-mcp
GitHub
s-bakire/rwasis-mcp

Three tools

ToolDescription
get_crops Returns all 6 crops in the RwaSIS system
get_soil_by_location(name, province?, district?, sector?) Two-step lookup: first resolves the name via /boundaries/location/, then fetches soil data via /boundaries. Returns disambiguation options when a name matches multiple locations. Optional province, district, and sector parameters narrow down ambiguous results on the second call.
get_soil_by_upi(upi) Resolves a UPI parcel ID to location hierarchy + fertilizer recommendations

Handling Ambiguous Location Names

Many location names in Rwanda exist at multiple administrative levels or in multiple provinces. "Gasabo" is both a district in Kigali and a cell in Rutunga sector, and a village in 8 different locations. "Rusororo" is a sector in Gasabo, a cell in Ngororero, and a village in 7 different places.

When get_soil_by_location is called with an ambiguous name, it returns all matches grouped by type instead of guessing. Claude presents the options and asks the user to pick.

Example conversation

USER
Get soil data for Gasabo
CLAUDE
Gasabo matches multiple locations. Which one did you mean?

District — Kigali / Gasabo
Cell — Kigali / Gasabo / Rutunga / Gasabo
Village — East / Bugesera / Rilima / Kimaranzara / Gasabo
Village — East / Kayonza / Ndego / Kiyovu / Gasabo
...and 4 more villages
USER
The district in Kigali
CLAUDE
Calls get_soil_by_location(name="Gasabo", province="Kigali", district="Gasabo") → returns real soil data for Gasabo district.

Disambiguation parameters

ParameterTypeExamplePurpose
provinceoptional string "Kigali" Narrow results by province
districtoptional string "Gasabo" Resolve directly to district level
sectoroptional string "Rusororo" Resolve to sector level
all three province + district + sector Pinpoint a specific sector directly

Resolution priority: Sector beats district beats auto-resolve. Passing district="Gasabo" and sector="Rusororo" together resolves to sector level, not district level. Village and cell picks automatically resolve to their parent sector, since the API supports data at sector level and above.

Claude Desktop setup

json · claude_desktop_config.json
{
  "mcpServers": {
    "rwasis": {
      "command": "rwasis-mcp"
    }
  }
}