{
  "openapi": "3.1.0",
  "info": {
    "title": "Leads Puller Developer API",
    "version": "1.0.0",
    "description": "Programmatic access to People Search and Company Search. Uses the same search engine as the dashboard. Authenticate search requests with an API key. Manage keys with a dashboard JWT session."
  },
  "servers": [
    {
      "url": "/api/v1",
      "description": "Developer API v1"
    }
  ],
  "tags": [
    { "name": "People", "description": "People (employee) search" },
    { "name": "Companies", "description": "Company search" },
    { "name": "API Keys", "description": "API key management (JWT session)" }
  ],
  "paths": {
    "/people/search": {
      "post": {
        "tags": ["People"],
        "summary": "Search people",
        "description": "Search employee records. Business type filters via related company. Emails are locked unless previously revealed. Costs credits per successful request.",
        "operationId": "searchPeople",
        "security": [{ "ApiKeyAuth": [] }, { "ApiKeyBearer": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SearchRequest" },
              "example": {
                "businessType": "HVAC",
                "location": "United States (US)",
                "page": 1,
                "limit": 25
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results",
            "headers": {
              "X-RateLimit-Limit": { "schema": { "type": "integer" } },
              "X-RateLimit-Remaining": { "schema": { "type": "integer" } },
              "X-RateLimit-Reset": { "schema": { "type": "integer" } }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "400": { "$ref": "#/components/responses/ValidationError" }
        }
      }
    },
    "/companies/search": {
      "post": {
        "tags": ["Companies"],
        "summary": "Search companies",
        "description": "Search company records. Location may resolve via related employees. Costs credits per successful request.",
        "operationId": "searchCompanies",
        "security": [{ "ApiKeyAuth": [] }, { "ApiKeyBearer": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SearchRequest" },
              "example": {
                "businessType": "HVAC",
                "location": "Austin",
                "page": 1,
                "limit": 25
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results",
            "headers": {
              "X-RateLimit-Limit": { "schema": { "type": "integer" } },
              "X-RateLimit-Remaining": { "schema": { "type": "integer" } },
              "X-RateLimit-Reset": { "schema": { "type": "integer" } }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchResponse" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "400": { "$ref": "#/components/responses/ValidationError" }
        }
      }
    },
    "/keys": {
      "get": {
        "tags": ["API Keys"],
        "summary": "List API keys",
        "security": [{ "BearerJwt": [] }],
        "responses": {
          "200": {
            "description": "Key list (secrets never included)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "keys": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/ApiKeyPublic" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "post": {
        "tags": ["API Keys"],
        "summary": "Create API key",
        "security": [{ "BearerJwt": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": { "type": "string", "maxLength": 100 }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created; secret returned once",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiKeyCreated" }
              }
            }
          }
        }
      }
    },
    "/keys/{id}": {
      "patch": {
        "tags": ["API Keys"],
        "summary": "Rename API key",
        "security": [{ "BearerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name": { "type": "string", "maxLength": 100 }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Updated key metadata" }
        }
      },
      "delete": {
        "tags": ["API Keys"],
        "summary": "Revoke API key",
        "security": [{ "BearerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": { "description": "Key revoked" }
        }
      }
    },
    "/keys/{id}/regenerate": {
      "post": {
        "tags": ["API Keys"],
        "summary": "Regenerate API key secret",
        "security": [{ "BearerJwt": [] }],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "New secret returned once",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiKeyCreated" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Developer API key (lp_live_…)"
      },
      "ApiKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Same API key as Bearer token (lp_live_…)"
      },
      "BearerJwt": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Dashboard session JWT for key management"
      }
    },
    "schemas": {
      "SearchRequest": {
        "type": "object",
        "properties": {
          "businessType": { "type": "string", "description": "Business type / keywords (comma-separated)" },
          "location": { "type": "string" },
          "website": { "type": "string" },
          "websiteStatus": { "type": "string", "enum": ["any", "has", "no"] },
          "companyName": { "type": "string" },
          "companyDomain": { "type": "string" },
          "businessEmail": { "type": "string" },
          "businessPhone": { "type": "string" },
          "descriptionKeywords": { "type": "string" },
          "jobTitles": { "type": "array", "items": { "type": "string" } },
          "excludeKeywords": { "type": "string" },
          "searchTags": { "type": "array", "items": { "type": "string" } },
          "newBusiness": { "type": "string", "enum": ["any", "yes", "no"] },
          "infoUpdatedFrom": { "type": "string", "format": "date" },
          "infoUpdatedTo": { "type": "string", "format": "date" },
          "page": { "type": "integer", "minimum": 1, "default": 1 },
          "limit": { "type": "integer", "minimum": 1, "maximum": 250, "default": 25 },
          "cursor": { "type": ["string", "null"] },
          "sort": {
            "type": "object",
            "properties": {
              "field": { "type": "string" },
              "dir": { "type": "string", "enum": ["asc", "desc"] }
            }
          },
          "fields": { "type": "array", "items": { "type": "string" } }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "object",
            "properties": {
              "rows": { "type": "array", "items": { "type": "object" } },
              "total": { "type": "integer" },
              "page": { "type": "integer" },
              "limit": { "type": "integer" },
              "nextCursor": { "type": ["string", "null"] },
              "paginationMode": { "type": "string" },
              "sort": { "type": "object" }
            }
          },
          "credits": {
            "type": "object",
            "properties": {
              "cost": { "type": "integer" },
              "balance": { "type": "integer" }
            }
          }
        }
      },
      "ApiKeyPublic": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "keyPrefix": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" },
          "lastUsedAt": { "type": ["string", "null"], "format": "date-time" },
          "revokedAt": { "type": ["string", "null"], "format": "date-time" },
          "active": { "type": "boolean" }
        }
      },
      "ApiKeyCreated": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "key": { "$ref": "#/components/schemas/ApiKeyPublic" },
          "secret": { "type": "string", "description": "Full API key; shown only once" },
          "message": { "type": "string" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "const": false },
          "code": { "type": "string" },
          "message": { "type": "string" }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid credentials",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "success": false,
              "code": "INVALID_API_KEY",
              "message": "Invalid API key"
            }
          }
        }
      },
      "InsufficientCredits": {
        "description": "Not enough credits",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "success": false,
              "code": "INSUFFICIENT_CREDITS",
              "message": "Insufficient credits"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": {
              "success": false,
              "code": "RATE_LIMIT_EXCEEDED",
              "message": "Developer API rate limit exceeded. Try again later."
            }
          }
        }
      },
      "ValidationError": {
        "description": "Invalid request body",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": { "type": "boolean" },
                "code": { "type": "string" },
                "message": { "type": "string" },
                "issues": { "type": "array" }
              }
            }
          }
        }
      }
    }
  }
}
