{
  "openapi": "3.0.3",
  "info": {
    "title": "Harbour API",
    "version": "0.2.0",
    "description": "Agency OS HTTP API. Production private routes require a harbour_session cookie (from POST /api/auth/session) or Authorization: Bearer $HARBOUR_API_KEY when configured."
  },
  "servers": [
    { "url": "https://getharbour.io" },
    { "url": "http://localhost:3000" }
  ],
  "components": {
    "securitySchemes": {
      "HarbourSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "harbour_session"
      },
      "HarbourApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Optional. Set HARBOUR_API_KEY in the environment."
      }
    }
  },
  "paths": {
    "/api/v1/overview": {
      "get": { "summary": "Agency health snapshot", "tags": ["v1"] }
    },
    "/api/v1/contacts": {
      "get": { "summary": "List contacts", "tags": ["v1"] },
      "post": { "summary": "Create contact / lead", "tags": ["v1"] }
    },
    "/api/v1/forms": {
      "get": { "summary": "List form submissions", "tags": ["v1"] },
      "post": { "summary": "Submit a form lead", "tags": ["v1"] }
    },
    "/api/v1/bookings": {
      "get": { "summary": "List bookings", "tags": ["v1"] },
      "post": { "summary": "Create a booking", "tags": ["v1"] }
    },
    "/api/v1/clients": {
      "get": { "summary": "List client workspaces", "tags": ["v1"] }
    },
    "/api/v1/reliability": {
      "get": { "summary": "Reliability metrics + issues", "tags": ["v1"] }
    },
    "/api/auth/session": {
      "post": {
        "summary": "Sign in / out (sets harbour_session cookie with agencyId)",
        "tags": ["auth"]
      }
    },
    "/api/connections": {
      "get": {
        "summary": "Connection status cards for the current agency",
        "tags": ["connections"],
        "security": [{ "HarbourSession": [] }, { "HarbourApiKey": [] }]
      }
    },
    "/api/stripe/connect/account": {
      "get": { "summary": "Get agency Stripe Connect account", "tags": ["stripe"] },
      "post": { "summary": "Create or resume Connect onboarding", "tags": ["stripe"] }
    },
    "/api/stripe/checkout": {
      "post": { "summary": "Create Checkout Session (platform or connected)", "tags": ["stripe"] }
    },
    "/api/stripe/checkout/session": {
      "get": { "summary": "Confirm a Checkout Session after return", "tags": ["stripe"] }
    },
    "/api/stripe/webhook": {
      "post": { "summary": "Stripe webhooks (signature required in production)", "tags": ["stripe"] }
    },
    "/api/sites/publish": {
      "get": { "summary": "Get published site document", "tags": ["sites"] },
      "post": { "summary": "Publish site snapshot to Blob + /s/{id}", "tags": ["sites"] }
    },
    "/api/sites/domains": {
      "get": { "summary": "List custom domains", "tags": ["sites"] },
      "post": { "summary": "Attach custom domain via Vercel", "tags": ["sites"] },
      "patch": { "summary": "Refresh domain verification", "tags": ["sites"] }
    },
    "/api/twilio/numbers": {
      "get": { "summary": "List or search Twilio numbers", "tags": ["phone"] },
      "post": { "summary": "Provision a phone number", "tags": ["phone"] }
    },
    "/api/twilio/webhook": {
      "post": { "summary": "Inbound SMS / voice webhook", "tags": ["phone"] }
    },
    "/api/inbox/messages": {
      "get": { "summary": "List durable inbox threads", "tags": ["inbox"] },
      "post": { "summary": "Send SMS via Twilio", "tags": ["inbox"] }
    },
    "/api/nylas/auth": {
      "get": { "summary": "Start Nylas hosted auth", "tags": ["nylas"] }
    },
    "/api/nylas/callback": {
      "get": { "summary": "Nylas OAuth callback", "tags": ["nylas"] }
    },
    "/api/nylas/send": {
      "post": { "summary": "Send email via Nylas", "tags": ["nylas"] }
    },
    "/api/nylas/webhook": {
      "post": { "summary": "Nylas inbound email webhook", "tags": ["nylas"] }
    },
    "/api/calendar/availability": {
      "get": {
        "summary": "Public availability slots",
        "tags": ["calendar"],
        "parameters": [
          {
            "name": "agencyId",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Agency id from the public booking link (/book?agency=…)"
          }
        ]
      },
      "post": {
        "summary": "Create calendar event / booking",
        "tags": ["calendar"],
        "description": "Requires bookingToken from GET (public) or a signed harbour_session (authenticated)."
      }
    },
    "/api/media/upload": {
      "post": { "summary": "Upload image to Vercel Blob", "tags": ["media"] }
    },
    "/api/unsplash": {
      "get": { "summary": "Search Unsplash photos", "tags": ["media"] }
    },
    "/api/marketing/campaigns": {
      "get": { "summary": "List SMS/email campaigns", "tags": ["marketing"] },
      "post": { "summary": "Create campaign", "tags": ["marketing"] }
    },
    "/api/marketing/campaigns/{id}/send": {
      "post": {
        "summary": "Send campaign via Twilio or Nylas (max 100 contacts)",
        "tags": ["marketing"]
      }
    },
    "/api/webhooks/endpoints": {
      "get": {
        "summary": "List outbound webhook endpoints + recent deliveries",
        "tags": ["webhooks"]
      },
      "post": {
        "summary": "Register outbound webhook endpoint",
        "tags": ["webhooks"],
        "description": "Events: contact.created, form.submitted, booking.created. Signed with X-Harbour-Signature."
      },
      "delete": { "summary": "Delete webhook endpoint (?id=)", "tags": ["webhooks"] }
    },
    "/api/migration/ghl": {
      "post": {
        "summary": "Import contacts from GoHighLevel (apiKey + locationId)",
        "tags": ["migration"]
      }
    },
    "/api/assist": {
      "post": {
        "summary": "Harbour Assist — LLM or rule-based reply from durable tenant snapshot",
        "tags": ["assist"]
      }
    },
    "/openapi.json": {
      "get": { "summary": "This OpenAPI document", "tags": ["meta"] }
    }
  }
}
