Skip to content

GRIMdata REST API

Query document metadata, the 194-country canonical scorecard, tags and timelines


Overview

The GRIMdata REST API queries your local document metadata, canonical scorecard workbook, tags and timelines. Document counts depend on the files in your instance. The published visualization snapshot is a separate scored dataset.

Self-hosted API base URL: http://localhost:5000/api for a local deployment. For production, use the hostname of your own deployed API. Follow the Quick Start to run your own instance.

Why Use the API?

  • Programmatic Access


    Query data directly from Python, R, JavaScript, or any language with HTTP support

  • Advanced Filtering


    Filter by country, region, tags, year ranges, document type, and more

  • Query Your Dataset


    Query your local data files and retrieve filtered results

  • Integration Ready


    Build dashboards, research tools, and applications on top of GRIMdata

Quick Comparison

Choose the right access method for your needs:

Access Method Best For Setup Time Flexibility
REST API Programmatic access, automation, integrations 5 minutes High - filter, paginate, sort
CSV Export One-time analysis, Excel, R dataframes 2 minutes Medium - static snapshots
Direct Files Deep exploration, custom processing Immediate High - full file access

Get Started


Features

API endpoints

Health & Info: - System status and data statistics

Documents API: - List documents with advanced filtering - Get detailed document metadata - Pagination and sorting

Scorecard API: - Countries summary with indicators - Country-specific details - Indicator statistics and analysis

Tags API: - Frequency analysis across documents - Version management (v1, v2, v3, digital) - Temporal and geographic filtering

Timeline API: - Tags over time (year × tag matrix) - Temporal trend analysis

Export API: - Download CSV datasets - SPDX license headers included

Technical Features

  • Authentication


    Optional API key for higher rate limits (100 → 1000 req/hr)

  • Rate Limiting


    Fair usage limits prevent abuse while allowing research

  • Caching


    15-minute cache for documents, 1-hour for scorecard

  • Validation


    All query parameters validated with clear error messages

  • Docker Ready


    Complete deployment with Redis and Nginx

  • Integration Tests


    Tests cover routes, services, authentication and rate limits


Example Use Cases

Research Applications

Analyze AI policy adoption in Africa:

curl "http://localhost:5000/api/documents?region=Africa&tags=AI&per_page=50"

Get LGBTQ+ legal status for all countries:

curl "http://localhost:5000/api/scorecard?per_page=200" | jq '.data.items[] | {country, lgbtq: .LGBTQ_Legal_Status}'

Track child rights tags over time (2018-2024):

curl "http://localhost:5000/api/timeline/tags?year_min=2018&year_max=2024" | jq '.data.timeline'

Integration Examples

Python Research Script:

import requests
import pandas as pd

# Fetch all documents about child protection in Kenya
response = requests.get(
    "http://localhost:5000/api/documents",
    params={"country": "Kenya", "tags": "ChildRights"}
)
docs = response.json()["data"]["items"]

# Convert to DataFrame for analysis
df = pd.DataFrame(docs)
print(df[["id", "year", "doc_type", "tags"]])

JavaScript Dashboard:

// Fetch scorecard data for visualization
fetch('http://localhost:5000/api/scorecard?per_page=200')
  .then(res => res.json())
  .then(data => {
    const countries = data.data.items;
    // Render heatmap, charts, etc.
  });

R Statistical Analysis:

library(httr)
library(jsonlite)

# Get tag frequency for Africa
response <- GET("http://localhost:5000/api/tags?region=Africa")
tags <- content(response, as = "parsed")$data$tags

# Analyze distribution
tags_df <- data.frame(
  tag = names(tags),
  count = unlist(tags)
)


Quick Examples

# Get all documents
curl http://localhost:5000/api/documents

# Filter by country and tags
curl "http://localhost:5000/api/documents?country=Kenya&tags=AI,ChildRights"

# Get Kenya's scorecard
curl http://localhost:5000/api/scorecard/Kenya

# Download scorecard CSV
curl "http://localhost:5000/api/export/scorecard_summary" -o scorecard.csv
import requests

# Get documents with filtering
response = requests.get(
    "http://localhost:5000/api/documents",
    params={
        "region": "Africa",
        "year_min": 2020,
        "tags": "AI",
        "per_page": 50
    }
)
documents = response.json()["data"]["items"]

# Get scorecard for specific country
response = requests.get("http://localhost:5000/api/scorecard/Kenya")
scorecard = response.json()["data"]
print(scorecard["indicators"])
// Fetch documents with async/await
async function getDocuments() {
  const response = await fetch(
    'http://localhost:5000/api/documents?region=Africa&tags=AI'
  );
  const data = await response.json();
  return data.data.items;
}

// Fetch scorecard
async function getScorecard(country) {
  const response = await fetch(
    `http://localhost:5000/api/scorecard/${country}`
  );
  const data = await response.json();
  return data.data;
}
library(httr)
library(jsonlite)

# Get documents
response <- GET("http://localhost:5000/api/documents?region=Africa")
documents <- content(response, as = "parsed")$data$items

# Get scorecard
response <- GET("http://localhost:5000/api/scorecard/Kenya")
scorecard <- content(response, as = "parsed")$data

Rate Limits & Authentication

Default Rate Limits (No API Key)

  • Documents/Tags/Timeline: 100 requests/hour
  • Export endpoints: 20 requests/hour

Authenticated Rate Limits (With API Key)

  • Documents/Tags/Timeline: 1000 requests/hour
  • Export endpoints: 200 requests/hour

Using API Keys

# Add X-API-Key header to your requests
curl -H "X-API-Key: your-api-key" http://localhost:5000/api/documents
# Python example with API key
headers = {"X-API-Key": "your-api-key"}
response = requests.get(
    "http://localhost:5000/api/documents",
    headers=headers
)

Configure API keys for your instance using the deployment guide.


Response Format

All API responses use consistent JSON structure:

Success Response:

{
  "status": "success",
  "data": {
    "items": [...],
    "pagination": {
      "page": 1,
      "per_page": 20,
      "total": 78,
      "total_pages": 4
    }
  },
  "timestamp": "2026-01-26T10:30:00Z"
}

Error Response:

{
  "status": "error",
  "error": {
    "code": "NOT_FOUND",
    "message": "Document not found",
    "details": {}
  },
  "timestamp": "2026-01-26T10:30:00Z"
}


Production Deployment

Deploy the API with Docker:

# Clone repository
git clone https://github.com/MissCrispenCakes/DigitalChild.git
cd DigitalChild

# Configure environment
cp .env.example .env
# Edit .env with your settings

# Start services (API + Redis + Nginx)
docker-compose up -d

# Verify
curl http://localhost:5000/api/health

See the Production Deployment Guide for complete setup instructions.


Documentation

  • Quick Start


    Get the API running in 5 minutes

    View Guide →

  • Full API Reference


    All 12 endpoints with parameters, examples, and response schemas

    View Reference →

  • Quick Reference


    Endpoint cheat sheet for quick lookup

    View Quick Ref →

  • Production Guide


    Deploy with Docker, configure Nginx, manage API keys

    View Guide →


Support


Technical Stack

  • Framework: Flask (version pinned in api_requirements.txt)
  • Caching: Redis
  • Web Server: Nginx (production)
  • Container: Docker + docker-compose
  • Testing: pytest unit and integration tests

License

  • API Code: MIT License
  • Data: CC BY 4.0

See LICENSE and LICENSE-DATA for details.