Skip to main content

Step 1: List Available Apps

curl -H "x-api-key: lma_your_api_key" \
  https://app.uselamina.ai/api/apps
Look through the response and choose an appId.

Step 2: Inspect The App

curl -H "x-api-key: lma_your_api_key" \
  https://app.uselamina.ai/api/apps/{appId}
Use this response to determine:
  • which fields are required
  • which parameters are text, options, or url
  • which default values are already defined

Step 3: Start Execution

curl -X POST \
  -H "x-api-key: lma_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": {
      "Prompt": "A cinematic ecommerce hero image",
      "Aspect Ratio": "16:9"
    }
  }' \
  "https://app.uselamina.ai/api/apps/{appId}/executions?webhook=https://your-server.com/callback"

Without webhook

curl -X POST \
  -H "x-api-key: lma_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": {
      "Prompt": "A cinematic ecommerce hero image",
      "Aspect Ratio": "16:9"
    }
  }' \
  https://app.uselamina.ai/api/apps/{appId}/executions
The response includes an executionId.

Step 4: Get Results

Via webhook

If you passed ?webhook=, your callback URL receives a POST when the execution completes:
{
  "data": {
    "executionId": "fc32ae7d-...",
    "status": "completed",
    "outputs": [
      {
        "id": "aiDesignerNode-...",
        "label": "Hero Image",
        "type": "image",
        "value": "https://storage.example.com/generated.png",
        "status": "completed",
        "error": null
      }
    ]
  }
}
Headers include X-Lamina-Webhook-Signature for verification. See Webhook Signing Key for details.

Via polling

If not using webhooks, poll until the execution reaches a terminal state:
curl -H "x-api-key: lma_your_api_key" \
  https://app.uselamina.ai/api/executions/{executionId}
Poll every 3-5 seconds. Stop when status is completed or failed.

JavaScript Example

const baseUrl = 'https://app.uselamina.ai';
const apiKey = process.env.LAMINA_API_KEY;

async function laminaFetch(path, init = {}) {
  const response = await fetch(`${baseUrl}${path}`, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': apiKey,
      ...(init.headers || {}),
    },
  });

  if (!response.ok) {
    const body = await response.text();
    throw new Error(`Lamina request failed: ${response.status} ${body}`);
  }

  return response.json();
}

// With webhook — start and forget (results arrive at your webhook)
async function runAppWithWebhook(appId, inputs, webhookUrl) {
  const started = await laminaFetch(
    `/api/apps/${appId}/executions?webhook=${encodeURIComponent(webhookUrl)}`,
    { method: 'POST', body: JSON.stringify({ inputs }) }
  );
  return started.data.executionId;
}

// With polling — start and wait
async function runAppWithPolling(appId, inputs) {
  const started = await laminaFetch(`/api/apps/${appId}/executions`, {
    method: 'POST',
    body: JSON.stringify({ inputs }),
  });

  const executionId = started.data.executionId;

  for (;;) {
    const status = await laminaFetch(`/api/executions/${executionId}`);
    const state = status.data.status;

    if (state === 'completed' || state === 'failed') {
      return status.data;
    }

    await new Promise((resolve) => setTimeout(resolve, 5000));
  }
}

Python Example

import os
import time
import requests
from urllib.parse import urlencode

BASE_URL = "https://app.uselamina.ai"
API_KEY = os.environ["LAMINA_API_KEY"]

headers = {
    "x-api-key": API_KEY,
    "Content-Type": "application/json",
}

# With webhook — start and forget
def run_app_with_webhook(app_id, inputs, webhook_url):
    r = requests.post(
        f"{BASE_URL}/api/apps/{app_id}/executions?webhook={webhook_url}",
        headers=headers,
        json={"inputs": inputs},
        timeout=60,
    )
    r.raise_for_status()
    return r.json()["data"]["executionId"]

# With polling — start and wait
def run_app_with_polling(app_id, inputs):
    started = requests.post(
        f"{BASE_URL}/api/apps/{app_id}/executions",
        headers=headers,
        json={"inputs": inputs},
        timeout=60,
    )
    started.raise_for_status()
    execution_id = started.json()["data"]["executionId"]

    while True:
        status = requests.get(
            f"{BASE_URL}/api/executions/{execution_id}",
            headers=headers,
            timeout=60,
        )
        status.raise_for_status()
        payload = status.json()["data"]

        if payload["status"] in ("completed", "failed"):
            return payload

        time.sleep(5)