Platform

AI Generation

Metaloot AI gives your game one endpoint for generated content: dialogue and item text, structured JSON your code can consume directly, and images — with no model keys of your own and no server to run. Calls are billed in Metaloot credits; every account starts with 100 free.

How It Works#

  • Create an API token with the ai:generate scope at /settings/api-tokens.
  • Call POST /api/ai/generate — directly, or through @metaloot/sdk/ai. The endpoint is CORS-open, so browser games can call it from any origin.
  • Metaloot runs the request on its own inference capacity, charges your credit balance for what the call actually consumed, and returns the result plus your remaining balance.
A token with ai:generate spends real credits. Anything you ship in a browser bundle is public — scope those tokens to ai:generate only, and rotate them if a build leaks.

Credits & Pricing#

One Metaloot credit is nominally $0.01 of generation. A short text or object call typically costs a handful of credits; an image costs more. The exact charge for a call comes back as creditsUsed, and your remaining balance as balance — no separate metering call needed.

Signup grant100 credits, granted automatically the first time you touch the AI API.
Starter — $5500 credits. Enough to prototype a generated level or two.
Indie — $202,500 credits. For a game shipping AI content to real players.
Studio — $7010,000 credits. Bulk credits for teams running generation in production.
Payments are coming soon. The packs above are live in /settings/billing but checkout is not enabled yet — if you run out of free credits while building, get in touch and we'll top you up.

SDK Usage#

The SDK wraps the endpoint with three flat helpers plus a balance read. Pass a token explicitly, or let createMetaloot() hold it.

Structured objects

The most useful mode for a game: describe the shape you want and get a parsed object back, never a string you have to clean up.

loot.ts
import { createMetaloot } from "@metaloot/sdk";

const metaloot = createMetaloot({ token: process.env.METALOOT_TOKEN });

const { result, creditsUsed, balance } = await metaloot.ai.generateObject({
  prompt: "A cursed sword for a level 12 player in a swamp biome.",
  schema: {
    type: "object",
    properties: {
      name: { type: "string" },
      rarity: { type: "string", enum: ["common", "rare", "legendary"] },
      damage: { type: "number" },
      curse: { type: "string" },
    },
    required: ["name", "rarity", "damage", "curse"],
  },
});

console.log(result.name, result.damage);   // typed object, already parsed
console.log(creditsUsed, balance);         // 4, 96

Text

barks.ts
import { generateText } from "@metaloot/sdk/ai";

const { text, balance } = await generateText(
  {
    system: "You write terse, funny NPC barks. One line, no quotes.",
    prompt: "A guard who has caught the player stealing a chicken.",
  },
  { token: METALOOT_TOKEN }
);

Images

Images come back as base64 — Metaloot never hands out upstream URLs, which are not publicly fetchable. Turn it into a data URL, a Blob, or a texture.

portrait.ts
import { generateImage } from "@metaloot/sdk/ai";

const { b64Json, contentType, creditsUsed } = await generateImage(
  {
    prompt: "Pixel-art portrait of a swamp witch, 32x32, muted palette",
    aspectRatio: "1:1",
    imageSize: "1K",
  },
  { token: METALOOT_TOKEN }
);

const img = new Image();
img.src = `data:${contentType};base64,${b64Json}`;

Balance

import { getAiCredits } from "@metaloot/sdk/ai";

const { balance, ledger } = await getAiCredits({ token: METALOOT_TOKEN });
// ledger: last 20 entries — { amount, kind, description, createdAt }

Raw HTTP#

No SDK required — it is one POST with a bearer token. type is text, object, or image.

Text
curl -X POST https://www.metaloot.app/api/ai/generate \
  -H "Authorization: Bearer mtl_api_…" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "text",
    "prompt": "Name three hazards for a swamp level.",
    "system": "You are a level designer. Be terse."
  }'
Object
curl -X POST https://www.metaloot.app/api/ai/generate \
  -H "Authorization: Bearer mtl_api_…" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "object",
    "prompt": "A cursed sword for a level 12 player.",
    "schema": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "damage": { "type": "number" }
      },
      "required": ["name", "damage"]
    }
  }'
Image
curl -X POST https://www.metaloot.app/api/ai/generate \
  -H "Authorization: Bearer mtl_api_…" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "prompt": "Pixel-art swamp witch portrait",
    "aspectRatio": "1:1",
    "imageSize": "1K"
  }'
Response
{
  "id": "gen_9f2c…",
  "type": "object",
  "model": "openai/gpt-5.4-mini",
  "result": { "name": "Mireblight", "damage": 42 },
  "creditsUsed": 4,
  "balance": 96
}

Full field-by-field request and error tables live in the API Reference.

Errors#

Errors use the OpenAI-style envelope — { "error": { "message", "code" } } — so client code can branch on code alone.

400 invalid_requestMalformed body: missing prompt, prompt over 8000 characters, or a schema on a non-object call.
401 / 403Missing or invalid token, or a token without the ai:generate scope.
402 insufficient_creditsYour balance is below the estimate for this call. Top up at /settings/billing.
502 upstream_errorGeneration failed upstream, or Metaloot AI capacity is momentarily unavailable. Safe to retry — you are not charged.
You are only charged once generation succeeds. A failed call leaves your balance untouched.