{
  "openapi": "3.1.0",
  "info": {
    "title": "EmailFinder API",
    "description": "Find verified email addresses for any person, company, LinkedIn profile, or decision maker. Every lookup performs real-time SMTP verification. Credits are charged only when a verified email is found.",
    "version": "1.0.0",
    "contact": { "name": "EmailFinder Support", "email": "support@emailfinder.dev" }
  },
  "servers": [{ "url": "https://www.emailfinder.dev", "description": "Production" }],
  "security": [{ "bearerAuth": [] }],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API token from the dashboard. Include as: Authorization: Bearer ef_live_xxx"
      }
    },
    "schemas": {
      "PersonEmailResponse": {
        "type": "object",
        "properties": {
          "credits_charged": { "type": "integer", "description": "Credits deducted (0 if not found)", "example": 1 },
          "input": { "type": "object", "description": "Echo of your input parameters" },
          "valid_email": { "type": "string", "description": "Verified email address", "example": "satyan@microsoft.com" }
        }
      },
      "CompanyEmailsResponse": {
        "type": "object",
        "properties": {
          "credits_charged": { "type": "integer", "description": "Credits deducted (0 if none found)", "example": 5 },
          "input": { "type": "object", "description": "Echo of your input parameters" },
          "valid_emails": { "type": "array", "items": { "type": "string" }, "description": "Up to 20 verified email addresses", "example": ["patrick@stripe.com", "john@stripe.com"] }
        }
      },
      "LinkedInEmailResponse": {
        "type": "object",
        "properties": {
          "credits_charged": { "type": "integer", "example": 1 },
          "input": { "type": "object" },
          "valid_email": { "type": "string", "example": "satyan@microsoft.com" },
          "person_full_name": { "type": "string", "example": "Satya Nadella" },
          "person_job_title": { "type": "string", "example": "Chairman and CEO" },
          "person_company_name": { "type": "string", "example": "Microsoft" }
        }
      },
      "DecisionMakerResponse": {
        "type": "object",
        "properties": {
          "credits_charged": { "type": "integer", "example": 5 },
          "input": { "type": "object" },
          "valid_email": { "type": "string", "example": "patrick@stripe.com" },
          "person_full_name": { "type": "string", "example": "Patrick Collison" },
          "person_job_title": { "type": "string", "example": "CEO" },
          "person_company_name": { "type": "string", "example": "Stripe" },
          "person_linkedin_url": { "type": "string", "example": "https://www.linkedin.com/in/patrickcollison" },
          "decision_maker_category": { "type": "string", "example": "ceo" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "example": "Unauthorized" }
        }
      }
    }
  },
  "paths": {
    "/api/find-email/person": {
      "get": {
        "operationId": "findPersonEmail",
        "summary": "Find Person Email",
        "description": "Find a verified email address by person name and company domain. Costs 1 credit per verified result. Not-found results are free.",
        "tags": ["Email Lookup"],
        "parameters": [
          { "name": "full_name", "in": "query", "schema": { "type": "string" }, "description": "Full name (use this OR first_name + last_name)", "example": "Satya Nadella" },
          { "name": "first_name", "in": "query", "schema": { "type": "string" }, "description": "First name (alternative to full_name)", "example": "Satya" },
          { "name": "last_name", "in": "query", "schema": { "type": "string" }, "description": "Last name (required with first_name)", "example": "Nadella" },
          { "name": "domain", "in": "query", "schema": { "type": "string" }, "description": "Company domain (preferred over company_name)", "example": "microsoft.com" },
          { "name": "company_name", "in": "query", "schema": { "type": "string" }, "description": "Company name (alternative to domain)", "example": "Microsoft" }
        ],
        "responses": {
          "200": { "description": "Verified email found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PersonEmailResponse" } } } },
          "400": { "description": "Invalid or missing parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "401": { "description": "Missing or invalid API token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "402": { "description": "Insufficient credits", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "403": { "description": "Account suspended", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "404": { "description": "No verified email found (0 credits charged)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PersonEmailResponse" } } } },
          "429": { "description": "Rate limit exceeded (max 1,000 requests per minute)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/api/find-email/company": {
      "get": {
        "operationId": "findCompanyEmails",
        "summary": "Find Company Emails",
        "description": "Discover up to 20 verified email addresses at a company domain. Costs 5 credits per successful result. Returns empty array if none found (0 credits charged).",
        "tags": ["Email Lookup"],
        "parameters": [
          { "name": "domain", "in": "query", "schema": { "type": "string" }, "description": "Company domain (preferred)", "example": "stripe.com" },
          { "name": "company_name", "in": "query", "schema": { "type": "string" }, "description": "Company name (alternative to domain)", "example": "Stripe" }
        ],
        "responses": {
          "200": { "description": "Verified emails found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompanyEmailsResponse" } } } },
          "400": { "description": "Invalid or missing parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "401": { "description": "Missing or invalid API token" },
          "402": { "description": "Insufficient credits" },
          "403": { "description": "Account suspended" },
          "404": { "description": "No emails found (0 credits charged)" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/api/find-email/linkedin": {
      "get": {
        "operationId": "findLinkedInEmail",
        "summary": "Find Email by LinkedIn URL",
        "description": "Extract a verified email address from a LinkedIn profile URL. Returns person details (name, title, company). Costs 1 credit per verified result.",
        "tags": ["Email Lookup"],
        "parameters": [
          { "name": "linkedin_url", "in": "query", "required": true, "schema": { "type": "string" }, "description": "LinkedIn profile URL", "example": "https://www.linkedin.com/in/satyanadella" }
        ],
        "responses": {
          "200": { "description": "Verified email found with person details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkedInEmailResponse" } } } },
          "400": { "description": "Invalid or missing LinkedIn URL" },
          "401": { "description": "Missing or invalid API token" },
          "402": { "description": "Insufficient credits" },
          "403": { "description": "Account suspended" },
          "404": { "description": "No verified email found (0 credits charged)" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/api/find-email/decision-maker": {
      "get": {
        "operationId": "findDecisionMakerEmail",
        "summary": "Find Decision Maker Email",
        "description": "Find the verified email of a decision maker at a company by role category. Returns person details and LinkedIn URL when available. Costs 5 credits per verified result.",
        "tags": ["Email Lookup"],
        "parameters": [
          { "name": "domain", "in": "query", "schema": { "type": "string" }, "description": "Company domain (preferred)", "example": "stripe.com" },
          { "name": "company_name", "in": "query", "schema": { "type": "string" }, "description": "Company name (alternative to domain)", "example": "Stripe" },
          { "name": "decision_maker_category", "in": "query", "required": true, "schema": { "type": "array", "items": { "type": "string", "enum": ["ceo","engineering","finance","hr","it","logistics","marketing","operations","buyer","sales"] } }, "description": "One or more role categories", "example": ["ceo"] }
        ],
        "responses": {
          "200": { "description": "Decision maker found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DecisionMakerResponse" } } } },
          "400": { "description": "Invalid or missing parameters" },
          "401": { "description": "Missing or invalid API token" },
          "402": { "description": "Insufficient credits" },
          "403": { "description": "Account suspended" },
          "404": { "description": "No decision maker found (0 credits charged)" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    }
  }
}
