Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Regulation to Control API

Detect regulatory changes and map them to obligations, policies, controls, products and evidence requirements.

Regulation to Control landing page

Production API: https://controlgraph-api.com

Get a free API key · Documentation · Pricing · Status

Free tier: 50 mapped changes/month. No card required. Paid plans from $499/month.

Quickstart

Request a key. The token arrives by email; exchange it for the key, which is shown once.

curl -X POST https://controlgraph-api.com/v1/keys \
  -H 'content-type: application/json' \
  -d '{"email": "you@example.com"}'

Then call the API:

curl -X POST https://controlgraph-api.com/v1/changes \
  -H "Authorization: Bearer $KEY" \
  -H 'content-type: application/json' \
  -d '{"controls":[
        {"controlId":"CTL-014","name":"Disclosure template review",
         "owner":"Payments Compliance","status":"implemented",
         "tags":["payments","disclosure"],"lastTestedAt":"2026-07-01",
         "evidence":[{"kind":"policy_document","collectedAt":"2026-07-02"},
                     {"kind":"notification_record","collectedAt":"2026-07-14"}]}],
      "change":{
        "changeId":"REG-2026-0117","citation":"12 CFR 1026.19(e)",
        "title":"Revised cost-of-credit disclosures","jurisdiction":"US",
        "changeType":"amendment","publishedAt":"2026-03-02",
        "effectiveAt":"2026-09-01","transitionEndsAt":"2026-12-01",
        "obligations":[
          {"obligationId":"OB-1","type":"disclosure",
           "text":"Provide the revised disclosure within three business days.",
           "appliesTo":["payments","disclosure"],"enforcement":"penalty"}]}}\'

Endpoints

Regulation to Control API reference, with a live playground for every endpoint

Every endpoint below has a runnable playground on the documentation page.

Endpoint Auth Description
GET /health public Liveness and deployed version
GET / public Service index — endpoints, auth and error format
POST /v1/changes API key Map regulatory changes onto your obligations, controls, evidence and deadlines
POST /v1/demo/map public Public demo — map one change with no API key
GET /v1/obligation-types public The code catalogue: obligation types, evidence kinds, findings and the priority weights
POST /v1/checkout public Start a hosted Square checkout for a paid tier
POST /v1/keys public Request a free sandbox API key (sends a verification email)
GET /v1/keys API key List your API keys for this API
POST /v1/keys/claim public Exchange an emailed claim token for the API key
POST /v1/keys/{id}/revoke API key Revoke one of your API keys
POST /v1/keys/{id}/rotate API key Replace one of your API keys with a new secret
GET /v1/usage API key Your consumption and remaining allowance for this period
GET /v1/subscription API key Your current plan, billing window and available changes (dashboard session required)
POST /v1/subscription/plan API key Upgrade or downgrade to another plan (dashboard session required)
POST /v1/subscription/cancel API key Cancel this plan and end metered access (dashboard session required)
GET /v1/invoices API key Every invoice issued against this account, newest first (dashboard session required)
GET /v1/payments API key Every payment attempted against this account and how it went (dashboard session required)

The full machine-readable contract is openapi.json, generated from the deployed route table rather than maintained by hand. A Postman collection is included.

SDKs

Pythonsdk/python

from regulation_control import RegulationControl

client = RegulationControl()          # reads REGULATION_CONTROL_API_KEY

res = client.map_change(
    controls=[
        {"controlId": "CTL-014", "name": "Disclosure template review",
         "owner": "Payments Compliance", "status": "implemented",
         "tags": ["payments", "disclosure"], "lastTestedAt": "2026-07-01",
         "evidence": [{"kind": "policy_document", "collectedAt": "2026-07-02"},
                      {"kind": "notification_record", "collectedAt": "2026-07-14"}]},
    ],
    change={
        "changeId": "REG-2026-0117",
        "citation": "12 CFR 1026.19(e)",
        "title": "Revised cost-of-credit disclosures",
        "jurisdiction": "US",
        "changeType": "amendment",
        "publishedAt": "2026-03-02",
        "effectiveAt": "2026-09-01",
        "transitionEndsAt": "2026-12-01",
        "obligations": [
            {"obligationId": "OB-1", "type": "disclosure",
             "text": "Provide the revised disclosure within three business days.",
             "appliesTo": ["payments", "disclosure"], "enforcement": "penalty"},
        ],
    },
)

mapped = res["changes"][0]
print(mapped["summary"])   # covered / weak / gaps, and the earliest deadline

# The gaps are the work nobody has started.
for ob in mapped["obligations"]:
    if ob["coverage"] == "gap":
        open_ticket(ob["obligationId"], ob["text"], ob["complianceDate"])

# Every score is reproducible arithmetic. Print the derivation next to it.
top = mapped["obligations"][0]
print(top["priority"]["score"], top["priority"]["band"])
for line in top["priority"]["derivation"]:
    print("   ", line)

TypeScriptsdk/typescript

import { RegulationControl } from './regulation-control.js'

const client = new RegulationControl()     // reads REGULATION_CONTROL_API_KEY

const { changes } = await client.map({
  controls: [
    { controlId: 'CTL-014', name: 'Disclosure template review',
      owner: 'Payments Compliance', status: 'implemented',
      tags: ['payments', 'disclosure'], lastTestedAt: '2026-07-01',
      evidence: [{ kind: 'policy_document', collectedAt: '2026-07-02' },
                 { kind: 'notification_record', collectedAt: '2026-07-14' }] },
  ],
  change: {
    changeId: 'REG-2026-0117',
    citation: '12 CFR 1026.19(e)',
    title: 'Revised cost-of-credit disclosures',
    jurisdiction: 'US',
    changeType: 'amendment',
    publishedAt: '2026-03-02',
    effectiveAt: '2026-09-01',
    transitionEndsAt: '2026-12-01',
    obligations: [
      { obligationId: 'OB-1', type: 'disclosure',
        text: 'Provide the revised disclosure within three business days.',
        appliesTo: ['payments', 'disclosure'], enforcement: 'penalty' },
    ],
  },
})

const mapped = changes[0]
console.log(mapped.summary)   // covered / weak / gaps, and the earliest deadline

// The gaps are the work nobody has started.
for (const ob of mapped.obligations) {
  if (ob.coverage === 'gap') openTicket(ob.obligationId, ob.text, ob.complianceDate)
}

// Every score is reproducible arithmetic. Print the derivation next to it.
const top = mapped.obligations[0]!
console.log(top.priority.score, top.priority.band, top.priority.derivation)

Errors

Every failure returns the same shape. Branch on code, which is a stable enum; message is for humans and may change.

{"error": {"code": "invalid_api_key", "message": "...", "requestId": "0f3c8b12-…"}}

requestId appears on every response and in the x-request-id header. Quote it in any support request.

Support

Open an issue in this repository, or see the contact route at https://controlgraph-api.com/docs.

About

Detect regulatory changes and map them to obligations, policies, controls, products and evidence requirements.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages