{
  "openapi": "3.0.3",
  "info": {
    "title": "OneAIKey — Requests API",
    "version": "1.0.3",
    "description": "MVP Requests API (unified chat + completion). Synchronous provider calls only.\n- Auth: Bearer token (Authorization: Bearer <your_unique_one_ai_key>)\n- No idempotency support in MVP.\n- Default max_output_tokens = 25000 (soft hint).\n",
    "contact": {
      "name": "OneAIKey API",
      "email": "api@oneaikey.com"
    }
  },
  "servers": [
    {
      "url": "https://www.oneaikey.com/api",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "requests",
      "description": "Request lifecycle (create, fetch, list)"
    }
  ],
  "paths": {
    "/v1/requests": {
      "post": {
        "tags": [
          "requests"
        ],
        "summary": "Create a request (chat or completion)",
        "description": "Unified endpoint to create an AI request. Synchronous provider call (blocking).\nProvider calls must respect provider timeout (configurable, e.g. 30000 ms).\nNo streaming and no idempotency in MVP.\n",
        "operationId": "createRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRequest"
              },
              "examples": {
                "chat_example": {
                  "summary": "Chat (messages)",
                  "value": {
                    "model": "gpt",
                    "messages": [
                      {
                        "role": "system",
                        "content": "You are a helpful assistant."
                      },
                      {
                        "role": "user",
                        "content": "Explain polymorphism in 3 lines."
                      }
                    ],
                    "max_output_tokens": 200,
                    "temperature": 0.2,
                    "metadata": {
                      "session_id": "abc123"
                    }
                  }
                },
                "completion_example": {
                  "summary": "Completion (prompt)",
                  "value": {
                    "model": "gpt-5-mini",
                    "prompt": "Write a short haiku about coffee.",
                    "max_output_tokens": 60
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request completed successfully (synchronous)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request / validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — invalid or missing token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Payment required — insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden — key disabled or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity — model resolution failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests / rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Provider error / bad gateway",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Provider timed out (gateway timeout)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "label": "typescript",
            "lang": "typescript",
            "source": "import { OneaikeyRequestsApiMvpTypescript } from \"@default-team-g8wkr/oneaikey-requests-api-mvp-typescript\";\n\nconst oneaikeyRequestsApiMvpTypescript = new OneaikeyRequestsApiMvpTypescript({\n  bearerAuth: \"<YOUR_BEARER_TOKEN_HERE>\",\n});\n\nasync function run() {\n  const result = await oneaikeyRequestsApiMvpTypescript.requests.createRequest({\n    model: \"gpt\",\n    messages: [\n      {\n        role: \"user\",\n        content: \"Hello\",\n      },\n    ],\n    maxOutputTokens: 200,\n    metadata: {},\n  });\n\n  console.log(result);\n}\n\nrun();"
          }
        ]
      },
      "get": {
        "tags": [
          "requests"
        ],
        "summary": "List requests (paginated)",
        "description": "Returns a paginated list of requests for the authenticated user (or admin).",
        "operationId": "listRequests",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Maximum items to return"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Cursor for pagination"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter start datetime (inclusive)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filter end datetime (inclusive)"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by request status"
          },
          {
            "name": "model_family",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by model_family (e.g., gpt, claude)"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestList"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "label": "typescript",
            "lang": "typescript",
            "source": "import { OneaikeyRequestsApiMvpTypescript } from \"@default-team-g8wkr/oneaikey-requests-api-mvp-typescript\";\n\nconst oneaikeyRequestsApiMvpTypescript = new OneaikeyRequestsApiMvpTypescript({\n  bearerAuth: \"<YOUR_BEARER_TOKEN_HERE>\",\n});\n\nasync function run() {\n  const result = await oneaikeyRequestsApiMvpTypescript.requests.listRequests({});\n\n  console.log(result);\n}\n\nrun();"
          }
        ]
      }
    },
    "/v1/requests/{id}": {
      "get": {
        "tags": [
          "requests"
        ],
        "summary": "Get request by id",
        "description": "Retrieve full request record. Auth - owner or admin.",
        "operationId": "getRequestById",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/requestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Request record",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "label": "typescript",
            "lang": "typescript",
            "source": "import { OneaikeyRequestsApiMvpTypescript } from \"@default-team-g8wkr/oneaikey-requests-api-mvp-typescript\";\n\nconst oneaikeyRequestsApiMvpTypescript = new OneaikeyRequestsApiMvpTypescript({\n  bearerAuth: \"<YOUR_BEARER_TOKEN_HERE>\",\n});\n\nasync function run() {\n  const result = await oneaikeyRequestsApiMvpTypescript.requests.getRequestById({\n    id: \"8517bcd9-aa17-4af2-9d10-288ff2316068\",\n  });\n\n  console.log(result);\n}\n\nrun();"
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key"
      }
    },
    "parameters": {
      "requestId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Request UUID"
      }
    },
    "schemas": {
      "Message": {
        "type": "object",
        "required": [
          "role",
          "content"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "user",
              "assistant"
            ]
          },
          "content": {
            "type": "string"
          }
        }
      },
      "CreateRequest": {
        "type": "object",
        "description": "Request body for creating a chat or completion request.",
        "properties": {
          "model": {
            "type": "string",
            "description": "Flexible model selector (exact provider name, family/qualifier, or family). Optional."
          },
          "mode": {
            "type": "string",
            "enum": [
              "chat",
              "completion"
            ],
            "description": "Optional; inferred from presence of messages or prompt."
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "description": "Chat format (preferred if present)."
          },
          "prompt": {
            "type": "string",
            "description": "Completion-style prompt. Required if messages absent."
          },
          "max_output_tokens": {
            "type": "integer",
            "description": "Soft hint for maximum output tokens. Default = 25000.",
            "default": 25000
          },
          "max_tokens": {
            "type": "integer",
            "description": "Alias for max_output_tokens."
          },
          "temperature": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "maximum": 2
          },
          "top_p": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "maximum": 1
          },
          "fallback_model": {
            "type": "string",
            "description": "Optional fallback model selector to try on provider failure."
          },
          "metadata": {
            "type": "object",
            "description": "Optional client-provided JSON object. Echoed back in response."
          }
        },
        "anyOf": [
          {
            "required": [
              "messages"
            ]
          },
          {
            "required": [
              "prompt"
            ]
          }
        ],
        "example": {
          "model": "gpt",
          "messages": [
            {
              "role": "user",
              "content": "Hello"
            }
          ],
          "max_output_tokens": 200,
          "metadata": {
            "session_id": "abc123"
          }
        }
      },
      "RequestResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "key_id": {
            "type": "string",
            "format": "uuid"
          },
          "model_requested": {
            "type": "string",
            "description": "The model selector the client sent (e.g., \"gpt\", \"gpt/flagship\", \"gpt-5-mini\")"
          },
          "model_resolved": {
            "type": "string",
            "description": "Resolved provider model id (e.g., \"gpt-5-32k\")"
          },
          "input_tokens": {
            "type": "integer"
          },
          "output_tokens": {
            "type": "integer"
          },
          "total_cost": {
            "type": "string",
            "description": "USD total cost as decimal string (matching decimal(12,6))"
          },
          "credits_used": {
            "type": "integer"
          },
          "credits_reserved": {
            "type": "integer",
            "description": "Credits reserved prior to provider call (optional; present if your implementation stores it)"
          },
          "status": {
            "type": "string",
            "description": "success | processing | failed | failed_insufficient_credits_postusage | etc."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "latency_ms": {
            "type": "integer",
            "description": "Provider roundtrip latency in ms"
          },
          "max_tokens": {
            "type": "integer",
            "description": "The requested max_output_tokens (store 25000 if omitted)"
          },
          "metadata": {
            "type": "object",
            "description": "Echo of client-supplied metadata"
          },
          "response": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "chat",
                  "completion"
                ]
              },
              "content": {
                "type": "string"
              },
              "raw_provider_payload": {
                "type": "object",
                "description": "Optional raw provider response (store with caution)"
              }
            }
          }
        },
        "required": [
          "id",
          "user_id",
          "key_id",
          "model_requested",
          "model_resolved",
          "status",
          "created_at"
        ],
        "example": {
          "id": "9a1f4f3e-1111-2222-3333-abcdef012345",
          "user_id": "f2d3c4b5-aaaa-bbbb-cccc-0123456789ab",
          "key_id": "e3f4a5b6-1111-2222-3333-0123456789ab",
          "model_requested": "gpt",
          "model_resolved": "gpt-5-32k",
          "input_tokens": 200,
          "output_tokens": 800,
          "total_cost": "0.008250",
          "credits_used": 1,
          "credits_reserved": 1,
          "status": "success",
          "created_at": "2025-09-25T12:00:00Z",
          "completed_at": "2025-09-25T12:00:02Z",
          "latency_ms": 1200,
          "metadata": {
            "session_id": "abc123"
          },
          "response": {
            "type": "chat",
            "content": "Here is the generated text...",
            "raw_provider_payload": {
              "provider_request_id": "prov_abc_123"
            }
          }
        }
      },
      "RequestList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RequestResponse"
            }
          },
          "next_cursor": {
            "type": "string",
            "description": "Cursor for next page (nullable)"
          }
        },
        "example": {
          "items": [
            {
              "id": "9a1f4f3e-1111-2222-3333-abcdef012345",
              "user_id": "f2d3c4b5-aaaa-bbbb-cccc-0123456789ab",
              "key_id": "e3f4a5b6-1111-2222-3333-0123456789ab",
              "model_requested": "gpt",
              "model_resolved": "gpt-5-32k",
              "input_tokens": 200,
              "output_tokens": 800,
              "total_cost": "0.008250",
              "credits_used": 1,
              "credits_reserved": 1,
              "status": "success",
              "created_at": "2025-09-25T12:00:00Z",
              "completed_at": "2025-09-25T12:00:02Z",
              "latency_ms": 1200,
              "metadata": {
                "session_id": "abc123"
              },
              "response": {
                "type": "chat",
                "content": "Here is the generated text...",
                "raw_provider_payload": {
                  "provider_request_id": "prov_abc_123"
                }
              }
            }
          ],
          "next_cursor": ""
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "description": "short error code (e.g., invalid_request, insufficient_credits, model_unavailable)"
              },
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "description": "optional internal code"
              },
              "details": {
                "type": "object",
                "description": "optional debugging details"
              }
            }
          }
        },
        "example": {
          "error": {
            "type": "insufficient_credits",
            "message": "You have 2 credits; 5 required.",
            "code": "ERR_INSUFFICIENT_CREDITS"
          }
        }
      }
    }
  }
}