Developer Platform

Build on AUDIGYD

Access your compliance data programmatically through our REST API, real-time Webhooks, and AI-ready MCP integration.

Three Ways to Connect

Whether you're building dashboards, automating workflows, or querying with AI — we have you covered.

REST API

Read-only RESTful API for accessing assessments, findings, reports, and templates. Authenticated via API keys with granular scope control.

  • JSON responses with pagination
  • Scoped API key authentication
  • Generous rate limits with 429 + Retry-After
  • Inbound evidence write endpoints

Webhooks

Real-time event notifications pushed to your endpoints. Get notified when assessments finalize, findings surface, or reports are ready.

  • 10 event types including evidence.added
  • HMAC-SHA256 signature verification
  • Automatic retries with backoff

MCP Integration

Connect directly to Claude, Cursor, or any MCP-compatible AI assistant. Query your compliance data with natural language.

  • 6 AI tools for compliance queries
  • Same API key authentication
  • SSE transport for real-time

Full Endpoint Reference

Every endpoint is documented with request parameters, response schemas, and copy-paste code examples in cURL, JavaScript, and Python.

Compliance Overview

Assessment counts, finding breakdowns, report totals

Assessment Responses

Individual answers, scores, verdicts, and reviewer overrides

Findings & Remediation

Filter by severity, status, and assessment

Pushing Evidence In

Direct-write or push/match endpoints to attach files & JSON payloads from Okta, AWS, Power Automate, or any source system

api-example.js
const response = await fetch(
  "https://audigyd.com/api/v1/overview",
  {
    headers: {
      "X-API-Key": process.env.AUDIGYD_KEY,
    },
  }
);

const { data } = await response.json();

console.log("Assessments:", data.assessments.total);
console.log("Open findings:", data.findings.by_status.open);
console.log("Critical:", data.findings.by_severity.critical);

Rate limits & retries

Limits are intentionally generous — they exist to catch runaway scripts and accidental loops, not to throttle real workloads. When you do hit one, we tell you exactly when to come back.

What the limits look like

  • Global baseline: 300 requests / minute, scoped per IP. Sized so normal integration traffic never trips it.
  • AI-powered routes (template generation, copilot, PII detection): 20 requests / minute, scoped per authenticated user (or per IP if unauthenticated).
  • File uploads: 30 requests / minute per user.
  • Tenant creation: 10 requests / minute per IP.
  • Auth, CRUD, reports, analytics: no per-route cap beyond the global baseline.

The global baseline and tenant-creation limiters are keyed per IP. The stricter AI and file-upload limiters are keyed per authenticated user (so teams behind a shared NAT or VPN aren't bucketed together) and fall back to IP for unauthenticated calls. Stripe and Azure malware-scan webhook callbacks plus the health check are excluded entirely.

Each limit uses a fixed one-minute window: short bursts are fine until you've used your minute's quota, after which further requests get a 429 with Retry-After set to the seconds remaining until the window resets.

The 429 response

Exceeding a limit always returns a JSON 429 Too Many Requests with standard rate-limit headers and a Retry-After value (in seconds) telling you exactly when to try again.

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 27
RateLimit-Limit: 300
RateLimit-Remaining: 0
RateLimit-Reset: 27

{
  "error": "Too many requests. Please try again later.",
  "retryAfter": "27"
}
1. Respect Retry-After

Always pause for at least the seconds advertised in Retry-After before retrying. The standard RateLimit-Reset header carries the same value.

2. Exponential backoff with jitter

If you also see transient 5xx responses, back off exponentially (e.g. 1s, 2s, 4s, 8s, capped at ~60s) and add a small random jitter so retries don't synchronise across workers.

3. Retry safely

GET requests are always safe to retry. For POST evidence pushes, treat retries as idempotent by reusing the same title + source + collected_at so accidental duplicates can be reconciled. Webhook deliveries (e.g. evidence.added) follow the same retry-with-backoff pattern from our side.

NEW

Pushing Evidence In

AUDIGYD provides the pipe; you own the relationship with your source systems. Push evidence from Okta, AWS, Jamf, Power Automate, or any tool — no third-party credentials stored in AUDIGYD.

POST/v1/assessments/:id/questions/:qid/evidence

Direct write

Attach a file (multipart, up to 100MB) or a structured JSON payload (up to 1MB) to a specific question when your integration knows the AUDIGYD IDs.

  • Tenant-isolated, runs files through the same malware scan as in-app uploads
  • Requires assessments:write scope
  • Optional result badge: pass · fail · info
POST/v1/assessments/:id/evidence/push

Push / match

Send a control_ref + question_match hint and let AUDIGYD find the right question by name — perfect for Power Automate, n8n, and cron jobs that don't know internal IDs.

  • Single match attaches automatically; ambiguous matches return candidates
  • Set allow_multiple: true to broadcast to every match (capped at 25)
  • Fires the evidence.added webhook once per question

Use case examples

Power Automate
Method:  POST
URL:     https://audigyd.com
         /api/v1/assessments
         /@{variables('id')}
         /evidence/push
Headers:
  X-API-Key: @{secrets('AUDIGYD')}
  Content-Type: application/json
Body:
{
  "control_ref": "Access Control",
  "question_match": "MFA admin",
  "title": "Okta @{utcNow()}",
  "source": "okta",
  "result": "pass",
  "payload":
    @{outputs('Get_Okta')?['body']}
}
push-evidence.sh
#!/usr/bin/env bash
set -euo pipefail

# Required positional args:
#   $1 = AUDIGYD assessment ID
#   $2 = AUDIGYD question ID (find via
#        GET /v1/assessments/:id/questions)
#   $3 = path to file to upload
ASSESSMENT_ID="$1"
QUESTION_ID="$2"
EVIDENCE_FILE="$3"

curl -fsS \
  -H "X-API-Key: $AUDIGYD_KEY" \
  -F "file=@${EVIDENCE_FILE}" \
  -F "source=jamf-export" \
  -F "collected_at=$(date -u +%FT%TZ)" \
  -F "result=pass" \
  "https://audigyd.com/api/v1/assessments\
/${ASSESSMENT_ID}/questions\
/${QUESTION_ID}/evidence"
push_evidence.py
import os, json, requests

API_KEY = os.environ["AUDIGYD_KEY"]
AID = os.environ["AUDIGYD_ASSESSMENT_ID"]

resp = requests.post(
    f"https://audigyd.com/api/v1"
    f"/assessments/{AID}/evidence/push",
    headers={
        "X-API-Key": API_KEY,
        "Content-Type": "application/json",
    },
    data=json.dumps({
        "control_ref": "Logging",
        "question_match": "centralized",
        "title": "CloudTrail status",
        "source": "aws",
        "result": "pass",
        "payload": {
            "multi_region": True,
            "log_file_validation": True,
        },
    }),
    timeout=30,
)
resp.raise_for_status()
print(resp.json())
Scope
assessments:write

Create the API key with this scope from Settings → API Keys.

Webhook event
evidence.added

Fires once per question with evidence_id, source, result, collected_at.

Safety

Pushes to finalized/archived assessments are rejected with 409; cross-tenant pushes return 404.

Built for Enterprise Workflows

Integrate AUDIGYD into the tools your team already uses.

Power BI

Build rich compliance dashboards with scheduled refresh

Power Automate

Trigger flows on findings, route to Teams or Jira

Custom Dashboards

React, Vue, or any frontend with our JSON API

AI Assistants

Ask Claude about your compliance posture via MCP

Ready to start building?

Explore the full API reference, webhook event catalog, and MCP setup guide in our developer documentation.