Integrations

Mobile (React Native)

Use Lelu in React Native apps to authorize AI agent actions on-device. Because mobile clients cannot safely store API keys, all Lelu calls must be proxied through your backend.

Recommended Architecture

  1. 1. Mobile app proposes action

    The React Native app sends the action + confidence score to your backend API (not to Lelu directly).

  2. 2. Backend calls Lelu Engine

    Your server receives the request and calls the Lelu Engine /authorize with the API key stored server-side.

  3. 3. Poll for approval (if needed)

    Backend returns a requestId. The mobile app polls your backend endpoint until the human approves or denies.

  4. 4. Result returned to app

    The backend returns the final allow/deny to the mobile app. The app proceeds or shows an error.

React Native Client

hooks/useLeluAction.ts
import { useState } from "react";

const API_BASE = process.env.EXPO_PUBLIC_API_URL;

export function useLeluAction() {
  const [status, setStatus] = useState<"idle" | "pending" | "approved" | "denied">("idle");

  async function authorize(action: string, confidence: number) {
    setStatus("pending");

    // Call your own backend (which calls Lelu internally)
    const res = await fetch(`${API_BASE}/authorize`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action, confidence }),
    });

    const { status: decision, requestId } = await res.json();

    if (decision === "pending") {
      // Poll for approval every 2 seconds
      return pollForApproval(requestId);
    }

    setStatus(decision === "allow" ? "approved" : "denied");
    return decision;
  }

  async function pollForApproval(requestId: string) {
    const poll = setInterval(async () => {
      const res = await fetch(`${API_BASE}/authorize/${requestId}`);
      const { status: decision } = await res.json();
      if (decision !== "pending") {
        clearInterval(poll);
        setStatus(decision === "allow" ? "approved" : "denied");
      }
    }, 2000);
  }

  return { authorize, status };
}