{
  "openapi": "3.1.0",
  "info": {
    "title": "Have It Sold AI Action API",
    "version": "1.0.0",
    "description": "Buyer-first deal API for AI assistants (ChatGPT, Claude, Gemini, custom agents). Read/analyze/prepare actions run freely within the authenticated user's account. Consequential actions return needsConfirmation + preview until called again with confirm: true. All data access is token-scoped to one account — the API can never read or change another account.",
    "x-core-principle": "Have it sold before you buy it. Consistency beats perfection."
  },
  "servers": [
    {
      "url": "https://haveitsold.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token created by the account owner at /api-docs. Format: his_<64 hex>."
      }
    }
  },
  "security": [
    {
      "bearerToken": []
    }
  ],
  "paths": {
    "/api/public/his/call": {
      "post": {
        "operationId": "callAction",
        "summary": "Execute one named action",
        "description": "Single endpoint. Body: { action, params?, confirm? }.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "getDeal",
                      "getDeals",
                      "getNeonGreenDeals",
                      "getGreenDeals",
                      "getBuyers",
                      "getBuyerProfile",
                      "getBuyerMatches",
                      "analyzeDeal",
                      "calculateSafeBid",
                      "getNextActions",
                      "prepareBuyerSubmission",
                      "createDeal",
                      "updateDeal",
                      "deleteDeal",
                      "createBuyer",
                      "updateBuyer",
                      "deleteBuyer",
                      "recordBuyerOffer",
                      "recordDealOutcome"
                    ]
                  },
                  "params": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "confirm": {
                    "type": "boolean",
                    "description": "Must be true for consequential actions. When omitted, the API returns needsConfirmation with a preview instead of executing."
                  }
                }
              },
              "examples": {
                "neonGreen": {
                  "summary": "Get my current NEON GREEN deals",
                  "value": {
                    "action": "getNeonGreenDeals",
                    "params": {}
                  }
                },
                "safeBid": {
                  "summary": "Calculate the maximum safe bid for this deal",
                  "value": {
                    "action": "calculateSafeBid",
                    "params": {
                      "dealId": "<dealId>"
                    }
                  }
                },
                "prepare": {
                  "summary": "Prepare this inventory for Buyer X using Buyer X's preferred format",
                  "value": {
                    "action": "prepareBuyerSubmission",
                    "params": {
                      "dealId": "<dealId>",
                      "buyerId": "<buyerId>"
                    }
                  }
                },
                "conversational": {
                  "summary": "'Can I bid $2,400 on this lot?'",
                  "value": {
                    "action": "calculateSafeBid",
                    "params": {
                      "dealId": "<dealId>",
                      "bidPrice": 2400
                    }
                  }
                },
                "confirm": {
                  "summary": "Consequential action with confirmation",
                  "value": {
                    "action": "recordBuyerOffer",
                    "params": {
                      "dealId": "<dealId>",
                      "buyerId": "<buyerId>",
                      "offer": 12500
                    },
                    "confirm": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action result, or needsConfirmation preview for consequential actions without confirm.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "examples": {
                  "analysis": {
                    "value": {
                      "analysis": {
                        "dealId": "<dealId>",
                        "title": "40x industrial MRO lot",
                        "classification": "neon",
                        "classificationLabel": "NEON GREEN — Verified Buyer / Executable Floor",
                        "maxSafeBuy": 9800,
                        "maxSafeHammerBid": 9200,
                        "verifiedBuyerPrice": 15800,
                        "projectedNetProfit": 4100,
                        "riskBufferCushion": 1750,
                        "openGaps": [],
                        "nextAction": "NEON GREEN — SUBMIT TO RODWELL NOW."
                      }
                    }
                  },
                  "needsConfirmation": {
                    "value": {
                      "needsConfirmation": true,
                      "message": "This action changes your account data. Review the preview, then call the same action again with confirm: true to execute.",
                      "preview": {
                        "action": "recordBuyerOffer",
                        "offer": 12500
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token."
          },
          "429": {
            "description": "Rate limited (120 calls/minute). Includes retry-after."
          }
        }
      }
    }
  },
  "x-action-index": [
    {
      "name": "getDeal",
      "description": "Fetch one deal with classification, max safe buy, max safe hammer bid, conservative exit, projected profit and next action.",
      "readOnly": true
    },
    {
      "name": "getDeals",
      "description": "List the account's deals (optionally by status) with the same decision summary.",
      "readOnly": true
    },
    {
      "name": "getNeonGreenDeals",
      "description": "List NEON GREEN deals — verified buyer / executable floor, money ready.",
      "readOnly": true
    },
    {
      "name": "getGreenDeals",
      "description": "List GREEN deals — strong conservative exits, sorted by error cushion.",
      "readOnly": true
    },
    {
      "name": "getBuyers",
      "description": "List buyers with categories, submission format, reliability and payment speed.",
      "readOnly": true
    },
    {
      "name": "getBuyerProfile",
      "description": "Full buyer profile: requirements, freight/payment rules, standing orders, history.",
      "readOnly": true
    },
    {
      "name": "getBuyerMatches",
      "description": "Rank buyers for a deal: verified active buyers, known buyers, and conflicts.",
      "readOnly": true
    },
    {
      "name": "analyzeDeal",
      "description": "Full decision analysis including break-even exit/acquisition and the risk buffer.",
      "readOnly": true
    },
    {
      "name": "calculateSafeBid",
      "description": "Check a proposed bid (or the current price) against the max safe hammer bid.",
      "readOnly": true
    },
    {
      "name": "getNextActions",
      "description": "Highest-value next action per deal, or for one deal.",
      "readOnly": true
    },
    {
      "name": "prepareBuyerSubmission",
      "description": "Transform a deal into a buyer's required submission format with a requirements check. Missing information is listed, never invented.",
      "readOnly": true
    },
    {
      "name": "createDeal",
      "description": "Create a deal. Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "updateDeal",
      "description": "Update deal fields (title, category, quantity, currentPrice, notes, status). Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "deleteDeal",
      "description": "Permanently delete a deal. Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "createBuyer",
      "description": "Create a buyer. Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "updateBuyer",
      "description": "Update buyer fields. Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "deleteBuyer",
      "description": "Permanently delete a buyer. Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "recordBuyerOffer",
      "description": "Record a buyer's quote; registers it as a Verified Buyer Floor candidate. Consequential — requires confirm.",
      "readOnly": false
    },
    {
      "name": "recordDealOutcome",
      "description": "Record the actual result and feed the projected-vs-actual learning engine. Consequential — requires confirm.",
      "readOnly": false
    }
  ],
  "x-connection-instructions": [
    "1. Sign in at haveitsold.com and open /api-docs.",
    "2. Create an API token (shown once).",
    "3. In your AI assistant's connector settings, set base URL https://haveitsold.com and Authorization: Bearer <token>.",
    "4. Point the assistant at the spec: GET https://haveitsold.com/api/public/his/openapi.",
    "5. Test with: getNeonGreenDeals, then calculateSafeBid on one deal, then prepareBuyerSubmission for one buyer."
  ]
}