openapi: 3.0.3
info:
  title: Parcel API
  version: 0.1.0
  description: >
    Parcel is the agent-native infrastructure layer for real estate.
    It provides trust, data, negotiation, and settlement capabilities
    that let AI agents identify, verify, and act on real property
    through one API. Built on MCP, A2A, DID/VC, and x402 standards.
  contact:
    name: Parcel (Sohala / Amplify Brands)
    url: https://parcel.sohala.ai
servers:
  - url: https://parcel.sohala.ai
    description: Production
  - url: http://localhost:8088
    description: Local development
paths:
  /v1/property/lookup:
    post:
      operationId: lookupPropertyByLocation
      summary: Identify a property at a GPS coordinate and return a structured dossier.
      description: >
        Resolve a GPS coordinate to an exact parcel (APN) via point-in-polygon
        matching, then assemble a structured property dossier from licensed
        public-record sources. Returns ownership, lot details, sale history,
        and a confidence-weighted AVM blended from multiple independent sources
        with full provenance. Metered at 1 credit per lookup.
      tags: [Property Data]
      security: [{ passport: [] }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [lat, lng]
              properties:
                lat: { type: number, description: "Latitude (-90 to 90)" }
                lng: { type: number, description: "Longitude (-180 to 180)" }
      responses:
        "200": { description: Dossier returned (metered, 1 credit) }
        "401": { description: Missing Parcel Passport }
        "402": { description: Payment required (insufficient credit or x402 challenge) }
        "403": { description: Passport lacks scope read:property }
        "404": { description: No parcel found at this coordinate }
  /v1/showing/request:
    post:
      operationId: requestShowing
      summary: Request a showing from the listing agent (agent-to-agent).
      description: >
        Agent-to-agent negotiation: request a property showing from the listing
        side's agent. Requires a Parcel Passport with scope act:request_showing
        AND a human-approved mandate scoped to this one action on this one parcel.
        The negotiation follows a typed state machine (requested -> acknowledged ->
        scheduled/declined/countered -> closed). Metered at 5 credits.
      tags: [Negotiation]
      security: [{ passport: [] }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [apn, preferredWhen, humanApproved]
              properties:
                apn: { type: string, description: "Assessor's Parcel Number" }
                preferredWhen: { type: string, description: "Preferred showing time (ISO 8601)" }
                humanApproved: { type: boolean, description: "Must be true — mandate requires human approval" }
      responses:
        "200": { description: Showing negotiated (metered, 5 credits) }
        "402": { description: Payment required }
        "403": { description: Forbidden — passport lacks scope or mandate not human-approved }
components:
  securitySchemes:
    passport:
      type: http
      scheme: bearer
      description: >
        Parcel Passport — a short-lived, scoped, DID/VC-shaped JWT credential.
        Every API call requires a valid Passport. Issue one via the Parcel SDK.
