PHPackages                             iajson/client - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. iajson/client

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

iajson/client
=============

PHP reference library for consuming ia.json files — the universal standard for AI interaction with websites

1.0.0(4mo ago)01MITPHPPHP ^8.1

Since Feb 13Pushed 4mo agoCompare

[ Source](https://github.com/Dandte/iajson-php)[ Packagist](https://packagist.org/packages/iajson/client)[ Docs](https://iajson.org)[ RSS](/packages/iajson-client/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (6)Versions (2)Used By (0)

iajson/client
=============

[](#iajsonclient)

PHP reference library for consuming [ia.json](https://iajson.org) files -- the universal standard for AI interaction with websites.

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- ext-json
- ext-hash

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

[](#installation)

```
composer require iajson/client
```

> Note: The package will be available on Packagist soon. In the meantime, install from GitHub:
>
> ```
> git clone https://github.com/Dandte/ai.json.git
> # Add a path repository in your composer.json pointing to libraries/php/
> ```

Quick Start
-----------

[](#quick-start)

```
use IaJson\Client\IaJsonClient;

// Discover a site's ia.json and create a client
$client = IaJsonClient::discover('techstore.example.com');

// Call a public endpoint (no authentication needed)
$results = $client->call('search_products', ['q' => 'wireless headphones']);

// Inspect the site
$site = $client->getSite();
echo $site['name']; // "TechStore"
echo $site['type']; // "ecommerce"
```

Discovery
---------

[](#discovery)

The library follows the ia.json discovery algorithm:

1. Tries `https://{domain}/ia.json`
2. Falls back to `https://{domain}/.well-known/ia.json`
3. Validates the spec structure and version compatibility

```
use IaJson\Client\Discovery;

$discovery = new Discovery();
$spec = $discovery->fetch('example.com');

// $spec is the full parsed ia.json array
echo $spec['version'];        // "1.0.0"
echo $spec['api']['base_url']; // "https://example.com/api/v1"
```

Browsing Endpoints
------------------

[](#browsing-endpoints)

```
$client = IaJsonClient::discover('techstore.example.com');

// Get all endpoints
$all = $client->getEndpoints();

// Get only public endpoints
$public = $client->getEndpoints('public');

// Get protected endpoints (require agent auth)
$protected = $client->getEndpoints('protected');

// Get user_required endpoints (require OAuth)
$userRequired = $client->getEndpoints('user_required');

// Check capabilities
if ($client->hasCapability('search')) {
    $results = $client->call('search_products', ['q' => 'laptop']);
}

// Get rate limit info
$rateLimit = $client->getRateLimit(); // e.g., "1000/hour"
```

Authentication
--------------

[](#authentication)

### Signed Key Registration

[](#signed-key-registration)

For `protected` endpoints, you must register your AI agent and receive credentials:

```
$client = IaJsonClient::discover('techstore.example.com');

// Step 1: Register your agent
$response = $client->register([
    'name' => 'My AI Assistant',
    'domain' => 'myai.example.com',
    'webhook_url' => 'https://myai.example.com/ia/verify',
    'contact' => 'admin@myai.example.com',
    'description' => 'AI shopping assistant',
]);

// Step 2: Your webhook receives a verification_code from the site.
// Step 3: Submit the verification code:
$credentials = $client->verify('vc_abc123def456');

// The client now has credentials set automatically.
// You can also store and re-use them:
echo $credentials['api_key']; // "ia_live_..."
echo $credentials['secret'];  // "sec_..."
```

### Using Existing Credentials

[](#using-existing-credentials)

If you already have credentials from a previous registration:

```
$client = IaJsonClient::discover('techstore.example.com');
$client->setCredentials('ia_live_abc123', 'sec_xyz789');

// Now you can call protected endpoints
$inventory = $client->call('get_inventory');
```

### OAuth2 (User Authorization)

[](#oauth2-user-authorization)

For `user_required` endpoints, you need the user's OAuth2 token:

```
$client = IaJsonClient::discover('techstore.example.com');
$client->setCredentials('ia_live_abc123', 'sec_xyz789');

// Get the OAuth helper
$oauth = $client->getOAuth(
    clientId: 'your_client_id',
    clientSecret: 'your_client_secret',
);

// Step 1: Get the authorization URL for the user to visit
$result = $oauth->getAuthorizationUrl(
    redirectUri: 'https://myai.example.com/callback',
    scopes: ['cart:read', 'cart:write', 'orders:write'],
    state: 'random_csrf_token',
);

echo $result['url']; // Redirect user here
// If PKCE is required, store $result['code_verifier'] in the session

// Step 2: After the user authorizes, exchange the code
$tokens = $oauth->exchangeCode(
    code: $_GET['code'],
    redirectUri: 'https://myai.example.com/callback',
    codeVerifier: $result['code_verifier'] ?? null, // If PKCE
);

// The OAuth helper stores tokens internally.
// Or set a token directly:
$client->setOAuthToken($tokens['access_token']);

// Now call user_required endpoints
$cart = $client->call('get_cart');
$client->call('add_to_cart', [
    'product_id' => 'prod_abc123',
    'quantity' => 2,
]);
```

Request Signing
---------------

[](#request-signing)

The `Signer` class implements the ia.json HMAC signing algorithm:

```
use IaJson\Client\Auth\Signer;

// Sign a request
$signature = Signer::sign(
    secret: 'sec_xyz789',
    timestamp: time(),
    body: '{"product_id":"prod_123","quantity":2}',
    algorithm: 'sha256',
);

// Generate all auth headers at once
$headers = Signer::createSignedHeaders(
    apiKey: 'ia_live_abc123',
    secret: 'sec_xyz789',
    body: '{"product_id":"prod_123"}',
    algorithm: 'sha256',
    prefix: 'X-IA-',
);

// Result:
// [
//     'X-IA-Key' => 'ia_live_abc123',
//     'X-IA-Signature' => 'a1b2c3d4...',
//     'X-IA-Timestamp' => '1707753600',
// ]

// Verify an incoming signature (server-side)
$valid = Signer::verify(
    secret: 'sec_xyz789',
    providedSignature: $incomingSignature,
    timestamp: (int) $incomingTimestamp,
    body: $rawRequestBody,
    algorithm: 'sha256',
    maxAgeSeconds: 60,
);
```

Error Handling
--------------

[](#error-handling)

The library throws typed exceptions for different error conditions:

```
use IaJson\Client\Exceptions\IaJsonException;
use IaJson\Client\Exceptions\AuthenticationException;
use IaJson\Client\Exceptions\RateLimitException;

try {
    $result = $client->call('get_inventory');
} catch (RateLimitException $e) {
    // HTTP 429 - retry after the suggested delay
    $retryAfter = $e->getRetryAfter(); // seconds, or null
    sleep($retryAfter ?? 60);
} catch (AuthenticationException $e) {
    // HTTP 401/403 - invalid key, expired signature, etc.
    echo $e->getErrorCode(); // e.g., "invalid_signature"
} catch (IaJsonException $e) {
    // Any other ia.json error
    echo $e->getMessage();
    echo $e->getErrorCode();
    print_r($e->getErrorDetails());
}
```

Laravel Integration
-------------------

[](#laravel-integration)

This package includes first-class Laravel support with auto-discovery.

### Setup

[](#setup)

1. Publish the configuration:

```
php artisan vendor:publish --tag=iajson-config
```

2. Add your credentials to `.env`:

```
IAJSON_DOMAIN=techstore.example.com
IAJSON_API_KEY=ia_live_abc123
IAJSON_SECRET=sec_xyz789

# Optional: OAuth2 credentials
IAJSON_OAUTH_CLIENT_ID=your_client_id
IAJSON_OAUTH_CLIENT_SECRET=your_client_secret

# Optional: Cache TTL in seconds (default: 3600)
IAJSON_CACHE_TTL=3600
```

### Using the Facade

[](#using-the-facade)

```
use IaJson\Client\Laravel\Facades\IaJson;

// Call endpoints
$products = IaJson::call('search_products', ['q' => 'laptop']);
$inventory = IaJson::call('get_inventory');

// Inspect the site
$site = IaJson::getSite();
$endpoints = IaJson::getEndpoints('public');
$capabilities = IaJson::getCapabilities();
```

### Dependency Injection

[](#dependency-injection)

```
use IaJson\Client\IaJsonClient;

class ProductController extends Controller
{
    public function search(Request $request, IaJsonClient $iajson)
    {
        $results = $iajson->call('search_products', [
            'q' => $request->input('query'),
        ]);

        return response()->json($results);
    }
}
```

### Verifying Incoming AI Agent Requests

[](#verifying-incoming-ai-agent-requests)

If your Laravel application serves as an ia.json-enabled site and receives requests from AI agents, use the `VerifyIaSignature` middleware:

1. Register the middleware alias in your `bootstrap/app.php` (Laravel 11+) or kernel:

```
// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'iajson.verify' => \IaJson\Client\Laravel\Middleware\VerifyIaSignature::class,
    ]);
})
```

```
// app/Http/Kernel.php (Laravel 10)
protected $middlewareAliases = [
    // ...
    'iajson.verify' => \IaJson\Client\Laravel\Middleware\VerifyIaSignature::class,
];
```

2. Apply it to your routes:

```
Route::middleware('iajson.verify')->prefix('api/v1')->group(function () {
    Route::get('/inventory', [InventoryController::class, 'index']);
    Route::post('/orders', [OrderController::class, 'store']);
});
```

3. Configure the secret resolver in `config/iajson.php`:

```
// Option A: Static key mapping
'verification' => [
    'keys' => [
        'ia_live_agent1_key' => 'sec_agent1_secret',
        'ia_live_agent2_key' => 'sec_agent2_secret',
    ],
],

// Option B: Custom resolver (e.g., from database)
'verification' => [
    'secret_resolver' => function (string $apiKey): ?string {
        $agent = \App\Models\AiAgent::where('api_key', $apiKey)->first();
        return $agent?->secret;
    },
],
```

The verified API key is available in the request:

```
public function index(Request $request)
{
    $apiKey = $request->attributes->get('iajson_api_key');
    // Use $apiKey to identify which agent is making the request
}
```

Configuration Reference
-----------------------

[](#configuration-reference)

The full `config/iajson.php` supports the following options:

KeyEnv VariableDescription`domain``IAJSON_DOMAIN`Domain to discover ia.json from`api_key``IAJSON_API_KEY`Agent API key`secret``IAJSON_SECRET`Agent secret`oauth.client_id``IAJSON_OAUTH_CLIENT_ID`OAuth2 client ID`oauth.client_secret``IAJSON_OAUTH_CLIENT_SECRET`OAuth2 client secret`cache_ttl``IAJSON_CACHE_TTL`Spec cache TTL in seconds`verification.algorithm``IAJSON_VERIFY_ALGORITHM`HMAC algorithm for verification`verification.header_prefix``IAJSON_VERIFY_HEADER_PREFIX`Auth header prefix`verification.max_age_seconds``IAJSON_VERIFY_MAX_AGE`Max timestamp ageSpec Compliance
---------------

[](#spec-compliance)

This library implements the ia.json v1.0.0 specification:

- Discovery at `/ia.json` and `/.well-known/ia.json`
- Version validation (major version check)
- File size limit enforcement (1 MB)
- All three access levels: `public`, `protected`, `user_required`
- HMAC-SHA256 and HMAC-SHA512 request signing
- Timestamp-based replay attack prevention
- Agent registration and domain verification flow
- OAuth2 with PKCE support
- Structured error responses per the spec format

License
-------

[](#license)

MIT License. See the [ia.json project](https://github.com/Dandte/ai.json) for the full specification.

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance74

Regular maintenance activity

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

141d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/eeef77613063be632f181deb0604b9b7e13fb5acb51a5bfe64232b1d08f0d015?d=identicon)[Dandte](/maintainers/Dandte)

---

Top Contributors

[![Dandte](https://avatars.githubusercontent.com/u/195594616?v=4)](https://github.com/Dandte "Dandte (1 commits)")

---

Tags

apilaravelaiAuthenticationdiscoveryAgentiajson

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/iajson-client/health.svg)

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

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.3k543.5M2.6k](/packages/aws-aws-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k656.1k38](/packages/neuron-core-neuron-ai)[google/auth

Google Auth Library for PHP

1.4k294.2M219](/packages/google-auth)[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k15](/packages/tempest-framework)[ellaisys/aws-cognito

Laravel Authentication using AWS Cognito (Web and API)

123256.9k1](/packages/ellaisys-aws-cognito)[oat-sa/tao-core

TAO core extension

66143.7k124](/packages/oat-sa-tao-core)

PHPackages © 2026

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