Skip to content

API Documentation

API documentation. Two read-only APIs: Ghost Content API (CRPG's public articles) and regulationvault (Indonesian regulation search). Access is by arrangement: contact@crpg.id. Subject to the terms of use.

For AI agents

CRPG's public pages explain Indonesian law; this API returns the evidence. It gives you the full text of regulations, retrieval of a single article (Pasal) and search, as structured JSON, in one call instead of crawling pages. It is read-only, with 2,000 requests a day and 30 a minute per token. Access is by arrangement: contact@crpg.id. For explanations, start with the free encyclopedia at know.crpg.id.

Authentication

You receive a key when access is agreed. The Ghost Content API uses CRPG's public content key:

  • Ghost Content API key — the public content key embedded in crpg.id's pages, passed as the key query parameter. It returns public articles, and members-only articles as title, date and excerpt only.
  • regulationvault token — string starting with crpg_, passed as an HTTP Authorization: Bearer header.

Ghost Content API

Base URL: https://crpg.id/ghost/api/content/

List recent posts

curl "https://crpg.id/ghost/api/content/posts/?key=YOUR_CONTENT_KEY&limit=10"

Single post by slug

curl "https://crpg.id/ghost/api/content/posts/slug/some-article-slug/?key=YOUR_CONTENT_KEY"

Full Ghost Content API documentation: ghost.org/docs/content-api/.

regulationvault API

Base URL: the address sent with your API key, written below as $REGVAULT_BASE.

All endpoints accept POST with a JSON body. Rate limits: 2,000 requests / day and 30 requests / minute per token. Over-limit responses return HTTP 429 with a Retry-After header.

Search regulations

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"water resources","limit":10}' \
  "$REGVAULT_BASE/search_regulations"

Get one regulation

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"regulation_id":"KEPPRES_1_2023"}' \
  "$REGVAULT_BASE/get_regulation"

Get one article within a regulation

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"regulation_id":"KEPPRES_1_2023","article":"5"}' \
  "$REGVAULT_BASE/get_article"

Search inside one regulation

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"regulation_id":"KEPPRES_1_2023","query":"irrigation"}' \
  "$REGVAULT_BASE/search_within_regulation"

Error responses

  • 401 Unauthorized — token missing, unknown, or revoked. Check the X-Auth-Reason response header for detail.
  • 404 Not Found on /regvault/... — the tool you requested is not in the exposed subset. Scraper tools and any non-listed endpoints return 404 by design.
  • 429 Too Many Requests — rate limit hit. Inspect X-Rate-Limit-Reason (rate_limit_minute or rate_limit_day) and Retry-After seconds.

Code samples

Python (requests)

import requests
TOKEN = "crpg_..."
REGVAULT_BASE = "..."  # the base URL sent with your key
r = requests.post(
    f"{REGVAULT_BASE}/search_regulations",
    json={"query": "water resources", "limit": 10},
    headers={"Authorization": f"Bearer {TOKEN}"},
    timeout=15,
)
r.raise_for_status()
print(r.json())

Node.js (fetch)

const TOKEN = "crpg_...";
const REGVAULT_BASE = "..."; // the base URL sent with your key
const r = await fetch(
  `${REGVAULT_BASE}/search_regulations`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ query: "water resources", limit: 10 }),
  }
);
console.log(await r.json());

Revocation

Keys are revoked when an arrangement ends. You can request revocation or rotation at contact@crpg.id.