# LeadContactInfo API

Production contact and company intelligence API.

- Base URL: https://api.leadcontactinfo.com
- Interactive Documentation: https://api.leadcontactinfo.com/docs
- OpenAPI 3.1 JSON: https://api.leadcontactinfo.com/openapi.json
- Authentication: Authorization: Bearer lci_live_YOUR_KEY
- Content Type For POST Requests: application/json

## Access And Limits

| Plan | API Credits | Rate Limit |
| --- | ---: | ---: |
| Pay As You Go | No API Access | — |
| Unlimited | 1,000 Per 28-Day Billing Period | 500/Minute For Email, Phone, And Reverse Search; 150/Minute For Domain Search; 60/Minute For Contact And Company Finder |
| API | Unlimited | 3,000/Minute Per Key On Every Protected Endpoint |

Rate-limit response headers are X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Billable responses also include X-Credits-Used and, for limited access, X-Credits-Remaining.

Use a unique Idempotency-Key header on POST requests. LeadContactInfo replays the original encrypted-at-rest response for a completed retry instead of making another upstream call or charging again.

## Authentication

Generate, copy, rotate, and revoke keys under Dashboard → API. A secret is displayed only once and stored only as a SHA-256 hash.

```bash
curl 'https://api.leadcontactinfo.com/api/employees/search?linkedin_url=https%3A%2F%2Flinkedin.com%2Fin%2Fusername' \
  --header 'Authorization: Bearer lci_live_YOUR_KEY'
```

## Response Envelope

```json
{
  "success": true,
  "message": "Employees fetched",
  "code": 200,
  "data": {},
  "meta": {
    "credits_used": 1,
    "remaining_credits": 999
  }
}
```

Common errors: 400 invalid JSON or parameter combination, 401 missing/invalid/revoked key, 402 insufficient limited-plan credits, 403 API access unavailable, 415 invalid content type, 422 validation error, 429 rate limited, 503 data service unavailable, and 504 timeout.

## GET /api/employees/search

Email Search. Provide linkedin_url, or provide company_url + first_name + last_name. If all four are supplied, LinkedIn is attempted first. One credit is charged only when a verified email is returned.

Query parameters:

- linkedin_url: Exact LinkedIn profile URL.
- company_url: Company URL or domain.
- first_name: Employee first name.
- last_name: Employee last name.

## GET /api/employees/phone-search

Phone Search. Identification rules match Email Search. One credit is charged only when a phone is returned. A no-result response has credits_used: 0 and reason: PHONE_NOT_FOUND.

## GET /api/employees/email-search

Reverse Email Lookup. Required query parameter: email. Returns one best matching employee. One credit is charged only on a match. A no-result response has credits_used: 0 and reason: EMAIL_NOT_FOUND.

## GET /api/employees/dataset-search

Domain Search. Required company_url; optional title, page (default 1), and has_email. Returns up to 20 contacts per page.

- With title: one credit per returned contact on the current page that contains email or phone data.
- Without title: a flat one credit for a non-empty page.
- Empty pages cost zero credits.

## POST /api/employees/contact-finder

Free masked-contact discovery endpoint. It never returns personal email or phone values and always uses zero credits.

Top-level fields: page (default 1), per_page (default 10, maximum 100), has_email, has_phone, plus filter objects for title, locality, company_name, company_url, number_of_employees, revenue, city, country_code, industry_linkedin, bio_li, and services.

Each filter accepts include and exclude arrays of no more than 50 strings. Values within one include list use OR; active dimensions use AND. At least one non-empty filter or true data-availability flag is required.

```bash
curl --request POST 'https://api.leadcontactinfo.com/api/employees/contact-finder' \
  --header 'Authorization: Bearer lci_live_YOUR_KEY' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: contact-search-2026-08-11-001' \
  --data '{"title":{"include":["CEO","Founder"],"exclude":["Assistant"]},"country_code":{"include":["US"],"exclude":[]},"has_email":true,"page":1,"per_page":25}'
```

## POST /api/companies/company-finder

Company discovery across home-page text, LinkedIn description, services, industry, employee range, revenue, country, city, company URL, and company name. One credit is charged per company returned. page defaults to 1; per_page defaults to 10 and has a maximum of 100. include_full_text optionally returns full website text.

Reserve logic uses per_page as the maximum possible charge before the call and settles to the exact number of companies actually returned.

## Public Lookup Endpoints

No key or data credits are required:

- GET /api/lookups/country-codes
- GET /api/lookups/industries
- GET /api/lookups/employee-ranges
- GET /api/lookups/employee-bands
- GET /api/lookups/revenue-ranges
- GET /api/lookups/company-services?q=software

Always use live lookup values for validated filters. Some upstream accepted values intentionally differ from common display formats.

## Employee Fields

Responses may include first_name, last_name, title, email, employee_phone, employee_phone_type, employee_linkedin, email_verification_date, company_url, company_name, email_domain, company_linkedin, company_phone, industry, revenue, employee_count, address, city, region_code, zip, and country_code.

## Operational Guidance

- Keep API keys server-side and never commit them to source control.
- Set a unique Idempotency-Key for every logical POST operation and reuse it only when retrying that same operation.
- Honor 429 Retry-After and X-RateLimit-Reset instead of retrying immediately.
- Treat 5xx responses as retryable with exponential backoff.
- Do not infer a charge from HTTP status alone; read X-Credits-Used or meta.credits_used.
- Download the canonical OpenAPI document for generated clients and schema validation.
