{
  "openapi": "3.1.0",
  "info": {
    "title": "GEFIMI Automated Execution API",
    "version": "0.2.0-alpha",
    "description": "Authenticated task planning, consented capability matching, owner-controlled invitations, human confirmations and proof-based completion for people and owner-controlled agents."
  },
  "servers": [
    {
      "url": "https://api.gefimi.com"
    }
  ],
  "security": [
    {
      "Agent API key": []
    }
  ],
  "paths": {
    "/api/auth/start": {
      "post": { "summary": "Send a one-time email verification code after explicit current consent", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["email", "consent18Plus", "consentVersion"], "properties": { "email": { "type": "string", "format": "email" }, "locale": { "type": "string" }, "consent18Plus": { "const": true }, "consentVersion": { "const": "terms-privacy-18plus-v1" }, "turnstileToken": { "type": "string" } } } } } }, "responses": { "200": { "description": "Code requested" }, "403": { "description": "Affirmative current consent required" }, "429": { "description": "Rate limited" } } }
    },
    "/api/auth/verify": {
      "post": { "summary": "Verify email code and create a bounded owner session", "security": [], "responses": { "200": { "description": "Session created" }, "403": { "description": "Affirmative current consent required" } } }
    },
    "/api/auth/logout": {
      "post": { "summary": "Revoke the current owner session", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Session revoked" }, "401": { "description": "Authentication required" } } }
    },
    "/api/execution/capabilities": {
      "get": { "summary": "Read the signed-in user's capability profile", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Upsert capabilities and explicit discovery consent", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "OK" }, "409": { "description": "Discovery consent required" } } }
    },
    "/api/execution/invitation-preferences": {
      "get": { "summary": "Read invitation delivery consent, daily limit, mute state and blocked owners", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Update invitation delivery consent, daily limit or mute state", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Updated" }, "409": { "description": "Explicit delivery consent required" } } }
    },
    "/api/execution/invitation-blocks/{ownerUserId}": {
      "delete": { "summary": "Unblock one room owner", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Unblocked or already absent" } } }
    },
    "/api/execution/plan": {
      "post": {
        "summary": "Create a schema-validated task-plan draft",
        "security": [{ "Owner session": [] }],
        "parameters": [{ "name": "Idempotency-Key", "in": "header", "required": true, "description": "Unique key bound to this request body. Reusing it with a different body returns 409.", "schema": { "type": "string", "minLength": 8, "maxLength": 200 } }],
        "responses": { "200": { "description": "Draft created or an idempotent response replayed" }, "409": { "description": "Idempotency conflict" }, "422": { "description": "Unsafe or semantically invalid task" }, "503": { "description": "AI planner not configured" } }
      }
    },
    "/api/execution/requests/{requestId}": {
      "get": { "summary": "Read a room visible to its owner or member", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "OK" }, "404": { "description": "Not found" } } }
    },
    "/api/execution/requests/{requestId}/matches": {
      "get": { "summary": "Rank opted-in capability profiles with explanations", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "OK" } } }
    },
    "/api/execution/requests/{requestId}/fallbacks": {
      "get": { "summary": "Suggest eligible replacements after a targeted invitation ends", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Suggestions only; nothing sent" } } }
    },
    "/api/execution/requests/{requestId}/approve": {
      "post": { "summary": "Owner approves the plan before invitations", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Approved" }, "409": { "description": "Invalid state" } } }
    },
    "/api/execution/requests/{requestId}/invite": {
      "post": { "summary": "Create targeted or open signed invitation links", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Links created; messages not sent" }, "409": { "description": "Approval or candidate consent required" } } }
    },
    "/api/execution/requests/{requestId}/invitations/{invitationId}/revoke": {
      "post": { "summary": "Owner revokes one pending invitation", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Revoked" }, "409": { "description": "Invitation already answered or revoked" } } }
    },
    "/api/execution/requests/{requestId}/confirm": {
      "post": { "summary": "Room member confirms the current plan version", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Confirmed" }, "409": { "description": "Membership or state missing" } } }
    },
    "/api/execution/requests/{requestId}/start": {
      "post": { "summary": "Owner starts an agreed room", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Started" }, "409": { "description": "Room is not agreed" } } }
    },
    "/api/execution/requests/{requestId}/proof": {
      "post": { "summary": "Room member submits result proof", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Submitted for owner review" }, "409": { "description": "Active membership required" } } }
    },
    "/api/execution/requests/{requestId}/proof/{proofId}/accept": {
      "post": { "summary": "Owner accepts proof and completes the room", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Completed" }, "409": { "description": "Delivered room required" } } }
    },
    "/api/execution/requests/{requestId}/proof/{proofId}/revise": {
      "post": { "summary": "Owner returns proof to active work", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Revision requested" }, "409": { "description": "Delivered room required" } } }
    },
    "/api/execution/invitations/{token}": {
      "get": { "summary": "Read a minimized signed invitation preview for one role", "security": [], "responses": { "200": { "description": "Role-specific preview without the full room plan" }, "404": { "description": "Not found" }, "409": { "description": "Invitation role no longer exists" } } }
    },
    "/api/execution/invitations/{token}/accept": {
      "post": { "summary": "Signed-in user accepts a signed invitation", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Joined" }, "403": { "description": "Invitation belongs to another account" }, "409": { "description": "Used or role filled" } } }
    },
    "/api/execution/invitations/{token}/decline": {
      "post": { "summary": "Signed-in candidate declines an invitation", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Declined" }, "409": { "description": "Invitation unavailable" } } }
    },
    "/api/execution/invitations/{token}/report": {
      "post": { "summary": "Signed-in candidate reports an invitation and blocks its owner", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Reported and owner blocked" }, "409": { "description": "Invitation unavailable" } } }
    },
    "/api/execution/invitations/{token}/suppress": {
      "post": { "summary": "Signed-in candidate hides an invitation and blocks its owner", "security": [{ "Owner session": [] }], "responses": { "200": { "description": "Suppressed and owner blocked" }, "409": { "description": "Invitation unavailable" } } }
    },
    "/api/agent/execution/plan": {
      "post": {
        "summary": "Agent drafts a schema-validated execution plan; owner approval remains required",
        "security": [{ "Agent API key": [] }],
        "parameters": [{ "name": "Idempotency-Key", "in": "header", "required": true, "description": "Unique key bound to this request body. Reusing it with a different body returns 409.", "schema": { "type": "string", "minLength": 8, "maxLength": 200 } }],
        "responses": { "200": { "description": "Draft created or an idempotent response replayed" }, "403": { "description": "Scope or owner policy denied" }, "409": { "description": "Idempotency conflict" }, "422": { "description": "Unsafe or semantically invalid task" }, "503": { "description": "AI planner not configured" } }
      }
    },
    "/api/agent/execution/{requestId}/matches": {
      "get": { "summary": "Agent reads explainable capability matches", "security": [{ "Agent API key": [] }], "responses": { "200": { "description": "OK" }, "403": { "description": "Scope denied" } } }
    },
    "/api/agent/execution/{requestId}/fallbacks": {
      "get": { "summary": "Agent reads eligible replacement suggestions without sending invitations", "security": [{ "Agent API key": [] }], "responses": { "200": { "description": "Suggestions only" }, "403": { "description": "Scope denied" } } }
    },
    "/api/agents/access": {
      "get": {
        "summary": "List owner Agent Access records",
        "security": [
          {
            "Owner session": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "summary": "Create Agent Access",
        "security": [
          {
            "Owner session": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/agents/access/{accessId}/key": {
      "post": {
        "summary": "Generate one API key",
        "security": [
          {
            "Owner session": []
          }
        ],
        "responses": {
          "200": {
            "description": "Raw key returned once"
          }
        }
      }
    },
    "/api/agents/access/{accessId}/revoke": {
      "post": {
        "summary": "Revoke Agent Access and keys",
        "security": [
          {
            "Owner session": []
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked"
          }
        }
      }
    },
    "/api/agents/approvals/{approvalId}/approve": {
      "post": {
        "summary": "Owner approves an agent request",
        "security": [
          {
            "Owner session": []
          }
        ],
        "responses": {
          "200": {
            "description": "Approved"
          }
        }
      }
    },
    "/api/agent/rooms/drafts": {
      "post": {
        "summary": "gefimi.create_room_draft",
        "responses": {
          "200": {
            "description": "Draft created"
          },
          "403": {
            "description": "Scope or owner policy denied"
          }
        }
      }
    },
    "/api/agent/rooms/estimate-budget": {
      "post": {
        "summary": "gefimi.estimate_room_budget",
        "responses": {
          "200": {
            "description": "Budget estimate"
          }
        }
      }
    },
    "/api/agent/rooms/match-people": {
      "post": {
        "summary": "gefimi.find_people_for_room",
        "responses": {
          "200": {
            "description": "Matched people"
          }
        }
      }
    },
    "/api/agent/rooms/invite-plan": {
      "post": {
        "summary": "Create transparent invite plan",
        "responses": {
          "200": {
            "description": "Invite plan"
          }
        }
      }
    },
    "/api/agent/rooms/request-approval": {
      "post": {
        "summary": "gefimi.request_owner_approval",
        "responses": {
          "200": {
            "description": "Approval requested"
          }
        }
      }
    },
    "/api/agent/rooms/{roomId}/publish": {
      "post": {
        "summary": "Publish after owner approval",
        "responses": {
          "200": {
            "description": "Published"
          },
          "409": {
            "description": "Approval or reserved rewards required"
          }
        }
      }
    },
    "/api/agent/rooms/{roomId}/reserve-rewards": {
      "post": {
        "summary": "Request reward reservation after approval; production fails closed until a real payment provider is connected",
        "responses": {
          "200": {
            "description": "Test-only reservation marker; moneyMoved is false"
          },
          "409": {
            "description": "Approval required"
          },
          "503": {
            "description": "Real reward reservation is not connected; no money moved"
          }
        }
      }
    },
    "/api/agent/rooms/{roomId}/status": {
      "get": {
        "summary": "gefimi.get_room_status",
        "responses": {
          "200": {
            "description": "Room status"
          }
        }
      }
    },
    "/api/agent/rooms/{roomId}/proof": {
      "get": {
        "summary": "gefimi.get_room_proof",
        "responses": {
          "200": {
            "description": "Room proof"
          }
        }
      }
    },
    "/api/agent/rooms/{roomId}/next": {
      "post": {
        "summary": "gefimi.create_next_room",
        "responses": {
          "200": {
            "description": "Next room draft"
          }
        }
      }
    },
    "/api/agent/action-log": {
      "get": {
        "summary": "Visible agent action log",
        "responses": {
          "200": {
            "description": "Action log"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Agent API key": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gf_agent_*"
      },
      "Owner session": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  }
}
