Base URL
oakmonttechnologies.com/api/v1
Auth
Bearer
Format
REST · JSON
Quota
By plan
/ Developer API

Build on OAKMONT,in your own stack.

Call our platform programmatically - accessibility scans, price quotes, and more - in CI, in your CMS, or in your own product. REST, JSON, authenticated with an API key and metered per call.

Get an API key See API plansNo account yet? Create one free, then generate a key under Portal → Developer API. The scan endpoint works on the free tier.

Request

curl -X POST https://oakmonttechnologies.com/api/v1/scan \
  -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.gov/about"}'

Response

{
  "id": "9f3c…",
  "url": "https://example.gov/about",
  "score": 82,
  "grade": "B",
  "totals": { "critical": 1, "serious": 2, "moderate": 1 },
  "issues": [
    { "impact": "critical", "wcag": "1.1.1",
      "title": "Images missing alt text (3)",
      "help": "Every <img> needs an alt attribute…", "count": 3 }
  ]
}

Authentication

Create a key under Portal → Developer API. Send it on every request:

Authorization: Bearer oak_live_xxx

Base URL: https://oakmonttechnologies.com/api/v1

POST /scan - accessibility scan

Scan any public URL for common WCAG 2.1 AA / Section 508 failures.

Request
curl -X POST https://oakmonttechnologies.com/api/v1/scan \
  -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.gov/about"}'
Response
{
  "id": "9f3c…",
  "url": "https://example.gov/about",
  "score": 82,
  "grade": "B",
  "totals": { "critical": 1, "serious": 2, "moderate": 1 },
  "issues": [
    { "impact": "critical", "wcag": "1.1.1",
      "title": "Images missing alt text (3)",
      "help": "Every <img> needs an alt attribute…", "count": 3 }
  ]
}

POST /quote - price a job

Get an itemized quote for a remediation job from the live rate card.

curl -X POST https://oakmonttechnologies.com/api/v1/quote \
  -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"plan_key": "page_508", "chars": 12000}'

The scanner family

The same engines behind the free tools, metered against your monthly quota: AI Act transparency, trackers and consent, email deliverability, and the Polish FA invoice structure check. Full request and response shapes live in the machine-readable index at GET /api/v1.

# AI Act transparency (Article 50)
curl -X POST https://oakmonttechnologies.com/api/v1/ai-scan -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" -d '{"url": "https://example.com"}'

# Trackers and consent platform
curl -X POST https://oakmonttechnologies.com/api/v1/privacy-scan -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" -d '{"url": "https://example.com"}'

# Deliverability: MX, SPF, DMARC, DKIM
curl -X POST https://oakmonttechnologies.com/api/v1/email-check -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" -d '{"domain": "example.com"}'

# Polish FA invoice structure (KSeF)
curl -X POST https://oakmonttechnologies.com/api/v1/ksef-check -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" -d '{"xml": "<Faktura>...</Faktura>"}'

# LLM regression grading (deterministic, no model runs)
curl -X POST https://oakmonttechnologies.com/api/v1/eval -H "Authorization: Bearer oak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"cases": [{"key": "refund", "assertions": [{"kind": "contains", "value": "30 days"}]}], "answers": {"refund": "You have 30 days to return it."}}'

POST /gate - The build gate

Your pipeline runs the checks, on branches and hosts nothing outside can reach, and posts what it found. This decides whether the build passes and says exactly why - including why each of the rules it did not fire on stayed quiet.

Request
# The ruleset your build is held to, worst first by what we actually see
curl https://oakmonttechnologies.com/api/v1/rules/ci?level=AA -H "Authorization: Bearer oak_live_xxx"

# Your pipeline ran the checks; this decides the build and can sign the verdict
curl -X POST https://oakmonttechnologies.com/api/v1/gate -H "Authorization: Bearer oak_live_xxx"   -H "Content-Type: application/json"   -d '{"url": "https://staging.internal/checkout", "level": "AA", "fail_on": "serious",
       "prove": true, "findings": [{"code": "input-no-label", "selector": "#cvc"}]}'
Response
{
  "passed": false,
  "level": "AA", "fail_on": "serious",
  "failures": [
    { "code": "input-no-label", "criterion": "1.3.1", "impact": "critical",
      "count": 1, "selectors": ["#cvc"] }
  ],
  "advisories": [
    { "code": "heading-skip", "criterion": "1.3.1",
      "advisory_because": "No criterion says heading levels may not skip." }
  ],
  "digest": "3f9a…",
  "proof": { "id": "…", "verify_url": "https://oakmonttechnologies.com/verify/…" }
}

Two false failures and somebody adds continue-on-error, and after that a gate is decoration. So a criterion above the level you asked for, a criterion WCAG 2.2 withdrew, and anything a machine cannot honestly decide are reported and never block. Ask for prove and the verdict comes with a signed receipt naming the exact ruleset, so a green build cannot be re-read later against a ruleset that has since been tightened.

The notary

A dated, publicly checkable receipt over a hash you compute yourself, so the file never leaves your side. Priced per receipt rather than per call, because a receipt is the thing your customer keeps.

How the notary works

Errors

Failed calls use standard HTTP status codes and return a JSON body with a detail message.

StatusMeaning
400Invalid request body, for example a malformed URL or a missing field.
401Missing, malformed, or revoked API key.
404Referenced resource not found, for example an unknown plan_key on /quote.
429Monthly API quota reached. See the Retry-After and X-RateLimit headers.
{ "detail": "Invalid or revoked API key." }

Limits

Calls are metered monthly per plan (Free 100 · Basic 5,000 · Pro 50,000). Exceeding your quota returns 429. Upgrade anytime from billing.

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (a Unix timestamp for the start of next month). A 429 also returns Retry-After in seconds.

HTTP/1.1 200 OK
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4987
X-RateLimit-Reset: 1751328000

# When the monthly quota is exhausted:
HTTP/1.1 429 Too Many Requests
Retry-After: 1209600
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0

From JavaScript

Same two calls, without curl.

const res = await fetch("https://oakmonttechnologies.com/api/v1/scan", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.OAKMONT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({url: "https://example.gov/about"}),
});
if (!res.ok) throw new Error(`OAKMONT ${res.status}: ${await res.text()}`);
const {score, grade, issues} = await res.json();

Machine-readable specification

The API describes itself. Point your generator at the OpenAPI document and get a typed client rather than hand-written fetch calls.

Open the OpenAPI document https://oakmonttechnologies.com/api/openapi.json

The document is generated from the running service, so it is never out of date with the endpoints it describes.

Embed the rate card

One line, no key, no build step. It reads the same catalogue /pricing reads, so a page carrying it cannot go out of date. data-ref carries your partner code through to every link; data-group narrows it to one family of plans.

<script src="https://oakmonttechnologies.com/embed/rate-card.js"
        data-ref="your-partner-code"
        data-group="managed_sub"></script>

Or read it as JSON: https://oakmonttechnologies.com/api/public/rate-card

Full reference

Browse the full, machine-readable endpoint index at /api/v1.

Ready to build?

Create your first key and make a call in under a minute.