Skip to main content
Use these endpoints to manage API keys for a user account. These endpoints require a valid Firebase ID token (not an API key) because they create or revoke keys.

Authentication

Provide an ID token using one of these methods:
  • Authorization: Bearer <ID_TOKEN>
  • x-id-token: <ID_TOKEN>
  • JSON body field idToken

Base URL

https://www.lettucestream.com

Endpoints

List API keys

GET /api/api-keys Response
{
  "keys": [
    {
      "id": "string",
      "label": "string",
      "prefix": "ls_live_AbCd...",
      "createdAt": "2026-02-06T18:02:12.123Z",
      "lastUsedAt": "2026-02-06T18:10:55.000Z",
      "revokedAt": null
    }
  ]
}
Example requests
curl "https://www.lettucestream.com/api/api-keys" \
  -H "Authorization: Bearer <ID_TOKEN>"

Create API key

POST /api/api-keys Body
{
  "label": "Production key"
}
Response
{
  "key": "ls_live_...",
  "keyId": "string",
  "keys": [
    {
      "id": "string",
      "label": "string",
      "prefix": "ls_live_AbCd...",
      "createdAt": "2026-02-06T18:02:12.123Z",
      "lastUsedAt": null,
      "revokedAt": null
    }
  ]
}
Example requests
curl -X POST "https://www.lettucestream.com/api/api-keys" \
  -H "Authorization: Bearer <ID_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"label":"Production key"}'
Notes
  • The full key value is returned only once. Store it securely.
  • The UI and API store only a SHA-256 hash of the key.

Revoke API key

DELETE /api/api-keys Body
{
  "keyId": "string"
}
Response
{
  "keys": [
    {
      "id": "string",
      "label": "string",
      "prefix": "ls_live_AbCd...",
      "createdAt": "2026-02-06T18:02:12.123Z",
      "lastUsedAt": "2026-02-06T18:10:55.000Z",
      "revokedAt": "2026-02-06T18:12:01.000Z"
    }
  ]
}
Example requests
curl -X DELETE "https://www.lettucestream.com/api/api-keys" \
  -H "Authorization: Bearer <ID_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"keyId":"key_123"}'

Example UI

Use a lightweight UI library like shadcn/ui with a free placeholder API to prototype your API-key dashboard layout before wiring it to the Lettuce Stream endpoints.
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";

const placeholderUrl = "https://jsonplaceholder.typicode.com/users";

export default function ApiKeysTable() {
  const [rows, setRows] = useState([]);

  useEffect(() => {
    const loadRows = async () => {
      const response = await fetch(placeholderUrl);
      const users = await response.json();

      setRows(
        users.slice(0, 5).map((user) => ({
          id: `key_${user.id}`,
          label: `${user.company.name} key`,
          prefix: "ls_live_AbCd...",
          createdAt: new Date().toISOString(),
          lastUsedAt: "-",
        }))
      );
    };

    loadRows();
  }, []);

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div>
          <p className="text-sm text-muted-foreground">
            Replace the placeholder API with your Lettuce Stream requests once
            your auth flow is ready.
          </p>
        </div>
        <Button>Create key</Button>
      </div>

      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Label</TableHead>
            <TableHead>Prefix</TableHead>
            <TableHead>Created</TableHead>
            <TableHead>Last used</TableHead>
            <TableHead className="text-right">Actions</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {rows.map((row) => (
            <TableRow key={row.id}>
              <TableCell className="font-medium">{row.label}</TableCell>
              <TableCell>{row.prefix}</TableCell>
              <TableCell>{row.createdAt}</TableCell>
              <TableCell>{row.lastUsedAt}</TableCell>
              <TableCell className="text-right">
                <Button variant="ghost">Revoke</Button>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </div>
  );
}

Limits

  • Maximum active keys per user: API_KEYS_MAX_ACTIVE (default 10).
  • Key prefix format: API_KEY_PREFIX (default ls_live_).
  • Prefix preview length: API_KEY_PREFIX_LENGTH (default 12).

Errors

  • 400 — Missing label or key id, or maximum active keys reached.
  • 401 — Missing or invalid authentication token.
  • 403 — Attempted to revoke a key not owned by the user.
  • 404 — API key not found.
  • 405 — Method not allowed (allowed: GET, POST, DELETE).
  • 500 — Server error.

Example (curl)

curl -X POST "https://www.lettucestream.com/api/api-keys" \
  -H "Authorization: Bearer <ID_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"label":"Prod key"}'

Using API keys on other endpoints

Other protected endpoints accept API keys via:
  • x-api-key: <API_KEY>
  • Authorization: Bearer <API_KEY>