API Reference
The PolicifyAI REST API lets you generate and retrieve compliance policies programmatically. Use it to automate policy creation for your clients, embed live policy content in your applications, or integrate into your CI/CD pipeline.
Authentication
All API endpoints require a Bearer token in the Authorization header. Two key formats are supported:
Create named keys from Dashboard → Integrations (any paid plan), or Agency Hub → API & Webhooks on agency plans. Each key has configurable scopes (read, write, webhooks) and, on agency plans, can optionally be scoped to a single client.
The original embed key. Still supported but will be removed in a future version. Migrate to named API keys.
Authorization: Bearer pak_live_abc123def456...
Endpoints
/api/v1/policies/generateGenerate a compliance policy for a client. Policies are generated by AI, scored for quality, and saved to your account.
Request body (JSON)
policy_typerequiredstringPolicy slug. E.g. privacy-policy, terms-of-service, cookie-policy, data-processing-agreementjurisdictionrequiredstringISO country / region code. E.g. GB, US-CA, EU, DE, AUlanguagestringISO 639-1 language code (default: en). E.g. de, fr, es, nlbusiness_namestringClient business name to embed in the policy.domainstringClient website URL, e.g. https://acme.comindustrystringIndustry category, e.g. e-commerce, saas, healthcarebusiness_typestringLegal structure, e.g. limited-company, corporation, gmbhResponse
{
"id": "3f4a9b12-...",
"policy_type": "privacy-policy",
"jurisdiction": "GB",
"language": "en",
"content": "## Privacy Policy\n\nThis Privacy Policy...",
"created_at": "2026-05-26T14:30:00.000Z"
}Example request
curl -X POST https://policifyai.com/api/v1/policies/generate \
-H "Authorization: Bearer pak_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"policy_type": "privacy-policy",
"jurisdiction": "GB",
"language": "en",
"business_name": "Acme Corp",
"domain": "https://acme.com",
"industry": "e-commerce",
"business_type": "limited-company"
}'Bulk generation
/api/v1/policies/bulkGenerate up to 20 policies in one request. Items are generated until your plan's remaining quota for the batch is used up - any beyond that are returned with status skipped. Limited to 5 requests/minute and 20 batches/day per key.
curl -X POST https://policifyai.com/api/v1/policies/bulk \
-H "Authorization: Bearer pak_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "policy_type": "privacy-policy", "jurisdiction": "GB", "business_name": "Acme Corp" },
{ "policy_type": "cookie-policy", "jurisdiction": "GB", "business_name": "Acme Corp" },
{ "policy_type": "terms-of-service","jurisdiction": "US-CA", "business_name": "Acme Corp" }
]
}'Response
{
"batch_id": "batch_xyz",
"total": 3,
"created": 3,
"failed": 0,
"results": [
{ "id": "pol_...", "policy_type": "privacy-policy", "status": "created" }
]
}MCP - Connect Claude
PolicifyAI is also an MCP (Model Context Protocol) server, so you can connect Claude - or any MCP client - and generate policies straight from a conversation. Add a custom connector pointing at the endpoint below, authenticated with your API key.
https://policifyai.com/api/mcpIn Claude Desktop or claude.ai → Settings → Connectors → Add custom connector:
{
"mcpServers": {
"policifyai": {
"url": "https://policifyai.com/api/mcp",
"headers": { "Authorization": "Bearer pak_live_YOUR_KEY" }
}
}
}Exposes a generate_policy tool. Generations count against your normal quota and fire the same webhooks as the REST API.
Embed API
The embed API allows you to fetch live policy content for display on client websites. Responses are cached at the CDN edge for 5 minutes.
/api/embed/policyFetch a live policy by site key and type. No auth required - use from client-side JS.
Query parameters
siteKeyrequiredstringYour site key (pk_*) from Dashboard → API & Webhooks.typerequiredstringPolicy type slug. Use hub to list all policies.GET /api/embed/policy?siteKey=pk_abc123&type=privacy-policy
Embed widget (recommended)
For most use cases, use the embed script instead of calling the API directly. It auto-detects the policy type from the page URL and handles rendering.
<!-- Add once in your <head> or at the bottom of <body> --> <script src="https://policifyai.com/embed.js" data-site-key="pk_YOUR_KEY" ></script> <!-- Or force a specific policy type --> <script src="https://policifyai.com/embed.js" data-site-key="pk_YOUR_KEY" data-policy="privacy-policy" data-theme="light" data-container="my-policy-div" ></script>
Webhooks
Configure webhooks to receive real-time events when policies are published, updated, or deleted, and when compliance activity happens across your workspace.
Available events
policy.publishedFired when a policy is published to a live URLpolicy.updatedFired when a policy is regenerated or editedpolicy.deletedFired when a policy is deletedconsent.recordedFired when a visitor records a cookie/consent choicedsar.submittedFired when a data subject access request is submittedcookie_scan.completedFired when a compliance scanner scan finishesintegration.connectedFired when an integration (e.g. WordPress, Shopify) is connectedintegration.disconnectedFired when an integration is disconnectedPayload format
{
"event": "policy.published",
"policy_id": "3f4a9b12-...",
"policy_type": "privacy-policy",
"brand_name": "Acme Corp",
"jurisdiction": "GB",
"language": "en",
"user_id": "user_id_here",
"timestamp": "2026-05-26T14:30:00.000Z"
}Signature verification
Every webhook request includes an X-PolicifyAI-Signature header - the HMAC-SHA256 hex digest of the raw body. The same digest is also sent prefixed, as X-PolicifyAI-Signature-256 (sha256=<hex>). Verify either one to confirm the request came from PolicifyAI:
// Node.js / Express
const crypto = require('crypto');
// Use the RAW body - re-serialising req.body will not byte-match what we signed.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
const received = req.headers['x-policifyai-signature'] || '';
const ok = received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!ok) {
return res.status(401).send('Unauthorized');
}
// Process event
const { event, policy_id } = JSON.parse(req.body.toString());
console.log('Received:', event, policy_id);
res.status(200).send('ok');
});Supported policy types
These are the most common slugs. The full list of 90+ policy types is available in the dashboard policy generator.
privacy-policycookie-policyterms-of-serviceterms-and-conditionsdata-processing-agreementimprintreturn-policyrefund-policydisclaimeracceptable-use-policyend-user-license-agreementshipping-policyccpa-noticegdpr-policydsar-policyJurisdiction codes
Use standard ISO 3166-1 alpha-2 country codes, or ISO 3166-2 for US states. The API supports 180 jurisdictions.
GBUnited KingdomUSUnited States (federal)US-CACalifornia (CCPA)EUEuropean Union (GDPR)DEGermanyFRFranceAUAustraliaCACanadaNLNetherlandsSESwedenNONorwaySGSingaporeError codes
Bad Request
Missing or invalid request parameters
Unauthorized
Missing, invalid, or revoked API key
Payment Required
Subscription expired or inactive
Forbidden
API key lacks required scope, or plan does not include API access
Not Found
Policy, client, or resource not found
Too Many Requests
Rate limit exceeded - wait and retry
Server Error
Internal error - generation may be retried
Support
Need help with the API? Contact us at [email protected] or open a request from your dashboard.