moth

mothDocs

Docs

Build on one key

One Moth API key reaches every model through one address, the Mothpoint, and the SDKs and agents you use today work once you point the base URL at it.

These docs describe the API at launch. The Mothpoint's address is published when the network opens, so the examples use $API_URL.

Start

Quickstart

  1. 01
    Open the app and sign in

    Connect a wallet on Robinhood Chain. There is no email or account form.

  2. 02
    Top up and create a key

    Add USDG or $MOTH to your balance, then create an API key in Moth Console and copy it once. Keys start with moth_.

  3. 03
    Point your SDK at the Mothpoint

    Set the Mothpoint as the base URL and your key as the API key in any OpenAI or Anthropic SDK, and name a model from the catalog.

Name a model by its ID in the model field. Copy one of these to try, or pick any model from the catalog.

  • Claude Sonnet 4.6Chat · $1.50 / $7.50 per 1M tokensclaude-sonnet-4.6
  • Gemini 3.8 FlashChat · $0.375 / $1.875 per 1M tokensgemini-3.8-flash
  • Nano Banana 2Image · $0.0471 per imagenano-banana-2
  • Veo 3.1 FastVideo · $0.06 per secondveo-3.1-fast

Every model and its ID

import osfrom openai import OpenAIclient = OpenAI(base_url=os.environ["API_URL"] + "/v1", api_key=os.environ["API_KEY"])reply = client.chat.completions.create(    model="claude-sonnet-4.6",    messages=[{"role": "user", "content": "Summarize this contract in five lines"}],)print(reply.choices[0].message.content)
client.py

Authentication

Send your key as Authorization: Bearer <key> or as x-api-key: <key>. Keys are stored hashed, so they are shown once when created and can't be read back.

Each key can carry a daily spend cap, and you can rename or revoke it in the app at any time. The app itself signs in with a wallet using Sign-In with Ethereum on Robinhood Chain.

Keep keys on your server. A key shipped inside a browser or mobile app can be read by anyone who has the app.

Models

Chat

POST /v1/chat/completions takes the OpenAI Chat Completions body, and POST /v1/messages takes the Anthropic Messages body. Both stream, both support tool use, and every chat model works on both.

What we drop before sending
FieldWhy
userIt identifies your end user
metadataIt can carry identifiers
storeNothing is stored
provider routing fieldsRouting is ours, and prices never change because of it

Catalog

GET /v1/models lists every model with its modality, its price, the maker's list price with its source and check date, the saving, its privacy label (anonymized or sealed) and its status.

GET /v1/modelssample
{ "data": [ {  "id": "claude-sonnet-4.6", "modality": "chat", "privacy": "anonymized", "status": "available",  "pricing": { "input_usd_per_mtok": "1.500000", "output_usd_per_mtok": "7.500000" },  "list_price": { "input_usd_per_mtok": "3.000000", "output_usd_per_mtok": "15.000000",                  "checked": "2026-10-13", "saving_pct": { "input": 50, "output": 50 } }} ] }

Images, video and music

POST /v1/images and POST /v1/jobs answer at once with a job id and hold the job's maximum price. GET /v1/jobs/{id} reports the status, and each finished output streams from GET /v1/jobs/{id}/output/{n} on our own domain.

A job that fails releases its hold in full. The job id is forgotten 24 hours after the job completes, so save outputs when they arrive. The app does this for you, in your browser.

Sealed models

GET /v1/sealed/models lists the Sealed models with their provider and pinned measurement, and GET /v1/sealed/attestation/{model} returns the hardware's current attestation so a client can check it.

A Sealed request is encrypted on the client to the attested hardware's key, and we pass the ciphertext through without reading it. The app does this at launch, and an SDK for API clients follows, since a plain OpenAI or Anthropic client can't encrypt to the hardware.

Account

Usage and charges

Each call holds its worst case first, then settles at its exact cost. Every reply carries a request id and, outside streams, what you paid in micro-dollars.

Reply headers
HeaderWhat it reports
moth-request-idThe request's id, for support
moth-charged-microsWhat the call cost you, in micro-dollars

GET /v1/usage returns your balance and your requests, tokens and spend by day and by model, with no content.

Errors

Errors come back in the shape of the endpoint you called, OpenAI's on /v1/chat/completions and Anthropic's on /v1/messages, with the same statuses on both.

Statuses
StatusTypeWhen it happens
400invalid_request_errorThe request body isn't valid
401authentication_errorThe key is missing, not valid or revoked
402insufficient_creditThe balance or the key's daily cap can't cover the call's worst case
404not_found_errorThe model isn't in the catalog
429rate_limit_errorThe key sent too many requests, so wait for retry-after
529overloaded_errorThe model can't be served at its price right now

Limits

Each key may send 60 chat requests a minute by default, and a retry-after header says when to try again. Daily spend caps are set per key in the app.