diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..540df44
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+# OS
+Thumbs.db
+.DS_Store
+
+# Editors
+.vs/
+.vscode/
+.idea/
+.fleet/
+.zed/
+
+# Generated
+*.pem
+*.backup
+coverage/
+
+# Output
+dist/
+build/
+output/
+
+# Environment
+.env*
+!.env.example
+
+# Logs
+logs/
+*.log
+*.log*
+
+# Other
+.ignore*/
+LLM.md
diff --git a/LICENSE b/LICENSE.txt
similarity index 95%
rename from LICENSE
rename to LICENSE.txt
index 5411374..93dd471 100644
--- a/LICENSE
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2023 Mintlify
+Copyright (c) 2025 Nvisy Redaction Software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
+SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..84bedfb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,36 @@
+# Makefile for docs.nvisy.com
+
+# Pretty output logging.
+define print-make
+@echo "[$(shell date '+%Y-%m-%d %H:%M:%S')] [MAKE] [$(MAKECMDGOALS)] $(1)"
+endef
+
+.PHONY: install
+install:
+ $(call print-make, "Installing Mintlify CLI...")
+ npm i -g mint
+ $(call print-make, "Mintlify CLI installed!")
+ mint version
+
+.PHONY: dev
+dev:
+ $(call print-make, "Checking Mintlify CLI...")
+ mint version
+ $(call print-make, "Running Mintlify CLI...")
+ mint dev
+
+.PHONY: check
+check:
+ $(call print-make, "Checking Mintlify CLI...")
+ mint version
+ $(call print-make, "Checking if an OpenAPI spec is valid...")
+ mint openapi-check
+ $(call print-make, "Checking for invalid internal links...")
+ mint broken-links
+
+.PHONY: update
+update:
+ mint version
+ $(call print-make, "Updating Mintlify CLI...")
+ mint update
+ $(call print-make, "Mintlify CLI updated!")
diff --git a/README.md b/README.md
deleted file mode 100644
index 055c983..0000000
--- a/README.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# Mintlify Starter Kit
-
-Use the starter kit to get your docs deployed and ready to customize.
-
-Click the green **Use this template** button at the top of this repo to copy the Mintlify starter kit. The starter kit contains examples with
-
-- Guide pages
-- Navigation
-- Customizations
-- API reference pages
-- Use of popular components
-
-**[Follow the full quickstart guide](https://starter.mintlify.com/quickstart)**
-
-## Development
-
-Install the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview your documentation changes locally. To install, use the following command:
-
-```
-npm i -g mint
-```
-
-Run the following command at the root of your documentation, where your `docs.json` is located:
-
-```
-mint dev
-```
-
-View your local preview at `http://localhost:3000`.
-
-## Publishing changes
-
-Install our GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app) to propagate changes from your repo to your deployment. Changes are deployed to production automatically after pushing to the default branch.
-
-## Need help?
-
-### Troubleshooting
-
-- If your dev environment isn't running: Run `mint update` to ensure you have the most recent version of the CLI.
-- If a page loads as a 404: Make sure you are running in a folder with a valid `docs.json`.
-
-### Resources
-- [Mintlify documentation](https://mintlify.com/docs)
diff --git a/ai-tools/claude-code.mdx b/ai-tools/claude-code.mdx
deleted file mode 100644
index bdc4e04..0000000
--- a/ai-tools/claude-code.mdx
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: "Claude Code setup"
-description: "Configure Claude Code for your documentation workflow"
-icon: "asterisk"
----
-
-Claude Code is Anthropic's official CLI tool. This guide will help you set up Claude Code to help you write and maintain your documentation.
-
-## Prerequisites
-
-- Active Claude subscription (Pro, Max, or API access)
-
-## Setup
-
-1. Install Claude Code globally:
-
- ```bash
- npm install -g @anthropic-ai/claude-code
-```
-
-2. Navigate to your docs directory.
-3. (Optional) Add the `CLAUDE.md` file below to your project.
-4. Run `claude` to start.
-
-## Create `CLAUDE.md`
-
-Create a `CLAUDE.md` file at the root of your documentation repository to train Claude Code on your specific documentation standards:
-
-````markdown
-# Mintlify documentation
-
-## Working relationship
-- You can push back on ideas-this can lead to better documentation. Cite sources and explain your reasoning when you do so
-- ALWAYS ask for clarification rather than making assumptions
-- NEVER lie, guess, or make up information
-
-## Project context
-- Format: MDX files with YAML frontmatter
-- Config: docs.json for navigation, theme, settings
-- Components: Mintlify components
-
-## Content strategy
-- Document just enough for user success - not too much, not too little
-- Prioritize accuracy and usability of information
-- Make content evergreen when possible
-- Search for existing information before adding new content. Avoid duplication unless it is done for a strategic reason
-- Check existing patterns for consistency
-- Start by making the smallest reasonable changes
-
-## Frontmatter requirements for pages
-- title: Clear, descriptive page title
-- description: Concise summary for SEO/navigation
-
-## Writing standards
-- Second-person voice ("you")
-- Prerequisites at start of procedural content
-- Test all code examples before publishing
-- Match style and formatting of existing pages
-- Include both basic and advanced use cases
-- Language tags on all code blocks
-- Alt text on all images
-- Relative paths for internal links
-
-## Git workflow
-- NEVER use --no-verify when committing
-- Ask how to handle uncommitted changes before starting
-- Create a new branch when no clear branch exists for changes
-- Commit frequently throughout development
-- NEVER skip or disable pre-commit hooks
-
-## Do not
-- Skip frontmatter on any MDX file
-- Use absolute URLs for internal links
-- Include untested code examples
-- Make assumptions - always ask for clarification
-````
diff --git a/ai-tools/cursor.mdx b/ai-tools/cursor.mdx
deleted file mode 100644
index fbb7761..0000000
--- a/ai-tools/cursor.mdx
+++ /dev/null
@@ -1,420 +0,0 @@
----
-title: "Cursor setup"
-description: "Configure Cursor for your documentation workflow"
-icon: "arrow-pointer"
----
-
-Use Cursor to help write and maintain your documentation. This guide shows how to configure Cursor for better results on technical writing tasks and using Mintlify components.
-
-## Prerequisites
-
-- Cursor editor installed
-- Access to your documentation repository
-
-## Project rules
-
-Create project rules that all team members can use. In your documentation repository root:
-
-```bash
-mkdir -p .cursor
-```
-
-Create `.cursor/rules.md`:
-
-````markdown
-# Mintlify technical writing rule
-
-You are an AI writing assistant specialized in creating exceptional technical documentation using Mintlify components and following industry-leading technical writing practices.
-
-## Core writing principles
-
-### Language and style requirements
-
-- Use clear, direct language appropriate for technical audiences
-- Write in second person ("you") for instructions and procedures
-- Use active voice over passive voice
-- Employ present tense for current states, future tense for outcomes
-- Avoid jargon unless necessary and define terms when first used
-- Maintain consistent terminology throughout all documentation
-- Keep sentences concise while providing necessary context
-- Use parallel structure in lists, headings, and procedures
-
-### Content organization standards
-
-- Lead with the most important information (inverted pyramid structure)
-- Use progressive disclosure: basic concepts before advanced ones
-- Break complex procedures into numbered steps
-- Include prerequisites and context before instructions
-- Provide expected outcomes for each major step
-- Use descriptive, keyword-rich headings for navigation and SEO
-- Group related information logically with clear section breaks
-
-### User-centered approach
-
-- Focus on user goals and outcomes rather than system features
-- Anticipate common questions and address them proactively
-- Include troubleshooting for likely failure points
-- Write for scannability with clear headings, lists, and white space
-- Include verification steps to confirm success
-
-## Mintlify component reference
-
-### Callout components
-
-#### Note - Additional helpful information
-
-
-Supplementary information that supports the main content without interrupting flow
-
-
-#### Tip - Best practices and pro tips
-
-
-Expert advice, shortcuts, or best practices that enhance user success
-
-
-#### Warning - Important cautions
-
-
-Critical information about potential issues, breaking changes, or destructive actions
-
-
-#### Info - Neutral contextual information
-
-
-Background information, context, or neutral announcements
-
-
-#### Check - Success confirmations
-
-
-Positive confirmations, successful completions, or achievement indicators
-
-
-### Code components
-
-#### Single code block
-
-Example of a single code block:
-
-```javascript config.js
-const apiConfig = {
- baseURL: 'https://api.example.com',
- timeout: 5000,
- headers: {
- 'Authorization': `Bearer ${process.env.API_TOKEN}`
- }
-};
-```
-
-#### Code group with multiple languages
-
-Example of a code group:
-
-
-```javascript Node.js
-const response = await fetch('/api/endpoint', {
- headers: { Authorization: `Bearer ${apiKey}` }
-});
-```
-
-```python Python
-import requests
-response = requests.get('/api/endpoint',
- headers={'Authorization': f'Bearer {api_key}'})
-```
-
-```curl cURL
-curl -X GET '/api/endpoint' \
- -H 'Authorization: Bearer YOUR_API_KEY'
-```
-
-
-#### Request/response examples
-
-Example of request/response documentation:
-
-
-```bash cURL
-curl -X POST 'https://api.example.com/users' \
- -H 'Content-Type: application/json' \
- -d '{"name": "John Doe", "email": "john@example.com"}'
-```
-
-
-
-```json Success
-{
- "id": "user_123",
- "name": "John Doe",
- "email": "john@example.com",
- "created_at": "2024-01-15T10:30:00Z"
-}
-```
-
-
-### Structural components
-
-#### Steps for procedures
-
-Example of step-by-step instructions:
-
-
-
- Run `npm install` to install required packages.
-
-
- Verify installation by running `npm list`.
-
-
-
-
- Create a `.env` file with your API credentials.
-
- ```bash
- API_KEY=your_api_key_here
- ```
-
-
- Never commit API keys to version control.
-
-
-
-
-#### Tabs for alternative content
-
-Example of tabbed content:
-
-
-
- ```bash
- brew install node
- npm install -g package-name
- ```
-
-
-
- ```powershell
- choco install nodejs
- npm install -g package-name
- ```
-
-
-
- ```bash
- sudo apt install nodejs npm
- npm install -g package-name
- ```
-
-
-
-#### Accordions for collapsible content
-
-Example of accordion groups:
-
-
-
- - **Firewall blocking**: Ensure ports 80 and 443 are open
- - **Proxy configuration**: Set HTTP_PROXY environment variable
- - **DNS resolution**: Try using 8.8.8.8 as DNS server
-
-
-
- ```javascript
- const config = {
- performance: { cache: true, timeout: 30000 },
- security: { encryption: 'AES-256' }
- };
- ```
-
-
-
-### Cards and columns for emphasizing information
-
-Example of cards and card groups:
-
-
-Complete walkthrough from installation to your first API call in under 10 minutes.
-
-
-
-
- Learn how to authenticate requests using API keys or JWT tokens.
-
-
-
- Understand rate limits and best practices for high-volume usage.
-
-
-
-### API documentation components
-
-#### Parameter fields
-
-Example of parameter documentation:
-
-
-Unique identifier for the user. Must be a valid UUID v4 format.
-
-
-
-User's email address. Must be valid and unique within the system.
-
-
-
-Maximum number of results to return. Range: 1-100.
-
-
-
-Bearer token for API authentication. Format: `Bearer YOUR_API_KEY`
-
-
-#### Response fields
-
-Example of response field documentation:
-
-
-Unique identifier assigned to the newly created user.
-
-
-
-ISO 8601 formatted timestamp of when the user was created.
-
-
-
-List of permission strings assigned to this user.
-
-
-#### Expandable nested fields
-
-Example of nested field documentation:
-
-
-Complete user object with all associated data.
-
-
-
- User profile information including personal details.
-
-
-
- User's first name as entered during registration.
-
-
-
- URL to user's profile picture. Returns null if no avatar is set.
-
-
-
-
-
-
-### Media and advanced components
-
-#### Frames for images
-
-Wrap all images in frames:
-
-
-
-
-
-
-
-
-
-#### Videos
-
-Use the HTML video element for self-hosted video content:
-
-
-
-Embed YouTube videos using iframe elements:
-
-
-
-#### Tooltips
-
-Example of tooltip usage:
-
-
-API
-
-
-#### Updates
-
-Use updates for changelogs:
-
-
-## New features
-- Added bulk user import functionality
-- Improved error messages with actionable suggestions
-
-## Bug fixes
-- Fixed pagination issue with large datasets
-- Resolved authentication timeout problems
-
-
-## Required page structure
-
-Every documentation page must begin with YAML frontmatter:
-
-```yaml
----
-title: "Clear, specific, keyword-rich title"
-description: "Concise description explaining page purpose and value"
----
-```
-
-## Content quality standards
-
-### Code examples requirements
-
-- Always include complete, runnable examples that users can copy and execute
-- Show proper error handling and edge case management
-- Use realistic data instead of placeholder values
-- Include expected outputs and results for verification
-- Test all code examples thoroughly before publishing
-- Specify language and include filename when relevant
-- Add explanatory comments for complex logic
-- Never include real API keys or secrets in code examples
-
-### API documentation requirements
-
-- Document all parameters including optional ones with clear descriptions
-- Show both success and error response examples with realistic data
-- Include rate limiting information with specific limits
-- Provide authentication examples showing proper format
-- Explain all HTTP status codes and error handling
-- Cover complete request/response cycles
-
-### Accessibility requirements
-
-- Include descriptive alt text for all images and diagrams
-- Use specific, actionable link text instead of "click here"
-- Ensure proper heading hierarchy starting with H2
-- Provide keyboard navigation considerations
-- Use sufficient color contrast in examples and visuals
-- Structure content for easy scanning with headers and lists
-
-## Component selection logic
-
-- Use **Steps** for procedures and sequential instructions
-- Use **Tabs** for platform-specific content or alternative approaches
-- Use **CodeGroup** when showing the same concept in multiple programming languages
-- Use **Accordions** for progressive disclosure of information
-- Use **RequestExample/ResponseExample** specifically for API endpoint documentation
-- Use **ParamField** for API parameters, **ResponseField** for API responses
-- Use **Expandable** for nested object properties or hierarchical information
-````
diff --git a/ai-tools/windsurf.mdx b/ai-tools/windsurf.mdx
deleted file mode 100644
index fce12bf..0000000
--- a/ai-tools/windsurf.mdx
+++ /dev/null
@@ -1,96 +0,0 @@
----
-title: "Windsurf setup"
-description: "Configure Windsurf for your documentation workflow"
-icon: "water"
----
-
-Configure Windsurf's Cascade AI assistant to help you write and maintain documentation. This guide shows how to set up Windsurf specifically for your Mintlify documentation workflow.
-
-## Prerequisites
-
-- Windsurf editor installed
-- Access to your documentation repository
-
-## Workspace rules
-
-Create workspace rules that provide Windsurf with context about your documentation project and standards.
-
-Create `.windsurf/rules.md` in your project root:
-
-````markdown
-# Mintlify technical writing rule
-
-## Project context
-
-- This is a documentation project on the Mintlify platform
-- We use MDX files with YAML frontmatter
-- Navigation is configured in `docs.json`
-- We follow technical writing best practices
-
-## Writing standards
-
-- Use second person ("you") for instructions
-- Write in active voice and present tense
-- Start procedures with prerequisites
-- Include expected outcomes for major steps
-- Use descriptive, keyword-rich headings
-- Keep sentences concise but informative
-
-## Required page structure
-
-Every page must start with frontmatter:
-
-```yaml
----
-title: "Clear, specific title"
-description: "Concise description for SEO and navigation"
----
-```
-
-## Mintlify components
-
-### Callouts
-
-- `` for helpful supplementary information
-- `` for important cautions and breaking changes
-- `` for best practices and expert advice
-- `` for neutral contextual information
-- `` for success confirmations
-
-### Code examples
-
-- When appropriate, include complete, runnable examples
-- Use `` for multiple language examples
-- Specify language tags on all code blocks
-- Include realistic data, not placeholders
-- Use `` and `` for API docs
-
-### Procedures
-
-- Use `` component for sequential instructions
-- Include verification steps with `` components when relevant
-- Break complex procedures into smaller steps
-
-### Content organization
-
-- Use `` for platform-specific content
-- Use `` for progressive disclosure
-- Use `` and `` for highlighting content
-- Wrap images in `` components with descriptive alt text
-
-## API documentation requirements
-
-- Document all parameters with ``
-- Show response structure with ``
-- Include both success and error examples
-- Use `` for nested object properties
-- Always include authentication examples
-
-## Quality standards
-
-- Test all code examples before publishing
-- Use relative paths for internal links
-- Include alt text for all images
-- Ensure proper heading hierarchy (start with h2)
-- Check existing patterns for consistency
-````
diff --git a/api-reference/endpoint/create.mdx b/api-reference/endpoint/create.mdx
deleted file mode 100644
index 5689f1b..0000000
--- a/api-reference/endpoint/create.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'Create Plant'
-openapi: 'POST /plants'
----
diff --git a/api-reference/endpoint/delete.mdx b/api-reference/endpoint/delete.mdx
deleted file mode 100644
index 657dfc8..0000000
--- a/api-reference/endpoint/delete.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'Delete Plant'
-openapi: 'DELETE /plants/{id}'
----
diff --git a/api-reference/endpoint/get.mdx b/api-reference/endpoint/get.mdx
deleted file mode 100644
index 56aa09e..0000000
--- a/api-reference/endpoint/get.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'Get Plants'
-openapi: 'GET /plants'
----
diff --git a/api-reference/endpoint/webhook.mdx b/api-reference/endpoint/webhook.mdx
deleted file mode 100644
index 3291340..0000000
--- a/api-reference/endpoint/webhook.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'New Plant'
-openapi: 'WEBHOOK /plant/webhook'
----
diff --git a/api-reference/introduction.mdx b/api-reference/introduction.mdx
index c835b78..978256e 100644
--- a/api-reference/introduction.mdx
+++ b/api-reference/introduction.mdx
@@ -1,33 +1,269 @@
---
-title: 'Introduction'
-description: 'Example section for showcasing API endpoints'
+title: 'API Reference'
+description: 'Complete REST API documentation for Nvisy document redaction'
---
-
- If you're not looking to build API reference documentation, you can delete
- this section by removing the api-reference folder.
-
+## Overview
-## Welcome
+The Nvisy REST API provides programmatic access to all document redaction features. Built on REST principles, the API uses standard HTTP methods, authentication, and status codes.
-There are two ways to build API documentation: [OpenAPI](https://mintlify.com/docs/api-playground/openapi/setup) and [MDX components](https://mintlify.com/docs/api-playground/mdx/configuration). For the starter kit, we are using the following OpenAPI specification.
-
-
- View the OpenAPI specification file
+
+ ```
+ https://api.nvisy.com/v1
+ ```
## Authentication
-All API endpoints are authenticated using Bearer tokens and picked up from the specification file.
+All API requests require authentication using Bearer tokens.
+
+### Get Your API Key
+
+1. Sign up at [nvisy.com](https://nvisy.com)
+2. Navigate to Settings → API Keys
+3. Generate a new API key
+
+### Using Your API Key
+
+Include your API key in the `Authorization` header:
+
+```bash
+curl https://api.nvisy.com/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -F "file=@document.pdf"
+```
+
+
+ Never expose your API key in client-side code or commit it to version control. Use environment variables or secure secret management.
+
+
+## Rate Limits
+
+API requests are rate-limited based on your plan:
+
+| Plan | Requests/Second | Daily Limit |
+|------|----------------|-------------|
+| Free | 10 | 100 |
+| Starter | 50 | 10,000 |
+| Pro | 200 | 100,000 |
+| Enterprise | Custom | Custom |
+
+### Rate Limit Headers
+
+Responses include rate limit information:
+
+```http
+X-RateLimit-Limit: 50
+X-RateLimit-Remaining: 45
+X-RateLimit-Reset: 1640995200
+```
+
+### Handling Rate Limits
+
+When rate limited, the API returns `429 Too Many Requests`:
+
+```json
+{
+ "error": {
+ "code": "rate_limit_exceeded",
+ "message": "Rate limit exceeded. Retry after 60 seconds.",
+ "retry_after": 60
+ }
+}
+```
+
+## Request Format
+
+All POST requests accept:
+- **Content-Type**: `multipart/form-data` for file uploads
+- **Content-Type**: `application/json` for JSON payloads
+
+### File Uploads
+
+```bash
+curl -X POST https://api.nvisy.com/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -F "file=@document.pdf" \
+ -F "detection_types=pii,phi" \
+ -F "confidence_threshold=0.8"
+```
+
+### JSON Payloads
+
+```bash
+curl -X POST https://api.nvisy.com/v1/webhooks \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "url": "https://your-app.com/webhooks",
+ "events": ["redaction.completed"]
+ }'
+```
+
+## Response Format
+
+All responses are JSON-encoded with standard HTTP status codes.
+
+### Success Response
+
+```json
+{
+ "document_id": "doc_abc123",
+ "status": "completed",
+ "detections": [...],
+ "created_at": "2024-01-15T10:30:00Z"
+}
+```
+
+### Error Response
```json
-"security": [
- {
- "bearerAuth": []
+{
+ "error": {
+ "code": "invalid_request",
+ "message": "Missing required parameter: detection_types",
+ "param": "detection_types"
}
-]
+}
```
+
+## HTTP Status Codes
+
+| Code | Description |
+|------|-------------|
+| `200` | Success |
+| `201` | Resource created |
+| `204` | Success with no content |
+| `400` | Bad request - invalid parameters |
+| `401` | Unauthorized - invalid API key |
+| `403` | Forbidden - insufficient permissions |
+| `404` | Not found |
+| `429` | Rate limit exceeded |
+| `500` | Internal server error |
+| `503` | Service unavailable |
+
+## Error Codes
+
+| Code | Description |
+|------|-------------|
+| `invalid_request` | Request has invalid parameters |
+| `invalid_api_key` | API key is invalid or expired |
+| `rate_limit_exceeded` | Too many requests |
+| `file_too_large` | Uploaded file exceeds size limit |
+| `unsupported_file_type` | File type not supported |
+| `processing_failed` | Document processing failed |
+| `insufficient_credits` | Account has insufficient credits |
+
+## Pagination
+
+List endpoints support pagination using `limit` and `offset` parameters:
+
+```bash
+curl "https://api.nvisy.com/v1/documents?limit=50&offset=0" \
+ -H "Authorization: Bearer YOUR_API_KEY"
+```
+
+Response includes pagination metadata:
+
+```json
+{
+ "data": [...],
+ "pagination": {
+ "total": 150,
+ "limit": 50,
+ "offset": 0,
+ "has_more": true
+ }
+}
+```
+
+## Idempotency
+
+POST requests support idempotency using the `Idempotency-Key` header:
+
+```bash
+curl -X POST https://api.nvisy.com/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -H "Idempotency-Key: unique-request-id" \
+ -F "file=@document.pdf"
+```
+
+The same key within 24 hours will return the cached response.
+
+## Webhooks
+
+Receive real-time notifications for events:
+
+```bash
+curl -X POST https://api.nvisy.com/v1/webhooks \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "url": "https://your-app.com/webhooks/nvisy",
+ "events": ["redaction.completed", "redaction.failed"]
+ }'
+```
+
+### Webhook Events
+
+- `redaction.completed` - Document redaction finished
+- `redaction.failed` - Document redaction failed
+- `document.uploaded` - Document uploaded
+- `document.deleted` - Document deleted
+
+### Webhook Signature Verification
+
+Verify webhook authenticity using the `X-Nvisy-Signature` header:
+
+```typescript
+import crypto from 'crypto';
+
+function verifyWebhook(payload, signature, secret) {
+ const hmac = crypto.createHmac('sha256', secret);
+ const digest = hmac.update(payload).digest('hex');
+ return crypto.timingSafeEqual(
+ Buffer.from(signature),
+ Buffer.from(digest)
+ );
+}
+```
+
+## Versioning
+
+The API is versioned via the URL path. The current version is `v1`.
+
+```
+https://api.nvisy.com/v1/documents/redact
+```
+
+We maintain backward compatibility within a version. Breaking changes will be introduced in new versions.
+
+## SDKs
+
+Use official SDKs for easier integration:
+
+
+
+ Node.js and browser support with full TypeScript types
+
+
+ Server-side Python applications
+
+
+
+## OpenAPI Specification
+
+
+ View the complete OpenAPI 3.0 specification
+
+
+## Support
+
+
+
+ View guides and tutorials
+
+
+ Report issues or contribute
+
+
diff --git a/api-reference/openapi.json b/api-reference/openapi.json
index da5326e..e01d968 100644
--- a/api-reference/openapi.json
+++ b/api-reference/openapi.json
@@ -1,16 +1,27 @@
{
- "openapi": "3.1.0",
+ "openapi": "3.0.0",
"info": {
- "title": "OpenAPI Plant Store",
- "description": "A sample API that uses a plant store as an example to demonstrate features in the OpenAPI specification",
- "license": {
- "name": "MIT"
+ "title": "Nvisy API",
+ "version": "1.0.0",
+ "description": "AI-powered document redaction API for enterprise-scale security and compliance",
+ "contact": {
+ "name": "Nvisy Support",
+ "email": "support@nvisy.com",
+ "url": "https://nvisy.com"
},
- "version": "1.0.0"
+ "license": {
+ "name": "MIT",
+ "url": "https://opensource.org/licenses/MIT"
+ }
},
"servers": [
{
- "url": "http://sandbox.mintlify.com"
+ "url": "https://api.nvisy.com/v1",
+ "description": "Production"
+ },
+ {
+ "url": "https://api.staging.nvisy.com/v1",
+ "description": "Staging"
}
],
"security": [
@@ -19,199 +30,416 @@
}
],
"paths": {
- "/plants": {
- "get": {
- "description": "Returns all plants from the system that the user has access to",
- "parameters": [
- {
- "name": "limit",
- "in": "query",
- "description": "The maximum number of results to return",
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "Plant response",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Plant"
- }
- }
- }
- }
- },
- "400": {
- "description": "Unexpected error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Error"
- }
- }
- }
- }
- }
- },
+ "/documents/redact": {
"post": {
- "description": "Creates a new plant in the store",
+ "summary": "Redact a document",
+ "description": "Upload and redact sensitive information from a document",
+ "operationId": "redactDocument",
+ "tags": ["Documents"],
"requestBody": {
- "description": "Plant to add to the store",
+ "required": true,
"content": {
- "application/json": {
+ "multipart/form-data": {
"schema": {
- "$ref": "#/components/schemas/NewPlant"
+ "type": "object",
+ "required": ["file"],
+ "properties": {
+ "file": {
+ "type": "string",
+ "format": "binary",
+ "description": "The document file to redact"
+ },
+ "detection_types": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": ["pii", "phi", "financial", "custom"]
+ },
+ "description": "Types of sensitive information to detect"
+ },
+ "confidence_threshold": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.8,
+ "description": "Minimum confidence score for detections"
+ },
+ "redaction_style": {
+ "type": "string",
+ "enum": ["black-box", "blur", "pixelate"],
+ "default": "black-box",
+ "description": "Visual style for redactions"
+ }
+ }
}
}
- },
- "required": true
+ }
},
"responses": {
"200": {
- "description": "plant response",
+ "description": "Document redacted successfully",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/Plant"
+ "$ref": "#/components/schemas/RedactionResult"
}
}
}
},
"400": {
- "description": "unexpected error",
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "429": {
+ "$ref": "#/components/responses/RateLimitExceeded"
+ }
+ }
+ }
+ },
+ "/documents/{documentId}": {
+ "get": {
+ "summary": "Get document details",
+ "description": "Retrieve information about a processed document",
+ "operationId": "getDocument",
+ "tags": ["Documents"],
+ "parameters": [
+ {
+ "name": "documentId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The document ID"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Document details",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/Error"
+ "$ref": "#/components/schemas/Document"
}
}
}
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
}
}
- }
- },
- "/plants/{id}": {
+ },
"delete": {
- "description": "Deletes a single plant based on the ID supplied",
+ "summary": "Delete a document",
+ "description": "Delete a document and all associated data",
+ "operationId": "deleteDocument",
+ "tags": ["Documents"],
"parameters": [
{
- "name": "id",
+ "name": "documentId",
"in": "path",
- "description": "ID of plant to delete",
"required": true,
"schema": {
- "type": "integer",
- "format": "int64"
- }
+ "type": "string"
+ },
+ "description": "The document ID"
}
],
"responses": {
"204": {
- "description": "Plant deleted",
- "content": {}
+ "description": "Document deleted successfully"
},
- "400": {
- "description": "unexpected error",
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ }
+ }
+ }
+ },
+ "/documents/{documentId}/download": {
+ "get": {
+ "summary": "Download redacted document",
+ "description": "Download the redacted version of a document",
+ "operationId": "downloadDocument",
+ "tags": ["Documents"],
+ "parameters": [
+ {
+ "name": "documentId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The document ID"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Redacted document file",
"content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Error"
- }
- }
+ "application/pdf": {},
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": {}
}
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
}
}
}
- }
- },
- "webhooks": {
- "/plant/webhook": {
+ },
+ "/webhooks": {
"post": {
- "description": "Information about a new plant added to the store",
+ "summary": "Create a webhook",
+ "description": "Register a webhook to receive redaction notifications",
+ "operationId": "createWebhook",
+ "tags": ["Webhooks"],
"requestBody": {
- "description": "Plant added to the store",
+ "required": true,
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/NewPlant"
+ "$ref": "#/components/schemas/WebhookCreate"
}
}
}
},
"responses": {
- "200": {
- "description": "Return a 200 status to indicate that the data was received successfully"
+ "201": {
+ "description": "Webhook created successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Webhook"
+ }
+ }
+ }
}
}
}
}
},
"components": {
+ "securitySchemes": {
+ "bearerAuth": {
+ "type": "http",
+ "scheme": "bearer",
+ "bearerFormat": "JWT",
+ "description": "API key authentication. Get your API key from the dashboard."
+ }
+ },
"schemas": {
- "Plant": {
- "required": [
- "name"
- ],
+ "RedactionResult": {
+ "type": "object",
+ "properties": {
+ "document_id": {
+ "type": "string",
+ "description": "Unique document identifier"
+ },
+ "status": {
+ "type": "string",
+ "enum": ["completed", "processing", "failed"],
+ "description": "Processing status"
+ },
+ "detections": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Detection"
+ }
+ },
+ "audit_trail": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AuditEntry"
+ }
+ },
+ "download_url": {
+ "type": "string",
+ "format": "uri",
+ "description": "Temporary URL to download redacted document"
+ }
+ }
+ },
+ "Detection": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Detection identifier"
+ },
+ "type": {
+ "type": "string",
+ "enum": ["pii", "phi", "financial", "custom"],
+ "description": "Type of sensitive information"
+ },
+ "confidence": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "description": "Confidence score"
+ },
+ "page": {
+ "type": "integer",
+ "description": "Page number where detected"
+ },
+ "text": {
+ "type": "string",
+ "description": "Detected text (masked)"
+ }
+ }
+ },
+ "Document": {
"type": "object",
"properties": {
- "name": {
- "description": "The name of the plant",
+ "id": {
"type": "string"
},
- "tag": {
- "description": "Tag to specify the type",
+ "filename": {
"type": "string"
+ },
+ "status": {
+ "type": "string",
+ "enum": ["completed", "processing", "failed"]
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "detections_count": {
+ "type": "integer"
}
}
},
- "NewPlant": {
- "allOf": [
- {
- "$ref": "#/components/schemas/Plant"
+ "AuditEntry": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
},
- {
- "required": [
- "id"
- ],
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "action": {
+ "type": "string"
+ },
+ "user": {
"type": "object",
"properties": {
"id": {
- "description": "Identification number of the plant",
- "type": "integer",
- "format": "int64"
+ "type": "string"
+ },
+ "email": {
+ "type": "string",
+ "format": "email"
}
}
}
- ]
+ }
},
- "Error": {
- "required": [
- "error",
- "message"
- ],
+ "WebhookCreate": {
"type": "object",
+ "required": ["url", "events"],
"properties": {
- "error": {
- "type": "integer",
- "format": "int32"
+ "url": {
+ "type": "string",
+ "format": "uri",
+ "description": "Webhook endpoint URL"
},
- "message": {
+ "events": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": ["redaction.completed", "redaction.failed", "document.uploaded"]
+ },
+ "description": "Events to subscribe to"
+ },
+ "secret": {
+ "type": "string",
+ "description": "Secret for signature verification"
+ }
+ }
+ },
+ "Webhook": {
+ "type": "object",
+ "properties": {
+ "id": {
"type": "string"
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ },
+ "events": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "Error": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
}
}
}
},
- "securitySchemes": {
- "bearerAuth": {
- "type": "http",
- "scheme": "bearer"
+ "responses": {
+ "BadRequest": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "Unauthorized": {
+ "description": "Unauthorized - Invalid or missing API key",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "NotFound": {
+ "description": "Resource not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "RateLimitExceeded": {
+ "description": "Rate limit exceeded",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
-}
\ No newline at end of file
+}
diff --git a/deployment/cloud/authentication.mdx b/deployment/cloud/authentication.mdx
new file mode 100644
index 0000000..66e3df4
--- /dev/null
+++ b/deployment/cloud/authentication.mdx
@@ -0,0 +1,324 @@
+---
+title: "Authentication"
+description: "Authenticate with the Nvisy cloud API"
+---
+
+## API Keys
+
+All Nvisy cloud API requests require authentication using API keys.
+
+## Getting Your API Key
+
+
+
+ Create an account at [nvisy.com](https://nvisy.com)
+
+
+ Navigate to your dashboard after logging in
+
+
+ Go to Settings → API Keys → Generate New Key
+
+
+ Copy the API key and store it securely (it won't be shown again)
+
+
+
+## Using API Keys
+
+### With cURL
+
+Include the API key in the `Authorization` header:
+
+```bash
+curl https://api.nvisy.com/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -F "file=@document.pdf" \
+ -F "detection_types=pii,phi"
+```
+
+### With TypeScript SDK
+
+```typescript
+import { NvisyClient } from '@nvisy/sdk';
+
+const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY
+});
+```
+
+### With Python SDK
+
+```python
+from nvisy import NvisyClient
+import os
+
+client = NvisyClient(
+ api_key=os.getenv('NVISY_API_KEY')
+)
+```
+
+## Environment Variables
+
+Store API keys in environment variables:
+
+
+
+```bash .env
+NVISY_API_KEY=nvsy_live_abc123...
+NVISY_ENVIRONMENT=production
+```
+
+```bash Shell
+export NVISY_API_KEY="nvsy_live_abc123..."
+export NVISY_ENVIRONMENT="production"
+```
+
+```yaml Docker Compose
+services:
+ app:
+ environment:
+ - NVISY_API_KEY=${NVISY_API_KEY}
+```
+
+```yaml Kubernetes
+apiVersion: v1
+kind: Secret
+metadata:
+ name: nvisy-credentials
+type: Opaque
+stringData:
+ api-key: nvsy_live_abc123...
+```
+
+
+
+
+ Never commit API keys to version control. Use environment variables or secret management systems.
+
+
+## API Key Types
+
+### Test Keys
+
+- Prefix: `nvsy_test_`
+- Use in development and testing
+- No charges applied
+- Limited to 100 requests/day
+
+### Live Keys
+
+- Prefix: `nvsy_live_`
+- Use in production
+- Usage is charged according to your plan
+- Higher rate limits
+
+## Key Management
+
+### Rotation
+
+Rotate API keys regularly for security:
+
+1. Generate new API key
+2. Update applications with new key
+3. Verify new key works
+4. Delete old key
+
+### Multiple Keys
+
+Use separate keys for different environments:
+
+- **Development**: `nvsy_test_dev_...`
+- **Staging**: `nvsy_test_staging_...`
+- **Production**: `nvsy_live_prod_...`
+
+### Permissions
+
+Configure key permissions (Enterprise plan):
+
+```json
+{
+ "key_id": "key_abc123",
+ "permissions": [
+ "documents:read",
+ "documents:redact",
+ "webhooks:create"
+ ],
+ "rate_limit": 100,
+ "expires_at": "2025-12-31"
+}
+```
+
+## Security Best Practices
+
+### 1. Use Environment Variables
+
+```typescript
+// ✓ Good
+const apiKey = process.env.NVISY_API_KEY;
+
+// ✗ Bad
+const apiKey = 'nvsy_live_abc123...';
+```
+
+### 2. Restrict API Keys
+
+- Use minimal required permissions
+- Set expiration dates
+- Rotate keys regularly
+- Use different keys per environment
+
+### 3. Secure Storage
+
+Use secret management systems:
+
+
+
+ ```typescript
+ import { SecretsManager } from '@aws-sdk/client-secrets-manager';
+
+ const client = new SecretsManager({ region: 'us-east-1' });
+ const response = await client.getSecretValue({
+ SecretId: 'nvisy-api-key'
+ });
+
+ const apiKey = response.SecretString;
+ ```
+
+
+
+ ```typescript
+ import vault from 'node-vault';
+
+ const client = vault({
+ endpoint: 'http://vault:8200',
+ token: process.env.VAULT_TOKEN
+ });
+
+ const { data } = await client.read('secret/nvisy');
+ const apiKey = data.api_key;
+ ```
+
+
+
+ ```typescript
+ import { SecretClient } from '@azure/keyvault-secrets';
+ import { DefaultAzureCredential } from '@azure/identity';
+
+ const client = new SecretClient(
+ 'https://my-vault.vault.azure.net',
+ new DefaultAzureCredential()
+ );
+
+ const secret = await client.getSecret('nvisy-api-key');
+ const apiKey = secret.value;
+ ```
+
+
+
+### 4. Monitor Usage
+
+Track API key usage in the dashboard:
+- Request volume
+- Error rates
+- Unusual patterns
+- Geographic distribution
+
+## Rate Limits
+
+Rate limits are enforced per API key:
+
+| Plan | Requests/Second | Daily Limit |
+|------|----------------|-------------|
+| Free | 10 | 100 |
+| Starter | 50 | 10,000 |
+| Pro | 200 | 100,000 |
+| Enterprise | Custom | Custom |
+
+### Rate Limit Headers
+
+Response headers indicate rate limit status:
+
+```http
+X-RateLimit-Limit: 50
+X-RateLimit-Remaining: 45
+X-RateLimit-Reset: 1640995200
+```
+
+### Handling Rate Limits
+
+```typescript
+import { RateLimitError } from '@nvisy/sdk';
+
+try {
+ const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii']
+ });
+} catch (error) {
+ if (error instanceof RateLimitError) {
+ const retryAfter = error.retryAfter;
+ console.log(`Rate limited. Retry after ${retryAfter} seconds`);
+
+ // Wait and retry
+ await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
+ // Retry request...
+ }
+}
+```
+
+## Troubleshooting
+
+### Invalid API Key
+
+```json
+{
+ "error": {
+ "code": "invalid_api_key",
+ "message": "The API key provided is invalid"
+ }
+}
+```
+
+**Solutions:**
+- Verify key is correct
+- Check for extra spaces or characters
+- Ensure key hasn't been deleted
+- Verify using the correct environment
+
+### Expired API Key
+
+```json
+{
+ "error": {
+ "code": "api_key_expired",
+ "message": "The API key has expired"
+ }
+}
+```
+
+**Solution:** Generate a new API key
+
+### Insufficient Permissions
+
+```json
+{
+ "error": {
+ "code": "insufficient_permissions",
+ "message": "API key does not have required permissions"
+ }
+}
+```
+
+**Solution:** Use a key with appropriate permissions or request access
+
+## Next Steps
+
+
+
+ Start using Nvisy cloud
+
+
+ Your first redaction
+
+
diff --git a/deployment/cloud/getting-started.mdx b/deployment/cloud/getting-started.mdx
new file mode 100644
index 0000000..90dec79
--- /dev/null
+++ b/deployment/cloud/getting-started.mdx
@@ -0,0 +1,229 @@
+---
+title: "Cloud Deployment"
+description: "Deploy Nvisy using our fully managed cloud service"
+---
+
+Deploy Nvisy in minutes using our fully managed cloud service. No infrastructure setup required—just sign up, get your API key, and start redacting documents.
+
+## Quick Start
+
+
+
+ Create a Nvisy account at [nvisy.com](https://nvisy.com)
+
+
+ Generate your API key from the dashboard
+
+
+ Use the API or SDKs to begin redacting documents
+
+
+
+## Features
+
+
+
+ Automatically scales to handle your workload
+
+
+ 99.9% uptime SLA with multi-region deployment
+
+
+ Always running the latest version with new features
+
+
+ Real-time metrics and performance monitoring
+
+
+
+## Architecture
+
+Cloud deployment uses a globally distributed architecture:
+
+```
+User Request
+ ↓
+Global Load Balancer
+ ↓
+Regional API Gateway (Multi-region)
+ ↓
+Redaction Service (Auto-scaling)
+ ↓
+AI Detection Engine (GPU-accelerated)
+ ↓
+Encrypted Storage (S3-compatible)
+```
+
+## Authentication
+
+All cloud API requests require authentication:
+
+```bash
+curl https://api.nvisy.com/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -F "file=@document.pdf"
+```
+
+
+ Keep your API key secure. Never commit it to version control or expose it in client-side code.
+
+
+## Regions
+
+Available regions:
+- **US East** (Virginia) - `us-east-1`
+- **US West** (Oregon) - `us-west-2`
+- **EU West** (Ireland) - `eu-west-1`
+- **Asia Pacific** (Singapore) - `ap-southeast-1`
+
+Specify region in your API calls:
+
+```typescript
+const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY,
+ region: 'us-east-1'
+});
+```
+
+## Pricing
+
+Cloud deployment uses usage-based pricing:
+
+| Tier | Pages/Month | Price per Page | Included Features |
+|------|-------------|----------------|-------------------|
+| **Free** | 100 | $0.00 | All features, 24hr support |
+| **Starter** | 1,000 | $0.10 | All features, email support |
+| **Pro** | 10,000 | $0.08 | All features, priority support |
+| **Enterprise** | Custom | Custom | SLA, dedicated support |
+
+
+ Pricing is per page processed, not per document. A 10-page PDF counts as 10 pages.
+
+
+## Security
+
+### Data Encryption
+- **In transit:** TLS 1.3 encryption
+- **At rest:** AES-256 encryption
+- **Key management:** AWS KMS or bring your own keys
+
+### Data Retention
+- **Processed documents:** Deleted after 30 days by default
+- **Audit trails:** Retained for 7 years
+- **Custom retention:** Available on Enterprise plan
+
+### Compliance Certifications
+- SOC 2 Type II
+- GDPR compliant
+- HIPAA compliant (BAA available)
+- ISO 27001
+
+## Rate Limits
+
+| Plan | Requests/Second | Concurrent Requests |
+|------|----------------|---------------------|
+| Free | 10 | 5 |
+| Starter | 50 | 20 |
+| Pro | 200 | 100 |
+| Enterprise | Custom | Custom |
+
+Rate limit headers included in responses:
+```
+X-RateLimit-Limit: 50
+X-RateLimit-Remaining: 45
+X-RateLimit-Reset: 1640995200
+```
+
+## Monitoring & Observability
+
+Access real-time metrics in the dashboard:
+- Request volume and success rate
+- Processing time and throughput
+- Detection accuracy metrics
+- Cost and usage analytics
+
+### Webhooks
+
+Set up webhooks for real-time notifications:
+
+```typescript
+const webhook = await nvisy.webhooks.create({
+ url: 'https://your-app.com/webhooks/nvisy',
+ events: ['redaction.completed', 'redaction.failed']
+});
+```
+
+## Support
+
+Cloud deployment includes:
+
+
+
+ support@nvisy.com
+
+
+ status.nvisy.com
+
+
+ docs.nvisy.com
+
+
+ Real-time API health monitoring
+
+
+
+## Migration from On-Premises
+
+Migrating to cloud from on-premises:
+
+
+
+ Document your current redaction workflows and integrations
+
+
+ Run cloud deployment alongside on-premises to verify results
+
+
+ Point your applications to cloud API endpoints
+
+
+ Monitor performance and adjust configuration as needed
+
+
+
+## Best Practices
+
+### API Key Management
+- Use environment variables for API keys
+- Rotate keys regularly
+- Use separate keys for development and production
+- Implement key rotation automation
+
+### Performance Optimization
+- Upload documents in parallel for batch processing
+- Use appropriate confidence thresholds
+- Enable only needed detection types
+- Cache results when possible
+
+### Cost Optimization
+- Set confidence thresholds appropriately to reduce false positives
+- Use batch processing for multiple documents
+- Implement client-side file validation before upload
+- Monitor usage regularly
+
+## Next Steps
+
+
+
+ Start redacting documents now
+
+
+ Explore API endpoints
+
+
+ Use the TypeScript SDK
+
+
+ View detailed pricing
+
+
diff --git a/deployment/on-premise/getting-started.mdx b/deployment/on-premise/getting-started.mdx
new file mode 100644
index 0000000..ac2e8ed
--- /dev/null
+++ b/deployment/on-premise/getting-started.mdx
@@ -0,0 +1,448 @@
+---
+title: "Getting Started"
+description: "Configure and start using Nvisy on-premises"
+---
+
+## Quick Start
+
+Get Nvisy running in 5 minutes:
+
+
+
+ Ensure your system meets the [requirements](/deployment/on-premise/requirements)
+
+
+ Follow the [installation guide](/deployment/on-premise/installation)
+
+
+ Set up basic configuration
+
+
+ Launch Nvisy services
+
+
+ Test that everything is working
+
+
+
+## Basic Configuration
+
+### Environment Variables
+
+Create a `.env` file with your configuration:
+
+```bash
+# License
+NVISY_LICENSE_KEY=your_license_key_here
+
+# Server
+NVISY_SERVER_HOST=0.0.0.0
+NVISY_SERVER_PORT=8080
+NVISY_LOG_LEVEL=info
+
+# Database
+NVISY_DB_URL=postgresql://nvisy:password@postgres:5432/nvisy
+
+# Redis
+NVISY_REDIS_URL=redis://redis:6379
+
+# Storage
+NVISY_STORAGE_TYPE=local
+NVISY_STORAGE_PATH=/var/lib/nvisy/data
+
+# Security
+NVISY_TLS_ENABLED=false # Set to true for production
+```
+
+### Configuration File
+
+Alternatively, use `config.yaml`:
+
+```yaml
+server:
+ host: 0.0.0.0
+ port: 8080
+
+license:
+ key: your_license_key_here
+
+database:
+ url: postgresql://nvisy:password@postgres:5432/nvisy
+
+redis:
+ url: redis://redis:6379
+
+storage:
+ type: local
+ path: /var/lib/nvisy/data
+
+ai:
+ gpu_enabled: false
+ max_concurrent_jobs: 10
+```
+
+## Starting Services
+
+### Docker Compose
+
+Start all services:
+
+```bash
+# Start in foreground
+docker-compose up
+
+# Start in background
+docker-compose up -d
+
+# View logs
+docker-compose logs -f
+
+# Check status
+docker-compose ps
+```
+
+### Kubernetes
+
+Deploy with Helm:
+
+```bash
+# Install
+helm install nvisy nvisy/nvisy \
+ --namespace nvisy \
+ --create-namespace \
+ --set license.key=your_license_key
+
+# Check status
+kubectl get pods -n nvisy
+
+# View logs
+kubectl logs -f -n nvisy -l app=nvisy
+```
+
+### Systemd
+
+Start the service:
+
+```bash
+# Start service
+sudo systemctl start nvisy
+
+# Enable on boot
+sudo systemctl enable nvisy
+
+# Check status
+sudo systemctl status nvisy
+
+# View logs
+sudo journalctl -u nvisy -f
+```
+
+## Verification
+
+### Health Check
+
+Verify Nvisy is running:
+
+```bash
+curl http://localhost:8080/health
+```
+
+Expected response:
+
+```json
+{
+ "status": "healthy",
+ "version": "1.0.0",
+ "checks": {
+ "database": "ok",
+ "redis": "ok",
+ "storage": "ok",
+ "ai_models": "ok"
+ }
+}
+```
+
+### Test Redaction
+
+Test with a sample document:
+
+```bash
+curl -X POST http://localhost:8080/v1/documents/redact \
+ -F "file=@test-document.pdf" \
+ -F "detection_types=pii" \
+ -o redacted.pdf
+```
+
+## Creating API Keys
+
+Generate API keys for your applications:
+
+```bash
+# Create an API key
+docker-compose exec nvisy nvisy admin create-api-key \
+ --name "my-application" \
+ --permissions "redact,read"
+
+# List all keys
+docker-compose exec nvisy nvisy admin list-api-keys
+
+# Revoke a key
+docker-compose exec nvisy nvisy admin revoke-api-key --key-id KEY_ID
+```
+
+## First Redaction
+
+### Using cURL
+
+```bash
+# Upload and redact
+curl -X POST http://localhost:8080/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -F "file=@document.pdf" \
+ -F "detection_types=pii,phi,financial" \
+ -F "confidence_threshold=0.8" \
+ -o redacted-document.pdf
+```
+
+### Using TypeScript SDK
+
+```typescript
+import { NvisyClient } from '@nvisy/sdk';
+
+const nvisy = new NvisyClient({
+ apiKey: 'YOUR_API_KEY',
+ baseUrl: 'http://localhost:8080' // Your on-premises instance
+});
+
+const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi', 'financial']
+});
+
+await result.downloadRedacted('./redacted.pdf');
+```
+
+### Using Python SDK
+
+```python
+from nvisy import NvisyClient
+
+client = NvisyClient(
+ api_key='YOUR_API_KEY',
+ base_url='http://localhost:8080'
+)
+
+result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii', 'phi', 'financial']
+)
+
+result.download_redacted('./redacted.pdf')
+```
+
+## Enabling TLS/HTTPS
+
+For production, enable TLS:
+
+### Generate Certificate
+
+```bash
+# Self-signed certificate (development)
+openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
+ -keyout /etc/nvisy/certs/tls.key \
+ -out /etc/nvisy/certs/tls.crt
+
+# Or use Let's Encrypt (production)
+certbot certonly --standalone -d nvisy.yourdomain.com
+```
+
+### Update Configuration
+
+```yaml
+server:
+ tls:
+ enabled: true
+ cert_file: /etc/nvisy/certs/tls.crt
+ key_file: /etc/nvisy/certs/tls.key
+```
+
+### Restart Services
+
+```bash
+docker-compose restart
+```
+
+## Setting Up Monitoring
+
+### Enable Metrics
+
+Configure Prometheus metrics:
+
+```yaml
+monitoring:
+ metrics:
+ enabled: true
+ port: 9090
+```
+
+### Prometheus Configuration
+
+```yaml
+# prometheus.yml
+scrape_configs:
+ - job_name: 'nvisy'
+ static_configs:
+ - targets: ['nvisy:9090']
+```
+
+### Grafana Dashboard
+
+Import the Nvisy dashboard (ID: coming soon) or create custom dashboards using metrics:
+
+- `nvisy_requests_total` - Total API requests
+- `nvisy_processing_duration_seconds` - Processing time
+- `nvisy_detections_total` - Total detections
+- `nvisy_errors_total` - Error count
+
+## User Management
+
+### Create Admin User
+
+```bash
+docker-compose exec nvisy nvisy admin create-user \
+ --email admin@yourcompany.com \
+ --role admin \
+ --password
+```
+
+### Assign Roles
+
+Available roles:
+- `admin` - Full system access
+- `operator` - Manage documents and settings
+- `user` - Redact documents only
+- `viewer` - Read-only access
+
+## Backup Configuration
+
+Set up automated backups:
+
+```bash
+# Create backup script
+cat > /usr/local/bin/nvisy-backup.sh << 'EOF'
+#!/bin/bash
+BACKUP_DIR=/backups/nvisy
+DATE=$(date +%Y%m%d-%H%M%S)
+
+# Backup database
+docker-compose exec -T postgres pg_dump nvisy | \
+ gzip > ${BACKUP_DIR}/db-${DATE}.sql.gz
+
+# Backup storage
+tar -czf ${BACKUP_DIR}/storage-${DATE}.tar.gz \
+ /var/lib/nvisy/data
+
+# Cleanup old backups (keep 30 days)
+find ${BACKUP_DIR} -mtime +30 -delete
+EOF
+
+chmod +x /usr/local/bin/nvisy-backup.sh
+
+# Add to crontab (daily at 2 AM)
+echo "0 2 * * * /usr/local/bin/nvisy-backup.sh" | crontab -
+```
+
+## Performance Tuning
+
+### Optimize Worker Count
+
+```yaml
+ai:
+ max_concurrent_jobs: 20 # Adjust based on CPU cores
+```
+
+Rule of thumb: `(CPU cores - 2) / 2`
+
+### Database Connection Pool
+
+```yaml
+database:
+ max_connections: 100
+ idle_timeout: 300
+```
+
+### Redis Cache Size
+
+```yaml
+redis:
+ max_memory: 8gb
+ eviction_policy: allkeys-lru
+```
+
+### Enable GPU Acceleration
+
+If you have an NVIDIA GPU:
+
+```yaml
+ai:
+ gpu_enabled: true
+ gpu_memory_fraction: 0.8 # Use 80% of GPU memory
+```
+
+## Common Tasks
+
+### View Logs
+
+```bash
+# Docker Compose
+docker-compose logs -f nvisy
+
+# Kubernetes
+kubectl logs -f -n nvisy -l app=nvisy
+
+# Systemd
+journalctl -u nvisy -f
+```
+
+### Restart Services
+
+```bash
+# Docker Compose
+docker-compose restart
+
+# Kubernetes
+kubectl rollout restart deployment/nvisy -n nvisy
+
+# Systemd
+sudo systemctl restart nvisy
+```
+
+### Check Resource Usage
+
+```bash
+# Docker Compose
+docker stats
+
+# Kubernetes
+kubectl top pods -n nvisy
+
+# System
+htop
+```
+
+## Next Steps
+
+
+
+ Explore the API
+
+
+ Use the SDK
+
+
+ Advanced configuration
+
+
+ Common issues and solutions
+
+
diff --git a/deployment/on-premise/installation.mdx b/deployment/on-premise/installation.mdx
new file mode 100644
index 0000000..93c63f4
--- /dev/null
+++ b/deployment/on-premise/installation.mdx
@@ -0,0 +1,569 @@
+---
+title: "On-Premises Deployment"
+description: "Deploy Nvisy in your own infrastructure for complete control and data sovereignty"
+---
+
+Deploy Nvisy within your own infrastructure for complete control over your data, security policies, and compliance requirements. Ideal for regulated industries and organizations with strict data residency needs.
+
+## Overview
+
+On-premises deployment gives you:
+- **Complete data sovereignty** - Documents never leave your network
+- **Full control** - Customize security, networking, and infrastructure
+- **Air-gap support** - Deploy in isolated environments
+- **Custom compliance** - Meet specific regulatory requirements
+
+## System Requirements
+
+### Minimum Requirements
+
+| Component | Requirement |
+|-----------|-------------|
+| **OS** | Ubuntu 20.04+, RHEL 8+, or compatible Linux |
+| **CPU** | 8 cores (x86_64) |
+| **RAM** | 16 GB |
+| **Storage** | 100 GB SSD |
+| **Network** | 1 Gbps |
+| **Container Runtime** | Docker 20.10+ or Kubernetes 1.21+ |
+
+### Recommended for Production
+
+| Component | Requirement |
+|-----------|-------------|
+| **CPU** | 16+ cores with AVX2 support |
+| **RAM** | 32 GB+ |
+| **Storage** | 500 GB+ NVMe SSD |
+| **GPU** | NVIDIA GPU with 8GB+ VRAM (optional, for faster processing) |
+| **Network** | 10 Gbps with load balancer |
+| **HA Setup** | 3+ nodes for high availability |
+
+## Installation Methods
+
+
+
+ ### Docker Compose Installation
+
+ Quick setup for development and small deployments:
+
+ ```bash
+ # Download the compose file
+ curl -O https://get.nvisy.com/docker-compose.yml
+
+ # Configure environment variables
+ cat > .env << EOF
+ NVISY_LICENSE_KEY=your_license_key
+ NVISY_ADMIN_EMAIL=admin@yourcompany.com
+ NVISY_STORAGE_PATH=/var/lib/nvisy
+ EOF
+
+ # Start Nvisy
+ docker-compose up -d
+
+ # Verify installation
+ curl http://localhost:8080/health
+ ```
+
+
+ Replace `your_license_key` with your actual license key from the Nvisy dashboard.
+
+
+
+
+ ### Kubernetes Installation
+
+ Production-ready deployment with Helm:
+
+ ```bash
+ # Add Nvisy Helm repository
+ helm repo add nvisy https://charts.nvisy.com
+ helm repo update
+
+ # Create namespace
+ kubectl create namespace nvisy
+
+ # Create license secret
+ kubectl create secret generic nvisy-license \
+ --from-literal=key=your_license_key \
+ -n nvisy
+
+ # Install Nvisy
+ helm install nvisy nvisy/nvisy \
+ --namespace nvisy \
+ --set ingress.enabled=true \
+ --set ingress.host=nvisy.yourcompany.com \
+ --set replicaCount=3
+
+ # Verify deployment
+ kubectl get pods -n nvisy
+ ```
+
+ Configuration options in `values.yaml`:
+
+ ```yaml
+ replicaCount: 3
+
+ image:
+ repository: nvisy/redaction-service
+ tag: "latest"
+
+ resources:
+ requests:
+ cpu: 4
+ memory: 8Gi
+ limits:
+ cpu: 8
+ memory: 16Gi
+
+ persistence:
+ enabled: true
+ size: 100Gi
+ storageClass: fast-ssd
+
+ postgresql:
+ enabled: true
+ auth:
+ database: nvisy
+ username: nvisy
+
+ redis:
+ enabled: true
+ architecture: standalone
+ ```
+
+
+
+ ### Binary Installation
+
+ Direct installation on Linux servers:
+
+ ```bash
+ # Download Nvisy binary
+ curl -L https://get.nvisy.com/nvisy-linux-amd64 -o nvisy
+ chmod +x nvisy
+
+ # Create configuration
+ cat > /etc/nvisy/config.yaml << EOF
+ license_key: your_license_key
+ server:
+ port: 8080
+ host: 0.0.0.0
+ storage:
+ type: local
+ path: /var/lib/nvisy/data
+ database:
+ url: postgresql://nvisy:password@localhost:5432/nvisy
+ EOF
+
+ # Install as systemd service
+ sudo ./nvisy install
+
+ # Start service
+ sudo systemctl start nvisy
+ sudo systemctl enable nvisy
+
+ # Check status
+ sudo systemctl status nvisy
+ ```
+
+
+
+## Configuration
+
+### Environment Variables
+
+```bash
+# Core Configuration
+NVISY_LICENSE_KEY=your_license_key
+NVISY_SERVER_PORT=8080
+NVISY_LOG_LEVEL=info
+
+# Storage Configuration
+NVISY_STORAGE_TYPE=s3 # local, s3, azure, gcs
+NVISY_STORAGE_PATH=/var/lib/nvisy
+NVISY_S3_BUCKET=nvisy-documents
+NVISY_S3_REGION=us-east-1
+
+# Database Configuration
+NVISY_DB_URL=postgresql://user:pass@localhost:5432/nvisy
+
+# Redis Configuration (for caching and queuing)
+NVISY_REDIS_URL=redis://localhost:6379
+
+# Security Configuration
+NVISY_API_KEY_REQUIRED=true
+NVISY_TLS_ENABLED=true
+NVISY_TLS_CERT=/etc/nvisy/certs/tls.crt
+NVISY_TLS_KEY=/etc/nvisy/certs/tls.key
+
+# AI Model Configuration
+NVISY_MODEL_PATH=/opt/nvisy/models
+NVISY_GPU_ENABLED=true
+NVISY_MAX_CONCURRENT_JOBS=10
+```
+
+### config.yaml
+
+```yaml
+server:
+ port: 8080
+ host: 0.0.0.0
+ tls:
+ enabled: true
+ cert_file: /etc/nvisy/certs/tls.crt
+ key_file: /etc/nvisy/certs/tls.key
+
+storage:
+ type: s3
+ s3:
+ bucket: nvisy-documents
+ region: us-east-1
+ endpoint: https://s3.amazonaws.com
+ retention:
+ documents: 30d
+ audit_logs: 7y
+
+database:
+ url: postgresql://nvisy:password@postgres:5432/nvisy
+ max_connections: 100
+ ssl_mode: require
+
+ai:
+ model_path: /opt/nvisy/models
+ gpu_enabled: true
+ max_concurrent: 10
+ detection_types:
+ - pii
+ - phi
+ - financial
+
+security:
+ api_keys:
+ required: true
+ header_name: Authorization
+ cors:
+ enabled: true
+ origins:
+ - https://app.yourcompany.com
+ rate_limiting:
+ enabled: true
+ requests_per_second: 100
+
+monitoring:
+ metrics:
+ enabled: true
+ port: 9090
+ tracing:
+ enabled: true
+ endpoint: http://jaeger:14268/api/traces
+```
+
+## Networking
+
+### Firewall Rules
+
+Required ports:
+
+| Port | Protocol | Purpose |
+|------|----------|---------|
+| 8080 | TCP | HTTP API |
+| 8443 | TCP | HTTPS API (if TLS enabled) |
+| 9090 | TCP | Metrics endpoint |
+| 5432 | TCP | PostgreSQL (if external) |
+| 6379 | TCP | Redis (if external) |
+
+### Load Balancer Configuration
+
+Example NGINX configuration:
+
+```nginx
+upstream nvisy_backend {
+ least_conn;
+ server nvisy-1:8080 max_fails=3 fail_timeout=30s;
+ server nvisy-2:8080 max_fails=3 fail_timeout=30s;
+ server nvisy-3:8080 max_fails=3 fail_timeout=30s;
+}
+
+server {
+ listen 443 ssl http2;
+ server_name nvisy.yourcompany.com;
+
+ ssl_certificate /etc/nginx/certs/tls.crt;
+ ssl_certificate_key /etc/nginx/certs/tls.key;
+
+ client_max_body_size 100M;
+
+ location / {
+ proxy_pass http://nvisy_backend;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ # Timeouts for long-running redaction jobs
+ proxy_read_timeout 300s;
+ proxy_connect_timeout 75s;
+ }
+}
+```
+
+## High Availability Setup
+
+### Architecture
+
+```
+ Load Balancer
+ │
+ ┌────────────────┼────────────────┐
+ │ │ │
+ Nvisy-1 Nvisy-2 Nvisy-3
+ │ │ │
+ └────────────────┼────────────────┘
+ │
+ ┌────────────┴────────────┐
+ │ │
+ PostgreSQL (Primary/Replica) Redis (Sentinel)
+```
+
+### Database Replication
+
+PostgreSQL with streaming replication:
+
+```yaml
+# Primary node
+postgresql:
+ replication:
+ enabled: true
+ user: replicator
+ password: secure_password
+
+# Replica nodes
+postgresql:
+ replication:
+ enabled: true
+ mode: slave
+ primary_host: postgres-primary
+ primary_port: 5432
+```
+
+## Backup & Recovery
+
+### Automated Backups
+
+```bash
+# PostgreSQL backup
+pg_dump nvisy | gzip > /backups/nvisy-$(date +%Y%m%d).sql.gz
+
+# Storage backup (if using local storage)
+tar -czf /backups/nvisy-storage-$(date +%Y%m%d).tar.gz /var/lib/nvisy
+
+# Kubernetes backup with Velero
+velero backup create nvisy-backup --include-namespaces nvisy
+```
+
+### Backup Schedule
+
+Recommended schedule:
+- **Database**: Daily full backup, hourly incrementals
+- **Storage**: Daily backup with 30-day retention
+- **Configuration**: Version-controlled in Git
+- **Disaster Recovery**: Test recovery quarterly
+
+## Monitoring
+
+### Metrics
+
+Nvisy exposes Prometheus metrics at `/metrics`:
+
+```yaml
+# Prometheus scrape config
+scrape_configs:
+ - job_name: 'nvisy'
+ static_configs:
+ - targets: ['nvisy:9090']
+```
+
+Key metrics:
+- `nvisy_requests_total` - Total API requests
+- `nvisy_processing_duration_seconds` - Processing time
+- `nvisy_detections_total` - Total detections
+- `nvisy_errors_total` - Error count
+
+### Health Checks
+
+```bash
+# Basic health check
+curl http://localhost:8080/health
+
+# Detailed health check
+curl http://localhost:8080/health/detailed
+```
+
+Response:
+```json
+{
+ "status": "healthy",
+ "checks": {
+ "database": "ok",
+ "redis": "ok",
+ "storage": "ok",
+ "ai_models": "ok"
+ }
+}
+```
+
+## Security Hardening
+
+### TLS Configuration
+
+Generate self-signed certificate (development):
+```bash
+openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
+ -keyout /etc/nvisy/certs/tls.key \
+ -out /etc/nvisy/certs/tls.crt
+```
+
+### API Key Management
+
+```bash
+# Generate API key
+nvisy admin create-api-key --name "production-app" --permissions "redact,read"
+
+# List API keys
+nvisy admin list-api-keys
+
+# Revoke API key
+nvisy admin revoke-api-key --key-id abc123
+```
+
+### Network Isolation
+
+Run in isolated network:
+```yaml
+# Docker Compose network isolation
+networks:
+ nvisy_internal:
+ driver: bridge
+ internal: true
+ nvisy_external:
+ driver: bridge
+
+services:
+ nvisy:
+ networks:
+ - nvisy_external
+ - nvisy_internal
+
+ postgres:
+ networks:
+ - nvisy_internal # Not exposed externally
+```
+
+## Troubleshooting
+
+### Common Issues
+
+
+
+ **Check logs:**
+ ```bash
+ docker logs nvisy
+ # or
+ journalctl -u nvisy -f
+ ```
+
+ **Common causes:**
+ - Invalid license key
+ - Database connection failure
+ - Port already in use
+ - Insufficient permissions
+
+
+
+ **Check resource usage:**
+ ```bash
+ docker stats nvisy
+ # or
+ kubectl top pods -n nvisy
+ ```
+
+ **Solutions:**
+ - Increase CPU/memory allocation
+ - Enable GPU acceleration
+ - Increase concurrent job limit
+ - Check network latency to storage
+
+
+
+ **Verify database:**
+ ```bash
+ psql -h localhost -U nvisy -d nvisy -c "SELECT 1"
+ ```
+
+ **Check:**
+ - Database URL is correct
+ - Credentials are valid
+ - Database is accessible from Nvisy
+ - SSL mode matches database config
+
+
+
+## Upgrading
+
+### Docker Compose Upgrade
+
+```bash
+# Backup database
+docker-compose exec postgres pg_dump nvisy > backup.sql
+
+# Pull new images
+docker-compose pull
+
+# Restart services
+docker-compose up -d
+
+# Verify upgrade
+curl http://localhost:8080/version
+```
+
+### Kubernetes Upgrade
+
+```bash
+# Backup
+velero backup create pre-upgrade-backup --include-namespaces nvisy
+
+# Upgrade with Helm
+helm upgrade nvisy nvisy/nvisy \
+ --namespace nvisy \
+ --version 2.0.0
+
+# Monitor rollout
+kubectl rollout status deployment/nvisy -n nvisy
+```
+
+## Support
+
+
+
+ Priority support with SLA for on-premises customers
+
+
+ Complete deployment guides and API reference
+
+
+ support@nvisy.com
+
+
+ Report issues or request features
+
+
+
+## Next Steps
+
+
+
+ View all configuration options
+
+
+ Integrate with your applications
+
+
diff --git a/deployment/on-premise/requirements.mdx b/deployment/on-premise/requirements.mdx
new file mode 100644
index 0000000..0086ada
--- /dev/null
+++ b/deployment/on-premise/requirements.mdx
@@ -0,0 +1,327 @@
+---
+title: "System Requirements"
+description: "Hardware and software requirements for on-premises deployment"
+---
+
+## Production Requirements
+
+| Component | Requirement |
+|-----------|-------------|
+| **Operating System** | Ubuntu 22.04 LTS or RHEL 9 |
+| **CPU** | 16+ cores with AVX2 support |
+| **RAM** | 32 GB+ |
+| **Storage** | 500 GB+ NVMe SSD |
+| **GPU** | NVIDIA GPU with 8GB+ VRAM (optional, for faster processing) |
+| **Network** | 10 Gbps with load balancer |
+| **Container Runtime** | Docker 20.10+ or Kubernetes 1.21+ |
+| **High Availability** | 3+ nodes for redundancy |
+
+## Operating System Support
+
+### Supported Distributions
+
+
+
+ - Ubuntu 20.04 LTS (Focal)
+ - Ubuntu 22.04 LTS (Jammy)
+ - Ubuntu 24.04 LTS (Noble)
+
+ **Recommended:** Ubuntu 22.04 LTS
+
+
+
+ - RHEL 8.x
+ - RHEL 9.x
+ - Rocky Linux 8.x, 9.x
+ - AlmaLinux 8.x, 9.x
+
+ **Recommended:** RHEL 9 or Rocky Linux 9
+
+
+
+ - Debian 11 (Bullseye)
+ - Debian 12 (Bookworm)
+
+ **Recommended:** Debian 12
+
+
+
+ - Amazon Linux 2023
+ - SUSE Linux Enterprise Server 15
+
+ Other distributions may work but are not officially supported.
+
+
+
+## Hardware Requirements
+
+### CPU
+
+- 16+ cores (32+ threads)
+- Intel Xeon or AMD EPYC
+- AVX2 instruction set support
+- 3.0 GHz+ base clock
+
+For high-volume processing:
+- 32+ cores
+- Latest generation processors
+- AVX-512 support
+
+### Memory (RAM)
+
+- **32 GB** - Supports ~25 concurrent jobs with adequate caching
+- **64 GB+** - For high-volume deployments (50+ concurrent jobs)
+
+### Storage
+
+- **500 GB NVMe SSD** - Recommended starting point
+- **1+ TB NVMe SSD** - For high-volume or long-term log retention
+- RAID 10 configuration recommended for production
+
+### Storage Performance
+
+| Requirement | Minimum | Recommended |
+|-------------|---------|-------------|
+| **IOPS** | 3,000 | 10,000+ |
+| **Throughput** | 125 MB/s | 500 MB/s+ |
+| **Latency** | < 10ms | < 1ms |
+
+### GPU (Optional)
+
+GPU acceleration significantly improves processing speed:
+
+**Supported GPUs:**
+- NVIDIA T4 (16 GB)
+- NVIDIA A10 (24 GB)
+- NVIDIA A100 (40/80 GB)
+- NVIDIA L4 (24 GB)
+- NVIDIA L40 (48 GB)
+
+**Requirements:**
+- CUDA 11.8 or higher
+- NVIDIA driver 520.61.05 or higher
+- Compute capability 7.0+
+
+**Performance Improvement:**
+- 3-5x faster processing with GPU
+- Recommended for high-volume deployments
+
+## Network Requirements
+
+### Bandwidth
+
+- **10 Gbps** - Recommended for production
+- **10+ Gbps with redundancy** - For enterprise deployments processing more than 1000 documents/hour
+
+### Ports
+
+Required network ports:
+
+| Port | Protocol | Purpose | Required |
+|------|----------|---------|----------|
+| 8080 | TCP | HTTP API | Yes |
+| 8443 | TCP | HTTPS API | Recommended |
+| 9090 | TCP | Metrics | Optional |
+| 5432 | TCP | PostgreSQL | Yes (if external) |
+| 6379 | TCP | Redis | Yes (if external) |
+
+### Firewall Rules
+
+Allow inbound traffic:
+```bash
+# HTTP API
+sudo ufw allow 8080/tcp
+
+# HTTPS API
+sudo ufw allow 8443/tcp
+
+# Metrics (from monitoring network only)
+sudo ufw allow from 10.0.0.0/8 to any port 9090
+```
+
+## Software Dependencies
+
+### Container Runtime
+
+
+
+ **Required Version:** 20.10+
+
+ **Installation:**
+ ```bash
+ # Ubuntu/Debian
+ curl -fsSL https://get.docker.com -o get-docker.sh
+ sudo sh get-docker.sh
+
+ # Verify
+ docker --version
+ ```
+
+ **Docker Compose:**
+ ```bash
+ # Required version: 2.0+
+ sudo apt-get install docker-compose-plugin
+ docker compose version
+ ```
+
+
+
+ **Required Version:** 1.21+
+
+ **Recommended:** 1.27+
+
+ **Supported Distributions:**
+ - Vanilla Kubernetes
+ - Amazon EKS
+ - Google GKE
+ - Azure AKS
+ - Red Hat OpenShift 4.10+
+ - Rancher
+
+ **Required Components:**
+ - kubectl CLI
+ - Helm 3.0+
+ - Persistent volume provisioner
+
+
+
+ **Supported:** Yes (experimental)
+
+ **Version:** 4.0+
+
+ **Note:** Limited testing, use Docker for production
+
+
+
+### Database
+
+**PostgreSQL** is required for metadata and audit logs:
+
+**Version:** 12+
+**Recommended:** 14+
+
+**Storage Requirements:**
+- 10 GB minimum
+- 50 GB recommended
+- Scales with audit log retention
+
+### Cache/Queue
+
+**Redis** is required for job queuing and caching:
+
+**Version:** 6.0+
+**Recommended:** 7.0+
+
+**Memory Requirements:**
+- 2 GB minimum
+- 8 GB recommended
+
+## High Availability Requirements
+
+For production HA deployment:
+
+### Compute
+
+- **Minimum:** 3 nodes
+- **Recommended:** 5+ nodes
+- **Load balancer:** NGINX, HAProxy, or cloud LB
+
+### Database
+
+- **PostgreSQL:** Primary + 2 replicas
+- **Replication:** Streaming replication
+- **Automatic failover:** Patroni or similar
+
+### Cache
+
+- **Redis:** Sentinel mode (3+ nodes)
+- **Cluster mode:** For > 100 GB cache
+
+### Storage
+
+- **Shared storage:** NFS, S3, or similar
+- **Replication:** 3x minimum
+- **Backup:** Daily with off-site replication
+
+## Cloud Provider Recommendations
+
+### AWS
+
+**Instance Types:**
+- **Minimum:** t3.xlarge (4 vCPU, 16 GB)
+- **Recommended:** c6i.4xlarge (16 vCPU, 32 GB)
+- **With GPU:** g5.2xlarge (1x A10G GPU)
+
+**Storage:** EBS gp3 with 10,000 IOPS
+
+### Azure
+
+**VM Sizes:**
+- **Minimum:** Standard_D4s_v5 (4 vCPU, 16 GB)
+- **Recommended:** Standard_D16s_v5 (16 vCPU, 64 GB)
+- **With GPU:** Standard_NC8as_T4_v3 (1x T4 GPU)
+
+**Storage:** Premium SSD
+
+### Google Cloud
+
+**Machine Types:**
+- **Minimum:** n2-standard-8 (8 vCPU, 32 GB)
+- **Recommended:** n2-standard-16 (16 vCPU, 64 GB)
+- **With GPU:** n1-standard-8 + 1x T4
+
+**Storage:** SSD persistent disk
+
+## Capacity Planning
+
+### Concurrent Jobs
+
+Estimate required resources based on workload:
+
+| Concurrent Jobs | CPU Cores | RAM | Storage IOPS |
+|----------------|-----------|-----|--------------|
+| 10 | 8 | 16 GB | 3,000 |
+| 25 | 16 | 32 GB | 10,000 |
+| 50 | 32 | 64 GB | 20,000 |
+| 100 | 64 | 128 GB | 40,000 |
+
+### Storage Sizing
+
+Calculate storage needs:
+
+```
+Total Storage = (Avg Document Size × Daily Documents × Retention Days) + Base Storage
+
+Example:
+(5 MB × 1000 documents × 30 days) + 50 GB = 200 GB
+```
+
+## Benchmarking
+
+Test your environment:
+
+```bash
+# CPU benchmark
+sysbench cpu --threads=16 --time=60 run
+
+# Memory benchmark
+sysbench memory --memory-total-size=100G run
+
+# Disk I/O benchmark
+fio --name=randwrite --ioengine=libaio --rw=randwrite \
+ --bs=4k --numjobs=4 --size=4g --runtime=60
+
+# Network benchmark
+iperf3 -c -t 60 -P 4
+```
+
+## Next Steps
+
+
+
+ Install Nvisy on-premises
+
+
+ Configure and start using Nvisy
+
+
diff --git a/development.mdx b/development.mdx
deleted file mode 100644
index ac633ba..0000000
--- a/development.mdx
+++ /dev/null
@@ -1,94 +0,0 @@
----
-title: 'Development'
-description: 'Preview changes locally to update your docs'
----
-
-
- **Prerequisites**:
- - Node.js version 19 or higher
- - A docs repository with a `docs.json` file
-
-
-Follow these steps to install and run Mintlify on your operating system.
-
-
-
-
-```bash
-npm i -g mint
-```
-
-
-
-
-Navigate to your docs directory where your `docs.json` file is located, and run the following command:
-
-```bash
-mint dev
-```
-
-A local preview of your documentation will be available at `http://localhost:3000`.
-
-
-
-
-## Custom ports
-
-By default, Mintlify uses port 3000. You can customize the port Mintlify runs on by using the `--port` flag. For example, to run Mintlify on port 3333, use this command:
-
-```bash
-mint dev --port 3333
-```
-
-If you attempt to run Mintlify on a port that's already in use, it will use the next available port:
-
-```md
-Port 3000 is already in use. Trying 3001 instead.
-```
-
-## Mintlify versions
-
-Please note that each CLI release is associated with a specific version of Mintlify. If your local preview does not align with the production version, please update the CLI:
-
-```bash
-npm mint update
-```
-
-## Validating links
-
-The CLI can assist with validating links in your documentation. To identify any broken links, use the following command:
-
-```bash
-mint broken-links
-```
-
-## Deployment
-
-If the deployment is successful, you should see the following:
-
-
-
-
-
-## Code formatting
-
-We suggest using extensions on your IDE to recognize and format MDX. If you're a VSCode user, consider the [MDX VSCode extension](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) for syntax highlighting, and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) for code formatting.
-
-## Troubleshooting
-
-
-
-
- This may be due to an outdated version of node. Try the following:
- 1. Remove the currently-installed version of the CLI: `npm remove -g mint`
- 2. Upgrade to Node v19 or higher.
- 3. Reinstall the CLI: `npm i -g mint`
-
-
-
-
- Solution: Go to the root of your device and delete the `~/.mintlify` folder. Then run `mint dev` again.
-
-
-
-Curious about what changed in the latest CLI version? Check out the [CLI changelog](https://www.npmjs.com/package/mintlify?activeTab=versions).
diff --git a/docs.json b/docs.json
index 46b44cc..ad360d4 100644
--- a/docs.json
+++ b/docs.json
@@ -1,69 +1,66 @@
{
"$schema": "https://mintlify.com/docs.json",
- "theme": "mint",
- "name": "Mint Starter Kit",
+ "theme": "willow",
+ "name": "Nvisy",
"colors": {
- "primary": "#16A34A",
- "light": "#07C983",
- "dark": "#15803D"
+ "primary": "#2563EB",
+ "light": "#3B82F6",
+ "dark": "#1E40AF"
},
- "favicon": "/favicon.svg",
+ "favicon": "/images/nvisy.png",
+ "openapi": "/api-reference/openapi.json",
"navigation": {
"tabs": [
{
- "tab": "Guides",
+ "tab": "Docs",
"groups": [
{
- "group": "Getting started",
- "pages": [
- "index",
- "quickstart",
- "development"
- ]
+ "group": "Overview",
+ "pages": ["index", "quickstart", "faq"]
},
{
- "group": "Customization",
+ "group": "Features",
"pages": [
- "essentials/settings",
- "essentials/navigation"
+ "features/redaction-workflow",
+ "features/ai-detection",
+ "features/supported-formats",
+ "features/audit-trails",
+ "features/integrations"
]
},
{
- "group": "Writing content",
- "pages": [
- "essentials/markdown",
- "essentials/code",
- "essentials/images",
- "essentials/reusable-snippets"
- ]
+ "group": "Cloud",
+ "pages": ["deployment/cloud/authentication", "deployment/cloud/getting-started"]
},
{
- "group": "AI tools",
+ "group": "On-Premise",
"pages": [
- "ai-tools/cursor",
- "ai-tools/claude-code",
- "ai-tools/windsurf"
+ "deployment/on-premise/requirements",
+ "deployment/on-premise/installation",
+ "deployment/on-premise/getting-started"
]
}
]
},
{
- "tab": "API reference",
+ "tab": "API Reference",
"groups": [
{
- "group": "API documentation",
- "pages": [
- "api-reference/introduction"
- ]
+ "group": "API Reference",
+ "pages": ["api-reference/introduction"]
+ }
+ ]
+ },
+ {
+ "tab": "SDKs & Libraries",
+ "groups": [
+ {
+ "group": "TypeScript",
+ "pages": ["sdks/typescript/quickstart", "sdks/typescript/api-reference", "sdks/typescript/examples"]
},
{
- "group": "Endpoint examples",
- "pages": [
- "api-reference/endpoint/get",
- "api-reference/endpoint/create",
- "api-reference/endpoint/delete",
- "api-reference/endpoint/webhook"
- ]
+ "group": "Python",
+ "pages": ["sdks/python/quickstart", "sdks/python/api-reference", "sdks/python/examples"]
}
]
}
@@ -71,52 +68,45 @@
"global": {
"anchors": [
{
- "anchor": "Documentation",
- "href": "https://mintlify.com/docs",
- "icon": "book-open-cover"
+ "anchor": "GitHub",
+ "href": "https://github.com/nvisycom",
+ "icon": "github"
+ },
+ {
+ "anchor": "Website",
+ "href": "https://nvisy.com",
+ "icon": "globe"
},
{
- "anchor": "Blog",
- "href": "https://mintlify.com/blog",
- "icon": "newspaper"
+ "anchor": "Community",
+ "href": "https://github.com/nvisycom",
+ "icon": "slack"
}
]
}
},
"logo": {
- "light": "/logo/light.svg",
- "dark": "/logo/dark.svg"
+ "light": "/images/nvisy.png",
+ "dark": "/images/nvisy.png"
},
"navbar": {
"links": [
{
"label": "Support",
- "href": "mailto:hi@mintlify.com"
+ "href": "mailto:support@nvisy.com"
}
],
"primary": {
"type": "button",
- "label": "Dashboard",
- "href": "https://dashboard.mintlify.com"
+ "label": "Get Started",
+ "href": "https://nvisy.com"
}
},
- "contextual": {
- "options": [
- "copy",
- "view",
- "chatgpt",
- "claude",
- "perplexity",
- "mcp",
- "cursor",
- "vscode"
- ]
- },
"footer": {
"socials": {
- "x": "https://x.com/mintlify",
- "github": "https://github.com/mintlify",
- "linkedin": "https://linkedin.com/company/mintlify"
+ "github": "https://github.com/nvisycom",
+ "linkedin": "https://linkedin.com/company/nvisy",
+ "website": "https://nvisy.com"
}
}
}
diff --git a/essentials/code.mdx b/essentials/code.mdx
deleted file mode 100644
index ae2abbf..0000000
--- a/essentials/code.mdx
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: 'Code blocks'
-description: 'Display inline code and code blocks'
-icon: 'code'
----
-
-## Inline code
-
-To denote a `word` or `phrase` as code, enclose it in backticks (`).
-
-```
-To denote a `word` or `phrase` as code, enclose it in backticks (`).
-```
-
-## Code blocks
-
-Use [fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) by enclosing code in three backticks and follow the leading ticks with the programming language of your snippet to get syntax highlighting. Optionally, you can also write the name of your code after the programming language.
-
-```java HelloWorld.java
-class HelloWorld {
- public static void main(String[] args) {
- System.out.println("Hello, World!");
- }
-}
-```
-
-````md
-```java HelloWorld.java
-class HelloWorld {
- public static void main(String[] args) {
- System.out.println("Hello, World!");
- }
-}
-```
-````
diff --git a/essentials/images.mdx b/essentials/images.mdx
deleted file mode 100644
index 1144eb2..0000000
--- a/essentials/images.mdx
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: 'Images and embeds'
-description: 'Add image, video, and other HTML elements'
-icon: 'image'
----
-
-
-
-## Image
-
-### Using Markdown
-
-The [markdown syntax](https://www.markdownguide.org/basic-syntax/#images) lets you add images using the following code
-
-```md
-
-```
-
-Note that the image file size must be less than 5MB. Otherwise, we recommend hosting on a service like [Cloudinary](https://cloudinary.com/) or [S3](https://aws.amazon.com/s3/). You can then use that URL and embed.
-
-### Using embeds
-
-To get more customizability with images, you can also use [embeds](/writing-content/embed) to add images
-
-```html
-
-```
-
-## Embeds and HTML elements
-
-
-
-
-
-
-
-Mintlify supports [HTML tags in Markdown](https://www.markdownguide.org/basic-syntax/#html). This is helpful if you prefer HTML tags to Markdown syntax, and lets you create documentation with infinite flexibility.
-
-
-
-### iFrames
-
-Loads another HTML page within the document. Most commonly used for embedding videos.
-
-```html
-
-```
diff --git a/essentials/markdown.mdx b/essentials/markdown.mdx
deleted file mode 100644
index a45c1d5..0000000
--- a/essentials/markdown.mdx
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: 'Markdown syntax'
-description: 'Text, title, and styling in standard markdown'
-icon: 'text-size'
----
-
-## Titles
-
-Best used for section headers.
-
-```md
-## Titles
-```
-
-### Subtitles
-
-Best used for subsection headers.
-
-```md
-### Subtitles
-```
-
-
-
-Each **title** and **subtitle** creates an anchor and also shows up on the table of contents on the right.
-
-
-
-## Text formatting
-
-We support most markdown formatting. Simply add `**`, `_`, or `~` around text to format it.
-
-| Style | How to write it | Result |
-| ------------- | ----------------- | --------------- |
-| Bold | `**bold**` | **bold** |
-| Italic | `_italic_` | _italic_ |
-| Strikethrough | `~strikethrough~` | ~strikethrough~ |
-
-You can combine these. For example, write `**_bold and italic_**` to get **_bold and italic_** text.
-
-You need to use HTML to write superscript and subscript text. That is, add `` or `` around your text.
-
-| Text Size | How to write it | Result |
-| ----------- | ------------------------ | ---------------------- |
-| Superscript | `superscript` | superscript |
-| Subscript | `subscript` | subscript |
-
-## Linking to pages
-
-You can add a link by wrapping text in `[]()`. You would write `[link to google](https://google.com)` to [link to google](https://google.com).
-
-Links to pages in your docs need to be root-relative. Basically, you should include the entire folder path. For example, `[link to text](/writing-content/text)` links to the page "Text" in our components section.
-
-Relative links like `[link to text](../text)` will open slower because we cannot optimize them as easily.
-
-## Blockquotes
-
-### Singleline
-
-To create a blockquote, add a `>` in front of a paragraph.
-
-> Dorothy followed her through many of the beautiful rooms in her castle.
-
-```md
-> Dorothy followed her through many of the beautiful rooms in her castle.
-```
-
-### Multiline
-
-> Dorothy followed her through many of the beautiful rooms in her castle.
->
-> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
-
-```md
-> Dorothy followed her through many of the beautiful rooms in her castle.
->
-> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
-```
-
-### LaTeX
-
-Mintlify supports [LaTeX](https://www.latex-project.org) through the Latex component.
-
-8 x (vk x H1 - H2) = (0,1)
-
-```md
-8 x (vk x H1 - H2) = (0,1)
-```
diff --git a/essentials/navigation.mdx b/essentials/navigation.mdx
deleted file mode 100644
index 60adeff..0000000
--- a/essentials/navigation.mdx
+++ /dev/null
@@ -1,87 +0,0 @@
----
-title: 'Navigation'
-description: 'The navigation field in docs.json defines the pages that go in the navigation menu'
-icon: 'map'
----
-
-The navigation menu is the list of links on every website.
-
-You will likely update `docs.json` every time you add a new page. Pages do not show up automatically.
-
-## Navigation syntax
-
-Our navigation syntax is recursive which means you can make nested navigation groups. You don't need to include `.mdx` in page names.
-
-
-
-```json Regular Navigation
-"navigation": {
- "tabs": [
- {
- "tab": "Docs",
- "groups": [
- {
- "group": "Getting Started",
- "pages": ["quickstart"]
- }
- ]
- }
- ]
-}
-```
-
-```json Nested Navigation
-"navigation": {
- "tabs": [
- {
- "tab": "Docs",
- "groups": [
- {
- "group": "Getting Started",
- "pages": [
- "quickstart",
- {
- "group": "Nested Reference Pages",
- "pages": ["nested-reference-page"]
- }
- ]
- }
- ]
- }
- ]
-}
-```
-
-
-
-## Folders
-
-Simply put your MDX files in folders and update the paths in `docs.json`.
-
-For example, to have a page at `https://yoursite.com/your-folder/your-page` you would make a folder called `your-folder` containing an MDX file called `your-page.mdx`.
-
-
-
-You cannot use `api` for the name of a folder unless you nest it inside another folder. Mintlify uses Next.js which reserves the top-level `api` folder for internal server calls. A folder name such as `api-reference` would be accepted.
-
-
-
-```json Navigation With Folder
-"navigation": {
- "tabs": [
- {
- "tab": "Docs",
- "groups": [
- {
- "group": "Group Name",
- "pages": ["your-folder/your-page"]
- }
- ]
- }
- ]
-}
-```
-
-## Hidden pages
-
-MDX files not included in `docs.json` will not show up in the sidebar but are accessible through the search bar and by linking directly to them.
diff --git a/essentials/reusable-snippets.mdx b/essentials/reusable-snippets.mdx
deleted file mode 100644
index 376e27b..0000000
--- a/essentials/reusable-snippets.mdx
+++ /dev/null
@@ -1,110 +0,0 @@
----
-title: "Reusable snippets"
-description: "Reusable, custom snippets to keep content in sync"
-icon: "recycle"
----
-
-import SnippetIntro from '/snippets/snippet-intro.mdx';
-
-
-
-## Creating a custom snippet
-
-**Pre-condition**: You must create your snippet file in the `snippets` directory.
-
-
- Any page in the `snippets` directory will be treated as a snippet and will not
- be rendered into a standalone page. If you want to create a standalone page
- from the snippet, import the snippet into another file and call it as a
- component.
-
-
-### Default export
-
-1. Add content to your snippet file that you want to re-use across multiple
- locations. Optionally, you can add variables that can be filled in via props
- when you import the snippet.
-
-```mdx snippets/my-snippet.mdx
-Hello world! This is my content I want to reuse across pages. My keyword of the
-day is {word}.
-```
-
-
- The content that you want to reuse must be inside the `snippets` directory in
- order for the import to work.
-
-
-2. Import the snippet into your destination file.
-
-```mdx destination-file.mdx
----
-title: My title
-description: My Description
----
-
-import MySnippet from '/snippets/path/to/my-snippet.mdx';
-
-## Header
-
-Lorem impsum dolor sit amet.
-
-
-```
-
-### Reusable variables
-
-1. Export a variable from your snippet file:
-
-```mdx snippets/path/to/custom-variables.mdx
-export const myName = 'my name';
-
-export const myObject = { fruit: 'strawberries' };
-```
-
-2. Import the snippet from your destination file and use the variable:
-
-```mdx destination-file.mdx
----
-title: My title
-description: My Description
----
-
-import { myName, myObject } from '/snippets/path/to/custom-variables.mdx';
-
-Hello, my name is {myName} and I like {myObject.fruit}.
-```
-
-### Reusable components
-
-1. Inside your snippet file, create a component that takes in props by exporting
- your component in the form of an arrow function.
-
-```mdx snippets/custom-component.mdx
-export const MyComponent = ({ title }) => (
-
-
{title}
-
... snippet content ...
-
-);
-```
-
-
- MDX does not compile inside the body of an arrow function. Stick to HTML
- syntax when you can or use a default export if you need to use MDX.
-
-
-2. Import the snippet into your destination file and pass in the props
-
-```mdx destination-file.mdx
----
-title: My title
-description: My Description
----
-
-import { MyComponent } from '/snippets/custom-component.mdx';
-
-Lorem ipsum dolor sit amet.
-
-
-```
diff --git a/essentials/settings.mdx b/essentials/settings.mdx
deleted file mode 100644
index 884de13..0000000
--- a/essentials/settings.mdx
+++ /dev/null
@@ -1,318 +0,0 @@
----
-title: 'Global Settings'
-description: 'Mintlify gives you complete control over the look and feel of your documentation using the docs.json file'
-icon: 'gear'
----
-
-Every Mintlify site needs a `docs.json` file with the core configuration settings. Learn more about the [properties](#properties) below.
-
-## Properties
-
-
-Name of your project. Used for the global title.
-
-Example: `mintlify`
-
-
-
-
- An array of groups with all the pages within that group
-
-
- The name of the group.
-
- Example: `Settings`
-
-
-
- The relative paths to the markdown files that will serve as pages.
-
- Example: `["customization", "page"]`
-
-
-
-
-
-
-
- Path to logo image or object with path to "light" and "dark" mode logo images
-
-
- Path to the logo in light mode
-
-
- Path to the logo in dark mode
-
-
- Where clicking on the logo links you to
-
-
-
-
-
- Path to the favicon image
-
-
-
- Hex color codes for your global theme
-
-
- The primary color. Used for most often for highlighted content, section
- headers, accents, in light mode
-
-
- The primary color for dark mode. Used for most often for highlighted
- content, section headers, accents, in dark mode
-
-
- The primary color for important buttons
-
-
- The color of the background in both light and dark mode
-
-
- The hex color code of the background in light mode
-
-
- The hex color code of the background in dark mode
-
-
-
-
-
-
-
- Array of `name`s and `url`s of links you want to include in the topbar
-
-
- The name of the button.
-
- Example: `Contact us`
-
-
- The url once you click on the button. Example: `https://mintlify.com/docs`
-
-
-
-
-
-
-
-
- Link shows a button. GitHub shows the repo information at the url provided including the number of GitHub stars.
-
-
- If `link`: What the button links to.
-
- If `github`: Link to the repository to load GitHub information from.
-
-
- Text inside the button. Only required if `type` is a `link`.
-
-
-
-
-
-
- Array of version names. Only use this if you want to show different versions
- of docs with a dropdown in the navigation bar.
-
-
-
- An array of the anchors, includes the `icon`, `color`, and `url`.
-
-
- The [Font Awesome](https://fontawesome.com/search?q=heart) icon used to feature the anchor.
-
- Example: `comments`
-
-
- The name of the anchor label.
-
- Example: `Community`
-
-
- The start of the URL that marks what pages go in the anchor. Generally, this is the name of the folder you put your pages in.
-
-
- The hex color of the anchor icon background. Can also be a gradient if you pass an object with the properties `from` and `to` that are each a hex color.
-
-
- Used if you want to hide an anchor until the correct docs version is selected.
-
-
- Pass `true` if you want to hide the anchor until you directly link someone to docs inside it.
-
-
- One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin"
-
-
-
-
-
-
- Override the default configurations for the top-most anchor.
-
-
- The name of the top-most anchor
-
-
- Font Awesome icon.
-
-
- One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin"
-
-
-
-
-
- An array of navigational tabs.
-
-
- The name of the tab label.
-
-
- The start of the URL that marks what pages go in the tab. Generally, this
- is the name of the folder you put your pages in.
-
-
-
-
-
- Configuration for API settings. Learn more about API pages at [API Components](/api-playground/demo).
-
-
- The base url for all API endpoints. If `baseUrl` is an array, it will enable for multiple base url
- options that the user can toggle.
-
-
-
-
-
- The authentication strategy used for all API endpoints.
-
-
- The name of the authentication parameter used in the API playground.
-
- If method is `basic`, the format should be `[usernameName]:[passwordName]`
-
-
- The default value that's designed to be a prefix for the authentication input field.
-
- E.g. If an `inputPrefix` of `AuthKey` would inherit the default input result of the authentication field as `AuthKey`.
-
-
-
-
-
- Configurations for the API playground
-
-
-
- Whether the playground is showing, hidden, or only displaying the endpoint with no added user interactivity `simple`
-
- Learn more at the [playground guides](/api-playground/demo)
-
-
-
-
-
- Enabling this flag ensures that key ordering in OpenAPI pages matches the key ordering defined in the OpenAPI file.
-
- This behavior will soon be enabled by default, at which point this field will be deprecated.
-
-
-
-
-
-
- A string or an array of strings of URL(s) or relative path(s) pointing to your
- OpenAPI file.
-
- Examples:
-
- ```json Absolute
- "openapi": "https://example.com/openapi.json"
- ```
- ```json Relative
- "openapi": "/openapi.json"
- ```
- ```json Multiple
- "openapi": ["https://example.com/openapi1.json", "/openapi2.json", "/openapi3.json"]
- ```
-
-
-
-
-
- An object of social media accounts where the key:property pair represents the social media platform and the account url.
-
- Example:
- ```json
- {
- "x": "https://x.com/mintlify",
- "website": "https://mintlify.com"
- }
- ```
-
-
- One of the following values `website`, `facebook`, `x`, `discord`, `slack`, `github`, `linkedin`, `instagram`, `hacker-news`
-
- Example: `x`
-
-
- The URL to the social platform.
-
- Example: `https://x.com/mintlify`
-
-
-
-
-
- Configurations to enable feedback buttons
-
-
-
- Enables a button to allow users to suggest edits via pull requests
-
-
- Enables a button to allow users to raise an issue about the documentation
-
-
-
-
-
- Customize the dark mode toggle.
-
-
- Set if you always want to show light or dark mode for new users. When not
- set, we default to the same mode as the user's operating system.
-
-
- Set to true to hide the dark/light mode toggle. You can combine `isHidden` with `default` to force your docs to only use light or dark mode. For example:
-
-
- ```json Only Dark Mode
- "modeToggle": {
- "default": "dark",
- "isHidden": true
- }
- ```
-
- ```json Only Light Mode
- "modeToggle": {
- "default": "light",
- "isHidden": true
- }
- ```
-
-
-
-
-
-
-
-
- A background image to be displayed behind every page. See example with
- [Infisical](https://infisical.com/docs) and [FRPC](https://frpc.io).
-
diff --git a/faq.mdx b/faq.mdx
new file mode 100644
index 0000000..705609b
--- /dev/null
+++ b/faq.mdx
@@ -0,0 +1,328 @@
+---
+title: "FAQ"
+description: "Frequently asked questions about Nvisy"
+---
+
+## General
+
+
+
+ Nvisy is an open-source AI-powered document redaction platform that automatically identifies and removes sensitive information from documents while preserving their integrity and formatting. It processes 50+ file formats with 99.9% accuracy.
+
+
+
+ Yes, Nvisy is open-source. You can find our code on [GitHub](https://github.com/nvisycom) and contribute to the project.
+
+
+
+ Nvisy can detect:
+ - **PII**: Names, addresses, SSN, phone numbers, email addresses
+ - **PHI**: Medical records, diagnoses, prescriptions, patient data
+ - **Financial**: Credit card numbers, bank accounts, tax IDs
+ - **Custom patterns**: Your organization-specific sensitive data
+
+
+
+ Nvisy achieves 99.9% accuracy across all detection types. Each detection includes a confidence score so you can review and approve before finalizing.
+
+
+
+ Nvisy supports 50+ formats including:
+ - PDF (text-based and scanned)
+ - Microsoft Office (Word, Excel, PowerPoint)
+ - OpenDocument formats
+ - Images (with OCR)
+ - Plain text, CSV, JSON, XML
+
+ [View complete list →](/features/supported-formats)
+
+
+
+## Pricing & Plans
+
+
+
+ Nvisy offers:
+ - **Free tier**: 100 pages/month
+ - **Starter**: $0.10/page for up to 1,000 pages/month
+ - **Pro**: $0.08/page for up to 10,000 pages/month
+ - **Enterprise**: Custom pricing with volume discounts
+
+ Pricing is per page processed, not per document.
+
+
+
+ Yes! The free tier includes 100 pages per month with all features enabled and no credit card required.
+
+
+
+ A page is a single page in a document. A 10-page PDF counts as 10 pages. For spreadsheets, each sheet counts as one page.
+
+
+
+ Yes! Nvisy offers on-premises deployment for organizations with strict data residency requirements. Contact sales for pricing.
+
+
+
+## Technical
+
+
+
+ Yes! Nvisy provides a REST API and official SDKs for TypeScript/JavaScript and Python.
+
+ [View API documentation →](/api-reference/introduction)
+
+
+
+ Rate limits vary by plan:
+ - Free: 10 requests/second, 100/day
+ - Starter: 50 requests/second, 10,000/day
+ - Pro: 200 requests/second, 100,000/day
+ - Enterprise: Custom limits
+
+
+
+ By default:
+ - Processed documents: 30 days
+ - Audit trails: 7 years
+
+ You can configure custom retention policies or use on-premises deployment for complete control.
+
+
+
+ Yes! Nvisy integrates with:
+ - Cloud storage (S3, Google Drive, Dropbox)
+ - Collaboration tools (Slack, Teams)
+ - CRM systems (Salesforce, HubSpot)
+ - Document management (SharePoint, Confluence)
+ - Workflow automation (Zapier, n8n)
+
+ [View all integrations →](/features/integrations)
+
+
+
+ Official SDKs:
+ - TypeScript/JavaScript (Node.js and browser)
+ - Python (coming soon)
+
+ You can also use the REST API with any language.
+
+
+
+ Yes! Nvisy includes OCR (Optical Character Recognition) to extract and redact text from scanned documents and images.
+
+
+
+## Security & Compliance
+
+
+
+ Yes, Nvisy is HIPAA compliant. We can provide a Business Associate Agreement (BAA) for healthcare organizations.
+
+
+
+ Yes, Nvisy is fully GDPR compliant with data protection and privacy controls built-in.
+
+
+
+ - SOC 2 Type II
+ - PCI-DSS
+ - ISO 27001 (in progress)
+
+
+
+ - **In transit**: TLS 1.3
+ - **At rest**: AES-256
+ - **Key management**: AWS KMS or bring your own keys
+
+
+
+ Cloud deployment uses multi-region storage in:
+ - US East (Virginia)
+ - US West (Oregon)
+ - EU West (Ireland)
+ - Asia Pacific (Singapore)
+
+ You can specify your preferred region. On-premises deployment gives you complete control over data location.
+
+
+
+ No. With on-premises deployment, your documents never leave your infrastructure. For cloud deployment, documents are encrypted and automatically deleted after 30 days (configurable).
+
+
+
+ Yes! Every redaction includes a complete audit trail showing:
+ - Who initiated the redaction
+ - What was detected
+ - What was redacted
+ - When it occurred
+ - Confidence scores
+
+ [Learn about audit trails →](/features/audit-trails)
+
+
+
+## Getting Started
+
+
+
+ 1. Sign up at [nvisy.com](https://nvisy.com)
+ 2. Generate an API key
+ 3. Install the SDK or use the REST API
+ 4. Redact your first document
+
+ [View quickstart guide →](/quickstart)
+
+
+
+ For the API and SDKs, yes. However, we also offer a web interface for non-technical users. Enterprise customers can request custom integrations.
+
+
+
+ Absolutely! Use the free tier to test with up to 100 pages per month, no credit card required.
+
+
+
+ We offer:
+ - Documentation and guides
+ - Email support (support@nvisy.com)
+ - GitHub issues
+ - Enterprise customers get priority support with SLA
+
+
+
+## Features
+
+
+
+ Yes! You can:
+ - Set confidence thresholds
+ - Define custom patterns
+ - Review and approve/reject detections
+ - Choose redaction styles (black box, blur, pixelate)
+
+
+
+ Yes! Nvisy supports batch processing with parallel execution for faster processing of multiple documents.
+
+
+
+ Yes, Nvisy preserves the original document structure, fonts, images, and layout while redacting sensitive information.
+
+
+
+ Yes! Set up webhooks to receive real-time notifications for:
+ - Redaction completed
+ - Redaction failed
+ - Document uploaded
+ - Document deleted
+
+ [Learn about webhooks →](/api-reference/introduction#webhooks)
+
+
+
+ You can:
+ 1. Adjust the confidence threshold
+ 2. Add custom patterns for organization-specific data
+ 3. Review detections before finalizing
+ 4. Manually mark additional items for redaction
+
+
+
+ Yes! You can specify exactly which types to detect:
+ ```typescript
+ detectionTypes: ['pii'] // Only PII
+ detectionTypes: ['phi'] // Only PHI
+ detectionTypes: ['financial'] // Only financial
+ detectionTypes: ['pii', 'phi'] // Multiple types
+ ```
+
+
+
+## Deployment
+
+
+
+ - **Cloud**: Fully managed, auto-scaling
+ - **On-premises**: Complete control in your infrastructure
+ - **Hybrid**: Combine cloud and on-premises
+
+ [Compare deployment options →](/deployment/cloud/getting-started)
+
+
+
+ Production requirements:
+ - 16+ CPU cores
+ - 32 GB+ RAM
+ - 500 GB+ NVMe SSD
+ - 10 Gbps network
+ - Docker or Kubernetes
+
+ [View complete requirements →](/deployment/on-premise/requirements)
+
+
+
+ Yes! Nvisy can be deployed on AWS, Azure, Google Cloud, or any Kubernetes-compatible environment.
+
+
+
+ Yes, enterprise customers can request professional services for deployment, training, and custom integrations.
+
+
+
+## Troubleshooting
+
+
+
+ Common causes:
+ - API key not set in environment variables
+ - Using test key in production (or vice versa)
+ - API key expired or revoked
+ - Extra spaces or characters in the key
+
+ [Troubleshoot authentication →](/deployment/cloud/authentication)
+
+
+
+ Processing time depends on:
+ - Document size (pages)
+ - File format (PDFs are fastest)
+ - Detection types enabled
+ - Current system load
+
+ Average processing time is under 60 seconds. Large documents (100+ pages) may take longer.
+
+
+
+ You've exceeded your plan's rate limit. Solutions:
+ - Wait for the rate limit to reset
+ - Upgrade to a higher plan
+ - Implement exponential backoff in your code
+ - Contact sales for custom limits
+
+
+
+ Check:
+ - File size (max 100 MB by default)
+ - File format is supported
+ - File is not corrupted
+ - API key has upload permissions
+
+
+
+## Still Have Questions?
+
+
+
+ Read our comprehensive guides
+
+
+ Report issues or contribute
+
+
+ Contact our support team
+
+
+ Talk to sales about enterprise needs
+
+
diff --git a/favicon.svg b/favicon.svg
index b785c73..d5ddc9c 100644
--- a/favicon.svg
+++ b/favicon.svg
@@ -1,19 +1,25 @@
-
-Everything you need to create world-class documentation.
+## SDKs
-
+
- Use MDX to style your docs pages.
+ Official SDK for Node.js and browser environments with full TypeScript support
- Add sample code to demonstrate how to use your product.
+ Python SDK for server-side applications (coming soon)
+
+
+
+## API Reference
+
+
+ Comprehensive REST API documentation for integrating Nvisy into your applications
+
+
+## Deployment Options
+
+
+
+ Fully managed cloud deployment
- Display images and other media.
+ Complete control in your infrastructure
- Write once and reuse across your docs.
+ Flexible hybrid deployment model
-
+
-## Need inspiration?
+## Support
-
- Browse our showcase of exceptional documentation sites.
-
+
+
+ Contribute to the open-source project or report issues
+
+
+ Get help from our support team
+
+
diff --git a/quickstart.mdx b/quickstart.mdx
index c711458..b5a9754 100644
--- a/quickstart.mdx
+++ b/quickstart.mdx
@@ -1,80 +1,151 @@
---
title: "Quickstart"
-description: "Start building awesome documentation in minutes"
+description: "Get started with Nvisy document redaction in minutes"
---
-## Get started in three steps
+Redact your first document in under 5 minutes using Nvisy's API or SDKs.
-Get your documentation site running locally and make your first customization.
+## Step 1: Get Your API Key
-### Step 1: Set up your local environment
+Sign up at [nvisy.com](https://nvisy.com) and generate an API key from your dashboard.
-
-
- During the onboarding process, you created a GitHub repository with your docs content if you didn't already have one. You can find a link to this repository in your [dashboard](https://dashboard.mintlify.com).
-
- To clone the repository locally so that you can make and preview changes to your docs, follow the [Cloning a repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) guide in the GitHub docs.
-
-
- 1. Install the Mintlify CLI: `npm i -g mint`
- 2. Navigate to your docs directory and run: `mint dev`
- 3. Open `http://localhost:3000` to see your docs live!
-
- Your preview updates automatically as you edit files.
-
-
+
+ Keep your API key secure. Never commit it to version control. Use environment variables.
+
-### Step 2: Deploy your changes
+## Step 2: Choose Your Method
-
-
- Install the Mintlify GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app).
+
+
+ Install the SDK:
- Our GitHub app automatically deploys your changes to your docs site, so you don't need to manage deployments yourself.
-
-
- For a first change, let's update the name and colors of your docs site.
+ ```bash
+ npm install @nvisy/sdk
+ ```
+
+ Initialize and redact:
+
+ ```typescript
+ import { NvisyClient } from '@nvisy/sdk';
- 1. Open `docs.json` in your editor.
- 2. Change the `"name"` field to your project name.
- 3. Update the `"colors"` to match your brand.
- 4. Save and see your changes instantly at `http://localhost:3000`.
+ const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY
+ });
- Try changing the primary color to see an immediate difference!
-
-
+ const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi', 'financial']
+ });
-### Step 3: Go live
+ await result.downloadRedacted('./redacted.pdf');
+ console.log(`Redacted ${result.detections.length} items`);
+ ```
+
+ [View full TypeScript guide →](/sdks/typescript/quickstart)
+
+
+
+ Install the SDK:
+
+ ```bash
+ pip install nvisy
+ ```
+
+ Initialize and redact:
+
+ ```python
+ from nvisy import NvisyClient
+ import os
-
- 1. Commit and push your changes.
- 2. Your docs will update and be live in moments!
-
+ client = NvisyClient(api_key=os.getenv('NVISY_API_KEY'))
-## Next steps
+ result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii', 'phi', 'financial']
+ )
-Now that you have your docs running, explore these key features:
+ result.download_redacted('./redacted.pdf')
+ print(f"Redacted {len(result.detections)} items")
+ ```
+
+ [View full Python guide →](/sdks/python/quickstart)
+
+
+
+ Redact via REST API:
+
+ ```bash
+ curl -X POST https://api.nvisy.com/v1/documents/redact \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -F "file=@document.pdf" \
+ -F "detection_types=pii,phi,financial" \
+ -o redacted.pdf
+ ```
+
+ [View API reference →](/api-reference/introduction)
+
+
-
+## Detection Types
-
- Learn MDX syntax and start writing your documentation.
-
+| Type | Detects |
+|------|---------|
+| `pii` | Names, SSN, addresses, phone numbers, email |
+| `phi` | Medical records, diagnoses, prescriptions |
+| `financial` | Credit cards, bank accounts, tax IDs |
+| `custom` | Your organization-specific patterns |
-
- Make your docs match your brand perfectly.
-
+## Common Use Cases
-
- Include syntax-highlighted code blocks.
-
+
+
+ ```typescript
+ const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii'],
+ confidenceThreshold: 0.9 // Higher = fewer false positives
+ });
+ ```
+
+
+
+ ```typescript
+ const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['custom'],
+ customPatterns: [{
+ name: 'employee_id',
+ pattern: /EMP-\d{6}/g,
+ description: 'Employee IDs'
+ }]
+ });
+ ```
+
+
+
+ ```typescript
+ const results = await nvisy.documents.batchRedact({
+ files: ['doc1.pdf', 'doc2.pdf', 'doc3.pdf'],
+ detectionTypes: ['pii', 'phi'],
+ parallel: true
+ });
+ ```
+
+
-
- Auto-generate API docs from OpenAPI specs.
-
+## Next Steps
+
+
+ Explore redaction capabilities
+
+
+ Complete API documentation
+
+
+ Advanced TypeScript examples
+
+
+ Deploy Nvisy
+
-
-
- **Need help?** See our [full documentation](https://mintlify.com/docs) or join our [community](https://mintlify.com/community).
-
diff --git a/sdks/python/api-reference.mdx b/sdks/python/api-reference.mdx
new file mode 100644
index 0000000..e642469
--- /dev/null
+++ b/sdks/python/api-reference.mdx
@@ -0,0 +1,376 @@
+---
+title: "API Reference"
+description: "Complete Python SDK API reference"
+---
+
+
+ The Python SDK is currently in development. This documentation represents the planned API.
+
+
+## NvisyClient
+
+The main client class for interacting with the Nvisy API.
+
+### Constructor
+
+```python
+NvisyClient(
+ api_key: str,
+ environment: str = 'production',
+ base_url: Optional[str] = None,
+ timeout: int = 30,
+ max_retries: int = 3
+)
+```
+
+**Parameters:**
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `api_key` | `str` | Required | Your API key |
+| `environment` | `str` | `'production'` | 'production' or 'staging' |
+| `base_url` | `Optional[str]` | `None` | Custom API base URL |
+| `timeout` | `int` | `30` | Request timeout in seconds |
+| `max_retries` | `int` | `3` | Max retry attempts |
+
+## Documents API
+
+### `documents.redact()`
+
+Redact sensitive information from a document.
+
+```python
+documents.redact(
+ file: Union[str, Path, BinaryIO],
+ detection_types: List[DetectionType],
+ confidence_threshold: float = 0.8,
+ custom_patterns: Optional[List[CustomPattern]] = None,
+ preserve_formatting: bool = True,
+ redaction_style: RedactionStyle = 'black-box'
+) -> RedactionResult
+```
+
+**Parameters:**
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `file` | `str \| Path \| BinaryIO` | Required | File to redact |
+| `detection_types` | `List[DetectionType]` | Required | Types to detect |
+| `confidence_threshold` | `float` | `0.8` | Minimum confidence (0-1) |
+| `custom_patterns` | `List[CustomPattern]` | `None` | Custom patterns |
+| `preserve_formatting` | `bool` | `True` | Preserve formatting |
+| `redaction_style` | `RedactionStyle` | `'black-box'` | Redaction style |
+
+**Returns:** `RedactionResult`
+
+```python
+@dataclass
+class RedactionResult:
+ document_id: str
+ status: str
+ detections: List[Detection]
+ audit_trail: List[AuditEntry]
+
+ def download_redacted(self, path: Union[str, Path]) -> None: ...
+ def get_redacted_bytes(self) -> bytes: ...
+ def get_redacted_url(self) -> str: ...
+```
+
+**Example:**
+
+```python
+result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii', 'phi'],
+ confidence_threshold=0.85
+)
+```
+
+### `documents.upload()`
+
+Upload a document without redaction.
+
+```python
+documents.upload(
+ file: Union[str, Path, BinaryIO],
+ metadata: Optional[Dict[str, Any]] = None
+) -> Document
+```
+
+**Example:**
+
+```python
+document = client.documents.upload(
+ file='./document.pdf',
+ metadata={'department': 'hr'}
+)
+```
+
+### `documents.get()`
+
+Retrieve document information.
+
+```python
+documents.get(document_id: str) -> Document
+```
+
+### `documents.list()`
+
+List all documents.
+
+```python
+documents.list(
+ limit: int = 50,
+ offset: int = 0,
+ status: Optional[str] = None,
+ sort_by: str = 'created_at',
+ sort_order: str = 'desc'
+) -> DocumentList
+```
+
+### `documents.delete()`
+
+Delete a document.
+
+```python
+documents.delete(document_id: str) -> None
+```
+
+### `documents.batch_redact()`
+
+Redact multiple documents.
+
+```python
+documents.batch_redact(
+ files: List[Union[str, Path]],
+ detection_types: List[DetectionType],
+ parallel: bool = False,
+ max_concurrent: int = 5
+) -> BatchResult
+```
+
+**Example:**
+
+```python
+results = client.documents.batch_redact(
+ files=['doc1.pdf', 'doc2.pdf'],
+ detection_types=['pii'],
+ parallel=True
+)
+```
+
+## Detections API
+
+### `detections.analyze()`
+
+Analyze without redacting.
+
+```python
+detections.analyze(
+ file: Union[str, Path, BinaryIO],
+ detection_types: List[DetectionType]
+) -> AnalysisResult
+```
+
+## Webhooks API
+
+### `webhooks.create()`
+
+Create a webhook.
+
+```python
+webhooks.create(
+ url: str,
+ events: List[str],
+ secret: Optional[str] = None
+) -> Webhook
+```
+
+### `webhooks.list()`
+
+List webhooks.
+
+```python
+webhooks.list() -> List[Webhook]
+```
+
+### `webhooks.delete()`
+
+Delete a webhook.
+
+```python
+webhooks.delete(webhook_id: str) -> None
+```
+
+## Types
+
+### DetectionType
+
+```python
+DetectionType = Literal['pii', 'phi', 'financial', 'custom']
+```
+
+### RedactionStyle
+
+```python
+RedactionStyle = Literal['black-box', 'blur', 'pixelate']
+```
+
+### CustomPattern
+
+```python
+@dataclass
+class CustomPattern:
+ name: str
+ pattern: str # Regex pattern
+ description: Optional[str] = None
+```
+
+### Detection
+
+```python
+@dataclass
+class Detection:
+ id: str
+ type: DetectionType
+ confidence: float
+ page: int
+ text: str
+ coordinates: Optional[Dict[str, float]] = None
+```
+
+### Document
+
+```python
+@dataclass
+class Document:
+ id: str
+ filename: str
+ status: str
+ created_at: str
+ detections_count: int
+```
+
+### AuditEntry
+
+```python
+@dataclass
+class AuditEntry:
+ id: str
+ timestamp: str
+ action: str
+ user: Optional[Dict[str, str]] = None
+ details: Optional[Dict[str, Any]] = None
+```
+
+## Utility Functions
+
+### `verify_webhook_signature()`
+
+Verify webhook signatures.
+
+```python
+def verify_webhook_signature(
+ payload: bytes,
+ signature: str,
+ secret: str
+) -> bool
+```
+
+**Example:**
+
+```python
+from nvisy import verify_webhook_signature
+from flask import request
+
+@app.route('/webhooks/nvisy', methods=['POST'])
+def handle_webhook():
+ signature = request.headers.get('X-Nvisy-Signature')
+
+ is_valid = verify_webhook_signature(
+ payload=request.data,
+ signature=signature,
+ secret=webhook_secret
+ )
+
+ if not is_valid:
+ return 'Invalid signature', 401
+
+ return 'OK', 200
+```
+
+## AsyncNvisyClient
+
+Async version of the client for better performance.
+
+```python
+from nvisy import AsyncNvisyClient
+
+async with AsyncNvisyClient(api_key='...') as client:
+ result = await client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii']
+ )
+```
+
+All methods have async equivalents with the same signatures.
+
+## Exceptions
+
+### NvisyError
+
+Base exception for all Nvisy errors.
+
+```python
+class NvisyError(Exception):
+ message: str
+ status_code: Optional[int]
+```
+
+### AuthenticationError
+
+Raised when API key is invalid.
+
+```python
+class AuthenticationError(NvisyError):
+ pass
+```
+
+### RateLimitError
+
+Raised when rate limit is exceeded.
+
+```python
+class RateLimitError(NvisyError):
+ retry_after: int # Seconds to wait
+```
+
+### ValidationError
+
+Raised when request parameters are invalid.
+
+```python
+class ValidationError(NvisyError):
+ errors: Dict[str, List[str]]
+```
+
+### NotFoundError
+
+Raised when resource is not found.
+
+```python
+class NotFoundError(NvisyError):
+ resource_type: str
+ resource_id: str
+```
+
+## Next Steps
+
+
+
+ View code examples
+
+
+ Try the TypeScript SDK
+
+
diff --git a/sdks/python/examples.mdx b/sdks/python/examples.mdx
new file mode 100644
index 0000000..ded8abe
--- /dev/null
+++ b/sdks/python/examples.mdx
@@ -0,0 +1,573 @@
+---
+title: "Examples"
+description: "Code examples for common use cases with the Python SDK"
+---
+
+
+ The Python SDK is currently in development. These examples represent the planned API.
+
+
+## Basic Redaction
+
+Simple document redaction:
+
+```python
+from nvisy import NvisyClient
+import os
+
+client = NvisyClient(api_key=os.getenv('NVISY_API_KEY'))
+
+result = client.documents.redact(
+ file='./sensitive-document.pdf',
+ detection_types=['pii', 'phi', 'financial']
+)
+
+print(f"Redacted {len(result.detections)} items")
+result.download_redacted('./redacted.pdf')
+```
+
+## Custom Detection Patterns
+
+Define organization-specific patterns:
+
+```python
+from nvisy import CustomPattern
+
+result = client.documents.redact(
+ file='./employee-records.pdf',
+ detection_types=['custom'],
+ custom_patterns=[
+ CustomPattern(
+ name='employee_id',
+ pattern=r'EMP-\d{6}',
+ description='Employee ID: EMP-######'
+ ),
+ CustomPattern(
+ name='project_code',
+ pattern=r'PRJ-[A-Z]{3}-\d{4}',
+ description='Project code'
+ )
+ ]
+)
+```
+
+## Batch Processing
+
+Process multiple documents:
+
+```python
+from pathlib import Path
+from concurrent.futures import ThreadPoolExecutor
+
+files = list(Path('./documents').glob('*.pdf'))
+
+def redact_file(file_path):
+ return client.documents.redact(
+ file=str(file_path),
+ detection_types=['pii']
+ )
+
+# Process in parallel
+with ThreadPoolExecutor(max_workers=5) as executor:
+ results = list(executor.map(redact_file, files))
+
+print(f"Processed {len(results)} documents")
+```
+
+Or use the batch API:
+
+```python
+batch_result = client.documents.batch_redact(
+ files=['./doc1.pdf', './doc2.pdf', './doc3.pdf'],
+ detection_types=['pii', 'phi'],
+ parallel=True,
+ max_concurrent=5
+)
+
+for i, result in enumerate(batch_result.results):
+ if result.status == 'completed':
+ print(f"✓ File {i+1}")
+ else:
+ print(f"✗ File {i+1}: {result.error}")
+```
+
+## Async Processing
+
+Use async/await for better performance:
+
+```python
+import asyncio
+from nvisy import AsyncNvisyClient
+
+async def redact_documents():
+ async with AsyncNvisyClient(api_key=os.getenv('NVISY_API_KEY')) as client:
+ # Redact multiple documents concurrently
+ tasks = [
+ client.documents.redact(
+ file=f'./doc{i}.pdf',
+ detection_types=['pii']
+ )
+ for i in range(1, 6)
+ ]
+
+ results = await asyncio.gather(*tasks)
+
+ for i, result in enumerate(results, 1):
+ print(f"Document {i}: {len(result.detections)} detections")
+
+asyncio.run(redact_documents())
+```
+
+## Streaming Large Files
+
+Handle large files efficiently:
+
+```python
+with open('./large-document.pdf', 'rb') as file:
+ result = client.documents.redact(
+ file=file,
+ detection_types=['pii', 'phi']
+ )
+```
+
+## Django Integration
+
+Integrate with Django:
+
+```python
+from django.http import JsonResponse, FileResponse
+from django.views.decorators.csrf import csrf_exempt
+from nvisy import NvisyClient
+import os
+import tempfile
+
+client = NvisyClient(api_key=os.getenv('NVISY_API_KEY'))
+
+@csrf_exempt
+def redact_document(request):
+ if request.method == 'POST' and request.FILES.get('document'):
+ file = request.FILES['document']
+
+ result = client.documents.redact(
+ file=file,
+ detection_types=['pii', 'phi', 'financial']
+ )
+
+ # Save to temporary file
+ with tempfile.NamedTemporaryFile(delete=False) as tmp:
+ result.download_redacted(tmp.name)
+
+ response = FileResponse(
+ open(tmp.name, 'rb'),
+ as_attachment=True,
+ filename=f'redacted_{file.name}'
+ )
+ return response
+
+ return JsonResponse({'error': 'Invalid request'}, status=400)
+```
+
+## Flask Integration
+
+Integrate with Flask:
+
+```python
+from flask import Flask, request, send_file, jsonify
+from nvisy import NvisyClient
+import os
+import tempfile
+
+app = Flask(__name__)
+client = NvisyClient(api_key=os.getenv('NVISY_API_KEY'))
+
+@app.route('/redact', methods=['POST'])
+def redact():
+ if 'file' not in request.files:
+ return jsonify({'error': 'No file provided'}), 400
+
+ file = request.files['file']
+
+ # Redact document
+ result = client.documents.redact(
+ file=file,
+ detection_types=['pii', 'phi', 'financial']
+ )
+
+ # Save to temporary file
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp:
+ result.download_redacted(tmp.name)
+ return send_file(
+ tmp.name,
+ as_attachment=True,
+ download_name=f'redacted_{file.filename}'
+ )
+
+if __name__ == '__main__':
+ app.run()
+```
+
+## Webhook Handler
+
+Handle webhook events:
+
+```python
+from flask import Flask, request
+from nvisy import verify_webhook_signature
+
+app = Flask(__name__)
+
+@app.route('/webhooks/nvisy', methods=['POST'])
+def handle_webhook():
+ signature = request.headers.get('X-Nvisy-Signature')
+
+ # Verify signature
+ is_valid = verify_webhook_signature(
+ payload=request.data,
+ signature=signature,
+ secret=os.getenv('WEBHOOK_SECRET')
+ )
+
+ if not is_valid:
+ return 'Invalid signature', 401
+
+ event = request.json
+
+ if event['type'] == 'redaction.completed':
+ document_id = event['data']['document_id']
+ print(f"Redaction completed: {document_id}")
+ # Process completed redaction
+
+ elif event['type'] == 'redaction.failed':
+ document_id = event['data']['document_id']
+ error = event['data']['error']
+ print(f"Redaction failed: {document_id} - {error}")
+ # Handle failure
+
+ return 'OK', 200
+```
+
+## Error Handling with Retry
+
+Implement retry logic:
+
+```python
+from nvisy.exceptions import RateLimitError, NvisyError
+import time
+
+def redact_with_retry(file_path, max_retries=3):
+ for attempt in range(max_retries):
+ try:
+ result = client.documents.redact(
+ file=file_path,
+ detection_types=['pii']
+ )
+ return result
+
+ except RateLimitError as e:
+ if attempt < max_retries - 1:
+ print(f"Rate limited, waiting {e.retry_after}s...")
+ time.sleep(e.retry_after)
+ continue
+ raise
+
+ except NvisyError as e:
+ if attempt < max_retries - 1:
+ wait_time = 2 ** attempt # Exponential backoff
+ print(f"Error occurred, retrying in {wait_time}s...")
+ time.sleep(wait_time)
+ continue
+ raise
+
+result = redact_with_retry('./document.pdf')
+```
+
+## Complete Workflow
+
+End-to-end example:
+
+```python
+from nvisy import NvisyClient
+from pathlib import Path
+import json
+import os
+
+def complete_workflow():
+ client = NvisyClient(api_key=os.getenv('NVISY_API_KEY'))
+
+ try:
+ # 1. Upload and redact
+ print('Processing document...')
+ result = client.documents.redact(
+ file='./sensitive-data.pdf',
+ detection_types=['pii', 'phi', 'financial'],
+ confidence_threshold=0.85
+ )
+
+ # 2. Review detections
+ print(f"\nFound {len(result.detections)} sensitive items:")
+ for i, detection in enumerate(result.detections, 1):
+ confidence_pct = detection.confidence * 100
+ print(f"{i}. {detection.type} ({confidence_pct:.1f}% confidence)")
+
+ # 3. Download redacted file
+ print('\nDownloading redacted document...')
+ result.download_redacted('./redacted-data.pdf')
+
+ # 4. Save audit trail
+ print('Saving audit trail...')
+ with open('./audit-trail.json', 'w') as f:
+ json.dump(
+ [vars(entry) for entry in result.audit_trail],
+ f,
+ indent=2
+ )
+
+ # 5. Generate report
+ detections_by_type = {}
+ for d in result.detections:
+ detections_by_type[d.type] = detections_by_type.get(d.type, 0) + 1
+
+ report = {
+ 'document_id': result.document_id,
+ 'processed_at': str(result.audit_trail[-1].timestamp),
+ 'detections_count': len(result.detections),
+ 'detections_by_type': detections_by_type
+ }
+
+ print('\nRedaction Report:')
+ print(json.dumps(report, indent=2))
+
+ print('\n✓ Workflow complete!')
+
+ except Exception as e:
+ print(f"❌ Workflow failed: {e}")
+ raise
+
+if __name__ == '__main__':
+ complete_workflow()
+```
+
+## Testing
+
+Mock the client for testing:
+
+```python
+from unittest.mock import Mock, patch
+import pytest
+from nvisy import NvisyClient
+
+def test_document_redaction():
+ # Mock the client
+ with patch('nvisy.NvisyClient') as MockClient:
+ mock_result = Mock()
+ mock_result.document_id = 'doc_123'
+ mock_result.status = 'completed'
+ mock_result.detections = [
+ Mock(type='pii', confidence=0.95)
+ ]
+
+ mock_client = MockClient.return_value
+ mock_client.documents.redact.return_value = mock_result
+
+ # Test
+ client = NvisyClient(api_key='test-key')
+ result = client.documents.redact(
+ file='./test.pdf',
+ detection_types=['pii']
+ )
+
+ assert result.status == 'completed'
+ assert len(result.detections) == 1
+ mock_client.documents.redact.assert_called_once()
+```
+
+## Logging
+
+Configure logging for debugging:
+
+```python
+import logging
+
+# Enable SDK logging
+logging.basicConfig(
+ level=logging.DEBUG,
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
+)
+
+logger = logging.getLogger('nvisy')
+logger.setLevel(logging.DEBUG)
+
+# Now SDK operations will be logged
+result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii']
+)
+```
+
+## Troubleshooting
+
+### Common Issues
+
+
+
+ **Cause**: Package not installed or wrong Python environment
+
+ **Solution**:
+ ```bash
+ # Verify installation
+ pip show nvisy
+
+ # Reinstall if needed
+ pip install nvisy
+
+ # Check which Python
+ which python
+ python --version
+ ```
+
+
+
+ **Cause**: Invalid or missing API key
+
+ **Solution**:
+ ```python
+ import os
+
+ # Check API key is set
+ api_key = os.getenv('NVISY_API_KEY')
+ if not api_key:
+ print("API key not set")
+
+ # Load from .env file
+ from dotenv import load_dotenv
+ load_dotenv()
+ ```
+
+
+
+ **Cause**: Too many requests
+
+ **Solution**:
+ ```python
+ from nvisy.exceptions import RateLimitError
+ import time
+
+ try:
+ result = client.documents.redact(...)
+ except RateLimitError as e:
+ # Wait before retrying
+ time.sleep(e.retry_after)
+ # Retry request
+ ```
+
+
+
+ **Cause**: Incorrect file path
+
+ **Solution**:
+ ```python
+ from pathlib import Path
+
+ # Check file exists
+ file_path = Path('./document.pdf')
+ if not file_path.exists():
+ print(f"File not found: {file_path}")
+
+ # Check file size
+ if file_path.stat().st_size > 100 * 1024 * 1024:
+ print("File too large (max 100MB)")
+ ```
+
+
+
+ **Cause**: Network or certificate issues
+
+ **Solution**:
+ ```python
+ # Not recommended for production
+ import urllib3
+ urllib3.disable_warnings()
+
+ # Or update certificates
+ pip install --upgrade certifi
+ ```
+
+
+
+### Debugging
+
+Enable debug logging:
+
+```python
+import logging
+
+# Enable SDK logging
+logging.basicConfig(
+ level=logging.DEBUG,
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
+)
+
+logger = logging.getLogger('nvisy')
+logger.setLevel(logging.DEBUG)
+```
+
+Inspect requests:
+
+```python
+import http.client as http_client
+
+# Enable HTTP debugging
+http_client.HTTPConnection.debuglevel = 1
+```
+
+### Performance Tips
+
+1. **Use context managers**:
+ ```python
+ with NvisyClient(api_key='...') as client:
+ result = client.documents.redact(...)
+ # Automatically cleaned up
+ ```
+
+2. **Async for better concurrency**:
+ ```python
+ import asyncio
+ from nvisy import AsyncNvisyClient
+
+ async with AsyncNvisyClient(api_key='...') as client:
+ tasks = [client.documents.redact(...) for _ in range(10)]
+ results = await asyncio.gather(*tasks)
+ ```
+
+3. **Reuse client instances**:
+ ```python
+ # Good: Reuse client
+ client = NvisyClient(api_key='...')
+ for file in files:
+ result = client.documents.redact(file=file)
+
+ # Bad: Create new client each time
+ for file in files:
+ client = NvisyClient(api_key='...') # ❌
+ ```
+
+4. **Use generators for large datasets**:
+ ```python
+ def process_documents(files):
+ for file in files:
+ yield client.documents.redact(file=file)
+
+ for result in process_documents(large_file_list):
+ print(f"Processed {result.document_id}")
+ ```
+
+## Next Steps
+
+
+
+ Complete API documentation
+
+
+ Try the TypeScript SDK
+
+
diff --git a/sdks/python/quickstart.mdx b/sdks/python/quickstart.mdx
new file mode 100644
index 0000000..d978ff3
--- /dev/null
+++ b/sdks/python/quickstart.mdx
@@ -0,0 +1,214 @@
+---
+title: "Quick Start"
+description: "Install and get started with the Python SDK in minutes"
+---
+
+
+ The Python SDK is currently in development and has not been published to PyPI yet. This documentation represents the planned API.
+
+
+## Installation
+
+Once published, install the Nvisy SDK from PyPI:
+
+
+
+```bash pip
+pip install nvisy
+```
+
+```bash poetry
+poetry add nvisy
+```
+
+```bash pipenv
+pipenv install nvisy
+```
+
+
+
+## Requirements
+
+- **Python** 3.8 or higher
+- **pip** or **poetry** for package management
+
+## Initialize the Client
+
+```python
+from nvisy import NvisyClient
+import os
+
+client = NvisyClient(
+ api_key=os.getenv('NVISY_API_KEY'),
+ environment='production', # or 'staging'
+ base_url='https://api.nvisy.com' # optional
+)
+```
+
+
+ Keep your API key secure. Never commit it to version control. Use environment variables.
+
+
+## Your First Redaction
+
+Redact a document in 3 lines of code:
+
+```python
+result = client.documents.redact(
+ file='./sensitive-document.pdf',
+ detection_types=['pii', 'phi', 'financial']
+)
+
+print(f"Found {len(result.detections)} sensitive items")
+result.download_redacted('./redacted.pdf')
+```
+
+## Constructor Parameters
+
+```python
+class NvisyClient:
+ def __init__(
+ self,
+ api_key: str, # Required
+ environment: str = 'production', # 'production' or 'staging'
+ base_url: Optional[str] = None, # Custom API URL
+ timeout: int = 30, # Request timeout in seconds
+ max_retries: int = 3 # Max retry attempts
+ )
+```
+
+## Basic Usage Patterns
+
+### Redact with Custom Confidence
+
+```python
+result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii'],
+ confidence_threshold=0.9 # Higher = fewer false positives
+)
+```
+
+### Redact with Custom Patterns
+
+```python
+from nvisy import CustomPattern
+
+result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['custom'],
+ custom_patterns=[
+ CustomPattern(
+ name='employee_id',
+ pattern=r'EMP-\d{6}',
+ description='Employee ID: EMP-######'
+ )
+ ]
+)
+```
+
+### Analyze Without Redacting
+
+```python
+analysis = client.detections.analyze(
+ file='./document.pdf',
+ detection_types=['pii', 'phi']
+)
+
+for detection in analysis.detections:
+ print(f"Found {detection.type} with {detection.confidence} confidence")
+```
+
+## Error Handling
+
+```python
+from nvisy.exceptions import (
+ NvisyError,
+ AuthenticationError,
+ RateLimitError,
+ ValidationError
+)
+
+try:
+ result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii']
+ )
+except AuthenticationError:
+ print("Invalid API key")
+except RateLimitError as e:
+ print(f"Rate limit exceeded. Retry after {e.retry_after}s")
+except ValidationError as e:
+ print(f"Invalid parameters: {e.message}")
+except NvisyError as e:
+ print(f"Nvisy error: {e.message}")
+```
+
+## Context Manager
+
+Use the client as a context manager:
+
+```python
+with NvisyClient(api_key=os.getenv('NVISY_API_KEY')) as client:
+ result = client.documents.redact(
+ file='./document.pdf',
+ detection_types=['pii']
+ )
+ result.download_redacted('./redacted.pdf')
+# Client automatically cleaned up
+```
+
+## Async Support
+
+Use async/await for better performance:
+
+```python
+import asyncio
+from nvisy import AsyncNvisyClient
+
+async def redact_documents():
+ async with AsyncNvisyClient(api_key=os.getenv('NVISY_API_KEY')) as client:
+ tasks = [
+ client.documents.redact(
+ file=f'./doc{i}.pdf',
+ detection_types=['pii']
+ )
+ for i in range(1, 6)
+ ]
+
+ results = await asyncio.gather(*tasks)
+
+ for i, result in enumerate(results, 1):
+ print(f"Document {i}: {len(result.detections)} detections")
+
+asyncio.run(redact_documents())
+```
+
+## Virtual Environment Setup
+
+We recommend using a virtual environment:
+
+```bash
+# Create virtual environment
+python -m venv venv
+
+# Activate (Linux/Mac)
+source venv/bin/activate
+
+# Activate (Windows)
+venv\Scripts\activate
+
+# Install Nvisy
+pip install nvisy
+```
+
+## Next Steps
+
+
+
+ View complete API documentation
+
+
+ Explore advanced examples
+
+
diff --git a/sdks/typescript/api-reference.mdx b/sdks/typescript/api-reference.mdx
new file mode 100644
index 0000000..96a42f4
--- /dev/null
+++ b/sdks/typescript/api-reference.mdx
@@ -0,0 +1,337 @@
+---
+title: "API Reference"
+description: "Complete TypeScript SDK API reference"
+---
+
+## NvisyClient
+
+The main client class for interacting with the Nvisy API.
+
+### Constructor
+
+```typescript
+new NvisyClient(options: NvisyClientOptions)
+```
+
+**Parameters:**
+
+| Parameter | Type | Required | Default | Description |
+|-----------|------|----------|---------|-------------|
+| `apiKey` | `string` | Yes | - | Your API key |
+| `environment` | `'production' \| 'staging'` | No | `'production'` | Environment |
+| `baseUrl` | `string` | No | `https://api.nvisy.com` | Custom API base URL |
+| `timeout` | `number` | No | `30000` | Request timeout in ms |
+| `maxRetries` | `number` | No | `3` | Max retry attempts |
+
+## Documents API
+
+### `documents.redact()`
+
+Redact sensitive information from a document.
+
+```typescript
+documents.redact(options: RedactOptions): Promise
+```
+
+**Parameters:**
+
+| Parameter | Type | Required | Default | Description |
+|-----------|------|----------|---------|-------------|
+| `file` | `string \| File \| Buffer \| ReadStream` | Yes | - | File to redact |
+| `detectionTypes` | `DetectionType[]` | Yes | - | Types to detect |
+| `confidenceThreshold` | `number` | No | `0.8` | Minimum confidence (0-1) |
+| `customPatterns` | `CustomPattern[]` | No | - | Custom regex patterns |
+| `preserveFormatting` | `boolean` | No | `true` | Preserve formatting |
+| `redactionStyle` | `RedactionStyle` | No | `'black-box'` | Redaction style |
+
+**Returns:** `Promise`
+
+```typescript
+interface RedactionResult {
+ documentId: string;
+ status: 'completed' | 'processing' | 'failed';
+ detections: Detection[];
+ auditTrail: AuditEntry[];
+ downloadRedacted: (path?: string) => Promise;
+ getRedactedBuffer: () => Promise;
+ getRedactedUrl: () => string;
+}
+```
+
+**Example:**
+
+```typescript
+const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi'],
+ confidenceThreshold: 0.85
+});
+```
+
+### `documents.upload()`
+
+Upload a document without immediate redaction.
+
+```typescript
+documents.upload(options: UploadOptions): Promise
+```
+
+**Parameters:**
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `file` | `string \| File \| Buffer \| ReadStream` | Yes | File to upload |
+| `metadata` | `Record` | No | Custom metadata |
+
+**Example:**
+
+```typescript
+const document = await nvisy.documents.upload({
+ file: './document.pdf',
+ metadata: {
+ department: 'hr',
+ tags: ['confidential']
+ }
+});
+```
+
+### `documents.get()`
+
+Retrieve document information.
+
+```typescript
+documents.get(documentId: string): Promise
+```
+
+**Example:**
+
+```typescript
+const document = await nvisy.documents.get('doc_abc123');
+console.log(document.status);
+```
+
+### `documents.list()`
+
+List all documents.
+
+```typescript
+documents.list(options?: ListOptions): Promise
+```
+
+**Parameters:**
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `limit` | `number` | `50` | Number of results |
+| `offset` | `number` | `0` | Offset for pagination |
+| `status` | `DocumentStatus` | - | Filter by status |
+| `sortBy` | `string` | `'created_at'` | Sort field |
+| `sortOrder` | `'asc' \| 'desc'` | `'desc'` | Sort order |
+
+**Example:**
+
+```typescript
+const documents = await nvisy.documents.list({
+ limit: 100,
+ status: 'completed'
+});
+```
+
+### `documents.delete()`
+
+Delete a document.
+
+```typescript
+documents.delete(documentId: string): Promise
+```
+
+**Example:**
+
+```typescript
+await nvisy.documents.delete('doc_abc123');
+```
+
+### `documents.batchRedact()`
+
+Redact multiple documents in parallel.
+
+```typescript
+documents.batchRedact(options: BatchRedactOptions): Promise
+```
+
+**Parameters:**
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `files` | `Array` | Yes | Files to redact |
+| `detectionTypes` | `DetectionType[]` | Yes | Types to detect |
+| `parallel` | `boolean` | No | Process in parallel |
+| `maxConcurrent` | `number` | No | Max concurrent jobs |
+
+**Example:**
+
+```typescript
+const results = await nvisy.documents.batchRedact({
+ files: ['doc1.pdf', 'doc2.pdf', 'doc3.pdf'],
+ detectionTypes: ['pii'],
+ parallel: true,
+ maxConcurrent: 5
+});
+```
+
+## Detections API
+
+### `detections.analyze()`
+
+Analyze without redacting.
+
+```typescript
+detections.analyze(options: AnalyzeOptions): Promise
+```
+
+**Example:**
+
+```typescript
+const analysis = await nvisy.detections.analyze({
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi']
+});
+```
+
+## Webhooks API
+
+### `webhooks.create()`
+
+Create a webhook.
+
+```typescript
+webhooks.create(options: WebhookOptions): Promise
+```
+
+**Parameters:**
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `url` | `string` | Yes | Webhook endpoint URL |
+| `events` | `WebhookEvent[]` | Yes | Events to subscribe |
+| `secret` | `string` | No | Secret for verification |
+
+**Example:**
+
+```typescript
+const webhook = await nvisy.webhooks.create({
+ url: 'https://your-app.com/webhooks/nvisy',
+ events: ['redaction.completed', 'redaction.failed'],
+ secret: 'webhook_secret'
+});
+```
+
+### `webhooks.list()`
+
+List webhooks.
+
+```typescript
+webhooks.list(): Promise
+```
+
+### `webhooks.delete()`
+
+Delete a webhook.
+
+```typescript
+webhooks.delete(webhookId: string): Promise
+```
+
+## Types
+
+### DetectionType
+
+```typescript
+type DetectionType = 'pii' | 'phi' | 'financial' | 'custom';
+```
+
+### RedactionStyle
+
+```typescript
+type RedactionStyle = 'black-box' | 'blur' | 'pixelate';
+```
+
+### CustomPattern
+
+```typescript
+interface CustomPattern {
+ name: string;
+ pattern: RegExp;
+ description?: string;
+}
+```
+
+### Detection
+
+```typescript
+interface Detection {
+ id: string;
+ type: DetectionType;
+ confidence: number;
+ page: number;
+ text: string;
+ coordinates?: {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+ };
+}
+```
+
+### AuditEntry
+
+```typescript
+interface AuditEntry {
+ id: string;
+ timestamp: string;
+ action: string;
+ user?: {
+ id: string;
+ email: string;
+ };
+ details?: Record;
+}
+```
+
+## Utility Functions
+
+### `verifyWebhookSignature()`
+
+Verify webhook signatures.
+
+```typescript
+function verifyWebhookSignature(
+ payload: any,
+ signature: string,
+ secret: string
+): boolean
+```
+
+**Example:**
+
+```typescript
+import { verifyWebhookSignature } from '@nvisy/sdk';
+
+const isValid = verifyWebhookSignature(
+ req.body,
+ req.headers['x-nvisy-signature'],
+ webhookSecret
+);
+```
+
+## Next Steps
+
+
+
+ View code examples
+
+
+ REST API documentation
+
+
diff --git a/sdks/typescript/examples.mdx b/sdks/typescript/examples.mdx
new file mode 100644
index 0000000..5584168
--- /dev/null
+++ b/sdks/typescript/examples.mdx
@@ -0,0 +1,594 @@
+---
+title: "Examples"
+description: "Code examples for common use cases with the TypeScript SDK"
+---
+
+## Basic Redaction
+
+Simple document redaction:
+
+```typescript
+import { NvisyClient } from '@nvisy/sdk';
+
+const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY
+});
+
+const result = await nvisy.documents.redact({
+ file: './sensitive-document.pdf',
+ detectionTypes: ['pii', 'phi', 'financial']
+});
+
+console.log(`Redacted ${result.detections.length} items`);
+await result.downloadRedacted('./redacted.pdf');
+```
+
+## Custom Detection Patterns
+
+Define organization-specific patterns:
+
+```typescript
+const result = await nvisy.documents.redact({
+ file: './employee-records.pdf',
+ detectionTypes: ['custom'],
+ customPatterns: [
+ {
+ name: 'employee_id',
+ pattern: /EMP-\d{6}/g,
+ description: 'Employee ID: EMP-######'
+ },
+ {
+ name: 'project_code',
+ pattern: /PRJ-[A-Z]{3}-\d{4}/g,
+ description: 'Project code: PRJ-XXX-####'
+ },
+ {
+ name: 'internal_phone',
+ pattern: /x\d{4}/gi,
+ description: 'Extension numbers'
+ }
+ ]
+});
+```
+
+## Batch Processing
+
+Process multiple documents:
+
+```typescript
+const files = [
+ './doc1.pdf',
+ './doc2.docx',
+ './doc3.xlsx'
+];
+
+// Option 1: Using Promise.all
+const results = await Promise.all(
+ files.map(file =>
+ nvisy.documents.redact({
+ file,
+ detectionTypes: ['pii']
+ })
+ )
+);
+
+// Option 2: Using batch API
+const batchResult = await nvisy.documents.batchRedact({
+ files: files,
+ detectionTypes: ['pii', 'phi'],
+ parallel: true,
+ maxConcurrent: 5
+});
+
+batchResult.results.forEach((result, i) => {
+ if (result.status === 'completed') {
+ console.log(`✓ ${files[i]}`);
+ } else {
+ console.log(`✗ ${files[i]}: ${result.error}`);
+ }
+});
+```
+
+## Streaming Large Files
+
+Handle large files efficiently:
+
+```typescript
+import { createReadStream } from 'fs';
+
+const stream = createReadStream('./large-document.pdf');
+
+const result = await nvisy.documents.redact({
+ file: stream,
+ detectionTypes: ['pii', 'phi']
+});
+```
+
+## Browser File Upload
+
+Handle file uploads in web applications:
+
+```typescript
+// React example
+function FileUploader() {
+ const handleUpload = async (event: React.ChangeEvent) => {
+ const file = event.target.files?.[0];
+ if (!file) return;
+
+ const nvisy = new NvisyClient({
+ apiKey: process.env.REACT_APP_NVISY_API_KEY
+ });
+
+ const result = await nvisy.documents.redact({
+ file: file,
+ detectionTypes: ['pii', 'phi']
+ });
+
+ // Download redacted file
+ const blob = await result.getRedactedBlob();
+ const url = URL.createObjectURL(blob);
+
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = `redacted-${file.name}`;
+ a.click();
+ };
+
+ return ;
+}
+```
+
+## Webhook Integration
+
+Set up webhooks for async processing:
+
+```typescript
+// Create webhook
+const webhook = await nvisy.webhooks.create({
+ url: 'https://your-app.com/webhooks/nvisy',
+ events: ['redaction.completed', 'redaction.failed'],
+ secret: 'your_webhook_secret'
+});
+
+// Express.js webhook handler
+import express from 'express';
+import { verifyWebhookSignature } from '@nvisy/sdk';
+
+const app = express();
+
+app.post('/webhooks/nvisy', express.raw({ type: 'application/json' }), (req, res) => {
+ const signature = req.headers['x-nvisy-signature'] as string;
+
+ const isValid = verifyWebhookSignature(
+ req.body,
+ signature,
+ webhook.secret
+ );
+
+ if (!isValid) {
+ return res.status(401).send('Invalid signature');
+ }
+
+ const event = JSON.parse(req.body.toString());
+
+ if (event.type === 'redaction.completed') {
+ console.log('Redaction completed:', event.data.document_id);
+ // Process completed redaction
+ }
+
+ res.status(200).send('OK');
+});
+```
+
+## Advanced Configuration
+
+Customize detection behavior:
+
+```typescript
+const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi'],
+ confidenceThreshold: 0.9,
+ preserveFormatting: true,
+ redactionStyle: 'blur',
+ metadata: {
+ department: 'legal',
+ case_number: 'CASE-2024-001'
+ }
+});
+
+// Review detections before finalizing
+result.detections.forEach(detection => {
+ console.log(`${detection.type}: ${detection.confidence.toFixed(2)}`);
+});
+```
+
+## Error Handling
+
+Comprehensive error handling:
+
+```typescript
+import {
+ NvisyError,
+ AuthenticationError,
+ RateLimitError,
+ ValidationError,
+ NotFoundError
+} from '@nvisy/sdk';
+
+async function redactWithRetry(file: string, maxRetries = 3) {
+ for (let i = 0; i < maxRetries; i++) {
+ try {
+ const result = await nvisy.documents.redact({
+ file,
+ detectionTypes: ['pii']
+ });
+ return result;
+
+ } catch (error) {
+ if (error instanceof AuthenticationError) {
+ throw new Error('Invalid API key - cannot retry');
+ }
+
+ if (error instanceof RateLimitError) {
+ const delay = error.retryAfter * 1000;
+ console.log(`Rate limited, waiting ${delay}ms...`);
+ await new Promise(resolve => setTimeout(resolve, delay));
+ continue;
+ }
+
+ if (error instanceof ValidationError) {
+ console.error('Validation error:', error.message);
+ throw error;
+ }
+
+ if (i === maxRetries - 1) {
+ throw error;
+ }
+
+ // Exponential backoff
+ await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
+ }
+ }
+}
+```
+
+## Testing
+
+Mock the SDK for testing:
+
+```typescript
+import { jest } from '@jest/globals';
+import { NvisyClient } from '@nvisy/sdk';
+
+// Mock the client
+jest.mock('@nvisy/sdk');
+
+describe('Document Redaction', () => {
+ it('should redact a document', async () => {
+ const mockRedact = jest.fn().mockResolvedValue({
+ documentId: 'doc_123',
+ status: 'completed',
+ detections: [
+ { type: 'pii', confidence: 0.95 }
+ ]
+ });
+
+ (NvisyClient as jest.Mock).mockImplementation(() => ({
+ documents: {
+ redact: mockRedact
+ }
+ }));
+
+ const nvisy = new NvisyClient({ apiKey: 'test-key' });
+ const result = await nvisy.documents.redact({
+ file: './test.pdf',
+ detectionTypes: ['pii']
+ });
+
+ expect(result.status).toBe('completed');
+ expect(mockRedact).toHaveBeenCalledWith({
+ file: './test.pdf',
+ detectionTypes: ['pii']
+ });
+ });
+});
+```
+
+## TypeScript Types
+
+Leverage full type safety:
+
+```typescript
+import type {
+ NvisyClient,
+ RedactionResult,
+ Detection,
+ DetectionType,
+ CustomPattern,
+ RedactionOptions
+} from '@nvisy/sdk';
+
+// Type-safe configuration
+const options: RedactionOptions = {
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi'],
+ confidenceThreshold: 0.85
+};
+
+// Type-safe result handling
+const result: RedactionResult = await nvisy.documents.redact(options);
+
+result.detections.forEach((detection: Detection) => {
+ // Full autocomplete and type checking
+ console.log(detection.type, detection.confidence);
+});
+```
+
+## Next.js API Route
+
+Server-side redaction in Next.js:
+
+```typescript
+// pages/api/redact.ts
+import { NvisyClient } from '@nvisy/sdk';
+import { NextApiRequest, NextApiResponse } from 'next';
+import formidable from 'formidable';
+
+export const config = {
+ api: {
+ bodyParser: false,
+ },
+};
+
+const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY!
+});
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ if (req.method !== 'POST') {
+ return res.status(405).json({ error: 'Method not allowed' });
+ }
+
+ const form = formidable();
+ const [fields, files] = await form.parse(req);
+
+ const file = files.file?.[0];
+ if (!file) {
+ return res.status(400).json({ error: 'No file uploaded' });
+ }
+
+ try {
+ const result = await nvisy.documents.redact({
+ file: file.filepath,
+ detectionTypes: ['pii', 'phi', 'financial']
+ });
+
+ res.status(200).json({
+ documentId: result.documentId,
+ detections: result.detections.length,
+ downloadUrl: result.getRedactedUrl()
+ });
+ } catch (error) {
+ res.status(500).json({ error: 'Redaction failed' });
+ }
+}
+```
+
+## Complete Workflow
+
+End-to-end example:
+
+```typescript
+import { NvisyClient } from '@nvisy/sdk';
+import { writeFile } from 'fs/promises';
+
+async function completeWorkflow() {
+ const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY
+ });
+
+ try {
+ // 1. Upload and redact
+ console.log('Uploading document...');
+ const result = await nvisy.documents.redact({
+ file: './sensitive-data.pdf',
+ detectionTypes: ['pii', 'phi', 'financial'],
+ confidenceThreshold: 0.85
+ });
+
+ // 2. Review detections
+ console.log(`\nFound ${result.detections.length} sensitive items:`);
+ result.detections.forEach((detection, i) => {
+ console.log(
+ `${i + 1}. ${detection.type} ` +
+ `(confidence: ${(detection.confidence * 100).toFixed(1)}%)`
+ );
+ });
+
+ // 3. Download redacted file
+ console.log('\nDownloading redacted document...');
+ await result.downloadRedacted('./redacted-data.pdf');
+
+ // 4. Save audit trail
+ console.log('\nSaving audit trail...');
+ await writeFile(
+ './audit-trail.json',
+ JSON.stringify(result.auditTrail, null, 2)
+ );
+
+ // 5. Generate report
+ const report = {
+ documentId: result.documentId,
+ processedAt: new Date().toISOString(),
+ detectionsCount: result.detections.length,
+ detectionsByType: result.detections.reduce((acc, d) => {
+ acc[d.type] = (acc[d.type] || 0) + 1;
+ return acc;
+ }, {} as Record)
+ };
+
+ console.log('\nRedaction Report:');
+ console.log(JSON.stringify(report, null, 2));
+
+ console.log('\n✓ Workflow complete!');
+ } catch (error) {
+ console.error('❌ Workflow failed:', error);
+ throw error;
+ }
+}
+
+completeWorkflow();
+```
+
+## Troubleshooting
+
+### Common Issues
+
+
+
+ **Cause**: Package not installed or wrong directory
+
+ **Solution**:
+ ```bash
+ # Verify installation
+ npm list @nvisy/sdk
+
+ # Reinstall if needed
+ npm install @nvisy/sdk
+
+ # Check you're in the right directory
+ ls package.json
+ ```
+
+
+
+ **Cause**: Invalid or missing API key
+
+ **Solution**:
+ ```typescript
+ // Check API key is set
+ console.log('API Key:', process.env.NVISY_API_KEY ? 'Set' : 'Not set');
+
+ // Verify .env file is loaded
+ import dotenv from 'dotenv';
+ dotenv.config();
+ ```
+
+
+
+ **Cause**: Too many requests
+
+ **Solution**:
+ ```typescript
+ import { RateLimitError } from '@nvisy/sdk';
+
+ try {
+ const result = await nvisy.documents.redact({...});
+ } catch (error) {
+ if (error instanceof RateLimitError) {
+ // Wait before retrying
+ await new Promise(r => setTimeout(r, error.retryAfter * 1000));
+ // Retry request
+ }
+ }
+ ```
+
+
+
+ **Cause**: File too large or invalid format
+
+ **Solution**:
+ ```typescript
+ import fs from 'fs';
+
+ // Check file size (max 100MB)
+ const stats = fs.statSync('./file.pdf');
+ if (stats.size > 100 * 1024 * 1024) {
+ console.error('File too large');
+ }
+
+ // Verify file exists
+ if (!fs.existsSync('./file.pdf')) {
+ console.error('File not found');
+ }
+ ```
+
+
+
+ **Cause**: Missing or outdated types
+
+ **Solution**:
+ ```bash
+ # Update to latest version
+ npm update @nvisy/sdk
+
+ # Verify TypeScript version (need 4.5+)
+ npx tsc --version
+ ```
+
+
+
+### Debugging
+
+Enable debug logging:
+
+```typescript
+const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY,
+ logLevel: 'debug' // Enable debug logs
+});
+```
+
+Check request details:
+
+```typescript
+nvisy.on('request', (config) => {
+ console.log('Request:', config);
+});
+
+nvisy.on('response', (response) => {
+ console.log('Response:', response);
+});
+```
+
+### Performance Tips
+
+1. **Use streaming for large files**:
+ ```typescript
+ import { createReadStream } from 'fs';
+ const stream = createReadStream('./large-file.pdf');
+ const result = await nvisy.documents.redact({ file: stream, ... });
+ ```
+
+2. **Enable parallel processing**:
+ ```typescript
+ const results = await Promise.all(
+ files.map(file => nvisy.documents.redact({ file, ... }))
+ );
+ ```
+
+3. **Reuse client instances**:
+ ```typescript
+ // Good: Reuse client
+ const nvisy = new NvisyClient({...});
+
+ // Bad: Create new client each time
+ for (const file of files) {
+ const nvisy = new NvisyClient({...}); // ❌
+ }
+ ```
+
+## Next Steps
+
+
+
+ Complete API documentation
+
+
+ Try the Python SDK
+
+
diff --git a/sdks/typescript/quickstart.mdx b/sdks/typescript/quickstart.mdx
new file mode 100644
index 0000000..b58845a
--- /dev/null
+++ b/sdks/typescript/quickstart.mdx
@@ -0,0 +1,169 @@
+---
+title: "Quick Start"
+description: "Install and get started with the TypeScript SDK in minutes"
+---
+
+## Installation
+
+Install the Nvisy SDK from npm:
+
+
+
+```bash npm
+npm install @nvisy/sdk
+```
+
+```bash yarn
+yarn add @nvisy/sdk
+```
+
+```bash pnpm
+pnpm add @nvisy/sdk
+```
+
+
+
+
+ View the package on npm
+
+
+## Requirements
+
+- **Node.js** 16 or higher (for server-side)
+- **Modern browser** with ES2020 support (for client-side)
+- **TypeScript** 4.5+ (optional, for type support)
+
+## Initialize the Client
+
+```typescript
+import { NvisyClient } from '@nvisy/sdk';
+
+const nvisy = new NvisyClient({
+ apiKey: process.env.NVISY_API_KEY,
+ // Optional: specify environment
+ environment: 'production', // or 'staging'
+ // Optional: custom base URL for self-hosted instances
+ baseUrl: 'https://api.nvisy.com'
+});
+```
+
+
+ Keep your API key secure. Never commit it to version control or expose it in client-side code. Use environment variables.
+
+
+## Your First Redaction
+
+Redact a document in 3 lines of code:
+
+```typescript
+const result = await nvisy.documents.redact({
+ file: './sensitive-document.pdf',
+ detectionTypes: ['pii', 'phi', 'financial']
+});
+
+console.log(`Found ${result.detections.length} sensitive items`);
+await result.downloadRedacted('./redacted.pdf');
+```
+
+## Constructor Options
+
+```typescript
+interface NvisyClientOptions {
+ apiKey: string; // Required: Your API key
+ environment?: 'production' | 'staging'; // Default: 'production'
+ baseUrl?: string; // Custom API base URL
+ timeout?: number; // Request timeout in ms (default: 30000)
+ maxRetries?: number; // Max retry attempts (default: 3)
+}
+```
+
+## Basic Usage Patterns
+
+### Redact with Custom Confidence
+
+```typescript
+const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii'],
+ confidenceThreshold: 0.9 // Higher confidence = fewer false positives
+});
+```
+
+### Redact with Custom Patterns
+
+```typescript
+const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['custom'],
+ customPatterns: [
+ {
+ name: 'employee_id',
+ pattern: /EMP-\d{6}/g,
+ description: 'Employee ID format: EMP-######'
+ }
+ ]
+});
+```
+
+### Upload and Analyze Without Redacting
+
+```typescript
+const analysis = await nvisy.detections.analyze({
+ file: './document.pdf',
+ detectionTypes: ['pii', 'phi']
+});
+
+analysis.detections.forEach(detection => {
+ console.log(`Found ${detection.type} with ${detection.confidence} confidence`);
+});
+```
+
+## Error Handling
+
+```typescript
+import { NvisyError, AuthenticationError, RateLimitError } from '@nvisy/sdk';
+
+try {
+ const result = await nvisy.documents.redact({
+ file: './document.pdf',
+ detectionTypes: ['pii']
+ });
+} catch (error) {
+ if (error instanceof AuthenticationError) {
+ console.error('Invalid API key');
+ } else if (error instanceof RateLimitError) {
+ console.error('Rate limit exceeded. Retry after:', error.retryAfter);
+ } else if (error instanceof NvisyError) {
+ console.error('Nvisy error:', error.message);
+ } else {
+ console.error('Unexpected error:', error);
+ }
+}
+```
+
+## TypeScript Configuration
+
+If using TypeScript, ensure your `tsconfig.json` includes:
+
+```json
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "commonjs",
+ "lib": ["ES2020"],
+ "esModuleInterop": true,
+ "strict": true
+ }
+}
+```
+
+## Next Steps
+
+
+
+ View complete API documentation
+
+
+ Explore advanced examples
+
+
diff --git a/snippets/snippet-intro.mdx b/snippets/snippet-intro.mdx
deleted file mode 100644
index e20fbb6..0000000
--- a/snippets/snippet-intro.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
-One of the core principles of software development is DRY (Don't Repeat
-Yourself). This is a principle that applies to documentation as
-well. If you find yourself repeating the same content in multiple places, you
-should consider creating a custom snippet to keep your content in sync.