{
  "openapi": "3.1.0",
  "info": {
    "title": "OpenCredits API",
    "version": "1.0.0",
    "summary": "Drop-in AI payments: prepaid credits, one OpenAI/Anthropic-compatible endpoint, 390+ AI models.",
    "description": "OpenCredits is payments and monetization infrastructure for AI apps. Users buy prepaid credits through an embedded Stripe checkout; apps route AI requests through one endpoint compatible with both the OpenAI and Anthropic API formats; each request is metered from the real token cost of the model used and deducted from the user's balance in credits. Partners set a commission on each request's provider cost and earn it on every request, with no monthly fees.\n\nAuthentication uses a user key (`oc_sk_...`), passed as `Authorization: Bearer`, `X-User-Key`, or the `api_key` parameter of the OpenAI/Anthropic SDKs. Integration guide for AI agents: https://opencredits.ai/skill.md",
    "contact": { "url": "https://opencredits.ai" }
  },
  "servers": [{ "url": "https://api.opencredits.ai" }],
  "paths": {
    "/v1/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "summary": "OpenAI-compatible chat completions (supports streaming)",
        "description": "Accepts the standard OpenAI Chat Completions request body. Use provider-prefixed model IDs, e.g. `anthropic/claude-sonnet-4-20250514` or `openai/gpt-4o`. Works as-is with the OpenAI SDK by setting `base_url` to `https://api.opencredits.ai/v1`.",
        "security": [{ "userKey": [] }, { "userKeyHeader": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["model", "messages"],
                "properties": {
                  "model": { "type": "string", "example": "anthropic/claude-sonnet-4-20250514" },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["role", "content"],
                      "properties": {
                        "role": { "type": "string", "enum": ["system", "user", "assistant"] },
                        "content": { "type": "string" }
                      }
                    }
                  },
                  "stream": { "type": "boolean", "default": false },
                  "max_tokens": { "type": "integer" },
                  "temperature": { "type": "number" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "OpenAI-format chat completion (or SSE stream when `stream: true`)." },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Anthropic-compatible messages (supports streaming)",
        "description": "Accepts the standard Anthropic Messages request body. Works as-is with the Anthropic SDK by setting `base_url` to `https://api.opencredits.ai` (the SDK appends /v1).",
        "security": [{ "userKey": [] }, { "userKeyHeader": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["model", "max_tokens", "messages"],
                "properties": {
                  "model": { "type": "string", "example": "anthropic/claude-sonnet-4-20250514" },
                  "max_tokens": { "type": "integer", "example": 1024 },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["role", "content"],
                      "properties": {
                        "role": { "type": "string", "enum": ["user", "assistant"] },
                        "content": {}
                      }
                    }
                  },
                  "stream": { "type": "boolean", "default": false },
                  "system": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Anthropic-format message (or SSE stream when `stream: true`)." },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List all available models (no auth required)",
        "description": "Returns the 390+ AI models available behind the OpenCredits endpoint, using provider-prefixed IDs (e.g. `anthropic/...`, `openai/...`, `google/...`).",
        "security": [],
        "responses": {
          "200": { "description": "List of available models." }
        }
      }
    },
    "/v1/credits/pricing": {
      "get": {
        "operationId": "getCreditPricing",
        "summary": "Credit cost estimates per model (no user auth required)",
        "parameters": [
          { "name": "publishable_key", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Partner publishable key (oc_pk_...)." },
          { "name": "models", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated model IDs to estimate." },
          { "name": "input_tokens", "in": "query", "required": false, "schema": { "type": "integer" } },
          { "name": "output_tokens", "in": "query", "required": false, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Per-model credit estimates for the given token counts." }
        }
      },
      "post": {
        "operationId": "postCreditPricing",
        "summary": "Credit cost estimates per model (POST body variant)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["publishable_key"],
                "properties": {
                  "publishable_key": { "type": "string" },
                  "models": { "type": "array", "items": { "type": "string" } },
                  "input_tokens": { "type": "integer" },
                  "output_tokens": { "type": "integer" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Per-model credit estimates for the given token counts." }
        }
      }
    },
    "/v1/credits/balance": {
      "get": {
        "operationId": "getCreditBalance",
        "summary": "Check the user's credit balance",
        "security": [{ "userKey": [] }, { "userKeyHeader": [] }],
        "responses": {
          "200": {
            "description": "Current balance in credits (100 credits = $1 USD).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "balance": { "type": "number", "description": "Current balance in credits." },
                    "currency": { "type": "string", "const": "credits" },
                    "minimum_required": { "type": "number", "description": "Minimum balance required to make requests." }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "userKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "User key (oc_sk_...) as Authorization: Bearer. Also accepted as the api_key parameter of the OpenAI or Anthropic SDKs."
      },
      "userKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-User-Key",
        "description": "User key (oc_sk_...) as a header — useful from browsers."
      }
    },
    "responses": {
      "Unauthorized": { "description": "Missing or invalid user key (401)." },
      "InsufficientCredits": { "description": "Insufficient credits (402) — prompt the user to top up, e.g. by opening the OpenCredits checkout." },
      "RateLimited": { "description": "Rate limited (429)." }
    }
  }
}
