Cheqi routes receipt contents without reading them. The merchant encrypts the definitive receipt payload for the customer's devices, and those devices generate and store the final receipt locally.
POST /recipient/resolvematches the customer and returns one temporary recipient for every device owned by that customer.- The merchant SDK serializes the definitive receipt payload locally and encrypts it independently for every returned device.
POST /receipt/encryptedconsumes the match and stores a durable encrypted generation job for each device.- Each device fetches its assigned job, decrypts the merchant payload, joins it in memory with Cheqi's server-known party and routing context, and generates its own CHEQI receipt with the shared Rust engine.
- One leased owner device resolves any downstream company or client-application recipients. It generates only the document formats those recipients require, encrypts a complete document bundle for each recipient, and submits the ciphertext for delivery.
- The backend stores hashes and routes ciphertext. It never receives the plaintext receipt contents or generated documents.
Push delivery is an optimization, not the source of truth. Devices also fetch the durable queue during normal synchronization, so a missed, throttled, offline, or force-quit push is repaired when the app can run again. See Mobile Delivery.
The protected data is the receipt body: line items, totals, taxes, payment details, fiscal data, and other issuer-supplied contents describing what was bought.
Cheqi legitimately knows the routing metadata it needs to match and deliver a receipt, including the recipient and issuer identity and payment information used for matching. It returns that server-known context to an authenticated owner device. The device performs the plaintext join in memory; the backend does not.
The merchant sends the encrypted generation input, not a server-generated receipt template. There is no plaintext template-generation step in the normal digital route.
Recipient IDs returned by /recipient/resolve are opaque, match-scoped, and short-lived. Do not store them as customer identifiers or reuse them in a later transaction.
The matchId is single-use. After /receipt/encrypted accepts the submission, the returned cheqiReceiptId and the backend's opaque generation-job ID identify the durable work. Mobile processing does not depend on the original match still existing.
Every matched owner device receives its own independently encrypted generation request and creates its own local CHEQI receipt. One device completing its work does not suppress the owner's other devices.
Third-party fan-out is different: exactly one active device holds the distribution lease. That device generates any required UBL documents and encrypts the downstream bundles. Other owner devices still generate and keep their local CHEQI copy, but do not duplicate downstream delivery.
Use a high-level complete-receipt method where available. It should:
- resolve the customer before encrypting
- select the explicit
deliveryRouteType - serialize the definitive receipt payload locally
- create a fresh symmetric key and ciphertext for every matched device
- submit exactly the device recipient set returned by the match
- preserve the
cheqiReceiptIdand delivery result for your records
The Cheqi mobile apps handle queue retrieval, local generation, durable local storage, downstream fan-out, and acknowledgement.
The download fallback is explicit and separate from the device-generated route:
DOWNLOAD_FALLBACKuses a client-encrypted download payload. The content key stays in the URL fragment, so the backend stores ciphertext it cannot decrypt.routeFound: falsemeans the healthy online flow must stop with customer-not-found. Do not bypass that result through the low-level download endpoint.
See Download Links for the offline and anonymous download-link rules.
- Use Recipient Resolution to match owner devices.
- Use Receipt Creation to build the definitive encrypted input.
- Use Sending Receipts for encryption and submission.
- Use Mobile Delivery for background processing and reliability behavior.
- Use the SDK pages for language-specific examples: