---
title: "Custody and Privacy"
description: "What XI Parallax does with your image bytes, what it stores, what another account can learn from a match, and what a published record deliberately tells everyone."
published: 2026-09-22T13:45:16.063415+00:00
updated: 2026-09-22T13:45:16.063415+00:00
tags: ["custody", "parallax", "privacy"]
url: https://xiobjects.com/docs/xio/parallax/rest-api/custody-and-privacy
source: XI Objects
---

<!-- xion:doctype xion+markdown -->
<!-- xion:metadata
{
  "version": "1.0",
  "content_type": "application/xion\u002Bmarkdown",
  "source_type": "xi-content/doc",
  "generator": "xio-content-publisher/1.0.0",
  "generated": "2026-09-22T13:44:09.5660262\u002B00:00",
  "encoding": "utf-8",
  "render_intent": "markdown",
  "title": "Custody and Privacy",
  "slug": "xio/parallax/rest-api/custody-and-privacy",
  "copyright": "\u00A9 2026 XI Objects Inc"
}
-->

# Custody and Privacy

XI Parallax is not in the business of holding your images. Two paths send pixels, and each disposes of them differently.

## A registration image

Your pixels are never kept.

An image you send to `POST /registrations` or to a slot upload is streamed into a single buffer. That buffer is hashed, then handed to the one engine call a registration image ever makes: a look-up that checks it against what is already registered and, when nothing matches, returns the registration packet. The instant that call answers, the buffer is zeroed and the zero is verified. That happens whichever way the call answered, including when the image is refused.

No registration image byte is ever written to storage. Not to a blob, not to a column, not to a log. What the slot holds between your upload and your commit is the derived registration packet, never pixels.

By the time a commit runs, the pixels are already gone. The engine's register call never sees a pixel.

## A look-up query image

A query image's pixels are held, briefly, because the engine needs them to answer.

The bytes are written to a held-bytes store when you upload the query, and read back once when you commit. As soon as the engine's verdict is in, they are deleted and their absence is verified.

They also go, unread, on any of these:

- You remove the entry with `DELETE /lookup/slots/{lookupSlotId}/entries/{imageHash}`.
- You abandon the slot with `DELETE /lookup/slots/{lookupSlotId}`.
- The slot's absolute expiry passes and the sweep reclaims it.

For `POST /lookup`, the whole cycle happens inside your one request. By the time the response reaches you, the pixels are gone.

Pixels are never logged, whole or encoded, and neither is the key they were stored under.

## What is stored

| Thing | Where it lives | How long |
|-------|----------------|----------|
| The SHA-256 of your image | On the registration | Until you take the registration down |
| Your manifests, exactly as given | On the registration | Until you take the registration down |
| The engine's outcome record | On the registration, returned to you as `engineRecord` | Until you take the registration down |
| A slot entry's derived registration packet | On the slot entry | Until commit, removal, abandon or expiry |
| A look-up verdict | On the look-up slot entry | Until the slot expires |
| Usage rows for billing | Append only | Indefinitely |
| Custody events | Append only | Indefinitely |

Nothing in that list is image bytes.

## The custody ledger

Every moment your bytes are in custody is recorded, append only: received, derived, and deleted with the check that verified they were gone. A row, once written, is never updated or deleted.

The operator can export the ledger for one account. Ask them for it if you need to show an auditor what happened to a specific image rather than take this page's word for it.

A delete that cannot be verified is recorded as such under its own kind, and retried on the next sweep, rather than being reported as a clean delete. The response you get is never changed by that uncertainty.

## What another account can learn

A look-up is global. It answers whether **anyone** holds a live registration for the image, not just you.

| Situation | What the caller sees |
|-----------|---------------------|
| The match is the caller's own registration | `matched: true`, the matched original image hash, and that registration's id. |
| The match is another account's | `matched: true`, and the matched original image hash. `candidates` is empty. |
| No live registration | `matched: false`, an empty hash list and an empty `candidates` array. |

Another account's registration id, owner and engine record are never disclosed here. A foreign match and one held by nobody the caller can see read identically.

The matched original image hash is disclosed on purpose. It is the engine's own hash of the original image's bytes, which is a fact about the image and not about who registered it, and the verdict has already told the caller the image is registered. It is the key to the published record, below.

Registrations, slots, quotas, usage and custody stay per account. A registration id or a slot id belonging to another account answers exactly the same `404` body as an id that never existed, down to the field set, so a caller cannot probe for real ids.

## What a published record deliberately tells everyone

There is one exception to account isolation, and it is the reason the service exists.

The manifests you register with an image are **public to every token holder**. Anyone can call `GET /records/{originalImageHash}` for any image, whoever registered it, and get the manifests back along with the material to verify the record. They do not have to own the image, and they do not have to have registered anything.

This is deliberate. Attribution that only its own author can read is not attribution. Somebody finds your image with its metadata stripped, looks it up, and recovers what you said about it. See [Recover an image's attribution](/docs/xio/parallax/rest-api/records).

What the record does **not** carry is any account detail. It names no account, no registration id and no slot, and there is no way to ask which account registered a given image. A reader learns what you chose to put in the manifests, and nothing else about you.

So treat a manifest as published, not as private. Put in it what you want the world to read.

## Image hashes are global

The SHA-256 of a set of bytes identifies one image everywhere. The pre-check that runs before every registration is global too: it asks whether any account already holds a live registration for your image, not just you. Only one account can hold a live registration for a given original at a time, and a second account's attempt to register the same bytes is refused while the first stays live. See [Register a single image](/docs/xio/parallax/rest-api/register-single-image). A take-down clears the block, and the bytes can be registered again, by you or by another account.

## What leaves the system

On a successful registration, the engine publishes a provenance record carrying the content hash, the signature, the key id, the certificate chain, and your manifest as an uninterpreted attribution payload. Your image bytes are not among them. Nothing else leaves on a register or a look-up.

## Take-down

`DELETE /registrations/{registrationId}` takes the registration down on its provenance record, then removes the row. It is final: nothing restores a taken-down record. See [Take down a registration](/docs/xio/parallax/rest-api/take-down).
<!-- xion:trust
{
  "v": 1,
  "canon_v": 1,
  "ctx": "xiobjects.com/content",
  "hash_blake3_hex": "f44e543eb5dd68b641aa6974d0377d3646c63ddfb21a07f82f624800e269ab72",
  "hash_sha256_hex": null,
  "sig_alg": "ed25519",
  "sig_b64": "5sF0BWTAFQ65n_ml2Jtw3Z_y6Oe3gXEi0509NRuaDKkgsJuUo0GEF3j7GvGxxiNsMUFYvhKbsa5Hw2T8ArSVDg",
  "pubkey_b64": "o4j1lUqY2QaQO9ku_UzWfnOV7E_MtWC6piiZeHNczzc",
  "x509_chain_pem": [
    "-----BEGIN CERTIFICATE-----\r\nMIIB9TCCAaegAwIBAgIRAMLfVK/j36eoLugMlAxtV9UwBQYDK2VwMC4xLDAqBgNV\r\nBAMMI1hJIE9iamVjdHMgSW5jIENvbnRyb2wgSW50ZXJtZWRpYXRlMB4XDTI2MDky\r\nMjEzMDUyM1oXDTI2MTAyMjEzMDUyM1owSzEeMBwGA1UEAwwVeGlvLWNvbnRlbnQt\r\ncHVibGlzaGVyMRcwFQYDVQQKDA5YSSBPYmplY3RzIEluYzEQMA4GA1UECwwHQ29u\r\ndGVudDAqMAUGAytlcAMhAKOI9ZVKmNkGkDvZLv1M1n5zlexPzLVguqYomXhzXM83\r\no4G8MIG5MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG\r\nCCsGAQUFBwMkMGUGA1UdIwReMFyAFDspt5hZsP6rNX4Cq7owpMYa05OyoS6kLDAq\r\nMSgwJgYDVQQDDB9JbnN0aXR1dGUgb2YgUHJvdmVuYW5jZSBSb290IENBghRSYDf4\r\nsUJ\u002B9h\u002Bod0\u002BZRK/X/JSUBTAdBgNVHQ4EFgQUy/uoDe3CJ5COIHD70XDiFWqA5zMw\r\nBQYDK2VwA0EAWpQV7vabZn8eh/eHf6TIdGqd/RmpyO1xcS8LYJ2OxbXI/IF9GojA\r\nMsuqTH4E6DFE\u002BZLRQAUjKw6pG67qRE40CQ==\r\n-----END CERTIFICATE-----\r\n",
    "-----BEGIN CERTIFICATE-----\r\nMIIByDCCAXqgAwIBAgIUUmA3\u002BLFCfvYfqHdPmUSv1/yUlAUwBQYDK2VwMCoxKDAm\r\nBgNVBAMMH0luc3RpdHV0ZSBvZiBQcm92ZW5hbmNlIFJvb3QgQ0EwHhcNMjUxMTAy\r\nMDMxNzEyWhcNMzAxMTAxMDMxNzEyWjAuMSwwKgYDVQQDDCNYSSBPYmplY3RzIElu\r\nYyBDb250cm9sIEludGVybWVkaWF0ZTAqMAUGAytlcAMhAFSS/pggSRmTcAMko7uc\r\nATH8OHgxVymd5mBFlPXbJkgio4GtMIGqMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\r\nVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ7KbeYWbD\u002BqzV\u002BAqu6MKTGGtOTsjBlBgNV\r\nHSMEXjBcgBQAZRTDswSVORu\u002BkUOKX6WvrOvmQKEupCwwKjEoMCYGA1UEAwwfSW5z\r\ndGl0dXRlIG9mIFByb3ZlbmFuY2UgUm9vdCBDQYIUJqoJlpiSFg\u002B7W5IJLMrLttgR\r\nQp4wBQYDK2VwA0EA5FOht7YOsVRPp/FOKMQ\u002B3Mo9JxrvGR3ylKWAWNm6OUV7N3DB\r\nI9cD62wU5I0d0EKDBy0CX9DnoqUyxv5yguraAA==\r\n-----END CERTIFICATE-----\r\n",
    "-----BEGIN CERTIFICATE-----\r\nMIIBaTCCARugAwIBAgIUJqoJlpiSFg\u002B7W5IJLMrLttgRQp4wBQYDK2VwMCoxKDAm\r\nBgNVBAMMH0luc3RpdHV0ZSBvZiBQcm92ZW5hbmNlIFJvb3QgQ0EwHhcNMjUxMTAy\r\nMDMwNTEyWhcNMzUxMDMxMDMwNTEyWjAqMSgwJgYDVQQDDB9JbnN0aXR1dGUgb2Yg\r\nUHJvdmVuYW5jZSBSb290IENBMCowBQYDK2VwAyEAEWNZl\u002Br3IC7\u002BgBh90Yo1kWk1\r\npZCVzVuFdFT7qBBU8W2jUzBRMB0GA1UdDgQWBBQAZRTDswSVORu\u002BkUOKX6WvrOvm\r\nQDAfBgNVHSMEGDAWgBQAZRTDswSVORu\u002BkUOKX6WvrOvmQDAPBgNVHRMBAf8EBTAD\r\nAQH/MAUGAytlcANBAO6QeydOFNrN75qNyftggYudsxMyl4w9qWkSdZ6hlhrRcbSr\r\niG9Si0kbrIJOwYB/LTBU0RM4Rl\u002Bo9PM3Qp0mPwo=\r\n-----END CERTIFICATE-----\r\n"
  ],
  "key_id": "Y3qJjjUQD3bpQwrMcz5raLrfTVObfcxBKRbUELm3-wc",
  "created_at": "2026-09-22T13:44:09Z"
}
-->