{
  "openapi": "3.0.3",
  "info": {
    "title": "LinkFinder AI API",
    "description": "LinkFinder AI turns a name, email, company, domain or LinkedIn URL into verified\ncontact and company data.\n\n**One endpoint.** Every operation is a `POST /` with a `type` field selecting the\nlookup. There are no per-operation paths — `type` is the discriminator.\n\n## Operations\n\n| `type` | Credits | Input | Mode |\n|---|---|---|---|\n| `lead_full_name_to_linkedin_url` | 1 | Person's full name and company, space-joined into one string | sync |\n| `email_to_linkedin_url` | 5 | A professional email address | sync |\n| `linkedin_profile_to_email` | 10 | A LinkedIn person profile URL | sync |\n| `linkedin_profile_to_phone` | 50 | A LinkedIn person profile URL | sync |\n| `linkedin_profile_to_linkedin_info` | 10 | A LinkedIn person profile URL | async |\n| `lead_full_name_to_email` | 7 | Person's full name and company, space-joined into one string | sync |\n| `company_name_to_website` | 1 | A company name | sync |\n| `company_name_to_email` | 1 | A company name | sync |\n| `company_name_to_phone` | 1 | A company name | sync |\n| `company_name_to_linkedin_url` | 1 | A company name | sync |\n| `company_name_to_employee_count` | 1 | A company name | sync |\n| `company_name_to_employees` | 1 | A company name | async |\n| `company_domain_to_employees` | 1 | A company domain (not a name) | async |\n| `linkedin_company_to_linkedin_info` | 6 | A LinkedIn company page URL | sync |\n| `linkedin_company_to_employee_count` | 1 | A LinkedIn company page URL | sync |\n| `linkedin_company_to_employees` | 1 | A LinkedIn company page URL | async |\n| `linkedin_post_to_reactions` | 1 | A LinkedIn post URL | sync |\n| `b2b_data_lookup` | 1 | Any company or person identifier when you don't know its type | sync |\n| `instagram_lookup` | 1 | An Instagram handle or profile URL | sync |\n\n**Credits are charged per call, including calls that find nothing.** Cost varies by\noperation from 1 to 50 credits — do not assume 1. Operations returning employee lists\nare billed at 0.5 credits per employee returned rather than a flat fee.\n\n## Synchronous vs asynchronous\n\nMost operations return `200` with the result inline. Some return `202` with a `job_id`\nand `poll_url`; poll `GET /status/{job_id}` every ~2s until `status` is `done` or\n`error`. `linkedin_profile_to_linkedin_info` is always async; any operation may return\n`202` under load, so **always handle the 202 branch**. Job results expire after 10\nminutes.\n\n## Errors\n\n`401` invalid/missing key · `402` insufficient credits · `422` bad type or input ·\n`429` rate limited · `5xx` retry in ~30s.\n",
    "version": "1.1.0",
    "contact": {
      "name": "LinkFinder AI Support",
      "url": "https://linkfinderai.com"
    }
  },
  "servers": [
    {
      "url": "https://api.linkfinderai.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/": {
      "post": {
        "operationId": "enrich",
        "summary": "Run an enrichment",
        "description": "Single entry point for all operations. Set `type` to choose one; see the table in the API description for costs, inputs and sync/async mode.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnrichmentRequest"
              },
              "examples": {
                "lead_full_name_to_linkedin_url": {
                  "summary": "lead_full_name_to_linkedin_url (1 credit)",
                  "value": {
                    "type": "lead_full_name_to_linkedin_url",
                    "input_data": "Bill Gates Microsoft"
                  }
                },
                "email_to_linkedin_url": {
                  "summary": "email_to_linkedin_url (5 credits)",
                  "value": {
                    "type": "email_to_linkedin_url",
                    "input_data": "john.doe@company.com"
                  }
                },
                "linkedin_profile_to_email": {
                  "summary": "linkedin_profile_to_email (10 credits)",
                  "value": {
                    "type": "linkedin_profile_to_email",
                    "input_data": "https://www.linkedin.com/in/someone"
                  }
                },
                "linkedin_profile_to_phone": {
                  "summary": "linkedin_profile_to_phone (50 credits)",
                  "value": {
                    "type": "linkedin_profile_to_phone",
                    "input_data": "https://www.linkedin.com/in/someone"
                  }
                },
                "linkedin_profile_to_linkedin_info": {
                  "summary": "linkedin_profile_to_linkedin_info (10 credits)",
                  "value": {
                    "type": "linkedin_profile_to_linkedin_info",
                    "input_data": "https://www.linkedin.com/in/someone"
                  }
                },
                "lead_full_name_to_email": {
                  "summary": "lead_full_name_to_email (7 credits)",
                  "value": {
                    "type": "lead_full_name_to_email",
                    "input_data": "Bill Gates Microsoft"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result returned inline",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "202": {
            "description": "Accepted for async processing — poll /status/{job_id}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncAcceptedResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unknown type or malformed input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/status/{job_id}": {
      "get": {
        "operationId": "getJobStatus",
        "summary": "Poll an async job",
        "description": "Poll with the `job_id` from a 202 response until `status` is `done` or `error`. Results expire 10 minutes after completion.",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "job_id from the 202 response"
          }
        ],
        "responses": {
          "200": {
            "description": "Job status or result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "Job not found or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key as a Bearer token. Server-side only — never expose it client-side."
      }
    },
    "schemas": {
      "EnrichmentRequest": {
        "type": "object",
        "required": [
          "type",
          "input_data"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Which operation to run. See the table in the API description for cost and input format.",
            "enum": [
              "lead_full_name_to_linkedin_url",
              "email_to_linkedin_url",
              "linkedin_profile_to_email",
              "linkedin_profile_to_phone",
              "linkedin_profile_to_linkedin_info",
              "lead_full_name_to_email",
              "company_name_to_website",
              "company_name_to_email",
              "company_name_to_phone",
              "company_name_to_linkedin_url",
              "company_name_to_employee_count",
              "company_name_to_employees",
              "company_domain_to_employees",
              "linkedin_company_to_linkedin_info",
              "linkedin_company_to_employee_count",
              "linkedin_company_to_employees",
              "linkedin_post_to_reactions",
              "b2b_data_lookup",
              "instagram_lookup"
            ]
          },
          "input_data": {
            "type": "string",
            "minLength": 1,
            "description": "The input, formatted for the chosen type. Name-based person lookups take full name and company space-joined, e.g. \"Bill Gates Microsoft\"."
          },
          "department": {
            "type": "string",
            "description": "Employee-list operations only — filter by department."
          },
          "seniority": {
            "type": "string",
            "description": "Employee-list operations only — filter by seniority."
          },
          "employee_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Employee-list operations only — cap how many employees to return. Billed 0.5 credits each."
          }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "success"
            ]
          },
          "result": {
            "type": "object",
            "nullable": true,
            "description": "The data found. `null` when nothing was found — the call is still charged."
          }
        }
      },
      "AsyncAcceptedResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "processing"
            ]
          },
          "job_id": {
            "type": "string"
          },
          "poll_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "JobStatusResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "done",
              "error"
            ]
          },
          "result": {
            "type": "object",
            "nullable": true
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "error"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "x-linkfinder-operations": {
    "lead_full_name_to_linkedin_url": {
      "credits": 1,
      "input": "Person's full name and company, space-joined into one string.",
      "example": "Bill Gates Microsoft",
      "async": false,
      "note": "Most-used operation. 348 users / 10,140 calls in the last 30 days."
    },
    "email_to_linkedin_url": {
      "credits": 5,
      "input": "A professional email address.",
      "example": "john.doe@company.com",
      "async": false
    },
    "linkedin_profile_to_email": {
      "credits": 10,
      "input": "A LinkedIn person profile URL.",
      "example": "https://www.linkedin.com/in/someone",
      "async": false
    },
    "linkedin_profile_to_phone": {
      "credits": 50,
      "input": "A LinkedIn person profile URL.",
      "example": "https://www.linkedin.com/in/someone",
      "async": false,
      "note": "Most expensive operation — surface the cost before calling it."
    },
    "linkedin_profile_to_linkedin_info": {
      "credits": 10,
      "input": "A LinkedIn person profile URL.",
      "example": "https://www.linkedin.com/in/someone",
      "async": true,
      "note": "ALWAYS asynchronous — returns 202 with a job_id."
    },
    "lead_full_name_to_email": {
      "credits": 7,
      "input": "Person's full name and company, space-joined into one string.",
      "example": "Bill Gates Microsoft",
      "async": false
    },
    "company_name_to_website": {
      "credits": 1,
      "input": "A company name.",
      "example": "Tesla",
      "async": false
    },
    "company_name_to_email": {
      "credits": 1,
      "input": "A company name.",
      "example": "Tesla",
      "async": false
    },
    "company_name_to_phone": {
      "credits": 1,
      "input": "A company name.",
      "example": "Tesla",
      "async": false
    },
    "company_name_to_linkedin_url": {
      "credits": 1,
      "input": "A company name.",
      "example": "Tesla",
      "async": false
    },
    "company_name_to_employee_count": {
      "credits": 1,
      "input": "A company name.",
      "example": "Tesla",
      "async": false
    },
    "company_name_to_employees": {
      "credits": 1,
      "input": "A company name.",
      "example": "Tesla",
      "async": true,
      "note": "Billed at 0.5 credits per employee returned, not a flat fee."
    },
    "company_domain_to_employees": {
      "credits": 1,
      "input": "A company domain (not a name).",
      "example": "tesla.com",
      "async": true,
      "note": "Billed at 0.5 credits per employee returned. Accepts department, seniority and employee_count filters."
    },
    "linkedin_company_to_linkedin_info": {
      "credits": 6,
      "input": "A LinkedIn company page URL.",
      "example": "https://www.linkedin.com/company/tesla-motors",
      "async": false
    },
    "linkedin_company_to_employee_count": {
      "credits": 1,
      "input": "A LinkedIn company page URL.",
      "example": "https://www.linkedin.com/company/tesla-motors",
      "async": false
    },
    "linkedin_company_to_employees": {
      "credits": 1,
      "input": "A LinkedIn company page URL.",
      "example": "https://www.linkedin.com/company/tesla-motors",
      "async": true,
      "note": "Billed at 0.5 credits per employee returned."
    },
    "linkedin_post_to_reactions": {
      "credits": 1,
      "input": "A LinkedIn post URL.",
      "example": "https://www.linkedin.com/posts/someone_activity-123",
      "async": false
    },
    "b2b_data_lookup": {
      "credits": 1,
      "input": "Any company or person identifier when you don't know its type. Prefer a specific operation when you do.",
      "example": "tesla.com",
      "async": false,
      "note": "General-purpose fallback — less reliable than a specific type."
    },
    "instagram_lookup": {
      "credits": 1,
      "input": "An Instagram handle or profile URL.",
      "example": "@nasa",
      "async": false
    }
  }
}
