Download the PHP package jcolombo/leadfeeder-api-php without Composer

On this page you can find all versions of the php package jcolombo/leadfeeder-api-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package leadfeeder-api-php

Leadfeeder API for PHP

Latest Version PHP Version GitHub Issues


Overview

This independently developed package provides a developer-friendly PHP toolkit for interacting with the Leadfeeder API. It is not affiliated with or endorsed by Leadfeeder / Dealfront.

Leadfeeder Homepage: https://www.leadfeeder.com API Documentation: https://docs.leadfeeder.com/api/

Stability Notice: This package is in active development (v0.x-alpha). The API surface may change before v1.0. Pin to ^0.x in production.


Features


Requirements


Installation

The package is published on Packagist and follows standard PSR-4 autoloading under the Jcolombo\LeadfeederApiPhp namespace. No additional configuration is required to get started — sensible defaults are loaded automatically from the bundled default.leadfeederapi.config.json.


Quick Start

Connecting and Selecting an Account

Authentication is Bearer token–based. Call Leadfeeder::connect() once with your token. The connection is cached as a singleton, so calling it again with the same token returns the same instance. Most API endpoints are scoped to a specific account ID, which you provide via setAccount().

Fetching Leads

Lead list requests require a date range. The dateRange() method sets the start_date and end_date server-side filters in a single call. Without a date range the Leadfeeder API will return an error; in devMode the SDK emits a warning before the request is sent.

Fetching Visits

Visit lists are also date-range-required. You can iterate over a collection directly with a foreach loop because collections implement the Iterator interface.


Supported Resources

The SDK models six Leadfeeder API entities. Each resource class lives under Jcolombo\LeadfeederApiPhp\Entity\Resource\.

Resource Class Scope Pattern Notes
Account Account Token list(), fetch($id) Lists all accounts for the token
Lead Lead Account list(), fetch($id) Date range required for list
Visit Visit Account list(), fetch($id) Date range required for list
CustomFeed CustomFeed Account list(), fetch($id) Read-only feed definitions
Location Location Include-only Resolved via include Cannot be fetched or listed directly
WebsiteTrackingScript WebsiteTrackingScript Account fetch() (singleton) list() throws RuntimeException

Account requests are token-scoped (no account ID needed). All other requests are automatically prefixed with accounts/{accountId}/ when an account has been set on the connection. The Location entity is resolved only as a relationship include on Lead and Visit responses — it has no standalone API endpoint.


Date Range Filtering

The Leadfeeder API requires start_date and end_date parameters on Lead and Visit list requests. Omitting them will cause the API to return an error. The SDK provides the dateRange() fluent method as a first-class concept to make this explicit and convenient.

Dates must be formatted as YYYY-MM-DD strings. Both start and end are inclusive.

devMode warning: When devMode is enabled in configuration, the SDK emits a WARN-level error if you call fetch() or fetchAll() on a Lead or Visit collection without first calling dateRange(). It does not throw an exception, so the request still proceeds — but the API will likely return an error response.


Pagination

The Leadfeeder API uses 1-indexed, page-number-based pagination with a configurable page size. The SDK default page size is 100. Individual requests return a single page; fetchAll() continues fetching until the links.next key is absent from the API response.

Fetching a Single Page

Controlling Page Number and Page Size

Auto-Pagination with fetchAll()

The fetchAll() method iterates through all available pages automatically, accumulating results into a single collection. For Lead collections, auto-pagination stops at 10,000 records regardless of whether more pages exist — this cap prevents runaway memory consumption on large accounts.

Key pagination facts:


Query Building

The SDK separates filtering into two complementary strategies: server-side WHERE filters that are sent as query parameters in the API request, and client-side HAS filters that are evaluated after the response is received. Understanding which approach to use for a given condition is important for both correctness and performance.

WHERE Filters (Server-Side)

Server-side filters are passed as query parameters and evaluated by the Leadfeeder API. Only the fields explicitly listed in each resource's WHERE_OPERATIONS constant are valid server-side filter keys.

Supported server-side filter fields by resource:

Resource Field Operator
Lead start_date =
Lead end_date =
Lead custom_feed_id =
Visit start_date =
Visit end_date =

Note that start_date and end_date are set automatically by dateRange() — you do not need to pass them via where() directly. Using where() for dates is supported but redundant when dateRange() is already called.

devMode warning: When devMode is enabled, calling where() with a field that is not in the resource's WHERE_OPERATIONS table emits a WARN-level error. This helps catch typos and unsupported filters during development.

HAS Filters (Client-Side)

Client-side HAS filters are evaluated in PHP after the API response is received. They can match against any property in the resource's PROP_TYPES definition, not just the fields supported as server-side query parameters. This makes has() useful for any narrowing that the API does not natively support.

Supported has() operators:

Operator Meaning
= Equal (default)
!= Not equal
> Greater than
>= Greater than or equal
< Less than
<= Less than or equal
like Case-insensitive substring match

The like operator uses PHP's str_contains() after lowercasing both sides. It is only valid for string properties; numeric properties use the comparison operators.


Relationship Includes

The Leadfeeder API supports sideloading related entities via the include query parameter. The SDK maps these to PHP entity objects automatically through its JSON:API parser. Currently, the only supported relationship include is locations on both Lead and Visit responses.

Including Locations on Leads

Including Locations on Visits

The Location entity is include-only — it has no standalone API path and cannot be fetched or listed directly. Calling Location::fetch() or Location::list() will throw a RuntimeException. Included Location objects expose the following properties: id, country, country_code, region, region_code, city, state_code.


Custom Feed Scoping

Custom Feeds are saved filter configurations in Leadfeeder that segment your leads into named groups. You can list all custom feeds to discover their IDs, then use forFeed() on a Lead collection to retrieve leads scoped to that feed. This sets a parent context that prefixes the API request path with custom-feeds/{feedId}/.

Listing Custom Feeds

Fetching Leads for a Specific Feed

forFeed() and the server-side where('custom_feed_id', ...) filter are complementary approaches to the same goal. forFeed() uses a nested URL path; where() passes the feed ID as a query parameter. In most cases forFeed() is the cleaner choice.


Lead-Scoped Visits

You can retrieve all visits attributed to a specific lead by calling forLead() on a Visit collection. This sets the parent context to leads/{leadId}/, scoping the API path to accounts/{accountId}/leads/{leadId}/visits.

The visit_route property is typed as array:object, meaning it is an array of associative arrays. Each element represents a single page view within the visit session.


Website Tracking Script (Singleton)

The Website Tracking Script is a singleton resource — there is exactly one per account, and it has no list endpoint. Fetch it by calling fetch() with no arguments. Calling list() on this resource will throw a RuntimeException.

Available properties: id, script_hash, script_html (typed html), timezone.

The list() method on WebsiteTrackingScript is disabled and throws: RuntimeException: WebsiteTrackingScript is a singleton entity and cannot be listed.


Export Workflow

The Leadfeeder export system is asynchronous. You create an export job, poll for completion, and then download the processed data once it is ready. The ExportManager class handles this full lifecycle.

Full Lifecycle: Create, Wait, Download

Manual Polling Alternative

If you need finer control over the polling interval or want to integrate the status check into your own event loop, use checkStatus() directly.

Filtering by Custom Feed

Pass custom_feed_id in the params array to scope the export to a specific feed.

Required parameters: account_id, start_date, end_date. custom_feed_id is optional.

The export creation POST request uses the export rate-limit scope (5 requests/minute). Status polls use the per-token rate limit scope. Download requests use an unauthenticated client — the pre-signed download URL itself serves as the credential.


IP Enrichment

The Leadfeeder Discover API lets you identify company information for a given IP address. This is a separate API service with its own endpoint (https://api.lf-discover.com) and authentication method (X-API-KEY header). It requires a distinct API key separate from your Leadfeeder token.

The IpEnrichClient can be created directly or via the Leadfeeder::connectIpEnrich() factory, which caches clients by API key.

Key points about IP Enrichment:


Configuration

The SDK ships with a default.leadfeederapi.config.json file that contains all default values. You can override any setting by loading a custom configuration file or by calling Configuration::set() at runtime.

Default Configuration

By default, the SDK connects to https://api.leadfeeder.com, disables caching and logging, and enables rate limiting with a 100-requests-per-minute general limit and 5-per-minute for exports.

Custom Configuration File

Create a leadfeederapi.config.json file in your project and load it at bootstrap. Only the keys you wish to override need to be present — values are merged recursively with the defaults.

Loading Configuration

overload() looks for a file named leadfeederapi.config.json in the given directory (or uses the path directly if it points to a file). If the file does not exist, it silently returns. load() requires the file to exist and throws on invalid JSON.

Configuration Options

Key Type Default Description
connection.url string https://api.leadfeeder.com Base API URL
connection.timeout int 30 HTTP request timeout in seconds
connection.verify bool true SSL certificate verification
ipEnrich.url string https://api.lf-discover.com Discover API base URL
ipEnrich.rateLimit.perMinute int 60 IP Enrichment rate limit
enabled.cache bool false Enable response caching
enabled.logging bool false Enable request logging
rateLimit.enabled bool true Enable rate limiting
rateLimit.perMinute int 100 General requests per minute
rateLimit.export.perMinute int 5 Export creation requests per minute
rateLimit.minDelayMs int 200 Minimum milliseconds between requests
rateLimit.safetyBuffer int 1 Subtract from perMinute before throttling
rateLimit.maxRetries int 3 Max 429 retry attempts
rateLimit.retryDelayMs int 2000 Initial retry delay in milliseconds
devMode bool false Enable development warnings
log.connections bool false Log new connection creation
log.requests bool true Log each HTTP request
error.enabled bool true Enable error handling
error.triggerPhpErrors bool false Trigger native PHP errors
error.handlers.notice array ["log"] Handlers for notice-level errors
error.handlers.warn array ["log"] Handlers for warning-level errors
error.handlers.fatal array ["log", "echo"] Handlers for fatal errors

Caching

The SDK includes a built-in file-based response cache for GET requests. Caching is disabled by default and must be explicitly enabled. Once enabled, successful GET responses are serialized and stored on disk; subsequent identical requests are served from cache within the configured lifespan. POST requests (such as export creation) automatically invalidate related cache entries via ScrubCache.

Option A: Enable via Configuration

Option B: PHP Constant

Define the LFAPI_REQUEST_CACHE_PATH constant before making any requests. The SDK looks for this constant to determine the cache directory. Both the constant and the enabled.cache config key must be set for caching to activate.

Cache files are written to a lfapi-cache/ subdirectory inside the configured path. The default lifespan is 300 seconds (5 minutes). Files older than the lifespan are deleted on the next access attempt.

Cache Behavior Summary

Custom Cache Backend

If you need Redis, Memcached, or any other storage layer, register three callables with Cache::registerCacheMethods():


Rate Limiting

The SDK implements multi-scope rate limiting with sliding window tracking. Each scope maintains an independent timestamp log, allowing fine-grained control over different request categories without one scope blocking another.

Four Rate Limit Scopes

Scope Key Applies To Default Limit
token:{hash} All requests using a specific token (no account set) 100/min
account:{id} All requests once setAccount() is called 100/min
export ExportManager::create() POST requests only 5/min
ipenrich:{hash} IpEnrichClient::lookup() requests 60/min

How Rate Limiting Works

Before each request, RateLimiter::waitIfNeeded() runs a three-stage check:

  1. Prune all timestamps older than 60 seconds from the sliding window
  2. If the number of recent requests has reached perMinute - safetyBuffer, sleep until the oldest timestamp in the window ages out of the 60-second window
  3. If the time elapsed since the last request is less than minDelayMs, sleep the remaining gap

On a 429 response from the API, the SDK retries up to maxRetries times (default 3) with exponential backoff starting at retryDelayMs (default 2,000ms). After exhausting all retries, a FATAL error is raised.

Rate limiting can be disabled entirely for testing or high-trust environments:


Error Handling

The SDK uses a three-level severity system for all internal error conditions. Error behavior is fully configurable — you can choose whether errors are logged, echoed, or trigger native PHP errors, independently per severity level.

Severity Levels

Level Enum Case Default Handlers Typical Cause
notice ErrorSeverity::NOTICE log Informational — non-critical conditions
warn ErrorSeverity::WARN log Potential problem — missing date range in devMode
fatal ErrorSeverity::FATAL log, echo Unrecoverable — rate limit exhausted, 402, 5xx

Customizing Error Behavior

Checking Response Success

Every request returns a RequestResponse object. Always check $response->success before processing the body. The entity and collection classes handle this internally, but when you need raw access:

In normal SDK usage — through resource fetch(), list()->fetch(), or ExportManager — errors are surfaced automatically through the configured error handlers. You do not need to unwrap response objects manually unless you are extending the SDK.


Working with Properties

Every resource entity exposes its properties through magic __get / __set accessors and the explicit get() / set() methods. Properties are automatically coerced to their defined types upon hydration.

Magic Property Access

Complex Type Examples

Some properties are typed as complex structures rather than scalar values.

Property Types

The SDK's type system covers all Leadfeeder data shapes:

Type PHP Representation Example Properties
text string name, website_url, id
integer int employee_count, quality, visits
date string (YYYY-MM-DD) first_visit_date, last_visit_date
datetime string (ISO 8601) started_at
array array (flat) tags, ga_client_ids
object array (assoc) employees_range
array:object array of array industries, visit_route
html string (raw HTML) script_html
enum:* string (validated) subscription, website_tracking_status

Serialization


Advanced Usage

Multiple Connections

The Leadfeeder::connect() factory is a singleton keyed by token. If you need to work with multiple API tokens simultaneously, call connect() with each distinct token — each returns its own independent connection with its own rate limit state.

Combining Web Visitor Leads with IP Enrichment

A common pattern is to retrieve leads from the web visitor feed and then enrich any leads that have a known IP address with additional company data from the Discover API.


Running Tests

The SDK ships with a custom zero-dependency test runner. No PHPUnit or other test framework is required. The test suite makes live API calls and requires valid credentials configured in the testing section of the config.

Running the Suite

CLI Options

The test runner script accepts the following options directly:

CLI Option Effect
--dry-run Parse and display the test plan without executing any requests
--verbose Print each individual assertion result as it runs
--resource=<name> Run only the test group for the named resource (e.g. lead, visit, account)

Test Credentials

Supply your API credentials via the testing block in a local leadfeederapi.config.json file. This file should never be committed to version control.

Then load the file before running tests, or place it in the project root where Configuration::overload() will pick it up automatically.


Contributing

Contributions are welcome. Please read CONTRIBUTING.md before submitting a pull request. The document covers branching conventions, the PR workflow, coding standards (PSR-12, PHP 8.1 minimum, strict_types), and the changelog maintenance requirement.


License

MIT — see LICENSE for details.


Credits

Developed and maintained by Joel Colombo at 360 PSG, Inc.

This package is independently developed and is not affiliated with or endorsed by Leadfeeder or Dealfront.


Changelog

See CHANGELOG.md for a detailed history of changes.


All versions of leadfeeder-api-php with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
ext-json Version *
guzzlehttp/guzzle Version ^7.8
adbario/php-dot-notation Version ^3.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package jcolombo/leadfeeder-api-php contains the following files

Loading the files please wait ...