rekhu

Seshat

Seshat: installation

Install the core package in Laravel or Node.js, add the app key, and run the first check of a print file.

Before you start

Seshat is called through the core package: rekhu/core for Laravel, @rekhu/core for Node.js. You need:

Laravel Node.js
Runtime PHP 8.2 or newer, Laravel 10.48 to 13 Node.js 20 or newer (Express, Next.js, Nuxt, Hono, Bun, Deno)
Package rekhu/core @rekhu/core
Key an app key from your Rekhu account the same

The package talks to Rekhu from your server. The key never goes to the browser.

Install in five steps

  1. Make a project for the app. In your Rekhu account, open Projects → New project, choose Laravel app or Node.js app, and give it a name. See Sites and keys.
  2. Add a key. On the project's Connection tab, press Add key for your first environment (local). The key starts with agk_ and is shown once: copy it. Add one key per environment later (staging, production); they all count toward the same project.
  3. Install the package. Run the commands below for your framework.
  4. Add Seshat. In Laravel, --install=seshat checks that your key may use Seshat and adds it to REKHU_KNOWERS. In Node.js, name it in knowers.
  5. Run the first check. Send one PDF with its order, as shown under The first check.

For Laravel, install the package and connect the app. The install command asks for the key, checks it with Rekhu and writes the settings to .env:

composer require rekhu/core:^0.10
php artisan rekhu:core --install
php artisan migrate
php artisan rekhu:core --install=seshat

For Node.js, install the package and put the key in the server's environment as REKHU_APP_KEY:

npm install @rekhu/core@^0.10

Configure the key

In Laravel the install command wrote REKHU_APP_KEY to .env; an app that already runs Rekhu Assistant can use its REKHU_ASSISTANT_KEY instead. In Node.js you create the client once, in a module of its own:

// config/rekhu.php, published by php artisan rekhu:core --install; the values come from .env:
// REKHU_APP_KEY=agk_…, REKHU_TENANCY=single, REKHU_LOCALES=en, REKHU_KNOWERS=seshat
return [
    'key' => env('REKHU_APP_KEY', env('REKHU_ASSISTANT_KEY')),
    'tenancy' => env('REKHU_TENANCY', 'single'),
    'locales' => explode(',', env('REKHU_LOCALES', 'en')),
    'knowers' => array_values(array_filter(explode(',', env('REKHU_KNOWERS', '')))),
    // …
];
// rekhu.js
import { createRekhu } from '@rekhu/core';

export const rekhu = createRekhu({
    key: process.env.REKHU_APP_KEY,
    knowers: ['seshat'],
    locales: ['en'],
});

REKHU_KNOWERS (or knowers) is optional. Empty means every knower the key allows.

Warning: keep the key on your server. Never put it in front-end code or a mobile app: anyone who has it can spend your credit. If a key leaks, block it on the project's Connection tab and add a new one.

Check the connection

In Laravel, --check calls Rekhu with the key and shows which platform answered, its version, the account and the app:

php artisan rekhu:core --check

A free call proves the key in both packages. codes() lists every finding code and fix, and costs nothing:

$codes = Rekhu::seshat()->codes();
$codes['version']; // the version of the code list
const codes = await rekhu.seshat().codes();
codes.version; // the version of the code list

A missing or revoked key, or a key made on another Rekhu platform, is refused with InvalidKey. See Errors.

The first check

Send a file and the order it is for. A route that takes an upload is enough to try it:

use Illuminate\Http\Request;
use Rekhu\Core\Rekhu;

Route::post('/artwork', function (Request $request) {
    $order = ['width_mm' => 148, 'height_mm' => 210, 'bleed_mm' => 3, 'pages' => 2, 'colour' => 'cmyk'];

    return Rekhu::seshat()->for($request->user())->check($request->file('artwork'), $order, explain: true);
});
import express from 'express';
import multer from 'multer';
import { rekhu } from './rekhu.js';

const app = express();
const upload = multer();

app.post('/artwork', upload.single('artwork'), async (req, res) => {
    const order = { width_mm: 148, height_mm: 210, bleed_mm: 3, pages: 2, colour: 'cmyk' };
    const check = await rekhu.seshat({ user: req.user }).check(req.file.buffer, { name: req.file.originalname, order, explain: true });
    res.json(check);
});

The answer holds:

  • status: ok, warning or error;
  • file: what Seshat read of the file (pages, sizes, colours, fonts, pictures);
  • findings: one entry per finding, each with its code and Seshat's decision;
  • explanation: a summary and a text per finding in the user's language, because explain was on;
  • file_id: the kept file, for the fix that may follow;
  • safety: the safety report of the file;
  • meta.usage: what the call cost, one line per item.

A Node.js file sent as bytes needs its name, so Seshat knows what it is. A path works too: check('/data/flyer.pdf', { order }) streams the file from disk.

Note: a multi-tenant app tells the package which of your customers a user belongs to, so usage shows per customer. See Tenants and languages.

Next