Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.indoralabs.com/llms.txt

Use this file to discover all available pages before exploring further.

The Indora Labs API lets you upload, index, and automatically redact sensitive data in video, audio, text, and images — all in one unified flow.

🚀 Quick Start (TypeScript Example)

Below is a minimal TypeScript example showing the full lifecycle — from uploading a file to receiving a redacted version.
import { useState } from "react";

/**
 * Quick Start Example
 * Upload → Index → Redact → Retrieve
 */
export default function QuickStart() {
  const [status, setStatus] = useState<string>("Idle");
  const [redactedUrl, setRedactedUrl] = useState<string>("");

  const handleUpload = async (file: File) => {
    try {
      setStatus("Initializing upload...");

      // 1️⃣ Initialize upload
      const initRes = await fetch("https://api.indoralabs.com/upload/init", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          filename: file.name,
          contentType: file.type,
          sizeBytes: file.size,
        }),
      });
      const init = await initRes.json();

      // 2️⃣ Upload directly to S3
      await fetch(init.putUrl, { method: "PUT", body: file });

      // 3️⃣ Complete upload
      const completeRes = await fetch("https://api.indoralabs.com/upload/complete", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          uploadId: init.uploadId,
          key: init.key,
        }),
      });
      const complete = await completeRes.json();
      const fileId = complete.file?.id;

      setStatus("Launching redaction...");

      // 4️⃣ Launch redaction
      const redactRes = await fetch(`https://api.indoralabs.com/files/${fileId}/redact`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          targets: ["juvenile faces", "HIPAA identifiers", "license plates"],
        }),
      });
      const job = await redactRes.json();

      // 5️⃣ Poll for completion
      let statusCheck = "pending";
      let outputUrl = "";
      while (statusCheck !== "succeeded") {
        const statusRes = await fetch(
          `https://api.indoralabs.com/files/${fileId}/redaction/status`
        );
        const statusData = await statusRes.json();
        statusCheck = statusData.status;
        setStatus(`Redaction status: ${statusCheck}`);
        if (statusCheck === "succeeded") {
          outputUrl = statusData.outputS3Uri;
          break;
        }
        await new Promise((r) => setTimeout(r, 3000));
      }

      // 6️⃣ Get signed download link
      const signedRes = await fetch(
        `https://api.indoralabs.com/files/${fileId}/redaction/signed-url`
      );
      const signed = await signedRes.json();

      setRedactedUrl(signed.url);
      setStatus("✅ Redaction complete!");
    } catch (err: any) {
      setStatus(`❌ Error: ${err.message}`);
    }
  };

  return (
    <div className="p-4 border rounded-lg max-w-lg">
      <h2 className="text-lg font-bold mb-2">Indora Labs Redaction Quickstart</h2>

      <input
        type="file"
        onChange={(e) => e.target.files?.[0] && handleUpload(e.target.files[0])}
        className="mb-3"
      />

      <p className="text-sm text-gray-700 mb-2">{status}</p>

      {redactedUrl && (
        <video controls width="400" src={redactedUrl}>
          Your browser does not support video playback.
        </video>
      )}
    </div>
  );
}

💡 How It Works

StepDescription
1️⃣ UploadCalls /upload/init and uploads the file directly to S3.
2️⃣ Auto IndexAfter completion, Indora automatically indexes your content for semantic search.
3️⃣ RedactCalls /files/{id}/redact with natural-language targets.
4️⃣ PollUses /files/{id}/redaction/status until the job completes.
5️⃣ RetrieveFetches a signed URL from /files/{id}/redaction/signed-url.

🧠 Tip: Using Natural Language Targets

Targets can be written in plain English — no model labels required.
["juveniles", "faces", "license plates", "names", "HIPAA identifiers"]
The redaction engine automatically maps these targets to the right detection models for each modality — video, audio, text, or image.
✅ In ~30 lines, you’ve built an end-to-end redaction workflow — from raw upload to sanitized, compliant output.