Skip to content

Defining Schemas

A schema defines the shape of your data. Think of it as a table definition. Schemas use the JSON Schema specification with constraints specific to Blind Insight's encryption model.

Constraints

  • The root type must be object.
  • Field types are limited to string, integer, and number.
  • integer and number fields require minimum and maximum bounds. These bounds define the encryption range.
  • number fields also require precision (number of decimal places).
  • All fields are encrypted individually using a unique key derived from your keyring.

Quickstart

Create a dataset, then create a schema inside it.

# 1. Create a dataset
curl -X POST https://api.app.blindinsight.io/api/datasets/ \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "People", "organization": "/api/organizations/<org_id>/"}'

# 2. Create a schema inside the dataset
curl -X POST https://api.app.blindinsight.io/api/schemas/ \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Person",
    "dataset": "/api/datasets/<dataset_id>/",
    "schema": {
      "type": "object",
      "properties": {
        "name":   {"type": "string"},
        "age":    {"type": "integer", "minimum": 0, "maximum": 150},
        "height": {"type": "number",  "minimum": 0, "maximum": 3, "precision": 2}
      },
      "required": ["name", "age", "height"]
    }
  }'
import requests

base_url = "https://api.app.blindinsight.io"
headers = {"Authorization": "Bearer <token>", "Content-Type": "application/json"}

# 1. Create a dataset
dataset = requests.post(f"{base_url}/api/datasets/", headers=headers, json={
    "name": "People",
    "organization": "/api/organizations/<org_id>/",
}).json()

# 2. Create a schema inside the dataset
schema = requests.post(f"{base_url}/api/schemas/", headers=headers, json={
    "name": "Person",
    "dataset": dataset["url"],
    "schema": {
        "type": "object",
        "properties": {
            "name":   {"type": "string"},
            "age":    {"type": "integer", "minimum": 0, "maximum": 150},
            "height": {"type": "number",  "minimum": 0, "maximum": 3, "precision": 2},
        },
        "required": ["name", "age", "height"],
    },
}).json()

print(schema["id"])
# Using the Blind Proxy CLI
blind schema create \
  --name "Person" \
  --dataset <dataset_id> \
  --schema person_schema.json

Schema Object

Field Type Required Description
name string yes Human-readable name
dataset URL yes The dataset this schema belongs to
schema object yes JSON Schema definition
slug string no Auto-generated if omitted
description string no Longer description

The response includes read-only fields:

{
  "id": "iKi3YbiG7Ax9cEZ7YPVNgw",
  "url": "/api/schemas/iKi3YbiG7Ax9cEZ7YPVNgw/",
  "dataset": "/api/datasets/FWaw3Gr7Gmv8xg8mpuabn7/",
  "name": "Person",
  "slug": "person",
  "description": "",
  "schema": {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "age": { "type": "integer", "minimum": 0, "maximum": 150 },
      "height": { "type": "number", "minimum": 0, "maximum": 3, "precision": 2 }
    },
    "required": ["name", "age", "height"]
  }
}

Field Types

string

String fields are encrypted as opaque values. You can search for exact matches.

{ "type": "string" }

integer

Integer fields are encrypted with range-preserving encryption. The minimum and maximum bounds define the valid range — values outside this range will fail validation.

{ "type": "integer", "minimum": 0, "maximum": 1000000 }

number

Floating-point fields. precision is the number of decimal places that will be preserved.

{ "type": "number", "minimum": 0.0, "maximum": 100.0, "precision": 2 }

Important

Choose minimum, maximum, and precision carefully. These values are baked into the encryption keys and cannot be changed after records are ingested without re-encrypting all records.

required Fields

List required fields in the required array at the schema root. Records missing required fields will fail validation on ingest.

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0, "maximum": 150 }
  },
  "required": ["name", "age"]
}

Example: Medical Records Schema

{
  "type": "object",
  "properties": {
    "patient_id": { "type": "string" },
    "date_of_birth": { "type": "string" },
    "systolic_bp": { "type": "integer", "minimum": 50, "maximum": 300 },
    "diastolic_bp": { "type": "integer", "minimum": 30, "maximum": 200 },
    "bmi": {
      "type": "number",
      "minimum": 10.0,
      "maximum": 80.0,
      "precision": 1
    },
    "diagnosis": { "type": "string" }
  },
  "required": ["patient_id", "date_of_birth"]
}

Example: Financial Records Schema

{
  "type": "object",
  "properties": {
    "account_id": { "type": "string" },
    "transaction_id": { "type": "string" },
    "amount": {
      "type": "number",
      "minimum": -1000000.0,
      "maximum": 1000000.0,
      "precision": 2
    },
    "merchant": { "type": "string" },
    "category": { "type": "string" }
  },
  "required": ["account_id", "transaction_id", "amount"]
}

Using the CLI

The Blind Proxy CLI provides schema management commands:

# List schemas in a dataset
blind schema list --dataset <dataset_id>

# Create a schema from a JSON file
blind schema create --name "Person" --dataset <dataset_id> --schema person.json

# Inspect a schema (decrypted view via proxy)
blind schema get --id <schema_id>

Next Steps