{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "LLM Wallet Router - Circle Gateway API",
    "version": "0.1.0",
    "description": "Fixed-price, model-selectable text inference for AI agents, paid in USDC over real multi-network x402 Circle Gateway. The direct-wallet actual-token API remains available separately.",
    "contact": {
      "email": "support@nuri.com"
    },
    "x-guidance": "Call POST /v1/gateway/chat/completions for a short text answer from a selected model. Supply model, ordered role/content messages and optional max_tokens (1-128). The fixed price is 0.010000 USDC via Circle Gateway on the networks advertised in the actual 402. An unpaid request returns a PAYMENT-REQUIRED header and does not generate an answer. A Gateway-aware wallet signs the challenge and retries with PAYMENT-SIGNATURE. Keep a private random UUIDv4 Idempotency-Key and the identical body across retries; a confirmed paid answer can be recovered without paying again. Stop on ambiguous/pending payment errors and contact support. A successful result contains choices[0].message.content and provider usage; PAYMENT-RESPONSE carries an opaque Circle transfer ID, not necessarily an on-chain hash. This rail requires funded Gateway balance. The separate existing direct-wallet Base and MCP routes use actual-token pricing without a Gateway deposit; see /docs."
  },
  "servers": [
    {
      "url": "https://402.paymentrequired.com",
      "description": "Live HTTPS API origin."
    }
  ],
  "externalDocs": {
    "url": "https://402.paymentrequired.com/docs",
    "description": "Request examples, Gateway funding requirements, direct-wallet alternative, payment and recovery behavior."
  },
  "security": [],
  "paths": {
    "/v1/gateway/chat/completions": {
      "post": {
        "operationId": "gatewayChatCompletion",
        "summary": "Generate one fixed-price text answer using Circle Gateway",
        "description": "Pay exactly 0.010000 USDC for one bounded successful answer. Official createGatewayMiddleware().require(\"$0.01\") handles real verification and settlement; the router prepares and persists the answer before permitting settlement. No router API key is required. Supply a private random UUIDv4 Idempotency-Key to recover the same response safely. Unknown payments are never automatically resettled.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USDC",
            "amount": "0.010000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "description": "A private, randomly generated UUIDv4 for this logical call. Preserve it with the exact body for free paid-answer recovery; never publish or reuse it for another request.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Private per-request UUIDv4 recovery capability."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "A bounded, text-only conversation and selected model. Validate the body before authorizing payment.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "One bounded text-only chat request. The successful response costs exactly 0.010000 USDC through Circle Gateway, regardless of token usage within these limits.",
                "additionalProperties": false,
                "required": [
                  "model",
                  "messages"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "enum": [
                      "subs/gpt-6-astra",
                      "subs/gpt-5.6-luna"
                    ],
                    "description": "Choose one of these available model IDs. The fixed Gateway price is the same for either model."
                  },
                  "messages": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 16,
                    "description": "Conversation in order, including previous assistant replies when continuing a conversation. Total request JSON must not exceed 16384 bytes.",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "role",
                        "content"
                      ],
                      "description": "One text message in the conversation. Images, tools and other modalities are not accepted.",
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "system",
                            "user",
                            "assistant"
                          ],
                          "description": "Who wrote the message: system instructions, the user question, or a previous assistant reply."
                        },
                        "content": {
                          "type": "string",
                          "description": "Plain-text content of the message. Do not include wallet keys, payment signatures or other credentials."
                        }
                      }
                    }
                  },
                  "max_tokens": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 128,
                    "default": 64,
                    "description": "Requested maximum generated tokens for this fixed-price Gateway endpoint. Default 64; allowed 1 through 128."
                  },
                  "stream": {
                    "type": "boolean",
                    "const": false,
                    "default": false,
                    "description": "Must be false or omitted. The API returns one complete buffered JSON answer, not a live token stream."
                  }
                }
              },
              "example": {
                "model": "subs/gpt-6-astra",
                "messages": [
                  {
                    "role": "user",
                    "content": "Reply exactly: CIRCLE_GATEWAY_OK"
                  }
                ],
                "max_tokens": 32
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paid model answer, or the identical cached answer with zero new charge.",
            "headers": {
              "PAYMENT-RESPONSE": {
                "description": "Base64 x402 settlement receipt. Its transaction field may be a Circle transfer ID rather than an on-chain hash.",
                "schema": {
                  "type": "string",
                  "description": "Base64-encoded JSON settlement receipt."
                }
              },
              "X-Charged-USDC": {
                "description": "USDC newly charged by this request: 0.01 on initial success, zero on cached recovery.",
                "schema": {
                  "type": "string",
                  "description": "Decimal USDC amount newly charged."
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "A real provider chat completion, with its answer, optional provider metadata/usage, and the router payment metadata.",
                  "required": [
                    "choices"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Provider-generated completion identifier."
                    },
                    "object": {
                      "type": "string",
                      "description": "Completion object type, normally chat.completion."
                    },
                    "created": {
                      "type": "integer",
                      "description": "Provider completion creation time as Unix seconds."
                    },
                    "model": {
                      "type": "string",
                      "description": "Provider-returned model identifier; it can differ from the router model alias requested."
                    },
                    "choices": {
                      "type": "array",
                      "minItems": 1,
                      "maxItems": 1,
                      "description": "The single generated answer.",
                      "items": {
                        "type": "object",
                        "description": "One assistant response.",
                        "required": [
                          "message"
                        ],
                        "properties": {
                          "index": {
                            "type": "integer",
                            "description": "Choice index, normally zero."
                          },
                          "message": {
                            "type": "object",
                            "description": "Generated assistant message.",
                            "required": [
                              "content"
                            ],
                            "properties": {
                              "role": {
                                "type": "string",
                                "description": "Role of the generated message, normally assistant."
                              },
                              "content": {
                                "type": "string",
                                "minLength": 1,
                                "description": "The model answer, released only after successful payment or authenticated recovery."
                              }
                            },
                            "additionalProperties": true
                          },
                          "finish_reason": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Provider reason generation finished, such as stop or length."
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "usage": {
                      "type": "object",
                      "description": "Provider-reported usage for the answer; this is informative and does not change the fixed Gateway price.",
                      "properties": {
                        "prompt_tokens": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Input tokens reported by the model provider."
                        },
                        "completion_tokens": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Output tokens reported by the model provider, including provider-accounted reasoning when applicable."
                        },
                        "total_tokens": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Total tokens reported by the model provider."
                        }
                      },
                      "additionalProperties": true
                    },
                    "x402": {
                      "type": "object",
                      "description": "Router invoice/receipt metadata for this fixed-price response. Recovered replies indicate zero new charge.",
                      "additionalProperties": true,
                      "properties": {
                        "protocol": {
                          "type": "string",
                          "description": "Payment protocol, x402-v2."
                        },
                        "scheme": {
                          "type": "string",
                          "description": "Payment scheme, exact."
                        },
                        "price": {
                          "type": "string",
                          "description": "Fixed per-answer price, 0.010000 USDC."
                        },
                        "amount_atomic": {
                          "type": "string",
                          "description": "Fixed invoice amount in six-decimal USDC units, 10000."
                        },
                        "network": {
                          "type": "string",
                          "description": "CAIP-2 network selected from the real Gateway challenge."
                        },
                        "asset": {
                          "type": "string",
                          "description": "USDC token contract for the selected network."
                        },
                        "charged_usdc": {
                          "type": "string",
                          "description": "New charge for this response: 0.01 initially, 0 for recovery."
                        },
                        "transaction": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Circle settlement transfer identifier; not necessarily an on-chain transaction hash."
                        },
                        "replayed": {
                          "type": "boolean",
                          "description": "Whether this response was recovered from an already paid result."
                        }
                      }
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "402": {
            "description": "Payment is required or invalid. An initial unpaid request includes a real multi-network x402 challenge. No model work or payment occurs for that initial discovery request.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64 JSON x402 v2 challenge with resource and accepts[] entries. Each entry declares its supported network, USDC asset, 10000-atomic-unit amount, seller and Gateway authorization domain.",
                "schema": {
                  "type": "string",
                  "description": "Base64-encoded x402 PaymentRequired JSON."
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Initial unpaid response is empty JSON; decode PAYMENT-REQUIRED for accepts[]. Verification failures may contain a structured error.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Invalid model, message, limit, recovery key or payment envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Structured request/payment/provider failure. An ambiguous payment must be reconciled before another payment is authorized.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Human-readable error or error code explaining the failure."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Additional payment failure reason when supplied."
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Server request identifier for support and reconciliation when available."
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "409": {
            "description": "The logical request or nonce is already in use; do not authorize another payment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Structured request/payment/provider failure. An ambiguous payment must be reconciled before another payment is authorized.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Human-readable error or error code explaining the failure."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Additional payment failure reason when supplied."
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Server request identifier for support and reconciliation when available."
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "502": {
            "description": "Provider failed or returned an invalid answer; no payment is submitted for failed preparation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Structured request/payment/provider failure. An ambiguous payment must be reconciled before another payment is authorized.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Human-readable error or error code explaining the failure."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Additional payment failure reason when supplied."
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Server request identifier for support and reconciliation when available."
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "503": {
            "description": "Payment/settlement state is unavailable or ambiguous; stop and request reconciliation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Structured request/payment/provider failure. An ambiguous payment must be reconciled before another payment is authorized.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Human-readable error or error code explaining the failure."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Additional payment failure reason when supplied."
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Server request identifier for support and reconciliation when available."
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    }
  }
}
