{
  "openapi": "3.1.0",
  "info": {
    "title": "courier-owl API",
    "version": "1.0.0",
    "description": "White-label Gmail API. A connected mailbox is a grant, addressed by your own user_id; your api_key alone identifies your organization. Responses use the envelope { request_id, data, next_cursor }.",
    "contact": { "name": "courier-owl", "url": "https://courier-owl-web.vercel.app/docs" }
  },
  "servers": [
    { "url": "https://tdgqo14n67.execute-api.us-east-1.amazonaws.com", "description": "dev" }
  ],
  "security": [{ "bearerAuth": [] }],
  "tags": [
    { "name": "Grants", "description": "Connected mailboxes" },
    { "name": "Messages", "description": "Read and send messages" },
    { "name": "Threads" },
    { "name": "Attachments" }
  ],
  "paths": {
    "/v1/grants": {
      "get": {
        "tags": ["Grants"],
        "operationId": "listGrants",
        "summary": "List connected mailboxes",
        "responses": {
          "200": {
            "description": "A list of grants.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": { "type": "string" },
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Grant" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/v1/grants/{grant_id}": {
      "parameters": [{ "$ref": "#/components/parameters/GrantId" }],
      "get": {
        "tags": ["Grants"],
        "operationId": "getGrant",
        "summary": "Retrieve a grant",
        "responses": {
          "200": { "$ref": "#/components/responses/GrantResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "delete": {
        "tags": ["Grants"],
        "operationId": "revokeGrant",
        "summary": "Revoke a grant (stops Gmail watching)",
        "responses": {
          "200": { "$ref": "#/components/responses/GrantResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/grants/{grant_id}/messages": {
      "parameters": [{ "$ref": "#/components/parameters/GrantId" }],
      "get": {
        "tags": ["Messages"],
        "operationId": "listMessages",
        "summary": "List messages",
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "maximum": 100, "default": 20 } },
          { "name": "cursor", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "A page of messages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": { "type": "string" },
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } },
                    "next_cursor": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/v1/grants/{grant_id}/messages/send": {
      "parameters": [{ "$ref": "#/components/parameters/GrantId" }],
      "post": {
        "tags": ["Messages"],
        "operationId": "sendMessage",
        "summary": "Send or reply as the mailbox",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["to"],
                "properties": {
                  "to": {
                    "description": "A recipient address, or a list of addresses / {email,name} objects.",
                    "oneOf": [
                      { "type": "string" },
                      { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } }
                    ]
                  },
                  "subject": { "type": "string" },
                  "body": { "type": "string" },
                  "thread_id": { "type": "string", "description": "Pass to reply within a thread." }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/MessageResponse" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/grants/{grant_id}/messages/{message_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/GrantId" },
        { "name": "message_id", "in": "path", "required": true, "schema": { "type": "string" } },
        { "name": "thread_id", "in": "query", "schema": { "type": "string" }, "description": "Provide for a fast read." }
      ],
      "get": {
        "tags": ["Messages"],
        "operationId": "getMessage",
        "summary": "Retrieve a message",
        "responses": {
          "200": { "$ref": "#/components/responses/MessageResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/grants/{grant_id}/threads/{thread_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/GrantId" },
        { "name": "thread_id", "in": "path", "required": true, "schema": { "type": "string" } }
      ],
      "get": {
        "tags": ["Threads"],
        "operationId": "getThread",
        "summary": "Retrieve a thread and its messages",
        "responses": {
          "200": {
            "description": "The thread.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": { "type": "string" },
                    "data": { "$ref": "#/components/schemas/Thread" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/grants/{grant_id}/attachments/{attachment_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/GrantId" },
        { "name": "attachment_id", "in": "path", "required": true, "schema": { "type": "string" } },
        { "name": "message_id", "in": "query", "required": true, "schema": { "type": "string" } },
        { "name": "thread_id", "in": "query", "schema": { "type": "string" } }
      ],
      "get": {
        "tags": ["Attachments"],
        "operationId": "downloadAttachment",
        "summary": "Download attachment bytes",
        "responses": {
          "200": {
            "description": "The raw attachment.",
            "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your organization's api_key (cok_…) as a Bearer token."
      }
    },
    "parameters": {
      "GrantId": {
        "name": "grant_id",
        "in": "path",
        "required": true,
        "description": "The connected mailbox — the user_id you chose for the connect link.",
        "schema": { "type": "string" }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid api_key.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Resource not found.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "BadRequest": {
        "description": "A required parameter is missing.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "GrantResponse": {
        "description": "A grant.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "request_id": { "type": "string" },
                "data": { "$ref": "#/components/schemas/Grant" }
              }
            }
          }
        }
      },
      "MessageResponse": {
        "description": "A message.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "request_id": { "type": "string" },
                "data": { "$ref": "#/components/schemas/Message" }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Grant": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "provider": { "type": "string", "example": "google" },
          "grant_status": { "type": "string", "enum": ["valid", "invalid"] },
          "email": { "type": "string" },
          "scope": { "type": "array", "items": { "type": "string" } },
          "created_at": { "type": "string" },
          "updated_at": { "type": "string" }
        }
      },
      "EmailAddress": {
        "type": "object",
        "properties": { "email": { "type": "string" }, "name": { "type": "string" } }
      },
      "Attachment": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "filename": { "type": "string" },
          "content_type": { "type": "string" },
          "size": { "type": "integer" }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "grant_id": { "type": "string" },
          "thread_id": { "type": "string" },
          "subject": { "type": "string" },
          "from": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } },
          "to": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } },
          "cc": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAddress" } },
          "date": { "type": "string" },
          "snippet": { "type": "string" },
          "unread": { "type": "boolean" },
          "starred": { "type": "boolean" },
          "folders": { "type": "array", "items": { "type": "string" } },
          "has_attachments": { "type": "boolean" },
          "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/Attachment" } },
          "body": { "type": "string" }
        }
      },
      "Thread": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "grant_id": { "type": "string" },
          "subject": { "type": "string" },
          "message_ids": { "type": "array", "items": { "type": "string" } },
          "message_count": { "type": "integer" },
          "has_attachments": { "type": "boolean" },
          "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "request_id": { "type": "string" },
          "error": {
            "type": "object",
            "properties": {
              "type": { "type": "string", "example": "api_error" },
              "message": { "type": "string" }
            }
          }
        }
      }
    }
  }
}
