PHPackages                             alancaptcha/php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. alancaptcha/php

ActiveLibrary

alancaptcha/php
===============

Alan Captcha API PHP SDK

0.0.2(1y ago)01052MITPHPPHP &gt;=8.0

Since Jul 25Pushed 1y ago2 watchersCompare

[ Source](https://github.com/alancaptcha/php)[ Packagist](https://packagist.org/packages/alancaptcha/php)[ RSS](/packages/alancaptcha-php/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (2)

Alan Captcha API PHP library
============================

[](#alan-captcha-api-php-library)

This package allows to make use of the Alan Captcha API.
See  for further details about the API and other options for integration like javascript widget and CMS plugins for WordPress, TYPO3 or Neos CMS.

Installation
------------

[](#installation)

Requires **PHP 8.0** or later.

**Install using [Composer](https://getcomposer.org/)**

```
composer require alancaptcha/php
```

Usage
-----

[](#usage)

### Retrieve a challenge

[](#retrieve-a-challenge)

A challenge is encoded in a `JWT` (`JSON Web Token`). To retrieve such token you only need to create an API instance and provide your public `siteKey`:

```
$api = new \AlanCaptcha\Php\AlanApi();
$challengeJWT = $api->challenge('YOUR-PUBLIC-SITEKEY');
```

You can then use this `JWT` to send them to clients and require them to solve the challenge encoded in the JWT.

#### Retrieve a more difficult challenge

[](#retrieve-a-more-difficult-challenge)

The `siteKey` encodes a default difficulty, which was specified during siteKey creation.
But, if you detect abuse of your infrastructure, you can also increase the difficulty on your own.

```
$api = new \AlanCaptcha\Php\AlanApi();
$challengeJWT = $api->challenge(siteKey: 'YOUR-PUBLIC-SITEKEY', difficulty: 19);
```

You might need to test a few difficulty variants to get a better understanding of the impact.

### Validate a solution

[](#validate-a-solution)

The solution for a challenge is an array of puzzle id's and the corresponding solution, e.g.

```
[
  {"id":"e362a59c229946c061bf1afa3ceed7","solution":"000000000362"},
  {"id":"ee0e97c214df54928fab2935760cd9","solution":"000000001616"}
]
```

To validate the solutions for a challenge JWT you need to provide your private apiKey, the challenge JWT and the solutions array:

```
$api = new \AlanCaptcha\Php\AlanApi();
$isValid = $api->challengeValidate($yourPrivateApiKey, $challengeJWT, $solutions);
```

### PSR-15 middleware

[](#psr-15-middleware)

This package also provides a PSR-15 middleware.
Using this middleware you can add Alan Captcha verification for your project easily by either using the provided middleware or override the middleware and change some relevant pieces specific of your project.

#### Features of the middleware

[](#features-of-the-middleware)

- It can verify challenges via HTTP request headers `X-Alan-JWT` and `X-Alan-Solution`, where `X-Alan-JWT` is the retrieved JWT used to solve the challenge and `X-Alan-Solution` is a json encoded array of solutions.
    Using HTTP request headers, there is minimal impact on your project and infrastructure, but provides good security for your HTTP endpoints.
- Validate form POST requests created by the Alan Captcha browser widget
- Configure which of your endpoints require Alan Captcha validation and which don't

#### Example

[](#example)

```
$alanMiddleware = new \AlanCaptcha\Php\Middleware\AlanCaptchaMiddleware();
$alanMiddleware->setApiKey('YOUR-PRIVATE-APIKEY')->setIncludePaths(['/\/api\/.*'/]);
```

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance42

Moderate activity, may be stable

Popularity10

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 66.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~187 days

Total

2

Last Release

475d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2139456?v=4)[web&amp;co](/maintainers/webandco)[@webandco](https://github.com/webandco)

---

Top Contributors

[![gjwnc](https://avatars.githubusercontent.com/u/19683930?v=4)](https://github.com/gjwnc "gjwnc (2 commits)")[![Liioooo](https://avatars.githubusercontent.com/u/59089018?v=4)](https://github.com/Liioooo "Liioooo (1 commits)")

### Embed Badge

![Health badge](/badges/alancaptcha-php/health.svg)

```
[![Health](https://phpackages.com/badges/alancaptcha-php/health.svg)](https://phpackages.com/packages/alancaptcha-php)
```

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k18.5M1.6k](/packages/cakephp-cakephp)[sentry/sentry-laravel

Laravel SDK for Sentry (https://sentry.io)

1.3k114.3M154](/packages/sentry-sentry-laravel)[bref/bref

Bref is a framework to write and deploy serverless PHP applications on AWS Lambda.

3.4k9.6M55](/packages/bref-bref)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[simplesamlphp/saml2

SAML2 PHP library from SimpleSAMLphp

30317.2M40](/packages/simplesamlphp-saml2)[thecodingmachine/graphqlite

Write your GraphQL queries in simple to write controllers (using webonyx/graphql-php).

5723.1M30](/packages/thecodingmachine-graphqlite)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
