Mobile apps
Use the Headless API for a native try-on flow, or host the browser SDK in a page inside your app. There is no Antla SDK for Swift, Kotlin, or React Native.
Choose the delivery model
Section titled “Choose the delivery model”| Approach | Best when | You implement |
|---|---|---|
| Native UI + Headless API | Native screens, photo capture, HTTP, and your Shopify cart | Photo picker, camera, image preparation, HTTP calls, email, polling, results, and Shopify cart |
| Hosted SDK in a WebView | You want Antla’s existing interface | A web page with antla-block, file and camera permissions, navigation, and cart session coordination |
| React Native + Headless API | Your app uses JavaScript with native controls | The same custom flow, with native adapters for image bytes and persistent storage |
The server contract is the same for all three. Native HTTP clients connect Headless API. WebView hosts need Headless SDK. Then read authentication.
Native implementation sequence
Section titled “Native implementation sequence”- Load product and selected variant from the connected Shopify store.
- Resolve a funnel from product tags.
- Ask the shopper to choose or take a photo.
- Decode and orient the image; prepare a supported MIME type and reasonable size.
- Request an upload target, then PUT the raw bytes to the signed URL.
- Load/save visitor identity and collect email if required.
- Start a generation once and persist its returned job ID.
- Poll while the relevant screen is active; show temporary and final states distinctly.
- Add the selected variant through your app’s Shopify cart flow.
The Antla API key is intended for client use. A Shopify private Storefront token is not appropriate for a mobile bundle.
Native image handling
Section titled “Native image handling”A camera’s local URI is not an imageUrl that Antla can retrieve. A native upload must read the file into bytes or stream the file body to the signed URL.
Use the same Content-Type when requesting the target and uploading. For cross-device interoperability, normalized JPEG is a practical default for a photo; PNG or WebP can also be appropriate. The API accepting a MIME value does not mean every downstream model/browser can decode every photo.
Native clients do not automatically receive the SDK’s client-side preprocessing. Apply your own orientation handling, resizing, size checks and visible progress. See Images and uploads.
Lifecycle, retry and persistence
Section titled “Lifecycle, retry and persistence”Persist jobId, the merchant/environment identifier, the selected product/variant and a non-null visitor ID after submission. Do not mix merchant sessions in one storage key.
When the app backgrounds, pause or reduce polling according to your app’s lifecycle policy. On foreground, resume the saved job if the user still expects the result. A server job continues independently of your screen.
If the app is closed during submission before it receives a job ID, the result can be unknown. There is no documented job-list or request-id recovery endpoint. Explain the uncertainty; do not automatically replay a saved POST on the next launch.
Use timeouts for each network request and an overall UI deadline. Honor Retry-After for IP throttling. A customer try-on limit needs a different UI from transient network failure.
Swift example
Section titled “Swift example”The example bundle includes a Swift URLSession client with SDK-key authentication, raw-byte upload, generation submission and bounded polling. It models PROCESSING, temporary SUCCESS, final SUCCESS and ERROR, and keeps the actual key out of the source.
The client is a reference implementation for your app, not an official distributed Antla package. Connect it to your own UI, storage and lifecycle.
Android and React Native
Section titled “Android and React Native”For Android, implement the same request sequence with the HTTP stack already used by your app. Include X-Antla-SDK-Key only for Antla requests. Use a PUT request body containing the image bytes for the storage request.
For React Native, the downloadable fetch client can perform Antla JSON requests and polling when your runtime provides fetch and AbortController. Supply the upload bytes via your native file/asset adapter; do not assume a browser File object or that fetching a local file: URI behaves consistently across platforms.
// Your native adapter supplies these values.const bytes = preparedPhotoBytes; // ArrayBuffer or compatible request bodyconst contentType = "image/jpeg";
const target = await client.createUpload(contentType, signal);await client.uploadBytes(target.uploadUrl, bytes, contentType, signal);const generation = await client.createGeneration({ funnelId, productId, variantId, imageUrl: target.imageUrl, ...(visitorId ? { uniqueUserId: visitorId } : {}),}, signal);
// Persist generation.jobId before starting the polling loop.Use the browser SDK in a WebView
Section titled “Use the browser SDK in a WebView”Host an HTTPS page you control with the SDK script and a populated antla-block. Configure product, variant and the current shopper’s cart before attaching the block.
Test on the actual app WebView.
- JavaScript, custom elements, and local storage.
- Photo picker and camera access, including denied permissions.
- HTTPS and camera permissions at both the native and web layer.
- Modal scrolling, safe areas, orientation, and keyboard display.
- Opening Shopify checkout and returning to the app.
- Cart identity shared with the app’s native cart session.
- Slow connectivity, temporary images, and app background or foreground transitions.
A native bridge is your application’s code. The SDK has no documented completion event or bridge contract. Do not design a native bridge around undocumented Shadow DOM internals. If the native app must receive structured result callbacks, use the Headless API path.
Before you ship
Section titled “Before you ship”Refresh the Headless key through remote app configuration. Do not log photos, emails, or cart IDs. Run the launch checklist. This API does not include an official native SDK, offline generation, AR overlay, or a Tapcart plug-in.