{
  "openapi": "3.1.0",
  "info": {
    "title": "BlockRun API (account entry point)",
    "version": "1.0.0",
    "description": "BlockRun is the routing and payment layer for AI. One OpenAI-compatible endpoint routes to 100+ LLMs plus image, video, music and speech generation, web search, prediction-market and on-chain data, and multi-chain RPC. This host is the account-balance entry point: authenticate with an API key and pay from a BlockRun account funded by card or wire \u2014 no wallet signature per call. The same services are also sold per call in USDC over x402 at blockrun.ai (Base), sol.blockrun.ai (Solana) and arc.blockrun.ai (Arc).",
    "contact": {
      "email": "hello@blockrun.ai",
      "url": "https://blockrun.ai"
    },
    "termsOfService": "https://blockrun.ai/terms"
  },
  "servers": [
    {
      "url": "https://api.blockrun.ai"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "BlockRun API key from https://user.blockrun.ai/dashboard/keys"
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/models": {
      "get": {
        "operationId": "get_models",
        "summary": "Live model catalog with per-token prices",
        "description": "Live model catalog with per-token prices. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/images/models": {
      "get": {
        "operationId": "get_images_models",
        "summary": "Image/video model catalog with per-call prices",
        "description": "Image/video model catalog with per-call prices. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "get_usage",
        "summary": "One row per request over a window",
        "description": "One row per request over a window. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/usage.csv": {
      "get": {
        "operationId": "get_usage_csv",
        "summary": "The same rows as a CSV file, whole window",
        "description": "The rows of /v1/usage for the whole window as a downloadable CSV (UTF-8 BOM, CRLF). No paging. Fails rather than serving a partial file when a day cannot be read. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/usage/summary": {
      "get": {
        "operationId": "get_usage_summary",
        "summary": "Totals over a window: per day, model, endpoint, key",
        "description": "Totals over a window: per day, model, endpoint, key. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/balance": {
      "get": {
        "operationId": "get_balance",
        "summary": "Available balance, recorded spend, open reservations",
        "description": "Available balance, recorded spend, open reservations. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/credits": {
      "get": {
        "operationId": "get_credits",
        "summary": "Balance, with OpenRouter's GET /credits body",
        "description": "Same answer as /v1/balance, plus `data: { total_credits, total_usage }` in OpenRouter's shape; `total_credits - total_usage` is the remaining balance. `total_credits` is null on an account with no ceiling. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/key": {
      "get": {
        "operationId": "get_key",
        "summary": "This key, in OpenRouter's GET /key shape",
        "description": "OpenRouter-compatible: `data.usage`, `usage_daily`, `usage_weekly` (UTC, Monday start) and `usage_monthly` are this key's spend; `limit` / `limit_remaining` are the account's (null when unbounded); `budgets` lists the daily spend cap and the balance. Alias: /v1/auth/key. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        }
      }
    },
    "/v1/activity": {
      "get": {
        "operationId": "get_activity",
        "summary": "Daily spend per model, in OpenRouter's GET /activity shape",
        "description": "OpenRouter-compatible: one row per UTC day, model and endpoint for the last 30 completed UTC days (today excluded). Optional `date` (YYYY-MM-DD) and `api_key_hash` (SHA-256 hex of a key on this account). Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Invalid date, or an unsupported filter (user_id, workspace_id, group_by)"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "404": {
            "description": "No key with that api_key_hash on this account"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "api_key_hash",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/generation": {
      "get": {
        "operationId": "get_generation",
        "summary": "One call's cost and tokens, in OpenRouter's GET /generation shape",
        "description": "OpenRouter-compatible. `id` is the response body's `id` or the `x-blockrun-request-id` header. Looks back 2 UTC days (at most 20,000 calls); a call is readable a few seconds after it completes. At most 60 lookups per minute per account. Use /v1/usage for older calls. Free.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Missing id"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "404": {
            "description": "Not found in the lookup window"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 4096
            }
          }
        ]
      }
    },
    "/v1/chat/completions": {
      "post": {
        "operationId": "post_chat_completions",
        "summary": "OpenAI Chat Completions for every model; streaming and tools",
        "description": "OpenAI Chat Completions for every model; streaming and tools. Billed per token from the account balance.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "model": "openai/gpt-4.1-mini",
                "messages": [
                  {
                    "role": "user",
                    "content": "hello"
                  }
                ]
              }
            }
          }
        },
        "x-billing": {
          "unit": "per token",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "post_messages",
        "summary": "Anthropic Messages, native envelopes",
        "description": "Anthropic Messages, native envelopes. Billed per token from the account balance.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-billing": {
          "unit": "per token",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/responses": {
      "post": {
        "operationId": "post_responses",
        "summary": "OpenAI Responses API",
        "description": "OpenAI Responses API. Billed per token from the account balance.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-billing": {
          "unit": "per token",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/images/generations": {
      "post": {
        "operationId": "post_images_generations",
        "summary": "Image generation",
        "description": "Image generation. Billed per image from the account balance.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-billing": {
          "unit": "per image",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/videos/generations": {
      "post": {
        "operationId": "post_videos_generations",
        "summary": "Video generation; returns a poll_url to use verbatim",
        "description": "Video generation; returns a poll_url to use verbatim. Billed per second from the account balance; reference video/audio clips add a per-clip surcharge, and the 202 body's price.amount is the exact quote.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "400": {
            "description": "Invalid request, or an input the model does not support (for example reference video/audio on a model without it)"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          },
          "503": {
            "description": "Reference-to-video temporarily disabled by the operator; Retry-After set. Existing jobs stay pollable."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-billing": {
          "unit": "per second",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/audio/speech": {
      "post": {
        "operationId": "post_audio_speech",
        "summary": "Text to speech",
        "description": "Text to speech. Billed per character from the account balance.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-billing": {
          "unit": "per character",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/search": {
      "post": {
        "operationId": "post_search",
        "summary": "Live web / news / X search",
        "description": "Live web / news / X search. Billed flat per call from the account balance.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "402": {
            "description": "Insufficient account balance \u2014 add credit at https://user.blockrun.ai/dashboard/credits"
          },
          "429": {
            "description": "Rate limited; Retry-After set"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-billing": {
          "unit": "flat per call",
          "source": "account balance",
          "priceSheet": "https://api.blockrun.ai/v1/models"
        }
      }
    },
    "/v1/decisions": {
      "post": {
        "operationId": "post_decisions",
        "summary": "Typed judgments for agents (OpenAI Decisions API compatible)",
        "description": "Answers typed questions about an input instead of generating text: `predicate` (probability it is true), `choice` (one of your values, with per-option probabilities and a confidence), `score` (probability-weighted position on your ordered levels, with per-level probabilities and a confidence); an answer may also be `type: \"refusal\"`. The request and response are the OpenAI Decisions API contract unchanged, so the OpenAI SDK works with base_url `https://api.blockrun.ai/v1`. `model` defaults to `gpt-6-luna`, the only model. Free for any registered key on this host.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "input",
                  "questions"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "default": "gpt-6-luna",
                    "enum": [
                      "gpt-6-luna",
                      "openai/gpt-6-luna"
                    ]
                  },
                  "input": {
                    "description": "A string, or messages `[{role, content}]` whose content carries text and inline base64 images (no image URLs). At most 120,000 characters of text and 8 images per call.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      }
                    ]
                  },
                  "questions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "name",
                        "instructions"
                      ],
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "predicate",
                            "choice",
                            "score"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "description": "Your id for the question; the answer carries it back."
                        },
                        "instructions": {
                          "type": "string"
                        },
                        "choices": {
                          "type": "array",
                          "description": "choice only.",
                          "items": {
                            "type": "object",
                            "required": [
                              "value",
                              "description"
                            ],
                            "properties": {
                              "value": {
                                "type": "string"
                              },
                              "description": {
                                "type": "string"
                              }
                            }
                          },
                          "maxItems": 255
                        },
                        "levels": {
                          "type": "array",
                          "description": "score only; ordered, indexed from 0.",
                          "items": {
                            "type": "object",
                            "required": [
                              "label",
                              "description"
                            ],
                            "properties": {
                              "label": {
                                "type": "string"
                              },
                              "description": {
                                "type": "string"
                              }
                            }
                          },
                          "maxItems": 255
                        }
                      }
                    },
                    "maxItems": 64,
                    "description": "At most 64 questions and 30,000 characters in all (measured over the whole array, every field), with at most 255 choices or levels each."
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Forwarded as is."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "`{model, answers:[{type, name, probability} | {type, name, choice, probabilities, confidence} | {type, name, score, probabilities, confidence} | {type:\"refusal\", ...}], usage}`",
            "headers": {
              "x-blockrun-backend": {
                "schema": {
                  "type": "string"
                },
                "description": "The model that answered."
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Calls left in this account's current hour."
              }
            }
          },
          "400": {
            "description": "Invalid request: over a cap (input text 120,000 chars, 8 images, 64 questions, 30,000 chars of questions, 255 choices or levels), or a model other than gpt-6-luna (refused before anything runs), or relayed verbatim from the model's validation. Not charged."
          },
          "413": {
            "description": "Body over 10 MB"
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Account suspended, or caller address outside the account's IP allowlist"
          },
          "429": {
            "description": "Per-account hourly quota spent (shared by /v1/decisions and /v1/decide); Retry-After set"
          },
          "502": {
            "description": "Upstream error; not charged"
          },
          "503": {
            "description": "Decisions is not configured on this host"
          },
          "504": {
            "description": "Upstream timed out"
          }
        },
        "x-billing": {
          "unit": "free",
          "source": "none",
          "note": "Registered key required; no balance needed. Get a key at https://user.blockrun.ai/dashboard/keys. 1000 calls per account per hour, shared by /v1/decisions and /v1/decide."
        }
      }
    },
    "/v1/decide": {
      "post": {
        "operationId": "post_decide",
        "summary": "Typed judgments in System One's wire format (alias of /v1/decisions)",
        "description": "Kept for callers built against System One's wire format: `state` (string or JSON object) plus `questions` keyed by your ids, of type `noul` (yes/no with a probability), `choice` (`criteria` = {label: description}) or `score` (`criteria` = ordered array). Translated to /v1/decisions and answered in the same shape, by the same model. A refusal is returned as `{type: \"refusal\", ...}` under your id. New integrations should use /v1/decisions. Free for any registered key on this host.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "state",
                  "questions"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "Ignored; the call is answered by `gpt-6-luna`. Accepted so existing bodies still validate."
                  },
                  "state": {
                    "description": "The thing to judge: a string, or a JSON object.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object"
                      }
                    ]
                  },
                  "questions": {
                    "type": "object",
                    "description": "Question id \u2192 question.",
                    "additionalProperties": {
                      "type": "object",
                      "required": [
                        "type",
                        "instructions"
                      ],
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "noul",
                            "choice",
                            "score"
                          ]
                        },
                        "instructions": {
                          "type": "string"
                        },
                        "criteria": {
                          "description": "noul: {\"true\": \u2026, \"false\": \u2026}; choice: {label: description}; score: ordered array of level descriptions.",
                          "oneOf": [
                            {
                              "type": "object"
                            },
                            {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "`{model, answers:{id: {noul} | {choice, probabilities, confidence} | {score, legend, probabilities, confidence} | {type:\"refusal\", ...}}, usage}`",
            "headers": {
              "x-blockrun-backend": {
                "schema": {
                  "type": "string"
                },
                "description": "The model that answered."
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Calls left in this account's current hour."
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Account suspended"
          },
          "413": {
            "description": "Body over 200 KB"
          },
          "429": {
            "description": "Per-account hourly quota spent; Retry-After set"
          },
          "422": {
            "description": "Not a valid System One body (same messages as before); not charged"
          },
          "502": {
            "description": "Upstream error; not charged"
          },
          "503": {
            "description": "Decisions is not configured on this host"
          },
          "504": {
            "description": "Upstream timed out"
          }
        },
        "x-billing": {
          "unit": "free",
          "source": "none",
          "note": "Registered key required; no balance needed. Get a key at https://user.blockrun.ai/dashboard/keys. 1000 calls per account per hour, shared by /v1/decisions and /v1/decide."
        }
      }
    }
  },
  "externalDocs": {
    "url": "https://api.blockrun.ai/llms.txt",
    "description": "Agent-readable reference"
  }
}
