{
  "openapi": "3.1.0",
  "info": {
    "title": "Flinkk Mail Email API",
    "version": "1.0.0",
    "description": "Send transactional email over HTTPS. Authenticate with a domain-scoped API key from Settings > API Keys, sent as `Authorization: Bearer <key>`. A key can only send from the domain it was created for.",
    "contact": {
      "url": "https://mail.flinkk.io/docs"
    }
  },
  "servers": [
    {
      "url": "https://mail.flinkk.io"
    }
  ],
  "paths": {
    "/api/v1/emails": {
      "post": {
        "operationId": "sendEmail",
        "summary": "Send an email",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Email"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendEmailResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key not valid for the from domain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key) or daily sending limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key reused with a different body, or the first request is still in progress",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Template not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Not sent: a recipient is on the suppression list (code `recipient_suppressed`, with the addresses)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Up to 255 printable characters. A retry with the same key and body returns the original email id (header `Idempotent-Replayed: true`) instead of sending again; the same key with a different body is 409. Keys last 24 hours.",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "get": {
        "operationId": "listEmails",
        "summary": "Search the log of sent email",
        "description": "Newest first. Inbound mail is excluded. Only the last 30 days are available (90 days on Scale). Subjects are encrypted at rest, so a `q` search scans the newest matches (up to 500 rows per request) and returns a `nextCursor` to continue.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Logs"
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Latest delivery status",
            "schema": {
              "type": "string",
              "enum": [
                "sent",
                "delivered",
                "bounce",
                "complaint"
              ]
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Recipient contains (case-insensitive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Sender contains (case-insensitive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Text in recipient, sender or subject",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "ISO 8601 date",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "description": "ISO 8601 date",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "opened",
            "in": "query",
            "required": false,
            "description": "Only opened mail",
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            }
          },
          {
            "name": "clicked",
            "in": "query",
            "required": false,
            "description": "Only mail with a link click",
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1 to 100 (default 25)",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "`nextCursor` from the previous page",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EmailSummary"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "retention_days": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid filter, date or cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/emails/batch": {
      "post": {
        "operationId": "sendBatch",
        "summary": "Send up to 100 emails in one request",
        "description": "Every item is validated before anything is sent; if one is invalid nothing is sent. Items are sent in order.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Email"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "minItems": 1,
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/SendEmailInput"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SendEmailResult"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key not valid for the from domain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key) or daily sending limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/emails/{id}": {
      "get": {
        "operationId": "getEmail",
        "summary": "Retrieve an email with its event timeline",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Email"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailDetail"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key) or daily sending limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates": {
      "get": {
        "operationId": "listTemplates",
        "summary": "List built-in and custom templates",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Templates"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Template"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createTemplate",
        "summary": "Create a custom template",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Templates"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Name already used",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates/render": {
      "post": {
        "operationId": "renderTemplate",
        "summary": "Render a template without sending",
        "description": "Returns the subject, html and text with variables filled in. 400 `missing_variables` lists any required variable not supplied.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Templates"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "template"
                ],
                "properties": {
                  "template": {
                    "type": "string"
                  },
                  "variables": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderedTemplate"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid variables",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates/{id}": {
      "get": {
        "operationId": "getTemplate",
        "summary": "Retrieve a template",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id, custom template name, or built-in template id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateTemplate",
        "summary": "Update a custom template",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id, custom template name, or built-in template id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "subject": {
                    "type": "string"
                  },
                  "html": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "404": {
            "description": "Not found or built-in",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteTemplate",
        "summary": "Delete a custom template",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id, custom template name, or built-in template id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found or built-in",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/suppressions": {
      "get": {
        "operationId": "listSuppressions",
        "summary": "List suppressed addresses",
        "description": "Addresses this workspace will not email: permanent bounces and complaints (added automatically from delivery events) and manual entries.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Suppressions"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Suppression"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "addSuppression",
        "summary": "Suppress an address manually",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Suppressions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suppression"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/suppressions/{email}": {
      "delete": {
        "operationId": "removeSuppression",
        "summary": "Remove an address from the suppression list",
        "description": "Only do this if the address owner confirms it is valid; sending to addresses that bounced or complained harms your sender reputation.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Suppressions"
        ],
        "parameters": [
          {
            "name": "email",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not on the list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent-inboxes": {
      "get": {
        "operationId": "listAgentInboxes",
        "summary": "List your instant agent inboxes",
        "description": "Inboxes this workspace created on the shared domain, with the agent and permissions of each. Uses your domain API key, not an agent key.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Agent inboxes"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AgentInbox"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createAgentInbox",
        "summary": "Create an instant agent inbox",
        "description": "One call creates an address on the shared domain (no DNS), an agent, a grant and an agent key. The key is returned once. New inboxes are locked down by default: draft-only (a person approves), reply-only (it can answer people who wrote in but cannot cold-email), 25 sends a day. To let it write first, pass `allowed_recipients` (exact addresses, max 25). Limits per plan: Free 3, Pro 10, Scale 50 inboxes.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Agent inboxes"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentInboxInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentInboxCreated"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, or the shared domain is not enabled (`shared_domain_not_configured`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Plan limit reached (`inbox_limit_reached`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Address taken (`address_taken`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent-inboxes/{id}": {
      "delete": {
        "operationId": "deleteAgentInbox",
        "summary": "Delete an instant agent inbox",
        "description": "Revokes the agent's keys, removes the agent and the address. Mail already received stays in your workspace.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Agent inboxes"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "summary": "List webhook endpoints",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createWebhook",
        "summary": "Create a webhook endpoint",
        "description": "The URL must be public https. The signing secret is returned once. Event payloads are described by the `WebhookEvent` schema; verify them with `verifyWebhook` in the SDKs.",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "enum": [
                        "email.sent",
                        "email.delivered",
                        "email.bounced",
                        "email.complained",
                        "email.opened",
                        "email.clicked",
                        "email.received",
                        "thread.updated",
                        "draft.pending_approval",
                        "draft.approved"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "description": "Invalid URL or events",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{id}": {
      "patch": {
        "operationId": "updateWebhook",
        "summary": "Enable or disable an endpoint",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "enabled"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "summary": "Delete an endpoint",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{id}/test": {
      "post": {
        "operationId": "testWebhook",
        "summary": "Send a signed ping",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "summary": "Recent deliveries and their status",
        "security": [
          {
            "apiKey": []
          }
        ],
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (120 requests/minute/key); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "Address": {
        "oneOf": [
          {
            "type": "string",
            "description": "`name@example.com` or `Name <name@example.com>`"
          },
          {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "string"
            }
          }
        ]
      },
      "SendEmailInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "from",
          "to"
        ],
        "description": "Provide `html`/`text`, or a `template` (a built-in id such as `welcome` or the name of your own) with `variables`. With a template, `subject` is optional and overrides the template's.",
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "$ref": "#/components/schemas/Address"
          },
          "cc": {
            "$ref": "#/components/schemas/Address"
          },
          "bcc": {
            "$ref": "#/components/schemas/Address"
          },
          "reply_to": {
            "$ref": "#/components/schemas/Address"
          },
          "subject": {
            "type": "string",
            "maxLength": 998
          },
          "html": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Custom headers (max 20). From, To, Subject, Reply-To, Message-ID, DKIM and similar are ignored."
          },
          "attachments": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "filename"
              ],
              "description": "Exactly one of `content` or `path`.",
              "properties": {
                "filename": {
                  "type": "string"
                },
                "content": {
                  "type": "string",
                  "description": "Base64"
                },
                "path": {
                  "type": "string",
                  "format": "uri"
                },
                "content_type": {
                  "type": "string"
                }
              }
            }
          },
          "template": {
            "type": "string"
          },
          "variables": {
            "type": "object",
            "description": "Values for `{{name}}` placeholders. Values are HTML-escaped. Variables named url/href/link must be http(s) or mailto links."
          },
          "unsubscribe": {
            "type": "boolean",
            "description": "Marks the message as marketing. Flinkk Mail adds a personal unsubscribe link and List-Unsubscribe headers, and skips people who unsubscribed. One recipient per message. Templates for marketing set this automatically. See /docs/unsubscribe."
          }
        }
      },
      "SendEmailResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        }
      },
      "Email": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bcc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reply_to": {
            "type": [
              "string",
              "null"
            ]
          },
          "subject": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_event": {
            "type": "string",
            "enum": [
              "sent",
              "delivered",
              "bounce",
              "complaint",
              "received"
            ],
            "description": "Latest delivery status"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Template": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "preset",
              "custom"
            ]
          },
          "description": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": [
              "string",
              "null"
            ]
          },
          "text": {
            "type": [
              "string",
              "null"
            ]
          },
          "variables": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "required": {
                  "type": "boolean"
                }
              }
            }
          },
          "design": {
            "type": "object",
            "description": "Block design from the visual editor: { v: 1, settings, blocks[] }. When present, html and text are generated from it on the server and replace any html/text you send. Up to 60 blocks.",
            "additionalProperties": true
          }
        }
      },
      "TemplateInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "subject"
        ],
        "description": "Provide html, text or both. Use `{{name}}` or `{{name | default}}` placeholders.",
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "design": {
            "type": "object",
            "description": "Block design from the visual editor: { v: 1, settings, blocks[] }. When present, html and text are generated from it on the server and replace any html/text you send. Up to 60 blocks.",
            "additionalProperties": true
          }
        }
      },
      "RenderedTemplate": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      },
      "Suppression": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "enum": [
              "bounce",
              "complaint",
              "manual",
              "unsubscribed"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AgentInboxInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80,
            "description": "The agent's name."
          },
          "username": {
            "type": "string",
            "description": "Local part of the address (3-30 characters: a-z, 0-9, dot, dash, underscore). Generated if omitted. Common role names such as postmaster, admin and support are reserved."
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "inbox:read",
                "inbox:draft",
                "inbox:send",
                "inbox:label"
              ]
            }
          },
          "mode": {
            "type": "string",
            "enum": [
              "draft_only",
              "auto_send"
            ],
            "default": "draft_only"
          },
          "daily_send_limit": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200,
            "default": 25
          },
          "allowed_recipients": {
            "type": "array",
            "maxItems": 25,
            "items": {
              "type": "string"
            },
            "description": "Exact addresses the agent may start conversations with. Without this the inbox is reply-only."
          }
        }
      },
      "AgentInbox": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "agent": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "status": {
                "type": "string"
              }
            }
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "type": "string"
          },
          "daily_send_limit": {
            "type": "integer"
          },
          "reply_only": {
            "type": "boolean"
          },
          "allowed_recipients": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "AgentInboxCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "address": {
            "type": "string",
            "example": "support-bot@agentmail.flinkk.io"
          },
          "agent": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "key": {
            "type": "object",
            "description": "Shown once. Use it as a Bearer token with the agent inbox API or the MCP server.",
            "properties": {
              "id": {
                "type": "string"
              },
              "value": {
                "type": "string"
              },
              "prefix": {
                "type": "string"
              }
            }
          },
          "grant": {
            "type": "object",
            "properties": {
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "mode": {
                "type": "string"
              },
              "daily_send_limit": {
                "type": "integer"
              },
              "reply_only": {
                "type": "boolean"
              },
              "allowed_recipients": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "note": {
            "type": "string"
          }
        }
      },
      "EmailSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_event": {
            "type": "string",
            "enum": [
              "sent",
              "delivered",
              "bounce",
              "complaint"
            ]
          },
          "opened": {
            "type": "boolean"
          },
          "clicks": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EmailDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_event": {
            "type": "string",
            "enum": [
              "sent",
              "delivered",
              "bounce",
              "complaint"
            ]
          },
          "opened": {
            "type": "boolean"
          },
          "clicks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "link": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "at": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "bcc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reply_to": {
            "type": [
              "string",
              "null"
            ]
          },
          "events": {
            "type": "array",
            "description": "Oldest first.",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "sent",
                    "delivered",
                    "bounced",
                    "complained",
                    "opened",
                    "clicked"
                  ]
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "details": {
                  "type": "object",
                  "description": "bounce_type, bounce_subtype, recipient, feedback_type, link, user_agent as relevant"
                }
              }
            }
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "email.sent",
                "email.delivered",
                "email.bounced",
                "email.complained",
                "email.opened",
                "email.clicked",
                "email.received",
                "thread.updated",
                "draft.pending_approval",
                "draft.approved"
              ]
            }
          },
          "enabled": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "secret": {
            "type": "string",
            "description": "Signing secret. Returned only when the endpoint is created."
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "delivered",
              "failed"
            ]
          },
          "attempts": {
            "type": "integer"
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "description": "The JSON body POSTed to your endpoint. Headers: `Flinkk-Signature: t=<unix>,v1=<hex>` (HMAC-SHA256 of `t.body` with your secret), `Flinkk-Event`, `Flinkk-Delivery`. Reply 2xx within 8 seconds; failures retry after 1m, 5m, 30m, 2h, 6h and 24h.",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "properties": {
              "emailId": {
                "type": "string"
              },
              "from": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "to": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "subject": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "occurredAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "bounceType": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "email.bounced: Permanent, Transient or Undetermined"
              },
              "bounceSubType": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "link": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "email.clicked"
              },
              "userAgent": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "email.opened and email.clicked"
              }
            }
          }
        }
      }
    }
  }
}
