Admin Tools API

Internal automation API for Lumail administrators - execute admin tools across all organizations with a single endpoint

The Admin Tools API is an internal, admin-only REST interface for platform automation. It exposes a registry of tools behind a single endpoint, secured by dedicated admin API keys.

Warning: Admin API keys grant read access across every organization on the platform. They are reserved for Lumail administrators — this API is not part of the public API and is not available to regular accounts. If you are looking for the customer-facing API, see Tools API (v2).

Quick Start

Both operations live on a single endpoint: /api/v1/admin/tools.

List all available tools:

curl https://lumail.io/api/v1/admin/tools \
  -H "Authorization: Bearer luma_YOUR_ADMIN_KEY"

Execute a tool:

curl -X POST https://lumail.io/api/v1/admin/tools \
  -H "Authorization: Bearer luma_YOUR_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tool": "get_org", "input": {"slug": "acme"}}'

Authentication

All requests require an admin API key as a Bearer token:

Authorization: Bearer luma_your_admin_key_here

Admin keys are managed from Admin → API Keys (/admin/api-keys) by platform administrators:

  • Keys use the luma_ prefix followed by 64 hex characters.
  • The plaintext key is shown once at creation — only a sha256 hash is stored.
  • Revoking a key from the admin panel cuts off access immediately.
  • Last used is tracked automatically (background write, throttled to once per minute).

Listing Tools

GET /api/v1/admin/tools is self-describing: it returns every registered tool with its JSON input schema, plus a usage block that shows how to execute them.

Response:

{
  "success": true,
  "usage": {
    "execute": "POST /api/v1/admin/tools",
    "body": { "tool": "<tool name>", "input": "<object matching inputSchema>" },
    "example": { "tool": "get_org", "input": { "slug": "acme" } }
  },
  "total": 1,
  "tools": [
    {
      "name": "get_org",
      "description": "Get an organization's general information...",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "Organization ID" },
          "slug": { "type": "string", "description": "Organization slug" }
        }
      }
    }
  ]
}

Executing Tools

POST /api/v1/admin/tools with a JSON body:

FieldTypeRequiredDescription
toolstringYesName of the tool to execute (e.g. get_org)
inputobjectNoInput matching the tool's inputSchema

The input is validated against the tool's schema before execution — invalid input returns a 400 with the exact validation issues.

Success response:

{
  "success": true,
  "tool": "get_org",
  "data": {
    /* tool-specific response */
  }
}

Errors

StatusMeaning
400Invalid input — the message lists each failing field and why
401Missing, malformed, or revoked admin API key
404Unknown tool — the message lists the available tool names
429IP rate limit exceeded — check the Retry-After header

Example — unknown tool:

{ "message": "Unknown tool: get_orgs. Available tools: get_org" }

Example — invalid input:

{ "message": "Invalid input: Provide only one of id or slug" }

Available Tools (1)

ToolDescription
get_orgGet an organization's general information (plan, stats, members) and its configured sending domains.

Get Organization

Tool: get_org

Get an organization's general information (plan, stats, members) and its configured sending domains with DNS verification status. Provide either id or slug — never both.

Parameters:

ParameterTypeRequiredDescription
idstringNo*Organization ID
slugstringNo*Organization slug

* Exactly one of id or slug is required.

Example:

curl -X POST https://lumail.io/api/v1/admin/tools \
  -H "Authorization: Bearer luma_YOUR_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tool": "get_org", "input": {"slug": "acme"}}'

Response:

{
  "success": true,
  "tool": "get_org",
  "data": {
    "organization": {
      "id": "aBcD1234...",
      "name": "Acme",
      "slug": "acme",
      "logo": "https://...",
      "email": "[email protected]",
      "timezone": "Europe/Paris",
      "verified": true,
      "createdAt": "2026-01-01T00:00:00.000Z"
    },
    "subscription": {
      "plan": "PREMIUM",
      "status": "active",
      "periodStart": "2026-07-01T00:00:00.000Z",
      "periodEnd": "2026-08-01T00:00:00.000Z",
      "cancelAtPeriodEnd": false,
      "customLimits": null
    },
    "stats": {
      "members": 3,
      "subscribers": 1200,
      "campaigns": 42
    },
    "domains": [
      {
        "id": "dom_...",
        "domain": "mail.acme.com",
        "status": "VERIFIED",
        "region": "EU_WEST_1",
        "sesRecords": [
          {
            "name": "_amazonses.mail.acme.com",
            "type": "TXT",
            "value": "...",
            "status": "verified"
          }
        ],
        "fallbackPriority": null,
        "verificationRequestedAt": null,
        "createdAt": "2026-02-01T00:00:00.000Z"
      }
    ]
  }
}
  • subscription is null when the organization has no active, trialing, or past-due subscription (free plan).
  • domains includes the full SES DNS records with per-record verification status — useful to debug deliverability without impersonating the account.

Adding New Tools

Tools live in an extensible registry in src/lib/admin-tools/. See src/lib/admin-tools/README.md in the repository for the step-by-step guide — new tools automatically appear in the GET listing, the execution endpoint, and the /admin/api-keys usage panel.