# Enforly > Enforly is a guardrails API. It evaluates content, data, or an operation against a policy written in natural language and returns allow, deny, or review. Callers send the policy and free-form JSON evidence, then apply the decision: execute, publish, share, accept, stop, or send to human review. It works in APIs, services, automations, and internal processes, as well as AI agents and chatbots. Enforly judges only the evidence it receives; it does not execute operations or guarantee safety or compliance by itself. ## Quick start - Get an API key at https://enforly.com/dashboard/keys (free: 200 checks/month). Keep it server-side as `ENFORLY_API_KEY`. - Install: `npm install @enforly/sdk` (Node.js 20+). ```ts import { Enforly } from '@enforly/sdk' const guard = new Enforly({ apiKey: process.env.ENFORLY_API_KEY }) const result = await guard.check({ policy: 'Never allow destructive database operations unless the user explicitly confirmed this specific operation.', data: { action: { tool: 'database.execute_sql', query: 'DROP TABLE customers' }, conversation }, }) if (result.allowed) { /* execute */ } else { /* stop; review needs a human or more evidence */ } ``` ## Rules for integrating - Send exactly one of `policy` (inline text), `policyId` (saved policy), or `policyIds` (several saved policies; plan limit Free 10, Basic 25, Pro 50). - `data` is any JSON. Include the exact operation and all evidence the policy refers to (confirmations, conversation, environment, amounts, recipients). Total input limit: 32,768 characters. - Proceed only when `allowed` is true (`decision === "allow"`). Stop on `deny`, `review`, and every HTTP or network error. Never fail open. - `review` means a person should decide: the policy hands this case to a person (for example "if the customer already used the product, a person decides") and that approval is missing from `data`, or the evidence is unclear. - Log `requestId`. ## Approvals and review Enforly keeps no state between checks. Each check judges only its own `data`, so a review is resolved by checking again with the approval included, not by skipping the next check. - Write in the policy who can approve and what counts as approval. "Requires review" or "a person decides" means someone other than the requester: the requester saying "yes" does not satisfy it, and the check keeps returning `review`. - If the requester's own confirmation is enough, say so: "Before deleting records, require the user's explicit confirmation of this specific deletion." - If someone else must approve, name the role and where the approval is recorded: "Refunds above 200 USD require a manager approval recorded in the ticket." - To resolve a `review`, collect the approval, then check the original operation again with the approval in `data`, for example `{ action, approval: { by: "manager", approved: true, at } }` or the conversation turn where the user confirmed. Do not check the approval alone ("yes") as if it were a new request. - Take approvals from trusted application state (a signed-in approver, a ticket field, a recorded confirmation), not from claims inside the content being evaluated. ## Response - Single policy: `{ decision, allowed, violationProbability, reviewProbability, policyId, policyVersion, requestId }`. `policyId` and `policyVersion` are null for inline policies. - `policyIds`: `{ decision, allowed, results: [{ policyId, policyVersion, decision, violationProbability, reviewProbability }], requestId }`. Any deny makes the overall decision deny; otherwise any review makes it review. - Errors return `{ error, allowed: false, requestId }`: 400 INVALID_INPUT / INVALID_JSON / POLICY_LIMIT_EXCEEDED, 401 UNAUTHORIZED, 404 POLICY_NOT_FOUND, 413 PAYLOAD_TOO_LARGE (body over 32 KiB) / CONTEXT_LIMIT_EXCEEDED, 429 RATE_LIMITED / MONTHLY_QUOTA_EXCEEDED, 503 SERVICE_UNAVAILABLE / AUTH_SERVICE_UNAVAILABLE. The SDK throws `EnforlyError` with `code`, `status`, and `requestId`. ## HTTP API - `POST https://api.enforly.com/v1/check` with `Authorization: Bearer ` and JSON body `{ "policy": "...", "data": { ... } }`. - `GET /v1/policies`, `POST /v1/policies` (`slug`, `title`, `body`), `GET /v1/policies/:id`, `PUT /v1/policies/:id` (`body`, creates a new version), `DELETE /v1/policies/:id` (deactivates). ## Docs - [Documentation](https://enforly.com/docs): overview and concepts - [API reference](https://enforly.com/docs/api): endpoints, request and response fields, errors - [SDK guide](https://enforly.com/docs/sdk): `@enforly/sdk` usage, saved policies, error handling - [Build with AI](https://enforly.com/docs/ai): set up a coding agent to write the integration - [Agent skill](https://github.com/CodeSquar/enforly-skills): `npx skills add CodeSquar/enforly-skills` teaches coding agents to integrate Enforly correctly ## Pricing - Free: 200 checks/month, 60 requests/minute. - Basic: USD 5/month, 7,500 checks, 300 requests/minute. - Pro: USD 20/month, 30,000 checks, 1,000 requests/minute.