Home SMS OTP Pricing Blog Log in Get started

How to Share Confidential Documents Securely

Email attachments and WhatsApp weren't built for this. Here's a document-sharing flow that verifies the recipient by SMS, scans for malware before release, and expires on its own.

Most "confidential" documents in Eswatini travel one of two ways: an email attachment, or a WhatsApp file. Neither actually confirms who opened it. An email can be forwarded, sit in an inbox for years, or land in the wrong address entirely from a single typo. A WhatsApp file is one screenshot away from leaving the conversation it was meant for.

For a contract, a case file, a client statement, or anything else where it genuinely matters who received the document, that's not good enough. Secure Share is Lunyazi's answer: a link that only resolves to a real download after the recipient proves, by SMS, that they are who the document was meant for.

How it works

Three things happen that a plain attachment can't do:

Sending a document

One API call creates the share and sends the link. The caller then uploads the file bytes directly to the returned upload URL, which goes straight to storage rather than through the API itself.

// Step 1: create the share -- this sends the link immediately const createResult = await fetch("https://api.lunyazi.com/sms/secure-share", { method: "POST", headers: { "X-Api-Key": process.env.LUNYAZI_API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ phone: "+26876123456", label: "Service Agreement", filename: "agreement.pdf", file_size: fileBytes.length, expires_days: 7 }) }).then(r => r.json()); // { success: true, share_id, upload_url, upload_fields, share_url, sms_sent: true }

The response includes everything needed for the second step: a presigned upload target plus the fields required to post to it.

// Step 2: upload the actual file -- goes straight to storage, not through the API const form = new FormData(); Object.entries(createResult.upload_fields).forEach(([k, v]) => form.append(k, v)); form.append("file", fileBlob); await fetch(createResult.upload_url, { method: "POST", body: form }); // HTTP 204 on success

That's it. The recipient already has createResult.share_url by SMS (and by email too, if an address was supplied) from the moment the first call succeeded.

What the recipient sees

Opening the link shows who sent the document and what it's called, nothing more. They request a code, enter it, and only then is a download link issued, assuming the file has already been scanned clean.

If the recipient verifies before the scan finishes (it normally takes well under a minute), they see a "scan in progress" message with a button to check again, rather than an error. No workaround exists to skip the scan, for anyone, including the sender's own uploads.

The detail that matters for integrations

A successful OTP check does not automatically mean a download link comes back. verified: true can still carry scan_status: "in_progress" instead of a download_url. Build for that state explicitly rather than assuming verification success means the file is ready.

scan_statusMeaningdownload_url present?
in_progressScan hasn't finished yet -- the normal state right after uploadNo
cleanScan completed, no threats foundYes
threat_foundMalware detected -- the file is permanently blockedNo
unavailableThe scan couldn't clear the file for another reasonNo

Limits worth knowing

Why this matters for regulated and sensitive work

Under Eswatini's Data Protection Act 2022, Section 14 requires appropriate technical measures to protect personal data. A document-sharing method where delivery can't be confirmed and access can't be verified doesn't meet that bar on its own. Phone-based verification, scan-before-release, and automatic expiry together give a real, auditable answer to "who actually received this and when."

Frequently Asked Questions

Does the recipient need to install anything or create an account?

No. They need only the phone number the sender specified, to receive the verification code. Everything else happens in the browser.

What happens if the recipient loses or mistypes the code?

They can request a new one, up to 5 times total per share. After that, they're asked to contact the sender for a fresh link.

Is the file scanned every time, with no way to skip it?

Yes. The scan check runs unconditionally before any download URL is issued, including for the account owner's own uploads. There is no bypass.

What's the maximum file size?

50MB, enforced at the storage layer itself rather than only checked by the API.

How long does the link stay valid?

Whatever the sender set when creating it, from 1 to 30 days. After that, the file is removed automatically.

Ready to send your first secure document?

Free to start, no credit card required. Create a Secure Share link in minutes from the dashboard or the API.

Get your API key →