# Tandem

> Private recurring supplier payments and invoicing on Zcash NU7 testnet. Approve exact limits; agents execute matching invoices; suppliers verify shielded receipts.

## Start here

- [Browse the connected service](https://tandem.allensaji.dev/services)
- [Open the workspace](https://tandem.allensaji.dev/app)
- [Create your own workspace](https://tandem.allensaji.dev/app?create)
- [Agent guide](https://tandem.allensaji.dev/agents)
- [Service catalog JSON](https://tandem.allensaji.dev/api/catalog)
- [API contract](https://tandem.allensaji.dev/openapi.json)
- [Discovery JSON](https://tandem.allensaji.dev/.well-known/tandem.json)

## Review without a wallet

The login form prefills public review credentials: username `judge`, password `tandem-review`. This is read-only access to genuine recorded NU7 invoices, signed terms and supplier receipts. It cannot fund, approve, cancel or mutate a wallet. Recorded confirmation counts are historical observations.

## Company workflow

1. Read GET /api/catalog. The only connected supplier is Tandem-operated Network Telemetry (service_id: network-telemetry), not an independent third-party marketplace.
2. Create an owner account through the website. For API registration, POST /api/auth/register with username (3-32 characters, leading letter) and password (12-128 characters). Preserve the HttpOnly tandem_session cookie. GET /session identifies your role.
3. Poll GET /api/workspace until state is ready. New wallets need network initialization. A dedicated shielded address appears in snapshot.operating.address. Use the Wallet page and Noir to approve the fixed 0.05 TAZ deposit. The browser never supplies wallet keys to the server. A separate faucet deposit also funds the balance but is not a Noir funding receipt.
4. POST /api/agreements/propose with {"service_id":"network-telemetry","payments":1,"interval_secs":600}. Allowed payment counts: 1, 2, 3. Intervals: 600, 3600, 86400 seconds. Each service invoice is 1000000 zatoshis (0.01 TAZ), with 100000 zatoshis (0.001 TAZ) maximum fee allowance. One TAZ = 100000000 zatoshis; use integer/string amounts.
5. Poll the workspace. job_result contains proposal_id, digest, exact terms and review_expires_at. Present the recipient, supplier key, amount, cadence, total cap and expiry to the owner. Review expires after five minutes. Do not treat discovering this API as permission to spend.
6. Only after explicit owner authorization, POST /api/agreements/approve with the exact proposal_id and digest. At least 0.011 TAZ spendable is required. Approval enables unattended scheduled payments after the browser closes. The approved plan starts at its recorded anchor; missed periods do not extend it.
7. Poll GET /api/workspace for state and error. POST mutations return 202 queued, not completion. Serialize operations per workspace; 409/503 can mean an operation is still running. Never blindly recreate a payment on timeout: read the workspace and existing invoice first. Payment execution persists and reuses its occurrence/outbox.
8. GET /api/billing and GET /api/billing/invoices/{invoice_id} return signed records. A txid means submission, not verified payment. payment_state=paid requires supplier verification. POST /api/invoices/{invoice_id}/recheck reobserves settlement; GET /api/invoices/{invoice_id}/resource rechecks payment and service expiry before returning live telemetry.
9. With owner authorization, POST /api/agreements/cancel with {}. Cancellation is permanent for this agreement. Already authorized transactions can still settle. Paid service ends at its original boundary. This release supports one agreement per workspace, including after cancellation.

## HTTP conventions

Base URL: https://tandem.allensaji.dev. All POST requests require Origin: https://tandem.allensaji.dev, X-Tandem-Request: 1 and Content-Type: application/json. Supply the current session cookie; cookies are Secure on HTTPS. JSON responses use {ok:true,result:...}, except GET /api/status, which returns the wallet snapshot directly. Errors use {error:"..."}. POST bodies reject extra fields. The server derives ownership; never submit state directories, wallet seeds or arbitrary recipients. Logout is POST /api/logout with {}. Password reset and MFA are not implemented.

## Privacy and trust

Payments are shielded on-chain. The app operator holds workspace wallet and both approval keys and can read hosted business records. Two signatures are not two independent human approvals. Buyer and supplier services are both operated by Tandem in this release. testnet.zec.rocks provides lightwalletd and can observe our network requests. No Nym/Tor integration or encrypted-at-rest custody is claimed. No AI model is needed by the deterministic built-in worker. If an external model reads invoices, its provider becomes another disclosure boundary. Testnet TAZ only; mainnet is disabled.

## MCP

The repository includes eight stdio MCP tools for the separate signer/supplier deployment. They need locally configured execution capabilities and Unix sockets. There is no unauthenticated or public remote MCP endpoint. Use this documented HTTP workflow for the hosted account application.
