Skip to content

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.

ApproachBest whenYou implement
Native UI + Headless APINative screens, photo capture, HTTP, and your Shopify cartPhoto picker, camera, image preparation, HTTP calls, email, polling, results, and Shopify cart
Hosted SDK in a WebViewYou want Antla’s existing interfaceA web page with antla-block, file and camera permissions, navigation, and cart session coordination
React Native + Headless APIYour app uses JavaScript with native controlsThe 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.

  1. Load product and selected variant from the connected Shopify store.
  2. Resolve a funnel from product tags.
  3. Ask the shopper to choose or take a photo.
  4. Decode and orient the image; prepare a supported MIME type and reasonable size.
  5. Request an upload target, then PUT the raw bytes to the signed URL.
  6. Load/save visitor identity and collect email if required.
  7. Start a generation once and persist its returned job ID.
  8. Poll while the relevant screen is active; show temporary and final states distinctly.
  9. 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.

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.

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.

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.

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 body
const 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.

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.

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.