API Integrations
The Certi-Lock® app integrates with three external APIs: Algolia for product catalog search, the Certi-Lock Image API for sealed item images, and the WordPress REST API for promotional banners and error logging.
Algolia Product Search
Overview
The app queries the Algolia search index to retrieve product data when a QR/barcode is scanned. The first 4 characters of the serial number are used as a filter to locate the matching product.
Configuration
| Setting | Environment Variable |
|---|---|
| App ID | EXPO_PUBLIC_ALGOLIA_APP_ID |
| API Key | EXPO_PUBLIC_ALGOLIA_API_KEY |
| Index Name | EXPO_PUBLIC_ALGOLIA_INDEX_NAME |
Request Format
// api/get-data.ts
const response = await fetch(
`https://${appId}-dsn.algolia.net/1/indexes/${indexName}/query`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Algolia-API-Key": apiKey,
"X-Algolia-Application-Id": appId,
},
body: JSON.stringify({
params: `filters=serial_number_prefix:${serialPrefix}`,
}),
}
);
Response Processing
The Algolia response includes product details that are mapped to the local database schema:
| Algolia Field | Local DB Column | Description |
|---|---|---|
name | name | Product display name |
subtitle | subtitle | Product subtitle/description |
image_url | imageUrl | Product image URL |
product_details | productDetails | JSON object with product specifications |
metal_type | metalType | Metal type (gold, silver) for fallback image |
shape | shape | Shape (round, bar) for fallback image |
Error Handling
- If no results are returned, the item is saved with default/placeholder data
- Network failures are caught and logged to Sentry and the WordPress error API
- The serial number is always preserved regardless of API response
Certi-Lock Image API
Overview
The Image API provides high-resolution sealed images for verified precious metals items. Each image is fetched by serial number and stored locally with a SHA256 hash-based filename.
Configuration
| Setting | Environment Variable |
|---|---|
| Base URL | EXPO_PUBLIC_IMAGE_API_URL |
| API Key | EXPO_PUBLIC_IMAGE_API_KEY |
Request Format
// api/get-image.ts
const response = await fetch(
`${baseUrl}?serial_number=${serialNumber}&api_key=${apiKey}`
);
Image Processing Flow
API Response (image data)
│
▼
SHA256 Hash Generation
(expo-crypto)
│
▼
Save to Document Directory
(expo-file-system)
│
▼
Store hash in SQLite
(imageHash column)
Step-by-step:
- Fetch image binary data from the Image API using the serial number
- Generate a SHA256 hash of the image content using
expo-crypto - Save the image file to the app's document directory with the hash as the filename
- Store the hash in the SQLite
imageHashcolumn for later retrieval - On subsequent views, load the image directly from the local filesystem using the stored hash
Fallback Images
When the Image API returns no image (e.g., image still processing), the app displays a fallback based on the product's metal type and shape:
| Metal Type | Shape | Fallback Image |
|---|---|---|
| Gold | Round | fallback-round-gold.png |
| Gold | Bar | fallback-bar-gold.png |
| Silver | Round | fallback-round-silver.png |
| Silver | Bar | fallback-bar-silver.png |
The fallback selection logic is in api/get-fallback-image.ts.
WordPress REST API
The WordPress REST API serves two purposes: promotional banners for the home screen and error logging for monitoring.
Configuration
| Setting | Environment Variable |
|---|---|
| Base URL | EXPO_PUBLIC_WP_API_URL |
| API Key | EXPO_PUBLIC_WP_API_KEY |
Promotional Banners
Banners are displayed on the home screen in a carousel. They are fetched from WordPress and cached locally for 24 hours.
// api/get-banners.ts — Simplified flow
const cached = await AsyncStorage.getItem("banners_cache");
if (cached) {
const { data, timestamp } = JSON.parse(cached);
const isExpired = Date.now() - timestamp > 24 * 60 * 60 * 1000;
if (!isExpired) return data;
}
const response = await fetch(`${baseUrl}/banners`, {
headers: { "X-API-Key": apiKey },
});
const banners = await response.json();
await AsyncStorage.setItem("banners_cache", JSON.stringify({
data: banners,
timestamp: Date.now(),
}));
return banners;
Cache behavior:
| Scenario | Action |
|---|---|
| Cache exists and is less than 24 hours old | Return cached data |
| Cache exists but is older than 24 hours | Fetch fresh data, update cache |
| No cache exists | Fetch from API, create cache |
| API request fails | Return cached data if available, otherwise empty array |
Error Logging
Critical errors are sent to the WordPress REST API for centralized monitoring alongside server-side logs:
// api/log-error.ts
const response = await fetch(`${baseUrl}/log-error`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": apiKey,
},
body: JSON.stringify({
error: errorMessage,
context: additionalContext,
}),
});
This supplements Sentry error tracking by providing logs accessible from the WordPress admin dashboard.
Sentry Error Tracking
Configuration
Sentry is integrated at the Metro bundler level and initialized in the root layout:
// metro.config.js
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
const config = getSentryExpoConfig(__dirname);
Runtime Configuration
| Setting | Value |
|---|---|
| DSN | https://1579b939d45a6ce0dbc68f417aaf12a4@o4509243283800064.ingest.us.sentry.io/4509243290681344 |
| Traces Sample Rate (Dev) | 1.0 (100%) |
| Traces Sample Rate (Prod) | 0.1 (10%) |
| Native Frame Tracking | Enabled |
| Auto Performance | Enabled |
What Gets Tracked
- Unhandled JavaScript exceptions
- Native crashes (iOS and Android)
- Navigation performance (screen transitions)
- API call durations
- Custom error events logged via
Sentry.captureException()
Environment Variables Summary
All API configuration is managed through environment variables prefixed with EXPO_PUBLIC_ to make them accessible in the client-side JavaScript bundle:
# Algolia Product Search
EXPO_PUBLIC_ALGOLIA_API_KEY=<search-only-api-key>
EXPO_PUBLIC_ALGOLIA_APP_ID=<application-id>
EXPO_PUBLIC_ALGOLIA_INDEX_NAME=<index-name>
# Certi-Lock Image API
EXPO_PUBLIC_IMAGE_API_KEY=<api-key>
EXPO_PUBLIC_IMAGE_API_URL=<base-url>
# WordPress REST API
EXPO_PUBLIC_WP_API_KEY=<api-key>
EXPO_PUBLIC_WP_API_URL=<base-url>
All EXPO_PUBLIC_ variables are embedded in the JavaScript bundle and visible to end users. Use read-only/search-only API keys with minimal permissions. Never expose admin or write-capable keys.