Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Kvk Api Bundle Laravel Package

connectholland/kvk-api-bundle

Symfony bundle for integrating the Dutch KVK API, offering configuration and services to query Chamber of Commerce company data such as profiles and registrations, with straightforward dependency injection setup.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Confirm you're on Symfony first. This is connectholland/kvk-api-bundle, a Symfony bundle, not a Laravel package. There is no service provider, no package discovery, no config/kvk.php. If you're in Laravel, stop and treat the repo as a spec rather than a dependency — you'll write ~100 lines of Http:: calls against the KvK REST API instead of dragging Symfony DI into your app.
  • Get credentials from developer.kvk.nl. You'll receive a test key and a production key. They are not interchangeable, and pairing a test key with the production base URL (or vice versa) is the single most common first failure.
  • Read the source before you write config. The README is thin. Open DependencyInjection/Configuration.php for the exact config root and option names, DependencyInjection/*Extension.php for env handling, and Resources/config/ for the service ID you'll inject. Those three files are the documentation.
  • Register and configure (Symfony):
// config/bundles.php
ConnectHolland\KvkApiBundle\ConnectHollandKvkApiBundle::class => ['all' => true],
# config/packages/connect_holland_kvk_api.yaml  (verify root name against Configuration.php)
connect_holland_kvk_api:
    api_key: '%env(KVK_API_KEY)%'
KVK_API_KEY=your-test-key
  • First use case: look up a single company by its 8-digit KvK number, map the basisprofiel response into your own DTO, render trade name + address. Get that working end-to-end before touching search (/zoeken) or branch (/vestigingen) endpoints — they have different response shapes and will distract you from the happy path.

Implementation Patterns

  • Inject the client, never pull from the container. Type-hint the service class registered by the bundle in a constructor. In Symfony that means autowiring; in a Laravel bridge it means binding that type in a service provider and constructing it with the key from config/services.php.
  • Wrap it in your own adapter. Define a narrow interface — CompanyRegistry::findByKvkNumber(string $kvk): ?Company — and implement it against the bundle's client. The vendor surface is small, the package is niche, and an adapter lets you cache, mock, and swap providers without vendor types leaking into controllers or domain code.
  • Respect the identifier hierarchy. kvkNummer (8 digits) identifies the legal entity, vestigingsnummer (12 digits) identifies a branch, and RSIN is a third thing entirely. Search results (/zoeken) return branches — always extract the underlying kvkNummer before calling the basisprofiel endpoint. Do not assume one number type works everywhere.
  • Cache by (endpoint, identifier) with a 24h–7d TTL. Company registry data changes slowly. Use Symfony Cache (cache.app) or Laravel's Cache::remember. This protects you from the KvK rate limits and keeps onboarding fast on repeat lookups.
  • Async where the UX allows it. For user-facing signup, a synchronous call with a short timeout (~3s) is fine. For bulk enrichment or CRM sync, push the lookup onto a queued job with backoff — do not loop synchronously through hundreds of KvK numbers in a request.
  • Test with a fake, not the network. Because the client is a normal service, bind your adapter in the test container and return fixture DTOs. Keep a small set of recorded JSON responses (basisprofiel, zoeken, vestiging) as fixtures so contract tests catch upstream shape changes.
  • Map errors into domain states. Wrap the client's exceptions in your own KvkNotFound, KvkUnavailable, KvkRateLimited. Controllers and onboarding flows should branch on those rather than on Guzzle exception types.

Gotchas and Tips

  • The bundle ≠ the KvK API. It's a thin DI wrapper. If you need an endpoint the bundle doesn't expose, you're calling the REST API yourself anyway — check the version of the KvK API v1/v2 the bundle targets before assuming parity with current docs.
  • Rate limits are the operational bottleneck, not package performance. KvK enforces per-key quotas and the bundle will not implement retry/backoff for you. Add your own retry policy (idempotent GETs only) and a circuit breaker so a KvK outage doesn't cascade into your onboarding flow.
  • Terms of use constrain caching and redistribution. KvK has rules on how long you may store company data and whether you may re-display it. A cache TTL is also a compliance decision — do not cache "forever because it's slow-changing." Review the KvK terms before you set the TTL, and be clear internally that this is registry identity verification, not credit risk or UBO/AML screening.
  • Version pinning is mandatory. With no stars, no dependents, and no visible release cadence, you are effectively the maintainer. Pin an exact version (or vendor/fork the client class), and watch PHP + Symfony component constraints on every upgrade. Symfony major bumps will break the bundle before they break your app.
  • The "sandbox" is really test credentials against a test endpoint. Don't assume the test environment's data mirrors production or that response shapes are identical. Record production-shaped fixtures during a pilot if you can.
  • Debugging tip: log the outbound request URL and the KvK correlation id. KvK support asks for it; without it, distinguishing "company does not exist" from "key lacks scope" from "temporary outage" is guesswork.
  • Extension points are limited, by design. The realistic extension seam is your adapter layer and your own HTTP middleware/event listener — not the bundle. If you need retries, metrics, or per-endpoint caching policy, build it around the injected client rather than expecting config flags.
  • Laravel teams: port, don't wrap. If the reason you're here is Dutch B2B onboarding, the correct move is a KvkService using Laravel's Http client, a Company DTO, a config/services.php entry, and a cache layer — a day of work you fully own. Use this repo to learn endpoint names and response shapes, then close the tab.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk