PrivacyPal SDK v1.0.0
Node.js Python

PrivacyPal SDK

The PrivacyPal SDK lets you encode sensitive data into Privacy Twins before it reaches an AI model, then decode the response to restore original values. Available for both Node.js and Python — identical API surface, same endpoint, same behavior.

Node.js

@privacypal/sdk

Async/await API. Works with Express, Next.js, Fastify, and any Node.js runtime.

npm install @privacypal/sdk
Python

privacypal-sdk

Synchronous API built on requests. Works with FastAPI, Django, Flask, and any Python 3.10+ runtime.

pip install privacypal-sdk

Installation

Install the SDK for your language. Both packages expose identical functionality.

npm install @privacypal/sdk

Requires Node.js 18 or later. TypeScript types are included.

pip install privacypal-sdk

Requires Python 3.10 or later. Installs requests as the only dependency.

Initialization

Create a client instance with your API URL and API key. You can obtain an API key from the PrivacyPal Portal.

initialize-client
import { PrivacyPalClient } from '@privacypal/sdk';

const client = new PrivacyPalClient({
  apiUrl: 'https://api.privacypal.ai',
  apiKey: process.env.PRIVACYPAL_API_KEY,
});

// Verify connectivity (optional)
const health = await client.healthCheck();
console.log(health.success); // true
from privacypal_sdk import PrivacyPalClient
import os

client = PrivacyPalClient(
  api_url='https://api.privacypal.ai',
  api_key=os.environ['PRIVACYPAL_API_KEY'],
)

# Verify connectivity (optional)
health = client.health_check()
print(health['success'])  # True

Encoding (Protect Data)

encode scans a string for PII and replaces sensitive values with Privacy Twins. Returns encodedData that is safe to pass to AI models, and a continuationId needed to decode later.

encode
const encoded = await client.encode({
  data: 'Patient: Jane Doe, DOB: 1985-03-15, SSN: 123-45-6789',
  sourceContainer: 'my-app',        // identifies your application
  sourceElement: 'patient-record',   // identifies the data field
  scoreThreshold: 0.35,              // PII confidence threshold (default)
  language: 'en',                    // language hint (default)
});

console.log(encoded.encodedData);    // "Patient: [TWIN-A1B2], DOB: [TWIN-C3D4]..."
console.log(encoded.continuationId); // keep this to decode later
console.log(encoded.transformations); // list of PII replacements made
encoded = client.encode(
  'Patient: Jane Doe, DOB: 1985-03-15, SSN: 123-45-6789',
  source_container='my-app',       # identifies your application
  source_element='patient-record',  # identifies the data field
  score_threshold=0.35,             # PII confidence threshold (default)
  language='en',                    # language hint (default)
)

print(encoded['encodedData'])     # "Patient: [TWIN-A1B2], DOB: [TWIN-C3D4]..."
print(encoded['continuationId'])  # keep this to decode later
print(encoded['transformations'])  # list of PII replacements made

To encode multiple items in one request, use encodeBatch / encode_batch. To encode a file (PDF, DOCX, CSV, image), use encodeFile / encode_file.

Decoding (Restore Data)

Pass the continuationId from the encode response alongside text containing Privacy Twins to restore original sensitive values.

decode
// Encode first
const encoded = await client.encode({
  data: 'Call me at 555-867-5309, I am Sarah Connor',
  sourceContainer: 'chatbot',
  sourceElement: 'user-message'
});

// Send encoded data to AI, get a response with Privacy Twins
const aiReply = await callOpenAI(encoded.encodedData);

// Decode the AI response — restore original values
const decoded = await client.decode({
  continuationId: encoded.continuationId,
  data: aiReply.content,
  sensitiveHashes: encoded.transformations.map(t => t.originalHash),
  authorization: { token: 'your-jwt', purpose: 'Display to user' },
});

console.log(decoded.decodedData); // Real names and numbers restored
# Encode first
encoded = client.encode(
  'Call me at 555-867-5309, I am Sarah Connor',
  source_container='chatbot',
  source_element='user-message'
)

# Send encoded data to AI, get a response with Privacy Twins
ai_reply = call_openai(encoded['encodedData'])

# Decode the AI response — restore original values
decoded = client.decode(
  continuation_id=encoded['continuationId'],
  data=ai_reply['content'],
  sensitive_hashes=[t['originalHash'] for t in encoded['transformations']],
  authorization={'token': 'your-jwt', 'purpose': 'Display to user'},
)

print(decoded['decodedData'])  # Real names and numbers restored

AI Chat (Built-in Encode/Decode)

Use chatWithAI to send prompts through PrivacyPal's AI gateway, which automatically encodes PII before forwarding to the LLM and decodes the response.

chat-with-ai
const result = await client.chatWithAI({
  prompt: 'Summarise the patient notes for Jane Doe.',
  model: 'gemini-2.0-flash-exp',
  provider: 'vertex',
});

console.log(result.decodedResponse); // Decoded — real names in the answer
result = client.chat_with_ai(
  prompt='Summarise the patient notes for Jane Doe.',
  model='gemini-2.0-flash-exp',
  provider='vertex',
)

print(result['decodedResponse'])  # Decoded — real names in the answer

Error Handling

Node.js: Throws Error — check err.message for status prefixes. Python: Raises typed exceptions (AuthenticationError, TrialExpiredError, NetworkError).

Exception / Pattern HTTP Status When it occurs
AuthenticationError / "401:"401Missing, expired, or invalid API key
TrialExpiredError / "403:" or "[Trial expired]"403Trial ended or subscription required
NetworkError / "Network Error:"Cannot reach the API (connection refused, DNS failure)
RequestError / "Request Error:"Request configuration error
error-handling
try {
  const encoded = await client.encode({ data: '...' });
} catch (err) {
  if (err.message?.startsWith('401:')) {
    console.error('Invalid or expired API key');
  } else if (err.message?.startsWith('403:') || err.message?.includes('Trial expired')) {
    console.error('Subscription required');
  } else if (err.message?.includes('Network Error')) {
    console.error('Cannot reach API');
  } else {
    throw err;
  }
}
from privacypal_sdk import (
  PrivacyPalClient,
  AuthenticationError,
  TrialExpiredError,
  NetworkError,
)

try:
  encoded = client.encode('...')
except AuthenticationError:
  print('Invalid or expired API key')
except TrialExpiredError:
  print('Subscription required')
except NetworkError:
  print('Cannot reach API')
except Exception as e:
  raise

Examples

Real workflows from production deployments — encode at the boundary, hand twins to an external agent or API, decode the response back to real values.

Agent entry point for secure A2A communication

Encode the sensitive input, hand the twins off to an external agent, then decode the response back to original values.

agent-a2a
const encoded = await client.encode({
  data: 'User: John Smith, Email: john@acme.com, ID: user-123',
  sourceContainer: 'my-agent',
  sourceElement: 'user_input',
});

// Share encoded data with an external agent
const response = await sendToExternalAgent(encoded.encodedData);

// Decode the response back to real values
const decoded = await client.decode({
  continuationId: encoded.continuationId,
  data: response.text,
});

console.log(decoded.decodedData);
encoded = client.encode(
  'User: John Smith, Email: john@acme.com, ID: user-123',
  source_container='my-agent',
  source_element='user_input',
)

# Share encoded data with an external agent
response = send_to_external_agent(encoded['encodedData'])

# Decode the response back to real values
decoded = client.decode(
  continuation_id=encoded['continuationId'],
  data=response['text'],
)

print(decoded['decodedData'])

Healthcare AI: patient data to a 3rd-party analyzer

Encode PHI before sending to a vendor API, decode the analysis on the way back — HIPAA-compliant by design.

healthcare-ai
const encoded = await client.encode({
  data: 'Patient: Jane Doe, DOB: 1985-03-15, Dx: Condition X',
  sourceContainer: 'ehr-system',
  sourceElement: 'patient-record',
});

const analysis = await fetch('https://vendor-api.com/analyze', {
  method: 'POST',
  body: JSON.stringify({ data: encoded.encodedData }),
});

const result = await client.decode({
  continuationId: encoded.continuationId,
  data: (await analysis.json()).report,
});
encoded = client.encode(
  'Patient: Jane Doe, DOB: 1985-03-15, Dx: Condition X',
  source_container='ehr-system',
  source_element='patient-record',
)

response = requests.post(
  'https://vendor-api.com/analyze',
  json={'data': encoded['encodedData']},
)

result = client.decode(
  continuation_id=encoded['continuationId'],
  data=response.json()['report'],
)

Financial services: decentralized dark pool x402 coming soon

Encode trade info to protect trader identity, match through Privacy Twins, and (in a future release) decode only after x402 payment is settled.

dark-pool
// Future: import { x402Middleware } from '@x402/payment';

const encoded = await client.encode({
  data: 'Trader: trader-789, Symbol: AAPL, Qty: 1000',
  sourceContainer: 'dark-pool',
  sourceElement: 'trade-request',
});

const match = await findCounterparty(encoded.encodedData);

if (match.found) {
  // Future: x402 payment required before decode
  const realData = await client.decode({
    continuationId: encoded.continuationId,
    data: match.counterpartyData,
  });
  return realData.decodedData;
}
# Future: from x402 import middleware

encoded = client.encode(
  'Trader: trader-789, Symbol: AAPL, Qty: 1000',
  source_container='dark-pool',
  source_element='trade-request',
)

match = find_counterparty(encoded['encodedData'])

if match['found']:
  # Future: x402 payment required before decode
  real_data = client.decode(
    continuation_id=encoded['continuationId'],
    data=match['counterpartyData'],
  )
  return real_data['decodedData']

Full API Reference

Explore all endpoints, request/response schemas, and try the API interactively. Open API Reference →