MahsaAlert APImahsaalert.app ↗
Access MahsaAlert map data via API: danger zones, confirmed attacks, evacuation warnings, military sites, and citizen reports across Iran, filterable by location and category.
What is the MahsaAlert API?
The MahsaAlert API provides access to 4 endpoints covering geolocated map layer data from mahsaalert.app, including danger zones, military infrastructure, evacuation warnings, and citizen-submitted incident reports across Iran. Use get_layers to enumerate all available layer keys and categories, then query individual layers or multi-layer geographic snapshots with bounding box and category filters to retrieve structured feature data including coordinates, province, verification tags, and associated media.
No input parameters required.
curl -X GET 'https://api.parse.bot/scraper/2e3f1623-b586-4881-aa92-b57bb2544017/get_layers' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace mahsaalert-app-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: MahsaAlert Map Data API — bounded, re-runnable; every call capped."""
from parse_apis.mahsaalert_map_data_api import MahsaAlert, LayerKey, CategoryName, NotFound
client = MahsaAlert()
# Fetch features from a specific layer using the enum key.
nuclear_layer = client.layer(key=LayerKey.NUCLEARPROGRAMS)
for feature in nuclear_layer.features(bbox="51.0,35.5,51.8,35.9", limit=3):
print(feature.id, feature.status, feature.coordinates.lng, feature.coordinates.lat)
# Multi-layer search filtered by category — returns layers with their features.
for layer_result in client.layers.search(category=CategoryName.DANGER_ZONES, limit=2):
print(layer_result.layer_key, layer_result.feature_count)
# Drill-down: take one feature and refresh its full detail.
first = nuclear_layer.features(limit=1).first()
if first:
detail = first.refresh()
print(detail.id, detail.source_id, detail.created_at, detail.info)
# Direct feature lookup by ID with typed error handling.
try:
feat = client.features.get(id=487)
print(feat.id, feat.status, feat.coordinates.lng, feat.coordinates.lat)
except NotFound as exc:
print(f"Feature not found: {exc}")
print("exercised: layer.features / layers.search / feature.refresh / features.get")
Get all available map layers with metadata including layer keys, categories, property schemas, and update timestamps. Use the returned layer keys/IDs to query features via get_layer_features or get_map_data.
No input parameters required.
{
"type": "object",
"fields": {
"total": "integer count of layers",
"layers": "array of Layer objects with id, key, name_en, title, enabled, visible, layer_type, date_filter, category, feature_updated_at, and properties"
},
"sample": {
"data": {
"total": 34,
"layers": [
{
"id": 6,
"key": "nuclearPrograms",
"title": "برنامه هستهای",
"enabled": true,
"name_en": "Nuclear Program",
"visible": true,
"category": {
"id": 2,
"title": "مناطق پرخطر",
"title_en": "Danger Zones"
},
"layer_type": "fill",
"properties": [
{
"key": "name:fa",
"type": "string",
"label": "نام"
}
],
"date_filter": false,
"feature_updated_at": "2026-04-01T05:09:25.749Z"
}
]
},
"status": "success"
}
}About the MahsaAlert API
What the API Covers
The MahsaAlert API surfaces structured geographic feature data organized into named map layers. Each layer belongs to a category such as Danger Zones, Monitor, Suppression Sites, Medical sites, or Iran-Israel War, and carries metadata including layer_type, date_filter support, and feature_updated_at timestamps. The get_layers endpoint returns the full list of layers with their key, name_en, title, enabled, and visible fields — essential for knowing which layer_key values to pass downstream.
Querying Features by Layer or Area
get_layer_features accepts either a layer_key (e.g. nuclearPrograms, missilePrograms, antiAirBase, radarBase, newTargets) or a numeric layer_id, with optional bbox filtering in min_lon,min_lat,max_lon,max_lat format. It returns a paginated features array where each item includes coordinates, verification_tag, status, and an info object containing city, province, description, date, mission, geolocates, and sources. The response also surfaces total_in_layer and returned counts for pagination via limit and offset.
get_map_data queries multiple layers simultaneously within a bounding box, defaulting to the Tehran area when no bbox is supplied. You can narrow results using the category parameter or a comma-separated layer_keys string. The response groups features by layer, each with a feature_count, making it useful for area-level situational overviews without pre-knowing which layers contain data.
Feature Detail and Media
get_feature_detail accepts a feature_id from any previous query and returns the fullest record available: bilingual name fields (name:fa, name:en), province, status, mission, sources, and a media array for associated visual attachments. The source_id field links back to the originating layer record, and created_at / updated_at ISO timestamps indicate when the feature was first logged and last modified.
The MahsaAlert API is a managed, monitored endpoint for mahsaalert.app — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when mahsaalert.app changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official mahsaalert.app API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Map active danger zones and confirmed attack sites across Iranian provinces using
get_layer_featureswith thenewTargetslayer key - Build an area-level threat overview for a specific city by querying
get_map_datawith a tight bounding box and filtering by theDanger Zonescategory - List all nuclear and missile program sites by querying the
nuclearProgramsandmissileProgramslayer keys and extractingcoordinatesandprovincefields - Track evacuation warning features with
verification_tagandstatusfields to distinguish confirmed from unverified citizen reports - Retrieve bilingual (Persian/English) feature names and source citations via
get_feature_detailfor display in multilingual incident dashboards - Paginate through large layers using
limitandoffsetinget_layer_featuresto sync full datasets for offline analysis - Monitor military infrastructure layers such as
antiAirBase,radarBase, andareowayBasefiltered to a geographic region of interest
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does MahsaAlert have an official developer API?+
What does `get_layer_features` return versus `get_map_data`?+
get_layer_features targets a single layer by layer_key or layer_id and returns a paginated feature list with full info objects, verification_tag, and total_in_layer count. get_map_data queries all layers (or a filtered subset) simultaneously within a bounding box and groups results by layer, returning feature_count per layer — better suited for area-wide snapshots when you don't know which layers have data in a region.How current is the feature data, and how do I detect stale layers?+
get_layers includes a feature_updated_at timestamp indicating when features in that layer were last updated. Individual features also carry created_at and updated_at ISO timestamps. Freshness depends on when mahsaalert.app updates its source data; there is no guaranteed update interval.Does the API expose historical incident timelines or trend data over time?+
created_at and updated_at timestamps and an info.date field, but does not provide a time-series or changelog endpoint for tracking how features evolve. You can fork the API on Parse and revise it to add a historical query endpoint if the source data supports it.Can I filter features by province or city directly?+
bbox bounding box parameter in get_layer_features and get_map_data. Province and city values are available in the info object of each returned feature and can be filtered client-side. You can fork the API on Parse and revise it to add server-side province or city parameters.