PiipeCustomer identity protection
Explore Piipe A safer home for customer identity.

Build on one trusted source for customer identity.

Piipe Developer Platform · API v1

Keep the business data.
Move the identity.

Piipe gives every application one trusted, purpose-bound home for personal information. Your business systems keep doing joins, transactions, segmentation and analytics; Piipe protects the fields that directly identify a person.

Application API
Authenticated HTTPS
Transport
TLS 1.3 · HTTPS
Trust model
Purpose-bound identity access
REFERENCE ARCHITECTURE Purpose: customer support
YOUR SERVICEAuthorised workflow

APPLICATION DATABASERelationships & metrics

  • customer_id
  • plan
  • orders
  • events

PIIPEProtected identity

  • name
  • email
  • phone
  • address

Query business data first. Retrieve only the approved PII fields for the final bounded result set.

The integration model

Make Piipe the single trusted source for customer identity.

Piipe does not replace PostgreSQL, MySQL, SQL Server, MongoDB or your warehouse. It gives direct identifiers and sensitive personal fields a dedicated protection boundary. A stable application-owned customer ID preserves the business relationship across both systems.

Keep every identity request server-side

Use the authenticated JSON HTTPS API from trusted services. Keep credentials out of browsers and request only the customer identity fields each approved workflow needs. Lower-level packet tooling is reserved for controlled appliance integrations.

01Use a random customer ID

Make a non-PII UUID the primary key for customers, orders, events and joins.

02Keep an opaque Piipe reference

Link business facts to an organisation-scoped pointer, never to the direct identity.

03Hydrate only when authorised

Resolve the minimum field list at the final step of an approved workflow.

Quickstart

Start with your organisation’s application credentials.

Normal server applications authenticate over HTTPS with the opaque Piipe organisation ID, App ID and Client Secret shown when the application is activated. The caller never supplies a tenant slot or username.

Server environment
PIIPE_URL="https://api.piipe.io"
PIIPE_ORGANIZATION_ID="org_your_opaque_piipe_id"
PIIPE_APP_ID="42"
PIIPE_CLIENT_SECRET="read-from-your-secret-manager"

# POST these three credential values to /api/login.
# Piipe returns a short-lived opaque session for the fixed piipe-api principal.
Server applicationsUse your runtime’s HTTPS clientNo Piipe package is required for the JSON API examples below.
Internal appliance integrationspython -m pip install './software/python[serial]'Optional lower-level packet tooling for controlled Piipe appliance work only.
  1. 1
    Create application credentials

    Store the opaque organisation ID, App ID and Client Secret in your server-side secrets manager.

  2. 2
    Use verified HTTPS

    Connect to api.piipe.io with your runtime’s normal trusted certificate store. Never disable hostname or certificate checks.

  3. 3
    Open an application session

    Call POST /api/login. Piipe binds the session to the fixed piipe-api application principal.

  4. 4
    Request explicit fields

    Prefer ["name", "email"] over "all" and retrieve only what the approved workflow needs.

PII field guide

What belongs in Piipe?

Store values that directly identify, contact, locate or reveal a sensitive fact about a person. Keep operational relationships and low-risk business facts in the system designed to query them.

PROTECT WITH PIIPEDirect identity
  • NameLegal, full or preferred name
  • EmailPersonal or work email address
  • PhoneCanonical international number
  • AddressFull street or postal address
  • Date of birthExact birth date
  • Document identifierLicence, passport or membership value
KEEP WITH YOUR APPLICATIONBusiness relationship
  • Random customer IDPrimary key and join target
  • Account statePlan, status and permissions
  • CommerceOrders, products, totals and invoices
  • Product activityEvents, sessions and feature use
  • Retention stateConsent and deletion workflow
  • Approved coarse dimensionsAge band or broad region when justified
USE A SPECIALIST SYSTEMSecrets & regulated payloads
  • Passwords and passkeysIdentity provider
  • Application secrets and signing keysSecret manager or key service
  • Payment card dataTokenised payment provider
  • Large document imagesApproved document or object-storage service
Supported identity fieldsCanonical Piipe field names
6 canonical types
emailphonenameaddressdobdocument

full_name maps to name; date_of_birth maps to dob. A bounded Piipe request supports up to four named fields and 44 combined UTF-8 value bytes.

Preserve query power

Your joins and reporting stay in SQL.

Move foreign keys away from email or phone and onto a random internal customer ID. Link the customer profile to its Piipe reference. Orders, events, subscriptions and reporting continue to join through the internal ID.

PostgreSQL
create table customers (
  id uuid primary key,
  workspace_id uuid not null,
  piipe_ref text not null,
  piipe_state text not null,
  plan_id bigint,
  account_status text not null,
  age_band text,
  created_at timestamptz not null,
  unique (workspace_id, piipe_ref)
);

create table orders (
  id uuid primary key,
  customer_id uuid references customers(id),
  product_id bigint not null,
  total numeric(12, 2) not null,
  created_at timestamptz not null
);
customer_id

Your relational keyStable random UUID used by foreign keys and application joins.

piipe_ref

Your protected-data pointerTenant-scoped reference used only when an approved workflow calls Piipe.

analytics_subject_id

Your destination-scoped aliasSeparate pseudonymous ID for each analytics destination.

Existing requirementPiipe pattern
Join orders to customersJoin on random customers.id. No PII lookup is needed.
Find an exact email or phoneUse an approved keyed lookup index or identity provider to resolve the random customer ID, then retrieve the authorised fields from Piipe.
Build a campaign segmentSegment on business facts first; retrieve approved delivery fields just in time.
Group by age or geographyStore a justified coarse value such as age_band or broad region, not raw DOB or address.
Sort or fuzzy-search a surnameRequires an explicitly reviewed derived index or transient sorting of a small authorised result set.
What does not stay unchanged

Piipe does exact subject or token lookup and selected-field retrieval. It does not expose arbitrary SQL, range filters, substring search, fuzzy matching, joins or analytical aggregation over raw PII. Most business queries remain unchanged; identity-centric search must use the Piipe path.

The subject helper is not a secret search index

It derives a deterministic, unkeyed 32-bit token. Tokens can collide and low-entropy values such as emails or phone numbers may be guessed. It is not encryption, anonymisation or a secret blind index. Prefer an application-owned random customer reference as the primary linkage; use a separately reviewed keyed index or identity provider when exact identity lookup is essential.

Customer analytics

Measure the customer journey without exporting the customer.

Funnels, cohorts, retention, product usage, lifetime value and churn models rarely need a name or email. Keep the event facts pseudonymous and resolve identity only for an approved final-mile action.

1
QUERYBuild the audience

Use orders, subscriptions, events, scores and approved coarse dimensions.

2
AUTHORISEDeclare the purpose

Confirm the workflow and exact Piipe fields permitted for this action.

3
HYDRATERetrieve at the edge

Resolve the bounded final set, use it transiently, then discard the PII.

Keep

Event type, product, timestamp, amount, plan, segment membership and destination-scoped pseudonymous IDs.

Do not export

Name, email, phone, exact address, exact DOB, Piipe responses or a reusable cross-platform Piipe reference.

The application database remains pseudonymous personal data, not anonymous data. It still needs access controls, retention limits and privacy governance.

Lifecycle patterns

Create, use and delete without unsafe shortcuts.

  1. 01

    Generate a random customer IDNever derive it from an email, phone number or unkeyed hash.

  2. 02

    Validate and minimise PIICollect only fields the workflow genuinely needs.

  3. 03

    Write identity to PiipeBind tenant, application, purpose and an exact field set.

  4. 04

    Store the reference in SQLUse piipe_state = pending|active|error for reconciliation.

Advanced · internal appliance packet SDK

Use this lower-level client only inside a controlled Piipe integration.

Normal server applications should use POST /api/login and the JSON HTTPS endpoints below. This internal packet example is deliberately separate: its numeric tenant_id parameter is a Piipe hardware slot, not a public organisation identifier, and it must never be sent to /api/login.

Python · internal authenticated packet
import json
import os

from piipe import (
    HttpsTransport,
    PiipeApplicationClient,
    PiipeConfig,
)

packet_key = bytes.fromhex(os.environ["PIIPE_PACKET_AUTH_KEY_HEX"])

with HttpsTransport(
    os.environ.get("PIIPE_HOST", "piipe.example.com"),
    port=int(os.environ.get("PIIPE_PORT", "443")),
    ca_file=os.environ.get("PIIPE_CA_FILE") or None,
) as transport:
    piipe = PiipeApplicationClient.from_transport(
        transport,
        PiipeConfig(
            # Internal hardware slot only; never send this to /api/login.
            tenant_id=int(os.environ["PIIPE_INTERNAL_HARDWARE_SLOT"]),
            application_id=int(os.environ["PIIPE_APP_ID"]),
            purpose_code=int(os.environ["PIIPE_PURPOSE_CODE"]),
            session_id=int(os.environ["PIIPE_SESSION_ID"]),
            packet_auth_key=packet_key,
            initial_request_id=int(os.environ["PIIPE_REQUEST_ID"], 0),
            initial_sequence=int(os.environ["PIIPE_SEQUENCE"], 0),
        ),
    )

    response = piipe.read_subject_fields(
        "crm_customer_12345",
        ["email", "phone"],
        subject_type="customer_id",
    )
    # Log decision metadata, never the protected response value.
    print(json.dumps({
        "status": response.status_name,
        "decision": response.decision_name,
        "request_id": response.request_id,
        "audit_id": response.audit_id,
    }, indent=2))
Reserve counters atomically

Persist the next request and sequence values before use, or provision a fresh session for each new process. Never restart a used session at one.

Do not disable TLS checks

The SDK verifies the certificate and hostname and requires TLS 1.3.

Use the SDK for mutations

The SDK validates session state before protected customer identity is changed.

Advanced · internal packet transport reference

Inspect the bounded appliance packet envelope.

This binary transport is for controlled Piipe appliance integrations. Normal server applications use the JSON HTTPS login and operation endpoints documented in the next section.

POST
https://<piipe-host>:<port>/api/v1/packet authenticated · binary · no-store
REQUEST64 bytes exactly
Content-Type
application/vnd.piipe.packet-v1
Accept
application/vnd.piipe.packet-v1
Cache-Control
no-store
Authentication
Bound inside the packet
RESPONSE256 bytes exactly
HTTP
200 · HTTP/1.1
Content-Type
application/vnd.piipe.packet-v1
Cache-Control
no-store
Transfer-Encoding
Forbidden

Machine-readable transport envelopeOpenAPI 3.1 · Piipe API v1

Download JSON

Internal packet operations

OperationPurposePiipe control
search_record / search_subjectExact existence lookup without returning PIISearch
read_fields / read_subject_fieldsRetrieve an explicit approved field setRetrieve
write_record / write_field_recordCreate a protected value or named identity field setAdd
write_subject_record / write_subject_field_recordCreate using a tenant-scoped subject lookupAdd
update_record / update_field_recordJournal and commit an intentional replacementEdit
delete_record / delete_subject_recordCreate a logical tombstoneDelete
verify_attributeVerify a field claim without returning identity dataRetrieve policy
detokenise_value / tokenise_valueCompatibility wrappers through the product policy pathPolicy dependent
ping / get_versionHealth and compatibility checksStatus

Response object

The internal packet SDK returns a typed response containing operation, status, request and audit identifiers, decision, timing, CRC state and the policy-filtered value. Creates may also return an existing token for an idempotent duplicate.

status_nameoperation_namerequest_idaudit_iddecision_namecyclesmasked_valuecrc_okduplicateexisting_token
Popular languages

Connect from your server stack.

Use the authenticated JSON HTTPS API from a trusted server environment. Keep credentials server-side, use finite timeouts, leave TLS verification enabled and close sessions when the workflow ends.

SERVER SIDE ONLY

Never place Piipe credentials in browser code. The HTTPS examples use standard server libraries and request only the identity fields the workflow needs.

PythonHTTPS integrationUse a TLS-verifying server HTTP client such as the standard library or your approved framework client.
JS · Go · Java · .NET · PHP · RubyHTTPS integrationUse each runtime’s trusted server-side HTTP client.
ContractOpenAPI 3.1Machine-readable request and response envelope for Piipe API v1.

Runtime setup

Use the runtime’s server-side HTTPS client; the examples share the same authenticated login and explicit-field read pattern.

Node.js 18+No package installBuilt-in fetch; place the fragment in an ES module such as client.mjs.
Go 1.20+Standard libraryUse net/http, encoding/json, context and time.
Java 11+JDK + JacksonUse java.net.http; add your organisation’s approved Jackson Databind release for JSON parsing.
.NET 6+No package installBuilt-in HttpClient and System.Text.Json.
PHP 8+ext-curl + ext-jsonEnable the standard cURL and JSON extensions in the server runtime.
Ruby 3+Standard libraryUses net/http, json, uri and openssl.

HTTPS endpoints

EndpointPurposeSession
POST /api/loginExchange organization_id, app_id and client_secret for an opaque session bound to the fixed piipe-api application principal.None
POST /api/subject-tokenSearch an exact tenant-scoped subject without returning PII.tenant_session
POST /api/writeAdd supported named fields for a subject.tenant_session
POST /api/readRetrieve the explicitly requested named fields.tenant_session
POST /api/updateReplace named field values through the edit path.tenant_session
POST /api/deleteCreate a logical tombstone for the subject.tenant_session
POST /api/logoutInvalidate the Piipe session.tenant_session
The application principal is fixed.

/api/login does not accept a username, user ID, numeric tenant slot, role or purpose. Piipe resolves the opaque organisation and returns the session as the organisation’s fixed piipe-api application principal.

Add · customer identity example
{
  "tenant_session": "opaque-session",
  "lookup": "subject",
  "subject": "crm_customer_12345",
  "subject_type": "customer_id",
  "record_mode": "fields",
  "field_data": {
    "email": "sample@example.test",
    "phone": "+61000000000"
  }
}
Retrieve · explicit fields
{
  "tenant_session": "opaque-session",
  "lookup": "subject",
  "subject": "crm_customer_12345",
  "subject_type": "customer_id",
  "record_mode": "fields",
  "fields": "email,phone"
}
Node.js 18+ · server side
const base = process.env.PIIPE_URL;

async function post(path, body) {
  const response = await fetch(base + path, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(body),
    signal: AbortSignal.timeout(10_000),
  });
  const data = await response.json();
  if (!response.ok || !data.ok) throw new Error(data.error);
  return data;
}

const login = await post("/api/login", {
  organization_id: process.env.PIIPE_ORGANIZATION_ID,
  app_id: Number(process.env.PIIPE_APP_ID),
  client_secret: process.env.PIIPE_CLIENT_SECRET,
});

const identity = await post("/api/read", {
  tenant_session: login.session,
  lookup: "subject",
  subject: "crm_customer_12345",
  subject_type: "customer_id",
  record_mode: "fields",
  fields: "email,phone",
});
console.log({
  ok: identity.ok,
  status: identity.response?.status,
  request_id: identity.response?.request_id,
  audit_id: identity.response?.audit_id,
});
Close the Piipe session.

After the final request, call POST /api/logout with {"tenant_session":"…"} from a finally, defer, ensure or equivalent cleanup path.

Verify HTTPS; never bypass it.api.piipe.io uses a publicly trusted certificate. Do not use curl -k, verify=False or a process-wide “accept all certificates” callback.

Reliability and errors

Treat a lost mutation response as unknown—not failed.

The HTTPS examples intentionally do not retry a POST after a transport failure. Piipe may have committed the operation before the connection was lost. Query or reconcile state before deciding whether another mutation is safe. The typed exceptions below belong to the advanced internal packet SDK; JSON clients receive the corresponding error envelope.

PipeClosedError

Your organisation’s Piipe Controls currently block this action. The exception carries the verified response.

HardwareEpochError

The protected session changed before a mutation completed. Refresh the session state before retrying.

PacketError

The fixed response failed size, version, operation, request, integrity or proof validation.

TransportError

TLS trust, hostname, HTTP framing, timeout or connection validation failed.

PipeControlConflictError

A Piipe Control changed after the request began. Refresh the control state before retrying.

PiipeError

The SDK rejected configuration or an operation returned a non-success status.

Piipe response codes
OKNOT_FOUNDDENIEDBAD_PACKETBAD_AUTHREPLAYOVERLOADEDPIPE_CLOSEDCONFLICTEPOCH_MISMATCH

Production integration checklist

  • Use random internal customer IDs and organisation-scoped Piipe references.
  • Keep the App ID and Client Secret out of browser code, logs and source control.
  • Use a certificate whose DNS name matches the Piipe endpoint.
  • Keep each opaque application session server-side and close it after the workflow.
  • Request explicit fields and apply least privilege to every workflow.
  • Use outbox or saga states for cross-system create, update and delete reconciliation.
  • Keep raw PII out of analytics, queues, URLs, cache keys and telemetry.
  • Complete an end-to-end security and privacy review before migrating customer PII.
Ready to protect customer PII?

Build on one trusted identity source.

Create your Piipe account, open your private workspace and connect your first application.

Create your account