Base URL
All endpoints below are served from this base URL. Append the locale parameter (en or ar) where supported.
https://econmetrics.dev.shibli.me/em-api
Authentication
Public browse endpoints answer without credentials:
/v1/series/v1/series/facets/v1/series/featured/v1/series/latest?series_ids={id}/v1/series/{id}/v1/series/{id}/children/v1/series/{id}/related/v1/series/{id}/regions/v1/series/{id}/partners/v1/series/{id}/forecast/v1/series/{id}/observations?preview=true/v1/series/compare?series_ids={ids}&preview=true/v1/series/rankings/v1/datasets/v1/datasets/{slug}/v1/datasets/{slug}/series/v1/datasets/{slug}/facets/v1/datasets/{slug}/tree/v1/datasets/{slug}/state/v1/indicators/v1/indicators/{slug}/v1/catalog/filters/v1/calendar/v1/calendar.ics/v1/coverage/v1/source-agencies/v1/source-agencies/{agency_id}/logo
Gated surfaces need an API key or a user session token — full observation history beyond the preview window, .csv and .xlsx exports, API keys, saved series, webhooks, organizations, billing, account routes and /admin:
X-API-Key: em_…— API keys for programmatic access, created in the dashboard (Pro plan) -- required for full observation history, CSV and XLSX.Authorization: Bearer …— Session tokens from POST /auth/login or /auth/register.
Quick start
Both calls below run as written, with no key: the sample uses SA.CPI.CAT.00.YOY, a real published series. Use q= to search series by localized name or ID, and preview=true for the public observation window; full history, CSV and XLSX need a Pro key.
import requests
API = "https://econmetrics.dev.shibli.me/em-api"
# The two calls below are public -- no API key required.
# SA.CPI.CAT.00.YOY is a real published series (GASTAT: CPI, year-on-year % change).
# List published series (name or id search via q=)
series = requests.get(
f"{API}/v1/series",
params={"q": "CPI", "published_only": "true"},
).json()
# Fetch observations for one series
# preview=true returns the public window on a published series.
# Full history, CSV and XLSX need a Pro API key.
obs = requests.get(
f"{API}/v1/series/SA.CPI.CAT.00.YOY/observations",
params={"preview": "true"},
).json()Interactive OpenAPI spec
Try every endpoint live, with request/response schemas, from the interactive OpenAPI docs:
Core endpoints
The most commonly used endpoints:
| Method | Path | Access | Description |
|---|---|---|---|
| GET | /v1/series | Public | List & search published series (name, ID, topic, region, agency, …) |
| GET | /v1/series/{id} | Public | Series metadata by ID |
| GET | /v1/series/{id}/observations | Public preview | Time-series observations as JSON |
| GET | /v1/series/{id}/observations.csv | API key | Observations export as CSV |
| GET | /v1/series/{id}/observations.xlsx | API key | Observations export as Excel (.xlsx) |
| GET | /v1/series/featured | Public | Curated featured series for the homepage |
| GET | /v1/series/compare | Public preview | Align up to 20 series on a shared period axis |
| GET | /v1/series/join | API key | Derive a per-capita ratio or a cross-series index from two series |
| GET | /v1/series/rankings | Public | Rank published series by latest value, period change or year-over-year change |
| GET | /v1/catalog/filters | Public | Available catalog facets (topics, agencies, regions, measure types, …) |
| GET | /v1/datasets | Public | Published datasets |
| GET | /v1/datasets/{slug}/series | Public | Series belonging to a dataset |
| GET | /v1/calendar | Public | Upcoming release calendar |
| GET | /v1/calendar.ics | Public | Subscribable release calendar feed (ICS, iCalendar) |
| GET | /v1/coverage | Public | Dataset coverage stats |
| GET | /v1/source-agencies | Public | Source agencies list |
Data formats
Observations are returned in three formats — pick the one that fits your pipeline:
- JSON — Structured records with values, frequencies, and metadata
- CSV —
/observations.csv(Flat tabular export for spreadsheets and ETL) - Excel —
/observations.xlsx(Excel workbook with formatting preserved)
Query filters
GET /v1/series combines all filters with AND. Search (q) matches the localized series name (substring) or the series id (prefix, e.g. "SA.CPI").
| Path | Description |
|---|---|
| q | Free-text search: series name (substring) or series id (prefix) |
| topic | Topic slug, e.g. inflation |
| source_agency | Source agency, e.g. GASTAT |
| dataset_id | Dataset id or slug |
| measure_type | Measure type, e.g. YoY |
| region | Region dimension, e.g. national |
| classification_system | Classification system |
| source_publication | Source publication |
| country_code | Country code (default SA) |
| published_only | Only published series (default true) |
| locale | Response locale: en or ar |
| limit | Page size, default 50, max 200 |
| offset | Pagination offset, default 0 |
Preview vs full
Observations return full history by default. Pass preview=true for a limited window on published series:
- Monthly series: last 12 months
- Annual series: last 5 years
- Daily/weekly series: preview unavailable (returns preview_blocked with reason granular)
Full observations require the series to be published; where entitlements are enforced, an active plan (Pro) is required.
Rate limits
Configured limits (per user or IP; enforcement is environment-configurable):
- Default: 100 requests/minute
- Unauthenticated public endpoints: 30 requests/minute
- Monthly API-request caps apply per plan — 3,000 requests on the 7-day Pro trial.
Enforcement may be relaxed on dev environments; production enforces configured limits.
Webhooks
Receive signed HTTP callbacks when series data is published or updated.