SDK Reference
Last Updated: 2026-02-17 SDK Versions: JavaScript 1.0.0 | Python 1.0.0
Overview#
cloak.business provides official SDKs for JavaScript/TypeScript and Python.
Package Links:
- JavaScript/TypeScript: npmjs.com/package/@cloak-business/sdk
- Python: pypi.org/project/cloak-business
Source Code: SDK_packages/ folder in the cloak.business repository
- JavaScript SDK:
SDK_packages/sdk-js/ - Python SDK:
SDK_packages/sdk-python/
These SDKs offer:
- Type-safe API access with full TypeScript/Python type hints
- Automatic error handling with typed error classes
- Retry logic with exponential backoff
- Client-side encryption for true zero-knowledge security
- All API endpoints wrapped in convenient methods
Table of Contents#
JavaScript/TypeScript SDK#
Installation#
npm install @cloak-business/sdk
# or
yarn add @cloak-business/sdk
# or
pnpm add @cloak-business/sdk
Requirements: Node.js 18+ or modern browser with Web Crypto API
Quick Start#
import { CloakClient } from '@cloak-business/sdk';
// Initialize client
const client = new CloakClient({
apiKey: process.env.CLOAK_API_KEY!,
});
// Analyze text for PII
const analysis = await client.analyze({
text: 'Contact John Doe at john@example.com',
language: 'en',
});
console.log(`Found ${analysis.results.length} entities`);
// Anonymize the text
const anonymized = await client.anonymize({
text: 'Contact John Doe at john@example.com',
analyzerResults: analysis.results,
operators: {
PERSON: { type: 'replace', new_value: '[REDACTED]' },
EMAIL_ADDRESS: { type: 'hash', hash_type: 'sha256' },
},
});
console.log(anonymized.text);
// Output: "Contact [REDACTED] at 3c4a7b8d9e0f..."
Client Configuration#
import { CloakClient, CloakClientConfig } from '@cloak-business/sdk';
const config: CloakClientConfig = {
// Required
apiKey: 'cb_your_api_key_here',
// Optional
baseUrl: 'https://cloak.business/api', // Default
timeout: 30000, // 30 seconds
maxRetries: 3, // Retry failed requests
};
const client = new CloakClient(config);
Text Analysis#
Basic Analysis
const result = await client.analyze({
text: 'My SSN is 123-45-6789',
language: 'en',
});
// Result:
// {
// results: [
// { entity_type: 'US_SSN', start: 10, end: 21, score: 0.95, text: '123-45-6789' }
// ],
// tokens_charged: 2
// }
With Options
const result = await client.analyze({
text: 'Call me at 555-123-4567',
language: 'en',
entities: ['PHONE_NUMBER', 'EMAIL_ADDRESS'], // Only detect these
scoreThreshold: 0.7, // Minimum confidence
});
Batch Analysis
const result = await client.batchAnalyze({
texts: [
'Email: john@test.com',
'Phone: 555-123-4567',
'SSN: 123-45-6789',
],
language: 'en',
});
// Access results by index
result.results.forEach((item, index) => {
console.log(`Text ${index}: ${item.entities.length} entities found`);
});
Custom Recognizers
const result = await client.analyze({
text: 'Employee ID: EMP-12345',
adHocRecognizers: [
{
entityType: 'EMPLOYEE_ID',
patterns: [
{ name: 'emp_pattern', regex: 'EMP-\\d{5}', score: 0.9 }
],
context: ['employee', 'staff', 'worker'],
},
],
});
Anonymization#
Basic Anonymization
// First analyze
const analysis = await client.analyze({ text: 'Contact John at john@test.com' });
// Then anonymize
const result = await client.anonymize({
text: 'Contact John at john@test.com',
analyzerResults: analysis.results,
});
// Default: replaces with <ENTITY_TYPE>
// Output: "Contact <PERSON> at <EMAIL_ADDRESS>"
Operator Types
const result = await client.anonymize({
text: 'John Doe, SSN: 123-45-6789, email: john@test.com',
analyzerResults: analysis.results,
operators: {
// Replace with custom value
PERSON: { type: 'replace', new_value: '[NAME REDACTED]' },
// Hash (one-way, irreversible)
EMAIL_ADDRESS: { type: 'hash', hash_type: 'sha256' },
// Mask partially
US_SSN: { type: 'mask', masking_char: '*', chars_to_mask: 5, from_end: false },
// Encrypt (reversible with key)
PHONE_NUMBER: { type: 'encrypt', key: 'your-32-char-encryption-key!!' },
// Remove completely
CREDIT_CARD: { type: 'redact' },
// Keep original (useful with presets)
DATE_TIME: { type: 'keep' },
},
});
Deanonymization (Decrypt)
// Store the anonymize result for later decryption
const anonymized = await client.anonymize({
text: 'Contact John Doe',
analyzerResults: [{ entity_type: 'PERSON', start: 8, end: 16, score: 0.85 }],
operators: {
PERSON: { type: 'encrypt', key: 'your-32-char-encryption-key!!' },
},
});
// Later: decrypt
const decrypted = await client.deanonymize({
text: anonymized.text,
anonymizerResults: anonymized.items,
operators: {
PERSON: { type: 'decrypt', key: 'your-32-char-encryption-key!!' },
},
});
console.log(decrypted.text); // "Contact John Doe"
Client-Side Encryption (JS)#
For true zero-knowledge security where encryption keys never leave your device, use the ClientCrypto module:
import { ClientCrypto } from '@cloak-business/sdk';
// Generate a random encryption key (store securely!)
const key = await ClientCrypto.generateKey();
console.log(key); // Base64-encoded 256-bit key
// Encrypt data locally
const encrypted = await ClientCrypto.encrypt(key, 'Sensitive data here');
// {
// ciphertext: 'base64...',
// iv: 'base64...',
// version: 1
// }
// Decrypt locally
const decrypted = await ClientCrypto.decrypt(key, encrypted);
console.log(decrypted); // 'Sensitive data here'
// Encrypt/decrypt objects
const user = { name: 'John', ssn: '123-45-6789' };
const encryptedUser = await ClientCrypto.encryptObject(key, user);
const decryptedUser = await ClientCrypto.decryptObject<typeof user>(key, encryptedUser);
Password-Derived Keys
// Derive key from password (for user-based encryption)
const salt = ClientCrypto.generateSalt();
const key = await ClientCrypto.deriveKeyFromPassword(
'user-password',
salt,
100000 // iterations (PBKDF2)
);
// Store the salt with the encrypted data (salt is not secret)
Security Notes
ClientCryptouses AES-256-GCM (AEAD cipher)- Keys are 32 bytes (256 bits)
- IVs are 12 bytes, randomly generated per encryption
- All operations use the Web Crypto API (CSPRNG)
Error Handling (JS)#
import {
CloakClient,
CloakError,
AuthenticationError,
RateLimitError,
InsufficientTokensError,
ValidationError,
} from '@cloak-business/sdk';
try {
const result = await client.analyze({ text: 'test' });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof InsufficientTokensError) {
console.error('Not enough tokens. Please top up.');
} else if (error instanceof ValidationError) {
console.error('Invalid request:', error.message);
} else if (error instanceof CloakError) {
console.error(`API error: ${error.code} - ${error.message}`);
}
}
Python SDK#
Installation (Python)#
pip install cloak-business
For client-side encryption:
pip install cloak-business[crypto]
# or
pip install cloak-business cryptography
Requirements: Python 3.9+
Quick Start (Python)#
from cloak_business import CloakClient
# Initialize client
client = CloakClient(api_key="cb_your_api_key_here")
# Analyze text
analysis = client.analyze(text="Contact John Doe at john@example.com")
print(f"Found {len(analysis.results)} entities")
# Anonymize
result = client.anonymize(
text="Contact John Doe at john@example.com",
analyzer_results=analysis.results,
operators={
"PERSON": {"type": "replace", "new_value": "[REDACTED]"},
"EMAIL_ADDRESS": {"type": "hash", "hash_type": "sha256"},
}
)
print(result.text)
Client Configuration (Python)#
from cloak_business import CloakClient, CloakClientConfig
config = CloakClientConfig(
api_key="cb_your_api_key_here",
base_url="https://cloak.business/api", # Optional
timeout=30.0, # Seconds
max_retries=3,
)
client = CloakClient(config=config)
# or simply:
client = CloakClient(api_key="cb_your_api_key_here")
Text Analysis (Python)#
# Basic analysis
result = client.analyze(text="My SSN is 123-45-6789")
for entity in result.results:
print(f"{entity.entity_type}: {entity.text} (score: {entity.score})")
# With options
result = client.analyze(
text="Call 555-123-4567",
language="en",
entities=["PHONE_NUMBER", "EMAIL_ADDRESS"],
score_threshold=0.7,
)
# Batch analysis
result = client.batch_analyze(
texts=["Email: john@test.com", "Phone: 555-1234"],
language="en",
)
# Custom recognizers
result = client.analyze(
text="Order ID: ORD-123456",
ad_hoc_recognizers=[
{
"entity_type": "ORDER_ID",
"patterns": [{"name": "order", "regex": r"ORD-\d{6}", "score": 0.9}],
}
],
)
Anonymization (Python)#
# Analyze first
analysis = client.analyze(text="John Doe, john@test.com, 555-1234")
# Anonymize with operators
result = client.anonymize(
text="John Doe, john@test.com, 555-1234",
analyzer_results=analysis.results,
operators={
"PERSON": {"type": "replace", "new_value": "[NAME]"},
"EMAIL_ADDRESS": {"type": "hash", "hash_type": "sha256"},
"PHONE_NUMBER": {"type": "mask", "masking_char": "*", "chars_to_mask": 4},
}
)
print(result.text)
# Output: "[NAME], 3c4a7b8d..., ***-1234"
Encryption & Deanonymization
ENCRYPTION_KEY = "your-32-character-key-here!!"
# Encrypt
anonymized = client.anonymize(
text="Contact John Doe",
analyzer_results=[{"entity_type": "PERSON", "start": 8, "end": 16, "score": 0.85}],
operators={"PERSON": {"type": "encrypt", "key": ENCRYPTION_KEY}},
)
# Later: decrypt
decrypted = client.deanonymize(
text=anonymized.text,
anonymizer_results=anonymized.items,
operators={"PERSON": {"type": "decrypt", "key": ENCRYPTION_KEY}},
)
print(decrypted.text) # "Contact John Doe"
Client-Side Encryption (Python)#
For true zero-knowledge encryption:
from cloak_business import ClientCrypto, ClientEncryptedData
# Check if cryptography library is available
if not ClientCrypto.is_available():
print("Install cryptography: pip install cryptography")
# Generate a random key
key = ClientCrypto.generate_key() # Base64-encoded 256-bit key
# Encrypt
encrypted: ClientEncryptedData = ClientCrypto.encrypt(key, "Sensitive data")
# Decrypt
decrypted = ClientCrypto.decrypt(key, encrypted)
print(decrypted) # "Sensitive data"
# Object encryption
data = {"name": "John", "ssn": "123-45-6789"}
encrypted = ClientCrypto.encrypt_object(key, data)
decrypted = ClientCrypto.decrypt_object(key, encrypted)
# Password-derived keys
salt = ClientCrypto.generate_salt()
derived_key = ClientCrypto.derive_key_from_password(
password="user-password",
salt=salt,
iterations=100000,
)
# Serialize for storage
encrypted_dict = ClientCrypto.encrypted_data_to_dict(encrypted)
restored = ClientCrypto.encrypted_data_from_dict(encrypted_dict)
Error Handling (Python)#
from cloak_business import (
CloakClient,
CloakError,
AuthenticationError,
RateLimitError,
InsufficientTokensError,
ValidationError,
NetworkError,
TimeoutError,
)
client = CloakClient(api_key="cb_your_key")
try:
result = client.analyze(text="test")
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except InsufficientTokensError:
print("Not enough tokens")
except ValidationError as e:
print(f"Invalid request: {e.message}")
except TimeoutError:
print("Request timed out")
except NetworkError:
print("Network error")
except CloakError as e:
print(f"API error: {e.code} - {e.message}")
Security Model#
Server-Side Encryption#
When using the encrypt operator through the API:
- Encryption key is transmitted over HTTPS
- Server encrypts data and immediately discards the key
- Server never stores your encryption key
- Convenient for most use cases
Client-Side Encryption (Zero-Knowledge)#
When using ClientCrypto:
- Encryption key never leaves your device
- All encryption/decryption happens locally
- Server never sees plaintext or keys
- Use for maximum security requirements
Choosing the Right Approach#
| Use Case | Recommendation |
|---|---|
| General PII anonymization | Server-side (encrypt operator) |
| Regulatory compliance (GDPR, HIPAA) | Server-side is compliant |
| Maximum security / zero-trust | Client-side (ClientCrypto) |
| Performance-critical applications | Server-side (less overhead) |
| Offline capability needed | Client-side |
Best Practices#
1. Secure Key Storage#
// DON'T: Hardcode keys
const key = "hardcoded-key"; // Bad!
// DO: Use environment variables
const key = process.env.ENCRYPTION_KEY;
// DO: Use a secrets manager
const key = await secretsManager.getSecret("cloak-encryption-key");
2. Error Handling#
// Always handle errors appropriately
try {
const result = await client.analyze({ text });
} catch (error) {
if (error instanceof RateLimitError) {
await sleep(error.retryAfter * 1000);
return retry();
}
throw error;
}
3. Batch Processing#
// DON'T: Make individual requests in a loop
for (const text of texts) {
await client.analyze({ text }); // Slow!
}
// DO: Use batch endpoint
const result = await client.batchAnalyze({ texts });
4. Key Rotation#
// Store key version with encrypted data
const encrypted = {
...await ClientCrypto.encrypt(currentKey, data),
keyVersion: 2,
};
// Decrypt with appropriate key version
const key = keyVersions[encrypted.keyVersion];
const decrypted = await ClientCrypto.decrypt(key, encrypted);
FAQ#
General Questions#
Q: Which SDK should I use? A: Choose based on your tech stack:
- JavaScript/TypeScript SDK: For Node.js backends, React/Vue/Angular frontends, or any JavaScript environment
- Python SDK: For Python backends, data pipelines, Jupyter notebooks, or ML workflows
Q: Are the SDKs open source?
A: Yes. The SDK source code is available in the SDK_packages/ folder in the cloak.business repository. You can view the implementations, report issues, and contribute improvements.
Q: Do the SDKs support all API features? A: Yes. Both SDKs support 100% of the cloak.business API including:
- Text analysis (single and batch)
- Anonymization with all operators (replace, redact, hash, mask, encrypt)
- Deanonymization (decrypt)
- Image analysis and redaction
- Account management (token balance, sessions)
- Custom recognizers
Installation#
Q: What are the minimum requirements? A:
- JavaScript SDK: Node.js 18+ or any modern browser with Web Crypto API
- Python SDK: Python 3.9+
Q: How do I install the crypto extras for Python?
A: Use the crypto extra: pip install cloak-business[crypto]. This installs the cryptography package needed for ClientCrypto.
Q: Do the SDKs work in browsers? A: The JavaScript SDK works in both Node.js and modern browsers. The Python SDK is designed for server-side use.
Client-Side Encryption#
Q: What's the difference between server-side and client-side encryption? A:
- Server-side (
encryptoperator): Key is sent over HTTPS, server encrypts, then discards the key immediately - Client-side (
ClientCrypto): Key never leaves your device, all encryption/decryption happens locally
Q: Which encryption algorithm does ClientCrypto use? A: AES-256-GCM (AEAD cipher) with randomly generated 12-byte IVs. This is the same algorithm used by major password managers and secure messaging apps.
Q: Can I use my own encryption key?
A: Yes. You can provide your own 32-byte (256-bit) key encoded as Base64, or derive a key from a password using deriveKeyFromPassword() with PBKDF2.
Q: What happens if I lose my encryption key? A: Data encrypted with a lost key cannot be recovered. Always securely back up your encryption keys. Consider using Shamir Secret Sharing for critical keys.
Error Handling#
Q: How do I handle rate limits?
A: The SDKs include automatic retry with exponential backoff. If you receive a RateLimitError, check the retryAfter property for the recommended wait time in seconds.
Q: What errors should I handle? A: At minimum, handle these error types:
AuthenticationError: Invalid or expired API keyRateLimitError: Too many requests (checkretryAfter)InsufficientTokensError: Account needs more tokensValidationError: Invalid request parameters
Versioning#
Q: How are SDK versions numbered? A: Both SDKs use semantic versioning (MAJOR.MINOR.PATCH) and are always released with the same version number to ensure compatibility.
Q: Will SDK updates break my code? A: We follow semver strictly:
- Patch updates (1.0.x): Bug fixes, no breaking changes
- Minor updates (1.x.0): New features, backwards compatible
- Major updates (x.0.0): Breaking changes (rare, with migration guides)
Related Documentation#
- API Reference - Complete REST API documentation
- Quick Start - Get started in 5 minutes
- Error Codes - All error codes explained
- Zero-Knowledge Auth - ZK authentication system
Document maintained by cloak.business Contact: support@cloak.business