API Reference

Complete reference for the Moonlit Legal Intelligence API. Search Dutch and European legal documents, retrieve full texts, and interact with Luna, our AI research assistant.

Base URL

https://api.moonlit.ai/v1.1

Authentication

Ocp-Apim-Subscription-Key

Rate Limit

50,000 requests / month

Response Format

JSON

Authentication

All API requests must include your subscription key in the Ocp-Apim-Subscription-Key header. Get in touch with our team to get your API key.

Keep your API key secret. Do not expose it in client-side code or public repositories. If your key is compromised, contact our team immediately.

curl -X POST "https://api.moonlit.ai/v1.1/search/keyword_search" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  -d '{"query": "huurrecht opzegging", "jurisdictions": ["Netherlands"]}'

Base URL

All API endpoints are relative to the following base URL:

https://api.moonlit.ai/v1.1

For example, the keyword search endpoint is available at https://api.moonlit.ai/v1.1/search/keyword_search.

Errors

The API uses standard HTTP status codes to indicate the success or failure of a request. Codes in the 2xx range indicate success, 4xx range indicate a client error, and 5xx range indicate a server error.

Status CodeMeaningDescription
400Bad RequestThe request body is malformed or missing required parameters.
401UnauthorizedThe API key is missing or invalid.
403ForbiddenYour API key does not have permission to access this resource.
422Validation ErrorThe request body failed validation. Check required fields and parameter types.
429Rate LimitedYou have exceeded your monthly request quota. Contact our team to discuss your plan.
500Server ErrorAn unexpected error occurred on our end. Try again or contact support if the issue persists.
504Gateway TimeoutThe search timed out. This can happen with complex hybrid or semantic queries. Try narrowing your filters or reducing num_results.

Error Response Format

{
  "error": {
    "code": 401,
    "message": "Invalid or missing API key."
  }
}

Which search should you use?

"I have a natural language question"

Hybrid Search (best default)

Need max precision? Add reranking

"I need exact terms, case numbers, Boolean logic"

Keyword Search

Sort by date or citations with sort_type

"I want concept-based discovery"

Semantic Search

Need max precision? Add reranking

"I just want answers, not document lists"

Luna API (streaming research assistant)

POST/v1.1/search/semantic_search_reranked

Semantic Search (Reranked)

Semantic search enhanced with a cross-encoder reranking stage. The initial retrieval is re-scored with a more powerful model for maximum precision. Slightly higher latency but significantly better result quality for complex queries.

Parameters

ParameterTypeRequiredDescription
querystringYesNatural language search query. Ask questions in plain language for best results.
jurisdictionsstring[]NoFilter by jurisdiction full names, e.g. ["European Union", "Netherlands"].
portalsstring[]NoFilter by portal values, e.g. ["1|eur-lex.europa.eu"]. Use the semantic portals endpoint to discover available portals.
documentTypesstring[]NoFilter by document type IDs obtained from the document types filter endpoint.
fieldsOfLawstring[]NoFilter by field of law IDs obtained from the fields of law filter endpoint.
sourcesstring[]NoFilter by source value obtained from the sources filter endpoint.
from_datestringNoStart date filter in YYYY-MM-DD format. Must be used together with until_date.
until_datestringNoEnd date filter in YYYY-MM-DD format. Must be used together with from_date.
pageintegerNoPage number for pagination (1-based). Default: 1.
num_resultsintegerNoNumber of results per page. Default: 20, max: 100.
rerankerTypeintegerNoReranker model: 1 = Google Vertex AI (default), 2 = Cohere.

Example Request

curl -X POST "https://api.moonlit.ai/v1.1/search/semantic_search_reranked" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "What is the standard of judicial review for administrative sanctions under the principle of proportionality?",
  "jurisdictions": ["European Union"],
  "num_results": 20,
  "rerankerType": 1
}'

Example Response

{
  "result": {
    "count": 405,
    "skip": 0,
    "top": 10,
    "results": [
      {
        "identifier": "62018CJ0311",
        "secondaryIdentifier": "ECLI:EU:C:2020:559",
        "tertiaryIdentifier": "C-311/18",
        "portal": "eur-lex.europa.eu",
        "title": "Data Protection Commissioner/Facebook Ireland Limited, Maximillian Schrems",
        "court": "European Court of Justice",
        "year": 2020,
        "sources": [
          {
            "id": "02045a9e2de3f3bd6c520ad0317efd0d",
            "parentId": "f7875ac0576a21c24937d480f6fde4f1",
            "shortName": "European Court of Justice",
            "name": "European Court of Justice"
          }
        ],
        "fieldsOfLaw": [
          {
            "id": "6c1022289490f6fca4adcf0e082d2524",
            "shortName": "European data protection law",
            "name": "European data protection law"
          }
        ],
        "documentTypes": [
          {
            "id": "04b42e5bf858a66de2229227deaa21e3",
            "shortName": "Decisions",
            "name": "Decisions"
          }
        ],
        "language": "EN",
        "referenced": 165,
        "score": 24.674826,
        "sourceUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:62018CJ0311"
      },
      {
        "identifier": "62019CJ0623",
        "secondaryIdentifier": "ECLI:EU:C:2022:857",
        "tertiaryIdentifier": "C-623/19",
        "portal": "eur-lex.europa.eu",
        "title": "Privacy International v Secretary of State for Foreign and Commonwealth Affairs",
        "court": "European Court of Justice",
        "year": 2022,
        "sources": [
          {
            "id": "02045a9e2de3f3bd6c520ad0317efd0d",
            "parentId": "f7875ac0576a21c24937d480f6fde4f1",
            "shortName": "European Court of Justice",
            "name": "European Court of Justice"
          }
        ],
        "fieldsOfLaw": [
          {
            "id": "6c1022289490f6fca4adcf0e082d2524",
            "shortName": "European data protection law",
            "name": "European data protection law"
          }
        ],
        "documentTypes": [
          {
            "id": "04b42e5bf858a66de2229227deaa21e3",
            "shortName": "Decisions",
            "name": "Decisions"
          }
        ],
        "language": "EN",
        "referenced": 87,
        "score": 19.312045,
        "sourceUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:62019CJ0623"
      }
    ]
  },
  "success": true
}
POST/v1.1/search/hybrid_search_reranked

Hybrid Search (Reranked)

The highest-quality search mode. Combines keyword + semantic retrieval via RRF fusion, then applies cross-encoder reranking. Best for research workflows where precision outweighs latency. Use this for RAG pipelines and critical legal analysis.

Parameters

ParameterTypeRequiredDescription
querystringYesSearch query combining keyword and semantic matching.
jurisdictionsstring[]NoFilter by jurisdiction full names, e.g. ["European Union", "Netherlands"].
portalsstring[]NoFilter by portal values, e.g. ["1|eur-lex.europa.eu"].
documentTypesstring[]NoFilter by document type IDs obtained from the document types filter endpoint.
fieldsOfLawstring[]NoFilter by field of law IDs obtained from the fields of law filter endpoint.
sourcesstring[]NoFilter by source value obtained from the sources filter endpoint.
from_datestringNoStart date filter in YYYY-MM-DD format. Must be used together with until_date.
until_datestringNoEnd date filter in YYYY-MM-DD format. Must be used together with from_date.
pageintegerNoPage number for pagination (1-based). Default: 1.
num_resultsintegerNoNumber of results per page. Default: 10, max: 100.
semantic_weightnumberNoWeight of the semantic component (0.0–1.0). 0 = pure keyword, 1 = pure semantic. Default: 0.6.
rerankerTypeintegerNoReranker model: 1 = Google Vertex AI (default), 2 = Cohere.

Example Request

curl -X POST "https://api.moonlit.ai/v1.1/search/hybrid_search_reranked" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "preliminary ruling procedure Article 267 TFEU admissibility criteria for national court references",
  "jurisdictions": ["European Union"],
  "semantic_weight": 0.6,
  "num_results": 10,
  "rerankerType": 1
}'

Example Response

{
  "result": {
    "count": 405,
    "skip": 0,
    "top": 10,
    "results": [
      {
        "identifier": "62018CJ0311",
        "secondaryIdentifier": "ECLI:EU:C:2020:559",
        "tertiaryIdentifier": "C-311/18",
        "portal": "eur-lex.europa.eu",
        "title": "Data Protection Commissioner/Facebook Ireland Limited, Maximillian Schrems",
        "court": "European Court of Justice",
        "year": 2020,
        "sources": [
          {
            "id": "02045a9e2de3f3bd6c520ad0317efd0d",
            "parentId": "f7875ac0576a21c24937d480f6fde4f1",
            "shortName": "European Court of Justice",
            "name": "European Court of Justice"
          }
        ],
        "fieldsOfLaw": [
          {
            "id": "6c1022289490f6fca4adcf0e082d2524",
            "shortName": "European data protection law",
            "name": "European data protection law"
          }
        ],
        "documentTypes": [
          {
            "id": "04b42e5bf858a66de2229227deaa21e3",
            "shortName": "Decisions",
            "name": "Decisions"
          }
        ],
        "language": "EN",
        "referenced": 165,
        "score": 24.674826,
        "sourceUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:62018CJ0311"
      },
      {
        "identifier": "62019CJ0623",
        "secondaryIdentifier": "ECLI:EU:C:2022:857",
        "tertiaryIdentifier": "C-623/19",
        "portal": "eur-lex.europa.eu",
        "title": "Privacy International v Secretary of State for Foreign and Commonwealth Affairs",
        "court": "European Court of Justice",
        "year": 2022,
        "sources": [
          {
            "id": "02045a9e2de3f3bd6c520ad0317efd0d",
            "parentId": "f7875ac0576a21c24937d480f6fde4f1",
            "shortName": "European Court of Justice",
            "name": "European Court of Justice"
          }
        ],
        "fieldsOfLaw": [
          {
            "id": "6c1022289490f6fca4adcf0e082d2524",
            "shortName": "European data protection law",
            "name": "European data protection law"
          }
        ],
        "documentTypes": [
          {
            "id": "04b42e5bf858a66de2229227deaa21e3",
            "shortName": "Decisions",
            "name": "Decisions"
          }
        ],
        "language": "EN",
        "referenced": 87,
        "score": 19.312045,
        "sourceUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:62019CJ0623"
      }
    ]
  },
  "success": true
}
GET/v1.1/search/filters/documenttypes

Document Types

Returns the hierarchical list of available document types that can be used as filters in search queries. Each type includes an id and may contain children.

Example Request

curl "https://api.moonlit.ai/v1.1/search/filters/documenttypes" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

{
  "DocumentTypes": [
    {
      "name": "Laws and regulations",
      "id": "18fead608f1a4dcb5671b9fc8aeab4d1",
      "children": [
        {
          "name": "National law",
          "id": "fbee5d2e827c7307c755601603c91bc3",
          "children": null
        },
        {
          "name": "European law",
          "id": "87a86c141d2c0649a699745ba63e4c6b",
          "children": null
        }
      ]
    },
    {
      "name": "Case law",
      "id": "04b42e5bf858a66de2229227deaa21e3",
      "children": [
        {
          "name": "Decisions",
          "id": "a3f5e7b8c9d0e1f2a3b4c5d6e7f8a9b0",
          "children": null
        },
        {
          "name": "Opinions",
          "id": "b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9",
          "children": null
        }
      ]
    }
  ]
}
GET/v1.1/search/filters/jurisdictions_portals

Jurisdictions & Portals

Returns all available jurisdictions and their associated portals with document counts. Use jurisdiction names for the jurisdictions parameter and portal values for the portals parameter in search queries.

Example Request

curl "https://api.moonlit.ai/v1.1/search/filters/jurisdictions_portals" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

[
  {
    "name": "European Union",
    "count": 350000,
    "portals": [
      {
        "name": "eur-lex.europa.eu",
        "value": "0|eur-lex.europa.eu",
        "count": 350000
      }
    ]
  },
  {
    "name": "Netherlands",
    "count": 2100000,
    "portals": [
      {
        "name": "rechtspraak.nl",
        "value": "1|rechtspraak.nl",
        "count": 800000
      },
      {
        "name": "wetten.overheid.nl",
        "value": "1|wetten.overheid.nl",
        "count": 120000
      }
    ]
  },
  {
    "name": "Germany",
    "count": 950000,
    "portals": [
      {
        "name": "gesetze-im-internet.de",
        "value": "2|gesetze-im-internet.de",
        "count": 450000
      },
      {
        "name": "rechtsprechung-im-internet.de",
        "value": "2|rechtsprechung-im-internet.de",
        "count": 500000
      }
    ]
  },
  {
    "name": "Belgium",
    "count": 680000,
    "portals": [
      {
        "name": "juridat.be",
        "value": "3|juridat.be",
        "count": 680000
      }
    ]
  }
]
GET/v1.1/search/filters/trees

Fields of Law

Returns the hierarchical taxonomy of fields of law. Each field includes an id and may contain child fields. Use field IDs to scope searches to a specific legal domain.

Example Request

curl "https://api.moonlit.ai/v1.1/search/filters/trees" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

{
  "FieldsOfLaw": [
    {
      "name": "Public law",
      "id": "2f6b898befaa9e641cd8ee258cd8f22e",
      "children": [
        {
          "name": "Constitutional law",
          "id": "abc123def456ghi789jkl012mno345pq",
          "children": null
        },
        {
          "name": "Administrative law",
          "id": "def456ghi789jkl012mno345pqr678stu",
          "children": null
        }
      ]
    },
    {
      "name": "Private law",
      "id": "9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
      "children": [
        {
          "name": "Contract law",
          "id": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
          "children": null
        },
        {
          "name": "Tort law",
          "id": "7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d",
          "children": null
        }
      ]
    },
    {
      "name": "Criminal law",
      "id": "e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8",
      "children": [
        {
          "name": "Economic criminal law",
          "id": "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8",
          "children": null
        }
      ]
    }
  ]
}
GET/v1.1/search/filters/sources

Sources

Returns available sources (courts, legislative bodies) in a hierarchical tree. Each source includes a value field and document count. Optionally filter by jurisdictions and portals using comma-separated query parameters.

Parameters

ParameterTypeRequiredDescription
jurisdictionsstringNoComma-separated jurisdiction names to filter sources, e.g. "European Union,Netherlands". Omit for all.
portalsstringNoComma-separated portal values to filter sources, e.g. "0|eur-lex.europa.eu,1|rechtspraak.nl". Omit for all.

Example Request

curl "https://api.moonlit.ai/v1.1/search/filters/sources?jurisdictions=European%20Union" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

{
  "Sources": [
    {
      "name": "International courts",
      "value": "f7875ac0576a21c24937d480f6fde4f1",
      "count": 50000,
      "parentId": null,
      "children": [
        {
          "name": "European Court of Justice",
          "value": "02045a9e2de3f3bd6c520ad0317efd0d",
          "count": 30000,
          "parentId": "f7875ac0576a21c24937d480f6fde4f1",
          "children": null
        },
        {
          "name": "General Court",
          "value": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
          "count": 20000,
          "parentId": "f7875ac0576a21c24937d480f6fde4f1",
          "children": null
        }
      ]
    },
    {
      "name": "Legislative bodies",
      "value": "b49c23adeaa6a345aa815e401c6d194b",
      "count": 120000,
      "parentId": null,
      "children": [
        {
          "name": "European Parliament",
          "value": "c9aca61be7de06a023b67cc6ab78bf72",
          "count": 80000,
          "parentId": "b49c23adeaa6a345aa815e401c6d194b",
          "children": null
        }
      ]
    }
  ]
}
GET/v1.1/search/semantic_portals

Semantic Portals

Returns the list of portals that support semantic and hybrid search. Not all portals have vector embeddings — use this endpoint to check availability before constructing semantic queries.

Example Request

curl "https://api.moonlit.ai/v1.1/search/semantic_portals" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

[
  {
    "name": "eur-lex.europa.eu",
    "value": "0|eur-lex.europa.eu"
  },
  {
    "name": "rechtspraak.nl",
    "value": "1|rechtspraak.nl"
  },
  {
    "name": "wetten.overheid.nl",
    "value": "1|wetten.overheid.nl"
  },
  {
    "name": "gesetze-im-internet.de",
    "value": "2|gesetze-im-internet.de"
  },
  {
    "name": "rechtsprechung-im-internet.de",
    "value": "2|rechtsprechung-im-internet.de"
  },
  {
    "name": "juridat.be",
    "value": "3|juridat.be"
  }
]
GET/v1.1/document/retrieve_document

Retrieve Document

Retrieves a full document including its complete text, HTML rendition, structured metadata, and an AI-generated summary. Use the document identifier obtained from search results.

Parameters

ParameterTypeRequiredDescription
DocumentIdentifierstringYesUnique document identifier from search results, e.g. "62018CJ0311" or "32019L0001".

Example Request

curl "https://api.moonlit.ai/v1.1/document/retrieve_document?DocumentIdentifier=62018CJ0311" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

{
  "identifier": "32019L0001",
  "language": "EN",
  "date": "2018-12-11",
  "title": "DIRECTIVE (EU) 2019/1 of the European Parliament and of the Council of 11 December 2018",
  "source": "European Parliament",
  "jurisdiction": "European Union",
  "portal": "eur-lex.europa.eu",
  "sourceUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32019L0001",
  "sourcePdf": "https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=32019L0001",
  "sources": [
    {
      "id": "b49c23adeaa6a345aa815e401c6d194b",
      "name": "Legislative bodies"
    },
    {
      "id": "c9aca61be7de06a023b67cc6ab78bf72",
      "parentId": "b49c23adeaa6a345aa815e401c6d194b",
      "name": "European Parliament"
    }
  ],
  "documentTypes": [
    {
      "id": "18fead608f1a4dcb5671b9fc8aeab4d1",
      "name": "Laws and regulations"
    },
    {
      "id": "87a86c141d2c0649a699745ba63e4c6b",
      "parentId": "18fead608f1a4dcb5671b9fc8aeab4d1",
      "name": "European law"
    }
  ],
  "text": "[Full plain text of the directive — truncated for brevity]",
  "html": "<h1>DIRECTIVE (EU) 2019/1...</h1>",
  "year": 2019,
  "inForce": true,
  "summary": "This directive establishes common rules for the internal market in the field of European competition law, setting out the powers of national competition authorities to enforce Articles 101 and 102 TFEU more effectively."
}
POST/v1.1/luna/initialize_chat

Luna: Initialize Chat

Starts a new Luna AI research session. Returns a chat_id that must be passed to subsequent ask_question calls. No request body or parameters required.

Example Request

curl -X POST "https://api.moonlit.ai/v1.1/luna/initialize_chat" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY"

Example Response

{
  "chat_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
POST/v1.1/luna/ask_question

Luna: Ask Question

Asks a question in an active Luna research session. Returns a Server-Sent Events (SSE) stream with the answer, including inline source citations. The response streams token by token for low-latency display. Previous conversation context is maintained within the session.

Parameters

ParameterTypeRequiredDescription
chat_idstringYesSession ID returned by initialize_chat.
inputstringYesThe research question or follow-up message.
jurisdictionsstring[]NoJurisdictions to scope this question, e.g. ["European Union", "Netherlands"].

Example Request

curl -N -X POST "https://api.moonlit.ai/v1.1/luna/ask_question" \
  -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "chat_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "input": "What are the key requirements for valid consent under GDPR Article 7, and how has the CJEU interpreted them?",
  "jurisdictions": ["European Union"]
}'

Example Response

event: message
data: Under Article 7 GDPR, valid consent must satisfy

event: message
data:  several cumulative conditions established

event: message
data:  by the CJEU in its landmark rulings.

event: sources
data: {"sources": [{"id": "62018CJ0311", "title": "Data Protection Commissioner v Facebook Ireland (Schrems II)", "relevance": 0.96}, {"id": "62017CJ0673", "title": "Case C-673/17 Planet49", "relevance": 0.93}, {"id": "62021CJ0252", "title": "Case C-252/21 Meta Platforms", "relevance": 0.89}]}

event: done
data: [DONE]