Deep Encrypt
Recursively encrypt all fields in a nested JSON object using the Cipherion API
Deep Encrypt
deep_encrypt recursively traverses a JSON object or array and encrypts every leaf field value — replacing each one with an encrypted package while preserving the original structure exactly. Keys, nesting levels, and array ordering are all maintained. Only the values at the leaves of the object tree are replaced.
This makes it ideal for encrypting complex server-side payloads — such as user records, order objects, or API request bodies — without changing the shape of the data your services depend on.
Endpoint
POST /deep_encrypt/:projectIdDeep encrypt is ideal for encrypting complex data structures (e.g. user records, order payloads) while preserving non-sensitive metadata like IDs and timestamps in plaintext.
How It Works
When you send a JSON payload to /deep_encrypt, the API walks the entire object tree recursively:
- Primitive leaf values (strings, numbers, booleans) are encrypted and replaced with an encrypted package string.
- Objects are traversed recursively — the API descends into each nested object and encrypts its leaf values.
- Arrays are processed element by element. If an array contains objects, each object is traversed recursively. If an array contains primitive values, each element is encrypted individually.
nullandundefinedvalues are preserved as-is and never encrypted.- Keys and structural metadata — field names, nesting, array indices — are never modified.
The result is a structurally identical object where every sensitive value has been replaced with an encrypted package, and non-sensitive fields (excluded via exclude_fields or exclude_patterns) remain in plaintext.
Recursive Traversal Example
Given this input:
{
"user_id": "u_99283",
"personal_info": {
"full_name": "Sarah Connor",
"ssn": "999-00-1234",
"address": {
"street": "123 Tech Blvd",
"city": "Cyberdyne"
}
},
"tags": ["customer", "premium"]
}After deep_encrypt (with user_id excluded):
{
"user_id": "u_99283",
"personal_info": {
"full_name": "5882eeda72....Encrypted Package",
"ssn": "c035c619cf....Encrypted Package",
"address": {
"street": "54511b48cf....Encrypted Package",
"city": "de02e1b0e5f....Encrypted Package"
}
},
"tags": [
"a9f3c2d1e4....Encrypted Package",
"b7e8f0a2c3....Encrypted Package"
]
}The object shape is preserved completely. Every leaf value is encrypted, except user_id which was excluded.
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Your project identifier |
Headers
| Header | Required | Description |
|---|---|---|
x-api-key | Yes | Your Cipherion API key |
Content-Type | Yes | Must be application/json |
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
data | object | Yes | The JSON object or array to encrypt recursively |
passphrase | string | Yes | Secure passphrase configured in the Cipherion dashboard |
exclude_fields | array | No | Exact field paths to skip (e.g. ["orders[0].items[0].name"]) |
exclude_patterns | array | No | Wildcard-based field name patterns to skip (e.g. ["user_id", "*_at"]) |
Exclusion Parameters
exclude_fields and exclude_patterns both prevent specific fields from being encrypted, leaving them in plain text in the output.
exclude_patterns supports wildcard matching against field names:
| Pattern | Matches |
|---|---|
*_at | created_at, updated_at, deleted_at, etc. |
user_id | Exact match — only the field named user_id |
timestamp | Exact match — only the field named timestamp |
Pattern matching is case-sensitive. *_At will not match created_at.
exclude_fields uses array-notation dot paths for nested or indexed field access:
{
"exclude_fields": ["orders[0].items[0].name", "orders[0].items[1].price"]
}Example Requests
Basic Example
Method: POST
URL: https://api.cipherion.in/api/v1/crypto/deep_encrypt/YOUR_PROJECT_ID
Headers:
x-api-key: YOUR_API_KEY
Content-Type: application/json
Body (raw JSON):
{
"data": {
"name": "John Doe",
"user_id": "12345"
},
"passphrase": "your-secure-passphrase"
}{
"data": {
"name": "John Doe",
"user_id": "12345"
},
"passphrase": "your-secure-passphrase"
}curl -X POST https://api.cipherion.in/api/v1/crypto/deep_encrypt/YOUR_PROJECT_ID \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"name": "John Doe",
"user_id": "12345"
},
"passphrase": "your-secure-passphrase"
}'Advanced Example — With Exclusions
Method: POST
URL: https://api.cipherion.in/api/v1/crypto/deep_encrypt/YOUR_PROJECT_ID
Headers:
x-api-key: YOUR_API_KEY
Content-Type: application/json
Body (raw JSON):
{
"data": {
"user_id": "u_99283",
"created_at": "2025-10-24T10:00:00Z",
"updated_at": "2025-10-25T11:30:00Z",
"personal_info": {
"full_name": "Sarah Connor",
"ssn": "999-00-1234",
"address": {
"street": "123 Tech Blvd",
"city": "Cyberdyne"
}
}
},
"passphrase": "your-secure-passphrase",
"exclude_patterns": ["user_id", "*_at", "timestamp"]
}{
"data": {
"user_id": "u_99283",
"created_at": "2025-10-24T10:00:00Z",
"updated_at": "2025-10-25T11:30:00Z",
"personal_info": {
"full_name": "Sarah Connor",
"ssn": "999-00-1234",
"address": {
"street": "123 Tech Blvd",
"city": "Cyberdyne"
}
}
},
"passphrase": "your-secure-passphrase",
"exclude_patterns": ["user_id", "*_at", "timestamp"]
}curl -X POST https://api.cipherion.in/api/v1/crypto/deep_encrypt/YOUR_PROJECT_ID \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"user_id": "u_99283",
"created_at": "2025-10-24T10:00:00Z",
"updated_at": "2025-10-25T11:30:00Z",
"personal_info": {
"full_name": "Sarah Connor",
"ssn": "999-00-1234",
"address": {
"street": "123 Tech Blvd",
"city": "Cyberdyne"
}
}
},
"passphrase": "your-secure-passphrase",
"exclude_patterns": ["user_id", "*_at", "timestamp"]
}'Encrypting a Server-Side Request Body (req.body)
A common pattern is to encrypt a request body before storing it or forwarding it to another service. Here is an example of what req.body might look like on your server before encryption, and the payload you would send to Cipherion:
Incoming req.body on your server:
{
"order_id": "ORD-4821",
"customer_id": "CUST-991",
"created_at": "2025-11-01T09:00:00Z",
"billing": {
"card_number": "4111111111111111",
"card_holder": "John Doe",
"expiry": "12/27",
"cvv": "389"
},
"shipping": {
"address": "742 Evergreen Terrace",
"city": "Springfield",
"zip": "62704"
},
"items": [
{ "product_id": "P-01", "name": "Wireless Keyboard", "price": 79.99 },
{ "product_id": "P-02", "name": "USB Hub", "price": 34.99 }
]
}Cipherion API request to encrypt it (excluding IDs and timestamps):
{
"data": {
"order_id": "ORD-4821",
"customer_id": "CUST-991",
"created_at": "2025-11-01T09:00:00Z",
"billing": {
"card_number": "4111111111111111",
"card_holder": "John Doe",
"expiry": "12/27",
"cvv": "389"
},
"shipping": {
"address": "742 Evergreen Terrace",
"city": "Springfield",
"zip": "62704"
},
"items": [
{ "product_id": "P-01", "name": "Wireless Keyboard", "price": 79.99 },
{ "product_id": "P-02", "name": "USB Hub", "price": 34.99 }
]
},
"passphrase": "your-secure-passphrase",
"exclude_patterns": ["order_id", "customer_id", "*_at"],
"exclude_fields": ["items[0].product_id", "items[1].product_id"]
}Encrypted response — safe to persist:
{
"order_id": "ORD-4821",
"customer_id": "CUST-991",
"created_at": "2025-11-01T09:00:00Z",
"billing": {
"card_number": "a3f8d9e2c1....Encrypted Package",
"card_holder": "b2e7f1a3c4....Encrypted Package",
"expiry": "c9d0e1f2a3....Encrypted Package",
"cvv": "d1e2f3a4b5....Encrypted Package"
},
"shipping": {
"address": "e2f3a4b5c6....Encrypted Package",
"city": "f3a4b5c6d7....Encrypted Package",
"zip": "a4b5c6d7e8....Encrypted Package"
},
"items": [
{ "product_id": "P-01", "name": "b5c6d7e8f9....Encrypted Package", "price": "c6d7e8f9a0....Encrypted Package" },
{ "product_id": "P-02", "name": "d7e8f9a0b1....Encrypted Package", "price": "e8f9a0b1c2....Encrypted Package" }
]
}Sensitive billing and shipping details are fully encrypted. The order_id, customer_id, created_at, and product_id fields remain in plaintext for querying and indexing.
Sending the Encrypted Payload from JavaScript
Once you have the encrypted object from Cipherion, you can forward it to another API or store it. This example shows a simple fetch call — not SDK usage:
// 1. Encrypt the payload via Cipherion
const cipherionRes = await fetch(
"https://api.cipherion.in/api/v1/crypto/deep_encrypt/YOUR_PROJECT_ID",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.CIPHERION_API_KEY,
},
body: JSON.stringify({
data: req.body,
passphrase: process.env.CIPHERION_PASSPHRASE,
exclude_patterns: ["order_id", "customer_id", "*_at"],
}),
}
);
const { data } = await cipherionRes.json();
// 2. Store or forward the encrypted payload
await fetch("https://your-storage-service.example.com/orders", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data.encrypted),
});Sending the Encrypted Payload from Python
import requests
import os
# 1. Encrypt the payload via Cipherion
cipher_response = requests.post(
f"https://api.cipherion.in/api/v1/crypto/deep_encrypt/{os.environ['PROJECT_ID']}",
headers={
"x-api-key": os.environ["CIPHERION_API_KEY"],
"Content-Type": "application/json",
},
json={
"data": request_body,
"passphrase": os.environ["CIPHERION_PASSPHRASE"],
"exclude_patterns": ["order_id", "customer_id", "*_at"],
},
)
encrypted_payload = cipher_response.json()["data"]["encrypted"]
# 2. Store or forward the encrypted payload
requests.post(
"https://your-storage-service.example.com/orders",
json=encrypted_payload,
)Responses
200 OK — Success
The output mirrors the input structure exactly. Every leaf field is replaced with an encrypted package, except those matched by exclude_fields or exclude_patterns.
{
"success": true,
"statusCode": 200,
"message": "Payload encrypted successfully",
"data": {
"encrypted": {
"user_id": "u_99283",
"created_at": "2025-10-24T10:00:00Z",
"updated_at": "2025-10-25T11:30:00Z",
"personal_info": {
"full_name": "5882eeda72....Encrypted Package",
"ssn": "c035c619cf....Encrypted Package",
"address": {
"street": "54511b48cf....Encrypted Package",
"city": "de02e1b0e5f....Encrypted Package"
}
}
},
"meta": {
"excluded_fields": [],
"excluded_patterns": ["user_id", "*_at", "timestamp"],
"failed_fields": [],
"fail_gracefully": false,
"operation": "deep_encrypt"
}
},
"timestamp": "2025-12-24T06:36:29.586Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
data.encrypted | object | The input object with all eligible leaf values encrypted |
data.meta.excluded_fields | array | Field paths that were excluded from encryption |
data.meta.excluded_patterns | array | Patterns used to exclude fields |
400 Bad Request — Missing Fields
{
"success": false,
"statusCode": 400,
"message": "Missing required fields: projectId (url), x-api-key header, data, or passphrase",
"data": null,
"timestamp": "2026-05-29T00:00:00.000Z"
}400 Bad Request — Invalid Passphrase or Corrupted Data
Returned when the passphrase does not match the one configured in the Cipherion dashboard, or the data is malformed.
{
"success": false,
"statusCode": 400,
"message": "Failed to unwrap AES key: possible invalid passphrase or corrupted data",
"data": null,
"error": {
"statusCode": 400,
"isOperational": "Failed to unwrap AES key: possible invalid passphrase or corrupted data"
},
"timestamp": "2025-12-24T06:19:16.669Z"
}401 Unauthorized
{
"success": false,
"statusCode": 401,
"message": "Invalid project or API key",
"data": null,
"error": {
"statusCode": 401,
"isOperational": true
},
"timestamp": "2025-12-24T06:18:26.585Z"
}413 Payload Too Large
{
"success": false,
"statusCode": 413,
"message": "Payload too large: maximum 10000 fields allowed per request (received X).",
"data": null,
"timestamp": "2026-05-29T00:00:00.000Z"
}422 Unprocessable Entity
{
"success": false,
"statusCode": 422,
"message": "Field limit exceeded: your plan allows a maximum of X fields per request...",
"data": null,
"timestamp": "2026-05-29T00:00:00.000Z"
}429 Too Many Requests
{
"success": false,
"statusCode": 429,
"message": "encryption quota exceeded: your plan includes X calls per billing period...",
"data": null,
"timestamp": "2026-05-29T00:00:00.000Z"
}500 Internal Server Error
{
"success": false,
"statusCode": 500,
"message": "Deep encryption failed",
"data": null,
"error": {},
"timestamp": "2026-05-29T00:00:00.000Z"
}Core Concepts
Recursive Processing
deep_encrypt does not operate on the top-level fields of your object only — it recursively descends into every nested object and array, no matter how deeply they are nested. This means a field buried five levels deep is treated the same as a top-level field. You do not need to flatten your payload or handle nesting yourself.
Nested Object Handling
Each nested object is treated as its own subtree. The API enters the object, processes each key, and if the value is itself an object, descends again. This continues until a primitive leaf value is reached, at which point encryption occurs. The result is that every leaf — regardless of depth — is encrypted, while the overall structure is preserved.
Array Handling
Arrays are processed element by element in order. For arrays of primitives (strings, numbers, booleans), each element is encrypted individually. For arrays of objects, the API recursively processes each object within the array. For arrays of arrays (nested arrays), the recursive process continues inward. Array indices are preserved — the output array has the same length and ordering as the input.
Payload Structure Preservation
The shape of the output payload is always identical to the shape of the input. Field names are never changed. Nesting levels are never collapsed or promoted. Array ordering is never modified. This guarantee means you can safely drop the encrypted payload directly into any storage, queue, or downstream service that expects the same structure.
Data Integrity Considerations
Only leaf string, number, and boolean values are encrypted. Structural elements — keys, brackets, braces — are never modified. null and undefined values are passed through unchanged. This ensures the payload can be deserialized, inspected for structure, and later passed to /deep_decrypt without any transformation.
Billable Fields
Only the fields that are actually encrypted count as billable. Fields excluded via exclude_fields or exclude_patterns are not charged. This means you can optimize costs by excluding non-sensitive metadata such as IDs, timestamps, and version fields.
Notes
- The JSON structure is preserved exactly — only the leaf string values are replaced with encrypted packages.
billableFieldsreflects only the fields that were actually encrypted. Excluded fields do not incur charges.- To reverse a deep encryption, pass the
encryptedobject to the/deep_decryptendpoint using the same passphrase.