{
  "openapi": "3.0.3",
  "info": {
    "title": "SendFox API",
    "description": "# Introduction\nSendFox's REST API lets you manage contacts, campaigns, lists, automations, and forms programmatically. It uses OAuth 2.0 for authentication.\n\nCompatible with AI agents (Claude, ChatGPT, etc.) via the OpenAPI spec. Available at `GET /openapi.yaml`.\n\n# Authentication\n### Personal Access Token\nCreate a personal access token at https://sendfox.com/account/oauth. Once created, use it in the `Authorization` header:\n```\nAuthorization: Bearer {TOKEN}\n```\n\n### OAuth 2.0 Client\nFor integrations that require user authentication, create an OAuth 2.0 client at https://sendfox.com/account/oauth\n\n* Authorization URL: https://sendfox.com/oauth/authorize\n* Access Token URL: https://sendfox.com/oauth/token\n\n# Rate Limits\nAPI requests are limited to **60 requests per minute** per authenticated user. Rate limit status is returned in response headers:\n- `X-RateLimit-Limit`: Maximum requests per minute\n- `X-RateLimit-Remaining`: Remaining requests in current window\n- `Retry-After`: Seconds until rate limit resets (only on 429 responses)\n\n# Error Responses\nAll error responses use standard HTTP status codes and Laravel's default error format:\n- `message`: Human-readable error description\n- `errors`: Field-level validation errors (on 422 responses)\n\n# Plans & API Access\nAPI access requires a **Lifetime** or **Empire** plan. Free users cannot use the API.\n",
    "version": "1.2.0",
    "x-logo": {
      "url": "/img/sendfox-logo.svg"
    }
  },
  "servers": [
    {
      "url": "https://api.sendfox.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://sendfox.com/oauth/authorize",
            "tokenUrl": "https://sendfox.com/oauth/token",
            "scopes": {}
          }
        }
      }
    },
    "schemas": {
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "ip_address": {
            "type": "string"
          },
          "unsubscribed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "email"
        ]
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "from_name": {
            "type": "string"
          },
          "from_email": {
            "type": "string",
            "format": "email"
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "timezone": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "title",
          "subject",
          "html",
          "from_name",
          "from_email"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Human-readable error description"
          },
          "errors": {
            "type": "object",
            "description": "Field-level validation errors (on 422 responses)",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "Form": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "landing_page_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "contacts_count": {
            "type": "integer"
          },
          "contact_limit": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UserContactField": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "user_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ContactList": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "user_id": {
            "type": "integer"
          },
          "average_email_open_percent": {
            "type": "number",
            "format": "float"
          },
          "average_email_click_percent": {
            "type": "number",
            "format": "float"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "name"
        ]
      },
      "Automation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "user_id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "automation_triggers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationTrigger"
            }
          },
          "automation_items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationItem"
            }
          }
        }
      },
      "AutomationTrigger": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "automation_id": {
            "type": "integer"
          },
          "type": {
            "type": "string",
            "enum": [
              "apply_list",
              "open_campaign",
              "click_campaign"
            ]
          },
          "list_id": {
            "type": "integer",
            "nullable": true
          },
          "campaign_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AutomationItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "automation_id": {
            "type": "integer"
          },
          "campaign_id": {
            "type": "integer"
          },
          "delay_hours": {
            "type": "integer"
          },
          "send_order": {
            "type": "integer"
          },
          "campaign": {
            "$ref": "#/components/schemas/Campaign"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CampaignStats": {
        "type": "object",
        "properties": {
          "sent_count": {
            "type": "integer"
          },
          "unique_open_count": {
            "type": "integer"
          },
          "unique_click_count": {
            "type": "integer"
          },
          "unsubscribe_count": {
            "type": "integer"
          },
          "bounce_count": {
            "type": "integer"
          },
          "spam_count": {
            "type": "integer"
          },
          "open_rate": {
            "type": "number",
            "format": "float"
          },
          "click_rate": {
            "type": "number",
            "format": "float"
          },
          "unsubscribe_rate": {
            "type": "number",
            "format": "float"
          },
          "bounce_rate": {
            "type": "number",
            "format": "float"
          },
          "spam_rate": {
            "type": "number",
            "format": "float"
          }
        }
      },
      "BatchResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer"
          },
          "updated": {
            "type": "integer"
          }
        }
      }
    }
  },
  "security": [
    {
      "oauth2": []
    }
  ],
  "paths": {
    "/contacts": {
      "get": {
        "operationId": "listContacts",
        "tags": [
          "Contacts"
        ],
        "summary": "List contacts",
        "description": "Returns a paginated list of contacts (100 per page)",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search query for filtering contacts"
          },
          {
            "name": "unsubscribed",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Filter unsubscribed contacts"
          },
          {
            "name": "email",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by specific email"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "createContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Create a new contact",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "ip_address": {
                    "type": "string"
                  },
                  "lists": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Array of list IDs to add the contact to"
                  },
                  "contact_fields": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Contact limit exceeded"
          }
        }
      }
    },
    "/contacts/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Get a specific contact",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      },
      "patch": {
        "operationId": "updateContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Update a contact",
        "description": "Update contact details including name, list memberships, and custom fields",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "lists": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Array of list IDs (replaces all current list memberships)"
                  },
                  "contact_fields": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Delete a contact",
        "description": "Soft-deletes a contact and cancels any scheduled deliverables",
        "responses": {
          "200": {
            "description": "Contact deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      }
    },
    "/contacts/{id}/activity": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getContactActivity",
        "tags": [
          "Contacts"
        ],
        "summary": "Get email activity for a contact",
        "description": "Returns paginated email deliverables and contact-level engagement summary",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "contact": {
                      "type": "object",
                      "properties": {
                        "last_sent_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_opened_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_clicked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "unsubscribed_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "bounced_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    },
                    "deliverables": {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "campaign_title": {
                                "type": "string"
                              },
                              "campaign_id": {
                                "type": "integer"
                              },
                              "sent_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "opened_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "clicked_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "bounced_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "unsubscribed_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "spam_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      }
    },
    "/contacts/batch": {
      "post": {
        "operationId": "batchImportContacts",
        "tags": [
          "Contacts"
        ],
        "summary": "Batch import contacts",
        "description": "Import up to 1,000 contacts in a single request. Creates new contacts or updates existing ones.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "contacts"
                ],
                "properties": {
                  "contacts": {
                    "type": "array",
                    "maxItems": 1000,
                    "items": {
                      "type": "object",
                      "required": [
                        "email"
                      ],
                      "properties": {
                        "email": {
                          "type": "string",
                          "format": "email"
                        },
                        "first_name": {
                          "type": "string"
                        },
                        "last_name": {
                          "type": "string"
                        },
                        "lists": {
                          "type": "array",
                          "items": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch import results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            }
          },
          "402": {
            "description": "Contact limit would be exceeded"
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/contacts/unsubscribed": {
      "get": {
        "operationId": "listUnsubscribedContacts",
        "tags": [
          "Contacts"
        ],
        "summary": "List unsubscribed contacts",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search query for filtering contacts"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/unsubscribe": {
      "patch": {
        "operationId": "unsubscribeContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Unsubscribe a contact by email",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact unsubscribed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns": {
      "get": {
        "operationId": "listCampaigns",
        "tags": [
          "Campaigns"
        ],
        "summary": "List campaigns",
        "description": "Returns a paginated list of campaigns (100 per page)",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Campaign"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createCampaign",
        "tags": [
          "Campaigns"
        ],
        "summary": "Create a new campaign",
        "description": "Creates a campaign as a draft. To send it, use the send endpoint or provide scheduled_at.\nSubject lines cannot start with \"RE:\" or \"FWD:\".\nAt least one list is required if scheduled_at is provided.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 191
                  },
                  "subject": {
                    "type": "string",
                    "maxLength": 191
                  },
                  "html": {
                    "type": "string",
                    "maxLength": 1000000,
                    "description": "Email body HTML content"
                  },
                  "from_name": {
                    "type": "string",
                    "maxLength": 191
                  },
                  "from_email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 191
                  },
                  "scheduled_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Schedule send time (omit for draft). Must include at least one list."
                  },
                  "lists": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Array of list IDs to send to"
                  }
                },
                "required": [
                  "title",
                  "subject",
                  "html",
                  "from_name",
                  "from_email"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campaign created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden (not subscribed or cannot schedule)"
          },
          "422": {
            "description": "Validation error or configuration required (e.g., timezone not set)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getCampaign",
        "tags": [
          "Campaigns"
        ],
        "summary": "Get a specific campaign",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Campaign not found"
          }
        }
      },
      "patch": {
        "operationId": "updateCampaign",
        "tags": [
          "Campaigns"
        ],
        "summary": "Update a draft campaign",
        "description": "Only draft campaigns (not yet sent) can be updated. All fields are optional.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 191
                  },
                  "subject": {
                    "type": "string",
                    "maxLength": 191
                  },
                  "html": {
                    "type": "string",
                    "maxLength": 1000000
                  },
                  "from_name": {
                    "type": "string",
                    "maxLength": 191
                  },
                  "from_email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 191
                  },
                  "scheduled_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "Set to null to unschedule, or a datetime to schedule"
                  },
                  "lists": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Replaces all list assignments"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Campaign updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "409": {
            "description": "Campaign already sent"
          },
          "422": {
            "description": "Validation error"
          }
        }
      },
      "delete": {
        "operationId": "deleteCampaign",
        "tags": [
          "Campaigns"
        ],
        "summary": "Delete a draft campaign",
        "description": "Only draft campaigns (not yet sent) can be deleted. Uses soft delete.",
        "responses": {
          "200": {
            "description": "Campaign deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "409": {
            "description": "Campaign already sent"
          }
        }
      }
    },
    "/campaigns/{id}/send": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "post": {
        "operationId": "sendCampaign",
        "tags": [
          "Campaigns"
        ],
        "summary": "Send a campaign immediately",
        "description": "Schedules a draft campaign for immediate sending. The campaign must:\n- Not already be sent or scheduled\n- Have at least one list assigned\n- The user must not be in a warmup/throttle period\n\nAll existing abuse prevention applies automatically: content approval workflow,\nsending throttles, spam detection, and bounce rate monitoring.\n",
        "responses": {
          "200": {
            "description": "Campaign scheduled for sending",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "400": {
            "description": "Campaign has no lists assigned"
          },
          "403": {
            "description": "Forbidden (cannot send or account warming up)"
          },
          "409": {
            "description": "Campaign already sent or scheduled"
          }
        }
      }
    },
    "/campaigns/{id}/stats": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getCampaignStats",
        "tags": [
          "Campaigns"
        ],
        "summary": "Get campaign performance statistics",
        "description": "Returns sent count, open/click/bounce/unsubscribe/spam counts and rates",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignStats"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Campaign not found"
          }
        }
      }
    },
    "/forms": {
      "get": {
        "operationId": "listForms",
        "tags": [
          "Forms"
        ],
        "summary": "List forms",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search query for filtering forms"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Form"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/forms/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getForm",
        "tags": [
          "Forms"
        ],
        "summary": "Get a specific form",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Form"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Form not found"
          }
        }
      }
    },
    "/me": {
      "get": {
        "operationId": "getCurrentUser",
        "tags": [
          "Users"
        ],
        "summary": "Get current user information",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/contact-fields": {
      "get": {
        "operationId": "listContactFields",
        "tags": [
          "Contact Fields"
        ],
        "summary": "List user contact fields",
        "description": "Returns custom contact fields defined by the user (20 per page)",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserContactField"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/lists": {
      "get": {
        "operationId": "listContactLists",
        "tags": [
          "Lists"
        ],
        "summary": "List contact lists",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search query for filtering lists"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ContactList"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "createContactList",
        "tags": [
          "Lists"
        ],
        "summary": "Create a new contact list",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "List created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactList"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/lists/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getContactList",
        "tags": [
          "Lists"
        ],
        "summary": "Get a specific contact list",
        "description": "Returns list details including average open and click rates",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactList"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "List not found"
          }
        }
      },
      "delete": {
        "operationId": "deleteContactList",
        "tags": [
          "Lists"
        ],
        "summary": "Delete a contact list",
        "description": "Soft-deletes a list. Returns 409 if the list is used by forms, landing pages, or automations.",
        "responses": {
          "200": {
            "description": "List deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "List not found"
          },
          "409": {
            "description": "List is in use",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "usages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "id": {
                            "type": "integer"
                          },
                          "title": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/lists/{list_id}/contacts": {
      "parameters": [
        {
          "name": "list_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "listContactsInList",
        "tags": [
          "Lists"
        ],
        "summary": "Get contacts in a list",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search query for filtering contacts"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          }
        }
      }
    },
    "/lists/{list_id}/contacts/{contact_id}": {
      "parameters": [
        {
          "name": "list_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        },
        {
          "name": "contact_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "delete": {
        "operationId": "removeContactFromList",
        "tags": [
          "Lists"
        ],
        "summary": "Remove a contact from a list",
        "responses": {
          "200": {
            "description": "Contact removed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Contact or list not found"
          }
        }
      }
    },
    "/automations": {
      "get": {
        "operationId": "listAutomations",
        "tags": [
          "Automations"
        ],
        "summary": "List automations",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Automation"
                      }
                    },
                    "current_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "createAutomation",
        "tags": [
          "Automations"
        ],
        "summary": "Create an automation",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "trigger_type": {
                    "type": "string",
                    "enum": [
                      "apply_list",
                      "open_campaign",
                      "click_campaign"
                    ]
                  },
                  "trigger_list_id": {
                    "type": "integer",
                    "description": "Required when trigger_type is apply_list"
                  },
                  "trigger_campaign_id": {
                    "type": "integer",
                    "description": "Required when trigger_type is open_campaign or click_campaign"
                  },
                  "active": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Automation created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Automation"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden (free users)"
          },
          "422": {
            "description": "Validation error"
          }
        }
      }
    },
    "/automations/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "get": {
        "operationId": "getAutomation",
        "tags": [
          "Automations"
        ],
        "summary": "Get a specific automation",
        "description": "Returns automation with triggers, items, and campaign stats",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Automation"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Automation not found"
          }
        }
      },
      "patch": {
        "operationId": "updateAutomation",
        "tags": [
          "Automations"
        ],
        "summary": "Update an automation",
        "description": "Update title, trigger, or active status. Activating reschedules stale deliverables.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "active": {
                    "type": "boolean"
                  },
                  "trigger_type": {
                    "type": "string",
                    "enum": [
                      "apply_list",
                      "open_campaign",
                      "click_campaign"
                    ]
                  },
                  "trigger_list_id": {
                    "type": "integer"
                  },
                  "trigger_campaign_id": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Automation updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Automation"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "422": {
            "description": "Validation error"
          }
        }
      },
      "delete": {
        "operationId": "deleteAutomation",
        "tags": [
          "Automations"
        ],
        "summary": "Delete an automation",
        "description": "Soft-deletes the automation and cancels all scheduled deliverables",
        "responses": {
          "200": {
            "description": "Automation deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Automation not found"
          }
        }
      }
    },
    "/automations/{id}/emails": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "post": {
        "operationId": "createAutomationEmail",
        "tags": [
          "Automations"
        ],
        "summary": "Add an email to an automation",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "html",
                  "from_name",
                  "from_email"
                ],
                "properties": {
                  "subject": {
                    "type": "string"
                  },
                  "html": {
                    "type": "string"
                  },
                  "from_name": {
                    "type": "string"
                  },
                  "from_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "delay_hours": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 5000,
                    "description": "Hours to wait before sending (default 24, first email defaults to 0)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Automation email created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutomationItem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "422": {
            "description": "Validation error"
          }
        }
      }
    },
    "/automation-emails/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          }
        }
      ],
      "patch": {
        "operationId": "updateAutomationEmail",
        "tags": [
          "Automations"
        ],
        "summary": "Update an automation email",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string"
                  },
                  "html": {
                    "type": "string"
                  },
                  "from_name": {
                    "type": "string"
                  },
                  "from_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "delay_hours": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 5000
                  },
                  "send_order": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Automation email updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutomationItem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "422": {
            "description": "Validation error"
          }
        }
      },
      "delete": {
        "operationId": "deleteAutomationEmail",
        "tags": [
          "Automations"
        ],
        "summary": "Remove an email from an automation",
        "responses": {
          "200": {
            "description": "Automation email deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Automation email not found"
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "Resources",
      "tags": [
        "Contacts",
        "Campaigns",
        "Lists",
        "Forms",
        "Automations",
        "Users",
        "Contact Fields"
      ]
    }
  ]
}