{
  "openapi": "3.1.0",
  "info": {
    "title": "Camile AI — Developer Platform API",
    "version": "1.0.0",
    "description": "API v1 para conectar sistemas externos às entidades da Camile AI. Três fluxos: (1) sua entidade via API key; (2) entidades criadas para os usuários do seu sistema; (3) conexão OAuth da entidade do próprio usuário (\"vincular minha entidade\").",
    "contact": { "url": "https://camileai.com/developers" },
    "license": { "name": "Proprietary" }
  },
  "servers": [{ "url": "https://camileai.com", "description": "Produção" }],
  "security": [{ "bearerAuth": [] }],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (cam_sk_live_…) ou access token OAuth (cam_at_…)."
      },
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://camileai.com/pt-BR/oauth/authorize",
            "tokenUrl": "https://camileai.com/api/oauth/token",
            "refreshUrl": "https://camileai.com/api/oauth/token",
            "scopes": {
              "entity:chat": "Conversar com a entidade autorizada",
              "entity:read": "Ler o histórico de conversas da entidade autorizada"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "const": false },
          "error": { "type": "string" },
          "code": { "type": "string", "enum": ["unauthorized", "insufficient_scope", "invalid_request", "entity_not_found", "entity_unavailable", "rate_limited", "internal_error"] }
        },
        "required": ["ok", "error"]
      },
      "Entity": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "slug": { "type": ["string", "null"] },
          "kind": { "type": "string", "enum": ["reference", "standard", "canary", "admin"] },
          "status": { "type": "string", "enum": ["BOOTING", "ACTIVE", "PAUSED", "STOPPED", "ARCHIVED"] },
          "locale": { "type": "string" },
          "purpose": { "type": ["string", "null"] },
          "created_at": { "type": "integer", "description": "epoch ms" }
        },
        "required": ["id", "name", "status"]
      },
      "Interaction": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "message": { "type": "string" },
          "response": { "type": ["string", "null"] },
          "preempted": { "type": "boolean" },
          "trajectoryId": { "type": ["string", "null"] },
          "resumed": { "type": "boolean" },
          "ts": { "type": "integer", "description": "epoch ms" },
          "correlationId": { "type": "string" }
        },
        "required": ["id", "message", "ts"]
      }
    }
  },
  "paths": {
    "/api/v1/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Identidade e limites da credencial",
        "responses": {
          "200": {
            "description": "Credencial válida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": { "type": "boolean", "const": true },
                    "subject": { "type": "object", "properties": { "type": { "type": "string", "enum": ["api_key", "oauth"] }, "id": { "type": "string" }, "name": { "type": "string" }, "entity_id": { "type": "string" }, "client_id": { "type": "string" } } },
                    "tenant": { "type": "object" },
                    "scopes": { "type": "array", "items": { "type": "string" } },
                    "limits": { "type": "object", "properties": { "requests_per_minute": { "type": "integer", "const": 120 } } },
                    "api_version": { "type": "string", "const": "v1" }
                  }
                }
              }
            }
          },
          "401": { "description": "Credencial inválida", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/v1/entities": {
      "get": {
        "operationId": "listEntities",
        "summary": "Lista entidades do tenant",
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "maximum": 200 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": {
          "200": {
            "description": "Lista paginada",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "entities": { "type": "array", "items": { "$ref": "#/components/schemas/Entity" } }, "total": { "type": "integer" } } } } }
          },
          "401": { "description": "Não autorizado" },
          "403": { "description": "Escopo insuficiente (entities:read)" }
        }
      },
      "post": {
        "operationId": "createEntity",
        "summary": "Cria uma entidade (Protocolo de Gênese)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": { "type": "string", "minLength": 2, "maxLength": 80 },
                  "gender": { "type": "string", "enum": ["feminino", "masculino", "neutro"] },
                  "purpose": { "type": "string", "maxLength": 2000 },
                  "locale": { "type": "string" },
                  "external_user_id": { "type": "string", "description": "Identificador do seu usuário final (quando a entidade é criada para ele)" }
                },
                "required": ["name"]
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Entidade criada", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "entity": { "$ref": "#/components/schemas/Entity" } } } } } },
          "400": { "description": "Requisição inválida" },
          "403": { "description": "Escopo insuficiente (entities:write)" }
        }
      }
    },
    "/api/v1/entities/{id}": {
      "get": {
        "operationId": "getEntity",
        "summary": "Detalhe de uma entidade",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Entidade", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "entity": { "$ref": "#/components/schemas/Entity" } } } } } },
          "404": { "description": "Não encontrada" }
        }
      }
    },
    "/api/v1/entities/{id}/messages": {
      "post": {
        "operationId": "sendMessage",
        "summary": "Envia mensagem à entidade e aguarda resposta (até 30s)",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": { "type": "string", "minLength": 1, "maxLength": 4000 },
                  "end_user_id": { "type": "string", "description": "Identificador do seu usuário final — a entidade desenvolve um modelo psicológico por pessoa" },
                  "end_user_name": { "type": "string" },
                  "conversation_mode": { "type": "string", "enum": ["social", "professional"], "default": "social" }
                },
                "required": ["message"]
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Resposta da entidade", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "interaction": { "$ref": "#/components/schemas/Interaction" } } } } } },
          "202": { "description": "Enfileirada; resposta ainda não pronta (consulte o GET)" },
          "409": { "description": "Entidade indisponível" }
        }
      },
      "get": {
        "operationId": "listMessages",
        "summary": "Histórico recente de conversas",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 30, "maximum": 100 } },
          { "name": "end_user_id", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Mensagens", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Interaction" } } } } } } }
        }
      }
    },
    "/api/oauth/token": {
      "post": {
        "operationId": "oauthToken",
        "summary": "Troca code por tokens / refresh (RFC 6749)",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "grant_type": { "type": "string", "enum": ["authorization_code", "refresh_token"] },
                  "code": { "type": "string" },
                  "redirect_uri": { "type": "string" },
                  "refresh_token": { "type": "string" },
                  "client_id": { "type": "string" },
                  "client_secret": { "type": "string" }
                },
                "required": ["grant_type", "client_id", "client_secret"]
              }
            },
            "application/json": { "schema": { "type": "object" } }
          }
        },
        "responses": {
          "200": {
            "description": "Tokens emitidos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": { "type": "string" },
                    "token_type": { "type": "string", "const": "Bearer" },
                    "expires_in": { "type": "integer" },
                    "refresh_token": { "type": "string" },
                    "scope": { "type": "string" },
                    "entity_id": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Erro OAuth (invalid_grant, unsupported_grant_type…)" },
          "401": { "description": "invalid_client" }
        }
      }
    },
    "/api/oauth/revoke": {
      "post": {
        "operationId": "oauthRevoke",
        "summary": "Revoga um grant (RFC 7009)",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": { "type": "string" },
                  "client_id": { "type": "string" },
                  "client_secret": { "type": "string" }
                },
                "required": ["token", "client_id", "client_secret"]
              }
            }
          }
        },
        "responses": { "200": { "description": "Revogado (ou token desconhecido — sempre 200 por RFC)" } }
      }
    }
  }
}
