{
  "openapi": "3.0.3",
  "info": {
    "title": "meCore Organization API",
    "version": "1.0.0",
    "description": "Create taste profiles from images. Authenticate with an organization API key."
  },
  "servers": [{ "url": "https://api.mecore.ai/api/v1/org" }],
  "components": {
    "securitySchemes": {
      "apiKey": { "type": "http", "scheme": "bearer", "description": "Your mco_live_… API key" }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "message": { "type": "string" },
          "status": { "type": "integer" }
        }
      },
      "Core": {
        "type": "object",
        "properties": {
          "status": { "type": "integer", "description": "HTTP status code" },
          "id": { "type": "string" },
          "name": { "type": "string" },
          "coreStatus": { "type": "string", "enum": ["processing", "ready", "failed"] },
          "taste": { "type": "string", "nullable": true },
          "styleAttributes": { "type": "array", "items": { "type": "string" } },
          "tags": { "type": "array", "items": { "type": "string" } },
          "images": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "imageURL": { "type": "string" },
                "caption": { "type": "string", "nullable": true }
              }
            }
          },
          "error": { "type": "string", "nullable": true },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      }
    }
  },
  "security": [{ "apiKey": [] }],
  "paths": {
    "/me": {
      "get": {
        "summary": "Verify an API key",
        "description": "Cheap ping to confirm a key is valid.",
        "responses": {
          "200": { "description": "Valid key" },
          "401": { "description": "Missing, invalid or revoked key" },
          "429": { "description": "Rate limited" }
        }
      }
    },
    "/cores": {
      "post": {
        "summary": "Create a core",
        "description": "Images are ingested synchronously; the taste profile generates in the background. Returns 202 with a jobId — poll GET /cores/{id} until coreStatus is \"ready\".",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "anyOf": [{ "required": ["imageUrls"] }, { "required": ["images"] }],
                "properties": {
                  "name": { "type": "string", "maxLength": 255 },
                  "imageUrls": {
                    "type": "array",
                    "items": { "type": "string", "format": "uri" },
                    "maxItems": 5,
                    "description": "Public https URLs. 1-5 images total across imageUrls and images."
                  },
                  "images": {
                    "type": "array",
                    "items": { "type": "string" },
                    "maxItems": 5,
                    "description": "Base64 data URLs, e.g. data:image/jpeg;base64,…"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": { "description": "Accepted — taste generating" },
          "400": { "description": "Validation failed, or an image could not be fetched" },
          "401": { "description": "Missing, invalid or revoked key" },
          "413": { "description": "Request body too large" },
          "429": { "description": "Rate limited" }
        }
      },
      "get": {
        "summary": "List cores",
        "parameters": [
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "query", "in": "query", "schema": { "type": "string" }, "description": "Synonym-aware search over name, tags and style attributes" }
        ],
        "responses": {
          "200": { "description": "Paginated cores" },
          "401": { "description": "Missing, invalid or revoked key" },
          "429": { "description": "Rate limited" }
        }
      }
    },
    "/cores/{id}": {
      "get": {
        "summary": "Get a core",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": {
            "description": "The core and its generation status",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Core" } } }
          },
          "401": { "description": "Missing, invalid or revoked key" },
          "404": { "description": "Not found, or belongs to another organization" },
          "429": { "description": "Rate limited" }
        }
      },
      "patch": {
        "summary": "Rename a core or replace its images",
        "description": "Replacing images starts a new taste job. A rename alone does not.",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": { "type": "string", "maxLength": 255 },
                  "imageUrls": { "type": "array", "items": { "type": "string" }, "maxItems": 5 },
                  "images": { "type": "array", "items": { "type": "string" }, "maxItems": 5 }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Updated" },
          "400": { "description": "Validation failed, or an image could not be fetched" },
          "401": { "description": "Missing, invalid or revoked key" },
          "404": { "description": "Not found" },
          "413": { "description": "Request body too large" },
          "429": { "description": "Rate limited" }
        }
      },
      "delete": {
        "summary": "Delete a core",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Deleted" },
          "401": { "description": "Missing, invalid or revoked key" },
          "404": { "description": "Not found" },
          "429": { "description": "Rate limited" }
        }
      }
    },
    "/jobs/{jobId}": {
      "get": {
        "summary": "Poll a taste generation job",
        "parameters": [{ "name": "jobId", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Job state — jobStatus is processing, ready or failed" },
          "401": { "description": "Missing, invalid or revoked key" },
          "404": { "description": "Not found" },
          "429": { "description": "Rate limited" }
        }
      }
    }
  }
}
