# QRchive > Permanent, scan-to-open document archives for physical things. Stick a > QRchive sticker on a furnace, a pump, a boat, a control panel, or a > job-site binder; scanning it opens the archive of manuals, photos, reports > and records that belong to that thing — for whoever is standing there next. QRchive is operated by Pacific Rim Wastewater Solutions Ltd., a British Columbia company. Files are stored on Canadian servers and handled under PIPEDA. Prices are Canadian dollars. ## The model in four lines - $49 CAD per archive, one time. No subscription. - One sticker, one archive. Stickers come on rolls; the first roll of 25 archives is free per company. - 1 GB of storage is included with each archive. Larger allowances can be bought. - Payment is always done by a person in a browser. An agent can prepare an unlock; it can never pay for one. ## What an agent can do today, with no credentials Every sticker carries a public address of the form: https://qrchive.ca/docs/QR-123456-AB7CD That address contains the two values every documented call needs: the code (`QR-123456`) and its 5-character token (`AB7CD`). An agent holding that address can, on an unlocked archive that accepts additions from anyone: - add files (photos, PDFs, spreadsheets, short videos) - list the sections inside the archive - check whether the archive has been unlocked An agent CANNOT, today, sign in as the owner, edit the archive's written details, create sections, or pay. Those need the owner's browser session. Scoped keys for machines are planned but not built; nothing here is a promise that they will be. ## Adding a file — the whole sequence 1. `POST https://qrchive.ca/api/upload/request` with JSON `{ "qrCodeId": "QR-123456", "fileName": "as-built.pdf", "fileSize": 482118, "fileType": "application/pdf" }`. Returns `{ "success": true, "uploadUrl": "...", "objectKey": "...", "expiresAt": "..." }`. The URL is good for 15 minutes. 2. `PUT` the raw bytes to `uploadUrl`. Send the same content type. No QRchive headers, no credentials — the URL carries its own signature. 3. `POST https://qrchive.ca/api/upload/confirm` with JSON `{ "r2ObjectKey": "", "qrCodeId": "QR-123456", "fileName": "as-built.pdf", "fileSize": 482118, "fileType": "application/pdf" }`. Returns `{ "success": true, "fileId": "..." }`. Skipping step 3 leaves the bytes in storage but not in the archive. Always confirm. ## Sending files by email Every archive also has its own address: qr-123456-ab7cd@in.qrchive.ca Anything that can send email can file documents. Attachments are validated the same way as an upload. Limit: 10 messages per hour per archive. ## Limits and rules - Accepted types: pdf, jpg, jpeg, png, heic, heif, webp, xlsx, docx, csv, mov, mp4. - 50 MB per file; 500 MB for video. - File contents are checked against the claimed type. A mismatch is rejected and the bytes are deleted. - Uploads count against the archive's storage allowance. - 500 upload requests per hour per address. - A locked archive, or one whose owner has turned off additions, refuses anonymous uploads. ## Errors Documented endpoints answer failures with: { "success": false, "error": { "message": "...", "code": "..." }, "code": "..." } Codes worth handling: `INVALID_FILE_TYPE`, `FILE_TOO_LARGE`, `MAGIC_BYTE_MISMATCH`, `STORAGE_FULL`, `NOT_ACTIVATED`, `RATE_LIMIT_EXCEEDED`. Retrying a `FILE_TOO_LARGE` will never succeed; retrying a `RATE_LIMIT_EXCEEDED` after the `Retry-After` seconds will. ## Machine-readable - OpenAPI 3.1: https://qrchive.ca/api/openapi.json - Written guide: https://qrchive.ca/agents ## What QRchive does not do QRchive runs no AI. It does not read, classify, summarise, or answer questions about the documents it holds. It stores them and hands them back when the sticker is scanned. Bring your own agent. ## Contact support@qrchive.ca