Download the PHP package captchaapi/laravel without Composer

On this page you can find all versions of the php package captchaapi/laravel. 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 laravel

captchaapi/laravel

Latest Version on Packagist Total Downloads Tests PHP Version Laravel Compatibility

Official Laravel SDK for captchaapi.eu — EU-hosted, GDPR-compliant proof-of-work CAPTCHA. Drop-in Blade component, validation rule, and Livewire trait. No cookies, no tracking, no Google.

Why captchaapi.eu

Requirements

Installation

Publish the config file:

Set the credentials in .env:

The site key is public and goes in the browser; the secret stays on your server. Get both from the project dashboard.

Usage

Plain HTML form

In your layout's <head> (renders the widget script and pushes config to window.CAPTCHA_*):

In your form, add data-captcha:

In your validation:

Or via the string alias:

Livewire

In your layout (same as above):

In your Livewire component:

validateWithCaptcha() is sugar for $this->validate(array_merge($rules, $this->rulesForCaptcha())). If you need to compose validateOnly() flows yourself, rulesForCaptcha() is still public.

In the component view, use the Livewire-aware form wrapper:

The wrapper sets data-captcha-mode="event", includes the hidden captchaapi_response input, and dispatches to your Livewire register method once the response arrives.

Showing the validation error

When ValidCaptcha rejects a response (invalid, expired, or already used), Laravel attaches the message to the captchaapi_response field. Render it with the included helper:

Defaults to :for="captchaapi_response" and renders a <p role="alert">. Override the field name, the wrapping tag, and pass through any attributes:

The component is a thin wrapper around Laravel's @error directive — if you prefer to keep markup in your own templates, write it yourself:

Both approaches work for plain HTML forms (after a redirect-with-errors) and for Livewire (after validateWithCaptcha()).

Status element styling

Place a <div data-captcha-status></div> anywhere inside (or near) your form to show the widget's current state to your users. Six states exist (waiting, idle, solving, ready, error, rate_limited), each rendered as an icon + a localised message. The widget sets data-captcha-state="…" on the element so you can target each state with CSS.

The status element is opt-in. A form without a [data-captcha-status] child runs silently — submission still works, only the visible signal is absent. There is no auto-injection.

Default colors

The widget injects a low-specificity stylesheet on first use that applies sensible default colors per state:

State Default color
waiting #6b7280 grey
idle #6b7280 grey
solving #6b7280 grey
ready #059669 emerald
error #dc2626 red
rate_limited #d97706 amber

You don't have to write any CSS to get those colors. They appear automatically on every [data-captcha-status] element the widget finds.

Override one state

Write a higher-specificity rule (two attribute selectors instead of one). The customer rule wins regardless of cascade order — no !important needed:

Take over completely (Tailwind / design system)

Add data-captcha-no-color to suppress the widget's default stylesheet entirely. Your own classes / CSS apply cleanly:

Note that waiting and ready share the shield icon and would be visually identical without color. If you opt out of the widget defaults, supply per-state colors in your own CSS so the two stay distinguishable.

Disabling the package

Flip CAPTCHAAPI_ENABLED=false in .env to disable both the validation rule and the widget without removing any wiring. The ValidCaptcha rule passes silently and <x-captchaapi::widget /> renders nothing, so you can keep the trait, the rule, and the Blade markup in place across local, CI, and staging environments where no live site key is set.

Defaults to true, so existing installs keep working unchanged. This is a permanent kill-switch, not a per-test bypass — for that, use FakeCaptchaapi::enable() (see Testing).

Configuration reference

Config key ENV variable Default Purpose
enabled CAPTCHAAPI_ENABLED true Master kill-switch. When false, the rule passes silently and the widget renders nothing.
site_key CAPTCHAAPI_SITE_KEY null Public site key from the dashboard. Required for widget rendering.
secret_key CAPTCHAAPI_SECRET_KEY null Project secret, sent as a Bearer token on the verify call. Server-side only.
base_url CAPTCHAAPI_BASE_URL null Override the API origin for the widget and the verify call. Defaults to https://captchaapi.eu.
timeout CAPTCHAAPI_VERIFY_TIMEOUT 5 Seconds to wait for the verify call before treating the server as unreachable.
fail_open CAPTCHAAPI_FAIL_OPEN true When the server is unreachable or returns a 5xx: true lets the submission through, false rejects it with a try-again message.
locale CAPTCHAAPI_LOCALE null Force widget language (en, de, cs, …). Falls back to <html lang> then en.
preload CAPTCHAAPI_PRELOAD lazy lazy waits for first form interaction; eager fires the challenge on page load.
debug CAPTCHAAPI_DEBUG false Log timing breakdown in the browser console.
mode CAPTCHAAPI_MODE null submit (native form POST) or event (CustomEvent for Livewire/SPA).

Fail policy

The verify call can fail to reach a verdict — the server is unreachable or returns a 5xx. fail_open decides what happens, and it defaults to true: the submission goes through. A CAPTCHA guards a public form, so your own outage blocking every submission is worse than the rare bot slipping past during it, and an attacker can't reach this path anyway — verification is server-to-server, off the browser.

Set it to false for sensitive actions (login, payment) where a missed bot costs more than a blocked visitor:

The visitor is then asked to try again, never told they failed the CAPTCHA. There is no automatic retry on either setting: the response is single-use, and a second verify call would spend a token the visitor already solved.

Secret key rotation

Rotate from the dashboard — the package needs no list of keys. While a rotation is pending, the server accepts both the old and the new secret on every challenge issued, so you deploy the new key without a hard cutover:

  1. In the dashboard, click Rotate secret key — issues a new key while the current one keeps working.
  2. Update CAPTCHAAPI_SECRET_KEY in your .env and deploy. From here both keys verify, so the timing of your deploy doesn't matter.
  3. In the dashboard, activate the new key, then retire the old one.

The only thing tied to the old key is a challenge a visitor was already solving when you clicked Rotate — it lives at most the token lifetime (~2 minutes), so any brief overlap clears itself.

For a suspected compromise, use Revoke immediately to drop the old key in one step. This skips the overlap, so in-flight solutions fail until the new secret is deployed.

Testing

In feature tests, enable fake mode so ValidCaptcha accepts any input without a real response or a call to the server:

The fake state is stored on the Captchaapi singleton — it does not persist across requests in production code.

Catching Fortify's double validation

Fortify runs the login validator twice in one request, so a single-use response must survive both passes. To prove your integration handles this instead of silently bypassing it, opt the fake into the server's single-use contract:

The value now verifies once per request — the per-request memo covers the double call — while a replay in a later request is rejected. A missing memoization then fails the test instead of passing silently.

Laravel Octane

The package is safe under Octane (Swoole, RoadRunner, FrankenPHP), where the application and its singletons stay resident across requests:

Security

If you discover a security vulnerability, please do not open a public GitHub issue. Use GitHub's private vulnerability reporting so we can coordinate a fix before details become public.

Contributing

Bug reports and feature requests welcome at github.com/captchaapi/laravel/issues.

For development:

License

MIT — see LICENSE.


All versions of laravel with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/contracts Version ^12.0|^13.0
illuminate/http Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
illuminate/validation Version ^12.0|^13.0
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 captchaapi/laravel contains the following files

Loading the files please wait ...