{
  "openapi": "3.1.0",
  "info": {
    "title": "סמוך עליי (SmochAlai) Protected Resource API",
    "version": "3.0.0",
    "description": "Machine-readable OpenAPI specification for סמוך עליי (SmochAlai / TrustMe, formerly Vybio וייביו). Declares zero-trust endpoints and granular OAuth2 / Bearer scoped permissions for autonomous AI agents and client integrations.",
    "contact": {
      "name": "סמוך עליי API Support",
      "url": "https://smochalai.netlify.app/contact.html"
    }
  },
  "servers": [
    {
      "url": "https://smochalai.netlify.app",
      "description": "Production edge gateway"
    },
    {
      "url": "https://api.smochalai.netlify.app",
      "description": "Core backend API"
    }
  ],
  "paths": {
    "/api/v1/profile": {
      "get": {
        "summary": "Get user profile",
        "description": "Retrieve public and contact-accessible profile information.",
        "operationId": "getProfile",
        "security": [
          {
            "OAuth2": [
              "profile:read"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Profile retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      },
      "put": {
        "summary": "Update user profile",
        "description": "Update user bio, handle, location, or social links.",
        "operationId": "updateProfile",
        "security": [
          {
            "OAuth2": [
              "profile:write"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Profile updated successfully"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/api/v1/recommendations": {
      "get": {
        "summary": "List living stack recommendations",
        "description": "List curated recommendations for contacts within the user's circle.",
        "operationId": "listRecommendations",
        "security": [
          {
            "OAuth2": [
              "recommendations:read"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of recommendations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StackItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      },
      "post": {
        "summary": "Create living stack recommendation",
        "description": "Add a new routine, service professional, or product recommendation.",
        "operationId": "createRecommendation",
        "security": [
          {
            "OAuth2": [
              "recommendations:write"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Recommendation created"
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/api/v1/contacts/match": {
      "post": {
        "summary": "Privacy-preserving contact matching",
        "description": "Match local SHA-256 phone hashes with registered contacts. Never transmits raw phone numbers.",
        "operationId": "matchContacts",
        "security": [
          {
            "OAuth2": [
              "contacts:match"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Matched registered phone hashes"
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/api/v1/ai/extract": {
      "post": {
        "summary": "AI Copilot extraction",
        "description": "Zero-trust edge endpoint extracting structured stack items from natural language (subject to 10 req/min rate limit).",
        "operationId": "extractStackItems",
        "security": [
          {
            "OAuth2": [
              "ai:extract"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Extracted structured stack blueprint"
          },
          "401": {
            "description": "Unauthorized"
          },
          "429": {
            "description": "Rate limit exceeded (maximum 10 requests per minute)"
          }
        }
      }
    },
    "/api/v1/link/unfurl": {
      "post": {
        "summary": "Unfurl URL preview metadata",
        "description": "Extract OpenGraph metadata with SSRF blocklists and HTTPS validation.",
        "operationId": "unfurlLink",
        "security": [
          {
            "OAuth2": [
              "link:unfurl"
            ],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OpenGraph metadata"
          },
          "400": {
            "description": "Invalid or blocked URL"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "OAuth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 authorization with scoped permissions for agents and client applications",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://smochalai.netlify.app/oauth/authorize",
            "tokenUrl": "https://smochalai.netlify.app/oauth/token",
            "scopes": {
              "profile:read": "Read public and contact-shared user profiles",
              "profile:write": "Update profile details, handle, bio, and preferences",
              "recommendations:read": "Read living stack recommendations, items, and categories",
              "recommendations:write": "Create and curate living stack recommendations",
              "recommendations:delete": "Delete user-owned living stack recommendations",
              "contacts:match": "Perform privacy-preserving phone hash contact matching",
              "ai:extract": "Extract living stack items via AI Copilot",
              "link:unfurl": "Unfurl preview metadata and images for links"
            }
          }
        }
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Bearer token with machine-readable scoped claims validated at edge functions"
      }
    },
    "schemas": {
      "Profile": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "handle": { "type": "string" },
          "bio": { "type": "string" },
          "location": { "type": "string" },
          "social_links": { "type": "object" },
          "followers_count": { "type": "integer" },
          "following_count": { "type": "integer" }
        }
      },
      "StackItem": {
        "type": "object",
        "required": ["id", "user_id", "category", "title"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "user_id": { "type": "string", "format": "uuid" },
          "category": {
            "type": "string",
            "enum": ["cosmetics", "service_pro", "fitness", "routine", "media", "habit", "food", "custom"]
          },
          "title": { "type": "string" },
          "subtitle": { "type": "string" },
          "metadata": { "type": "object" },
          "url": { "type": "string", "format": "uri" },
          "image_url": { "type": "string", "format": "uri" },
          "is_public": { "type": "boolean" }
        }
      }
    }
  }
}
