Skip to content

API documentation

REST API v1: rating, researchers, works and search; keys, limits and examples for the portal and journal platforms.

Basics

The REST API returns JSON; every path starts with the /v1/ prefix.

  • Base URL: https://research.milliykengash.com/v1
  • Format: JSON requests and responses (Accept: application/json).
  • Language: ?lang=uz|ru|en — institution and unit names in the chosen language (default uz).
  • Timestamps are ISO-8601 UTC (2026-09-16T09:10:00Z), dates are YYYY-MM-DD.
  • Pagination: ?page=&page_size= (page_size ≤ 200); responses contain items, total, page, page_size, next.
Paginated responsejson
{
  "items": [ ... ],
  "total": 1234,
  "page": 1,
  "page_size": 50,
  "next": "/v1/rating/researchers?institution=12&page=2"
}

Authentication and keys

Public read endpoints work without signing in. API keys are issued for integrations.

Access types
AccessForLimit
publicAnyone: rating, researcher, work and search endpoints120 requests per minute per IP
rating:readThe milliykengash.com main portal — rating and its breakdown (column 2)Unlimited
usage:writejournal.* and conference.* platforms — view and download events≤ 1,000 events per request
  • Send the key in the header: Authorization: Bearer RESEARCH_API_KEY.
  • Keys are issued by the MilliyKengash research administrator; a key is shown only once at creation and stored as a hash.
  • Never put the key in browser code or a public repository — use it on the server side only.

Limits

Limits keep the service stable for everyone.

  • Public endpoints: 120 requests per minute from a single IP address.
  • When exceeded — a 429 response with the throttled error code; retry after the time given in the Retry-After header.
  • With an API key (rating:read), portal requests are not rate-limited.

Caching and ETag

Responses are cached — use ETags to fetch frequently requested data quickly and cheaply.

  • Cache lifetime: rating lists 60 seconds, page data 300 seconds (Cache-Control: public, max-age=…).
  • ETag: send the If-None-Match header on the next request — if the data has not changed, you get 304 Not Modified.
  • Live vs snapshot: without date the rating is live (≤ 5 minutes delay); ?date=YYYY-MM-DD returns that day's official snapshot.
Conditional request with ETagshell
curl -si "https://research.milliykengash.com/v1/works/20.1042/talim/2026/v12_i3/48213907"
# HTTP/1.1 200 OK
# Cache-Control: public, max-age=300
# ETag: "a1b2c3d4"

curl -si "https://research.milliykengash.com/v1/works/20.1042/talim/2026/v12_i3/48213907" -H 'If-None-Match: "a1b2c3d4"'
# HTTP/1.1 304 Not Modified

Endpoints

The full schema is in the OpenAPI document. The main endpoints are listed below.

Rating (portal and public)

Rating (portal and public)
EndpointDescriptionAccessCache
GET/v1/rating/institutions?region=&type=&date=&q=&lang=Institution rating: rank, change, R, column 2, breakdown; with date — a snapshotpublic60 s
GET/v1/rating/institutions/{id}Institution breakdown, unit rankings, top 10 researchers, yearly chartspublic300 s
GET/v1/rating/institutions/{id}/history?from=&to=Institution rating history (daily snapshots)public300 s
GET/v1/rating/departments?institution=&level=Faculty and department rankings (within an institution)public300 s
GET/v1/rating/units/{level}/{id}Faculty or department page datapublic300 s
GET/v1/rating/researchers?institution=&faculty=&department=&q=&page=Researcher ranking: H-index ↓, citations ↓, works ↓public60 s
GET/v1/methodologyCurrent methodology: parameters, versions, sourcespublic300 s

Public read

Public read
EndpointDescriptionAccessCache
GET/v1/stats/overviewOverall totals: institutions, researchers, works, citationspublic300 s
GET/v1/sourcesData source status and schedulepublic300 s
GET/v1/filtersRegions, institution types, subjects, year rangepublic300 s
GET/v1/search?q=&type=&year_from=&year_to=&institution=&subject=&page=Search works, researchers and institutions (Latin/Cyrillic, DRI)public300 s
GET/v1/researchers/{milliy_id}Researcher profile, metrics and rankpublic300 s
GET/v1/researchers/{milliy_id}/metricsResearcher metrics (public even for private profiles)public300 s
GET/v1/researchers/{milliy_id}/works?sort=citations|year&page=Researcher's works; private profile → 403 profile_privatepublic300 s
GET/v1/researchers/{milliy_id}/citations-by-yearCitations by yearpublic300 s
GET/v1/researchers/{milliy_id}/cited-by?page=“Cited by”; private profile → 403public300 s
GET/v1/works/{dri}Work passport, metrics (by source), linkspublic300 s
GET/v1/works/{dri}/metricsWork metrics and monthly usagepublic300 s
GET/v1/works/{dri}/citationsThe work's reference list and matching statuspublic300 s
GET/v1/works/{dri}/cited-by?page=Works citing this workpublic300 s

Integration and service

Integration and service
EndpointDescriptionAccessCache
POST/v1/usage/eventsIngest view and download events (batched)usage:write
GET/v1/openapi.jsonOpenAPI 3 specificationpublic
GET/v1/docsInteractive Swagger documentationpublic
GET/v1/healthService healthpublic
A DRI in the path keeps its slashes: /v1/works/20.1042/talim/2026/v12_i3/48213907 — no encoding is required, though each segment may be encoded separately.

Portal: rating API

The main portal takes column 2 from this endpoint. Key: rating:read.

Requestshell
curl -s "https://research.milliykengash.com/v1/rating/institutions?lang=uz" \
  -H "Authorization: Bearer $RESEARCH_API_KEY" \
  -H "Accept: application/json"
Response (abridged)json
{
  "method_version": "2026.1",
  "computed_at": "2026-09-16T09:10:00Z",
  "snapshot_date": null,
  "is_live": true,
  "items": [
    {
      "rank": 1,
      "delta_rank": 2,
      "institution": {
        "id": 12,
        "portal_id": "otm-12",
        "name": "Toshkent davlat pedagogika universiteti",
        "short_name": "TDPU",
        "region": "Toshkent shahri",
        "type": "university"
      },
      "R": 0.76,
      "score_33": 25.3,
      "components": {
        "avg_h": 6.0, "downloads_ps": 12.5, "views_ps": 100.0,
        "H_n": 1.0, "Y_n": 0.166667, "K_n": 0.266667,
        "contrib": { "h": 0.7, "downloads": 0.033333, "views": 0.026667 }
      },
      "staff_count": 412,
      "works_count": 1830,
      "citations": 5210,
      "downloads": 5150.5,
      "views": 41200.0
    }
  ],
  "total": 187,
  "filters": {
    "regions": ["Toshkent shahri", "Samarqand viloyati"],
    "types": [{ "code": "university", "name": "Universitet" }]
  }
}
  • rank / delta_rank — rank and change since yesterday's snapshot (positive means moved up; null if there is no snapshot for yesterday).
  • score_33 — column 2 score (33.3 × R, 1 decimal); R — research score (0–1).
  • components — avg_h, downloads_ps, views_ps, normalized H_n/Y_n/K_n and the contrib contributions.
  • method_version / computed_at — methodology version and time of the last computation; is_live — live rating or snapshot.
Daily official snapshotshell
curl -s "https://research.milliykengash.com/v1/rating/institutions?date=2026-09-15" \
  -H "Authorization: Bearer $RESEARCH_API_KEY"

Usage events

journal.* and conference.* platforms send page views and PDF downloads in batches. Key: usage:write.

Requesthttp
POST https://research.milliykengash.com/v1/usage/events
Authorization: Bearer <usage:write>
Idempotency-Key: 5f0c2d1e-journal-2026-09-16T10:20
Content-Type: application/json

{
  "source": "journal",
  "events": [
    { "dri": "20.1042/talim/2026/v12_i3/48213907", "type": "view",
      "ts": "2026-09-16T10:15:00+05:00", "visitor_hash": "sha256(ip+ua+salt)",
      "referrer": "https://google.com" },
    { "dri": "20.1042/talim/2026/v12_i3/48213907", "type": "download",
      "ts": "2026-09-16T10:16:10+05:00", "visitor_hash": "sha256(ip+ua+salt)" }
  ]
}
Responsejson
HTTP/1.1 202 Accepted

{
  "accepted": 2,
  "rejected": 1,
  "duplicates": 0,
  "errors": [
    { "index": 2, "code": "too_old", "message": "Hodisa 7 kundan eski" }
  ]
}
  • Batches: at most 1,000 events per request; send events within 5 minutes.
  • Duplicates: the same (dri, type, visitor_hash) is counted once per 24 hours (duplicates).
  • Time: events older than 7 days or more than 10 minutes in the future are rejected (too_old, invalid).
  • Bots are rejected based on referrer and user-agent signals (bot).
  • Idempotency-Key: a request repeated with the same key within 24 hours returns the original response.
  • Privacy: visitor_hash is computed on the platform (IP addresses are not stored) and must be irreversible.

Errors

All errors share one format: code, message, details and request identifier.

Error responsejson
HTTP/1.1 403 Forbidden

{
  "error": {
    "code": "profile_private",
    "message": "Tadqiqotchi profili yopiq",
    "details": []
  },
  "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
Error codes
HTTPCodeMeaning
400validation_errorInvalid parameter; details contain the field and reason
401not_authenticatedA key or session is required
403permission_deniedThe key lacks the required scope
403profile_privateThe researcher's profile is private — works and citing works are hidden
404not_foundObject not found
404profile_mergedThe profile was merged into another; details contain the primary Milliy ID
404snapshot_not_foundNo snapshot was published for this date
429throttledRate limit exceeded
500server_errorInternal server error

Webhook

The portal is notified when a daily snapshot is published.

Verify the signature: compute HMAC-SHA256 of the request body with the shared secret and compare it with the X-Research-Signature header.

rating.snapshot.publishedhttp
POST <PORTAL_WEBHOOK_URL>
X-Research-Signature: sha256=<HMAC(body, PORTAL_WEBHOOK_SECRET)>
Content-Type: application/json

{
  "event": "rating.snapshot.published",
  "date": "2026-09-16",
  "method_version": "2026.1",
  "url": "/v1/rating/institutions?date=2026-09-16"
}