{
  "openapi": "3.1.0",
  "info": {
    "title": "CURB",
    "version": "0.1.0",
    "description": "CURB — agent-to-agent inference swap rail. Settlement is single-payee x402 USDC on Base (eip155:8453): buyer pays gross ONCE to an on-chain 0xSplits split, CURB fans out seller + protocol fee on-chain. Hub does not hold upstream LLM keys.",
    "x-guidance": "1) GET /v1/offers (free) to browse capacity. 2) POST /v1/offers to sell (include sellerPayTo Base 0x…). 3) POST /v1/intents to buy — hub auto-matches. 4) POST /v1/matches/{id}/pay bare → 402 with a SINGLE Base accept (gross = full price to the split address on eip155:8453). Unknown/placeholder ids still 402 with a catalog sample (paywall before not_found). Sign ONE payment for the gross amount to that accept's payTo; retry with payment-signature / X-Payment. CURB splits seller + protocol fee ON-CHAIN via 0xSplits distribute() on Base. 5) Discovery probe: bare POST /v1/pay → sample 402 (no side effects). Refunds/billing: contact@numetal.xyz.",
    "contact": {
      "email": "contact@numetal.xyz",
      "name": "Numetal Labs",
      "url": "https://curb.numetal.xyz"
    }
  },
  "servers": [
    {
      "url": "https://api.curb.numetal.xyz"
    }
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "OpenAPI 3.1 document (free)",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 JSON",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/x402": {
      "get": {
        "operationId": "wellKnownX402",
        "summary": "x402 discovery manifest (free)",
        "security": [],
        "responses": {
          "200": {
            "description": "x402 resources + accepts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Health",
        "security": [],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "product": {
                      "type": "string"
                    },
                    "brand": {
                      "type": "string"
                    },
                    "openOffers": {
                      "type": "number"
                    },
                    "rails": {
                      "type": "object"
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/offers": {
      "get": {
        "operationId": "listOffers",
        "summary": "List open sell offers",
        "security": [],
        "responses": {
          "200": {
            "description": "offers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "offers": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "offers"
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createOffer",
        "summary": "Create sell offer",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sellerPayTo",
                  "endpoint",
                  "model",
                  "mtok",
                  "priceUsd"
                ],
                "properties": {
                  "sellerPayTo": {
                    "type": "string",
                    "description": "Seller Base (EVM) USDC payTo — 0x…"
                  },
                  "endpoint": {
                    "type": "string",
                    "format": "uri"
                  },
                  "model": {
                    "type": "string"
                  },
                  "mtok": {
                    "type": "number"
                  },
                  "priceUsd": {
                    "type": "number"
                  },
                  "attestation": {
                    "type": "string"
                  },
                  "note": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "created"
          }
        }
      }
    },
    "/v1/intents": {
      "post": {
        "operationId": "createIntent",
        "summary": "Create buy intent (auto-match when possible)",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mtok"
                ],
                "properties": {
                  "model": {
                    "type": "string"
                  },
                  "mtok": {
                    "type": "number"
                  },
                  "maxPriceUsd": {
                    "type": "number"
                  },
                  "offerId": {
                    "type": "string"
                  },
                  "buyer": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "intent + optional match"
          }
        }
      }
    },
    "/v1/matches/{id}": {
      "get": {
        "operationId": "getMatch",
        "summary": "Get match",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "match"
          }
        }
      }
    },
    "/v1/pay": {
      "post": {
        "operationId": "discoveryPayProbe",
        "summary": "Discovery probe — bare POST returns sample single-payee x402 402 (no side effects)",
        "description": "Stable URL for x402scan / AgentCash discovery. Returns HTTP 402 with a SINGLE Base accept (gross = full price to the split address, sample $0.10). Does not create a match. Real settlement uses POST /v1/matches/{id}/pay. Paywall runs before body validation.",
        "tags": [
          "Payments"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.100000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "security": [
          {
            "x402": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "note": {
                    "type": "string",
                    "description": "Optional; ignored on unpaid probe."
                  }
                },
                "example": {
                  "note": "optional; ignored on unpaid probe"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paid probe ack (demo / header present) — no grant; use match pay for real swaps.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "probe": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok",
                    "probe",
                    "message"
                  ],
                  "example": {
                    "ok": true,
                    "probe": true,
                    "message": "Probe ack only — settle real swaps via POST /v1/matches/{id}/pay"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment Required — single-payee x402 (ONE gross accept → the on-chain 0xSplits split) on Base USDC. WWW-Authenticate carries an IETF Payment challenge; PAYMENT-REQUIRED carries the x402 v2 body (incl. extensions.bazaar).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "const": 2
                    },
                    "error": {
                      "type": "string"
                    },
                    "resource": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "description": {
                          "type": "string"
                        },
                        "mimeType": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "url"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "description": "CAIP-2 network (eip155:8453 Base mainnet)."
                          },
                          "amount": {
                            "type": "string",
                            "description": "USDC atomic units (6 decimals)."
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC contract (EVM 0x…)."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The 0xSplits split address (gross lands here)."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer"
                          },
                          "extra": {
                            "type": "object",
                            "description": "EVM: EIP-712 domain {name, version} + role=gross + display breakdown."
                          }
                        },
                        "required": [
                          "scheme",
                          "network",
                          "amount",
                          "asset",
                          "payTo",
                          "maxTimeoutSeconds"
                        ]
                      },
                      "example": [
                        {
                          "scheme": "exact",
                          "network": "eip155:8453",
                          "amount": "100000",
                          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                          "payTo": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                          "maxTimeoutSeconds": 300,
                          "extra": {
                            "name": "USD Coin",
                            "version": "2",
                            "role": "gross",
                            "amountUsd": "0.10",
                            "feeBps": 500,
                            "breakdown": {
                              "sellerUsd": "0.095",
                              "feeUsd": "0.005"
                            },
                            "splitAddress": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                            "splitType": "0xsplits-push-v2"
                          }
                        }
                      ]
                    },
                    "extensions": {
                      "type": "object",
                      "description": "x402 v2 extensions — bazaar input/output schemas for discovery."
                    }
                  },
                  "required": [
                    "x402Version",
                    "resource",
                    "accepts"
                  ]
                },
                "example": {
                  "x402Version": 2,
                  "error": "payment_required",
                  "resource": {
                    "url": "https://api.curb.numetal.xyz/v1/pay",
                    "description": "CURB discovery probe — USDC x402 on Base (sample price)",
                    "mimeType": "application/json"
                  },
                  "accepts": [
                    {
                      "scheme": "exact",
                      "network": "eip155:8453",
                      "amount": "100000",
                      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                      "payTo": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                      "maxTimeoutSeconds": 300,
                      "extra": {
                        "name": "USD Coin",
                        "version": "2",
                        "role": "gross",
                        "amountUsd": "0.10",
                        "feeBps": 500,
                        "breakdown": {
                          "sellerUsd": "0.095",
                          "feeUsd": "0.005"
                        },
                        "splitAddress": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                        "splitType": "0xsplits-push-v2"
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64(JSON) x402 v2 PaymentRequired — same object as the JSON body (incl. extensions.bazaar).",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "description": "IETF Payment challenge (draft-httpauth-payment). Example: Payment id=\"…\", realm=\"api.curb.numetal.xyz\", method=\"x402\", intent=\"charge\", expires=\"…\", opaque=\"…\", request=\"…\"",
                "schema": {
                  "type": "string",
                  "example": "Payment id=\"…\", realm=\"api.curb.numetal.xyz\", method=\"x402\", intent=\"charge\", expires=\"2026-07-09T13:00:00Z\", opaque=\"…\", request=\"…\""
                }
              }
            }
          }
        }
      }
    },
    "/v1/matches/{id}/pay": {
      "post": {
        "operationId": "payMatch",
        "summary": "Pay match — 402 single-payee accept without payment header; settle with header",
        "description": "Match-specific price (dynamic). Paywall runs before not_found: bare POST always returns 402 (live match challenge, or catalog sample when id is unknown/placeholder — same single-payee shape as POST /v1/pay). Retry with payment-signature / X-Payment (ONE gross payment to the split address). 404 only when a payment header is present and the match id does not exist.",
        "tags": [
          "Payments"
        ],
        "x-payment-info": {
          "price": {
            "mode": "dynamic",
            "currency": "USD",
            "min": "0.001",
            "max": "100.000000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "security": [
          {
            "x402": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Match id from POST /v1/intents. Discovery scanners may probe with `probe` or `{id}`; unpaid unknown ids still return HTTP 402 with a catalog sample challenge.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "example": "probe"
            },
            "example": "probe"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "example": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paid — grant issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "matchId": {
                      "type": "string"
                    },
                    "grant": {
                      "type": "object"
                    }
                  },
                  "example": {
                    "ok": true,
                    "matchId": "match_…",
                    "grant": {
                      "token": "grant_…",
                      "endpoint": "https://seller.example/v1/chat/completions"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required (ONE gross accept → the on-chain 0xSplits split on Base). WWW-Authenticate: Payment …; PAYMENT-REQUIRED: base64 x402 v2. Unknown match ids still 402 (catalog sample) when unpaid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "x402Version": {
                      "type": "integer",
                      "const": 2
                    },
                    "error": {
                      "type": "string"
                    },
                    "resource": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "description": {
                          "type": "string"
                        },
                        "mimeType": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "url"
                      ]
                    },
                    "accepts": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "properties": {
                          "scheme": {
                            "type": "string",
                            "enum": [
                              "exact"
                            ]
                          },
                          "network": {
                            "type": "string",
                            "description": "CAIP-2 network (eip155:8453 Base mainnet)."
                          },
                          "amount": {
                            "type": "string",
                            "description": "USDC atomic units (6 decimals)."
                          },
                          "asset": {
                            "type": "string",
                            "description": "USDC contract (EVM 0x…)."
                          },
                          "payTo": {
                            "type": "string",
                            "description": "The 0xSplits split address (gross lands here)."
                          },
                          "maxTimeoutSeconds": {
                            "type": "integer"
                          },
                          "extra": {
                            "type": "object",
                            "description": "EVM: EIP-712 domain {name, version} + role=gross + display breakdown."
                          }
                        },
                        "required": [
                          "scheme",
                          "network",
                          "amount",
                          "asset",
                          "payTo",
                          "maxTimeoutSeconds"
                        ]
                      },
                      "example": [
                        {
                          "scheme": "exact",
                          "network": "eip155:8453",
                          "amount": "100000",
                          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                          "payTo": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                          "maxTimeoutSeconds": 300,
                          "extra": {
                            "name": "USD Coin",
                            "version": "2",
                            "role": "gross",
                            "amountUsd": "0.10",
                            "feeBps": 500,
                            "breakdown": {
                              "sellerUsd": "0.095",
                              "feeUsd": "0.005"
                            },
                            "splitAddress": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                            "splitType": "0xsplits-push-v2"
                          }
                        }
                      ]
                    },
                    "extensions": {
                      "type": "object",
                      "description": "x402 v2 extensions — bazaar input/output schemas for discovery."
                    }
                  },
                  "required": [
                    "x402Version",
                    "resource",
                    "accepts"
                  ]
                },
                "example": {
                  "x402Version": 2,
                  "error": "payment_required",
                  "resource": {
                    "url": "https://api.curb.numetal.xyz/v1/matches/probe/pay",
                    "description": "CURB discovery probe — USDC x402 on Base (sample price)",
                    "mimeType": "application/json"
                  },
                  "accepts": [
                    {
                      "scheme": "exact",
                      "network": "eip155:8453",
                      "amount": "100000",
                      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                      "payTo": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                      "maxTimeoutSeconds": 300,
                      "extra": {
                        "name": "USD Coin",
                        "version": "2",
                        "role": "gross",
                        "amountUsd": "0.10",
                        "feeBps": 500,
                        "breakdown": {
                          "sellerUsd": "0.095",
                          "feeUsd": "0.005"
                        },
                        "splitAddress": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
                        "splitType": "0xsplits-push-v2"
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64(JSON) x402 v2 PaymentRequired — same object as the JSON body (incl. extensions.bazaar).",
                "schema": {
                  "type": "string"
                }
              },
              "WWW-Authenticate": {
                "description": "IETF Payment challenge (draft-httpauth-payment). Example: Payment id=\"…\", realm=\"api.curb.numetal.xyz\", method=\"x402\", intent=\"charge\", expires=\"…\", opaque=\"…\", request=\"…\"",
                "schema": {
                  "type": "string",
                  "example": "Payment id=\"…\", realm=\"api.curb.numetal.xyz\", method=\"x402\", intent=\"charge\", expires=\"2026-07-09T13:00:00Z\", opaque=\"…\", request=\"…\""
                }
              }
            }
          },
          "404": {
            "description": "Match not found — only when payment-signature / X-Payment is present and the id does not exist. Unpaid probes never 404."
          }
        }
      }
    },
    "/mcp": {
      "get": {
        "operationId": "mcpInfo",
        "summary": "MCP transport info (free)",
        "security": [],
        "responses": {
          "200": {
            "description": "MCP JSON-RPC transport metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "mcp",
        "summary": "MCP JSON-RPC (tools/list, tools/call)",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string"
                  },
                  "method": {
                    "type": "string"
                  },
                  "params": {
                    "type": "object"
                  },
                  "id": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "mcp"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "x402": {
        "type": "apiKey",
        "in": "header",
        "name": "payment-signature",
        "description": "x402 pay-per-call (USDC on Base eip155:8453). Bare request → 402 with PAYMENT-REQUIRED; sign and retry. Single-payee: sign ONE gross payment to the accept's payTo (the on-chain 0xSplits split); CURB fans out seller + protocol fee on-chain."
      }
    }
  },
  "x-numetal": {
    "product": "numetal-curb",
    "brand": "CURB",
    "feeBps": 500,
    "settlementModel": "single-payee-to-splitter",
    "split": {
      "base": "0x546217c24617bCF9faD565E8ECABe5dE2D41326b",
      "provider": "0xsplits-push-v2",
      "note": "Buyer pays gross once to split; keeper distribute() fans out seller + hub on-chain."
    },
    "hubPayTo": "0x3eee81B5b4cf1983b7DB36cf042B5d06c04F33eE",
    "networks": [
      "eip155:8453"
    ],
    "assets": {
      "base": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    },
    "noUpstreamKeys": true,
    "settlement": {
      "mode": "verify",
      "note": "demo: a present payment header settles but the grant is marked verified:false (NOT verified on-chain). verify (SETTLE_MODE=verify + CDP secrets): only a facilitator-verified+settled payment mints a grant; fake/bare headers get 402."
    }
  }
}