Skip to main content

Using Veryfi Lens Instant App or App Clip

You can launch our Android Instant App or iOS App Clip to process a document directly from your WhatsApp bot.

Steps:

  1. Create a Call-to-Action (CTA) component in your WhatsApp bot.

  2. Refer to the WhatsApp documentation:

  3. Set the action URL based on the user's device:

    iOS:

    https://appclip.apple.com/id?p=com.veryfi.Lens-Demo.Clip&${urlParams}

    Android:

    https://whatsapp-bot.veryfi.com/instantapp/?${urlParams}
  4. Build the URL parameters with the desired Lens configuration:

const urlParams = new URLSearchParams({
documentType,
showDocumentTypes,
autoDocDetectionAndCropIsOn,
blurDetectionIsOn,
locationServicesIsOn,
webhook,
uploadWithoutProcessingIsOn,
tags,
externalId,
campaignId,
username: encodeURIComponent(username),
clientId: encodeURIComponent(clientId),
key: encryptedApiKey
});

Parameters

ParameterDescription
documentTypeType of document to capture (e.g., "receipt", "invoice").
showDocumentTypesShow document type selection screen (true / false).
autoDocDetectionAndCropIsOnEnable automatic document detection and cropping (true / false).
blurDetectionIsOnEnable blur detection before capturing (true / false).
locationServicesIsOnEnable location tracking during capture (true / false).
dataExtractionEngineSet to "api" to use the Veryfi Data Extraction API.
externalIdAdd a unique reference identifier for a scan, allowing you to easily map the document back to your system
campaignIdLink the document to an existing campaign on your system
tagsOptional list of custom tags for Veryfi to use in tagging submitted documents
uploadWithoutProcessingIsOnIf dataExtractionEngine is none it will upload the package to our servers but will defer the processing to the webhook, default: true
webhookA url that will be used instead of the one owned by Veryfi to send the package data
usernameVeryfi username (URL-encoded).
clientIdVeryfi Client ID (URL-encoded).
keyEncrypted Veryfi API key.

🔐 Encrypting the apiKey Parameter

To securely send your Veryfi API key in the Lens Instant App or App Clip URL, you must encrypt it using our public key.

Note: Only the Instant App or App Clip (holding the corresponding private key) can decrypt it.

1. Download the Public Key

Download the Lens Instant App / App Clip public key here:

📄 veryfi_recipient_public.pem

2. Encrypt the API Key in Your Backend

Use RSA-OAEP with SHA-256 to encrypt the API key. This example shows how to do it in Node.js:

// crypto/encryptKey.js
import crypto from "crypto";
import fs from "fs";

// Convert buffer to URL-safe Base64 (base64url)
const b64u = (buf) =>
Buffer.from(buf).toString("base64")
.replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");

export function encryptApiKeyForApp(publicKeyPem, apiKeyPlaintext) {
const ciphertext = crypto.publicEncrypt(
{
key: publicKeyPem,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
},
Buffer.from(apiKeyPlaintext, "utf8")
);
return b64u(ciphertext); // URL-safe string
}

// Example usage:
const publicKeyPem = fs.readFileSync("./veryfi_lens_public.pem", "utf8");
const encryptedKey = encryptApiKeyForApp(publicKeyPem, process.env.VERYFI_API_KEY);

console.log("Encrypted key:", encryptedKey);

4. How it Looks in WhatsApp

Below is an example of how this Call-to-Action (CTA) button with the encrypted key parameter will appear inside a WhatsApp conversation:

📸 Screenshot Example

WhatsApp Lens Example 1

5. Payload sent to the webhook

5.1 If uploadWithoutProcessingIsOn = true and dataExtractionEngine = none, then the payload will contain the data to find the document location so that you can process it via API:

{
"data": {
"bucket": "veryfi-lens-uploads",
"document_type": "receipt",
"external_id": "your-external-id",
"img_original_path": "path/to/original/image.jpg",
"img_stitched_pdf_path": "path/to/stitched.pdf",
"img_thumbnail_path": "path/to/thumbnail.jpg",
"package_path": "path/to/package.zip",
"upload_time_s": 3,
"img_paths": ["path/to/image1.jpg", "path/to/image2.jpg"]
},
"device_id": "ed259234-5610-33b7-ab5b-4b2bc3f2cac2",
"document_type": "receipt",
"package_id": "package-456",
"status": "success"
}

5.2 If dataExtractionEngine = api, then the full processed response will be sent:

{
"package_id": "edc8653e4c2b4ef1",
"data": {"account_number": "", "bill_to": {"address": "", "name": ""}, "card_number": "", "category": "Meals & Entertainment", "created_date": "2021-01-14 05: 19: 51", "currency_code": "USD", "date": "2021-01-14 05: 19: 51", "delivery_date": "", "discount": 0, "due_date": "", "external_id": "", "id": 31428417, "img_file_name": "xxxxxxxxx.png", "img_thumbnail_url": "https: \/\/cdn.veryfi.com\/partner-receipts\/xxxxxxxxx_t.png", "img_url": "https: \/\/cdn.veryfi.com\/partner-receipts\/xxxxxxxxx.png", "incoterms": "", "insurance": "", "invoice_number": "", "line_items": [], "notes": "", "ocr_text": "starbucks 23.4", "order_date": "", "payment": {"card_number": "", "display_name": "No Payment,", "type": "no_payment,"}, "phone_number": "", "purchase_order_number": "", "reference_number": "VBDEC-0000", "service_end_date": "", "service_start_date": "", "ship_date": "", "shipping": 0, "subtotal": 23.4, "tags": [], "tax": 0, "tip": 0, "total": 23.4, "total_weight": "", "vendor": {"abn_number": "", "address": "", "fax_number": "", "logo": "https: \/\/cdn.veryfi.com\/logos\/us\/910419611.png", "name": "Starbucks", "phone_number": "", "raw_name": "Starbucks", "type": "", "vat_number": ""}}
}

Important Notes

note
  • Do not send the raw API key in the URL.
  • The encryption must be done on your backend, never in frontend code.
  • The encrypted value is already URL-safe (base64url); avoid double-encoding.