rekhu

Docs · Seshat

What do you want to do with the file?

Seshat knows PDFs and print files the way a prepress expert does. Pick your question: each tells you what to send, what comes back, and the one call it takes. Checks and fixes run on Rekhu's own servers in the EU, without an AI model; a model only writes explanations. What Seshat is, and its prices ↗

Install composer require rekhu/core (Laravel) or npm install @rekhu/core (Node.js). Send the file once with check or upload; Rekhu keeps it for a day, so every fix that follows takes its file_id. Several fixes go in one call, in a sensible order, as one charge.

Check a file

Is this file good to print, for this order?

Is my file ready to print?

Live

You send

The file (PDF, EPS, ZIP, JPG, PNG, TIFF, WEBP or BMP) and the order: width_mm, height_mm, bleed_mm, pages, colour, min_ppi, max_ink, profile.

You get back

Findings, each with a decision: fix (Seshat repairs it), ask (the customer chooses, with the options), refuse or note. Size, bleed, trim, resolution per picture, RGB and spot colours, fonts, total ink, pages, small text, thin lines, white overprint, transparency, text near the cut.

Laravel

$check = Rekhu::seshat()->check($path, $order);

Node.js

const check = await rekhu.seshat({ user }).check(file, { name: 'flyer.pdf', order });

Good to know: A ZIP is checked file by file. An order key Seshat does not know is refused, so a misspelt one never passes unnoticed.

Can the customer read why?

Live

You send

The same check with explain on; the language comes from the user.

You get back

A short explanation per finding in the customer's language, included in the check of the file.

Laravel

Rekhu::seshat()->check($path, $order, explain: true);

Node.js

await seshat.check(file, { name, order, explain: true });

Can the customer approve a proof?

Live

You send

A checked file and a page.

You get back

The page as a picture with the trim (green), bleed (blue) and safe zone (orange).

Laravel

Rekhu::seshat()->preview($fileId, page: 1);

Node.js

await seshat.preview(fileId, { page: 1 });

Is my file very large?

Live

You send

Any file up to 10 GB. The package sends a file over 20 MB in parts of 32 MB by itself; a part that fails is sent again, and an upload that stopped goes on with resumeUpload.

You get back

A file_id, kept for a day, with its safety report. check, fix and the other calls take the file_id; Seshat works on files up to 2 GB in one piece.

Laravel

$file = Rekhu::seshat()->uploadInParts($path); Rekhu::seshat()->check($file['file_id'], $order);

Node.js

const file = await seshat.uploadInParts('/path/catalogue.pdf'); await seshat.check(file.file_id, { order });

Good to know: The file goes straight to storage, part by part: nothing waits for the whole file to be in memory, on your side or ours.

Is the file safe?

Live

You send

Nothing extra: every file a customer sends is checked before Seshat works on it.

You get back

safety in the answer: clean, remove (scripts, embedded files, forms that send data or media; the fix clean_up takes them out) or refuse (a virus, a program inside the file or one that starts a program, a file that is not what its name says, a picture built to exhaust memory). A refused file is not kept.

Laravel

$check['safety']['verdict'];

Node.js

check.safety.verdict;

Good to know: Every file is scanned for viruses with signatures updated every day, and read for what it really is, not what its name says.

Which codes and fixes are there?

Live

You send

Nothing.

You get back

Every finding code, decision, fix and option, and every order key, as one versioned list to map your own names against. Free.

Laravel

Rekhu::seshat()->codes();

Node.js

await seshat.codes();

Ready to print

The mistakes people make who are not designers, found before the press does.

Is the file finished?

Live

You send

Nothing extra: every check looks for it.

You get back

Placeholder text (Lorem ipsum, "your text here", XXX), a picture bank's name on a stock photo, crop marks drawn into the artwork, screenshots, empty pages, damaged pictures and shapes or text that are fully transparent. Each finding says where it is: page and box.

Laravel

$check = Rekhu::seshat()->check($path, $order);

Node.js

const check = await seshat.check(file, { name, order });

Good to know: Switch these finer checks off with checks: false in the order.

Typos and wrong phone numbers?

Live

You send

The file; language in the order, or found by itself (en, nl, de, fr, es, it, pt).

You get back

Phone numbers, email addresses, web addresses and dates that cannot be right, words typed twice, and words the language does not know with a suggestion. Names and brands with capitals are left alone.

Laravel

Rekhu::seshat()->check($path, $order + ['language' => 'nl']);

Node.js

await seshat.check(file, { name, order: { ...order, language: 'nl' } });

Black that will not dry?

Live

You send

The file. The check finds small text in rich black, black made of the colour inks only, and large areas of four-colour black.

You get back

pure_black_text sets the text in black only; fix_rich_black sets black areas to C60 M40 Y40 K100.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'fix_rich_black'], ['fix' => 'pure_black_text']], $order);

Node.js

await seshat.fix(id, [{ fix: 'fix_rich_black' }, { fix: 'pure_black_text' }], order);

Cut lines, white ink, varnish, foil?

Live

You send

The file. Seshat knows them by the name of their spot colour or layer (CutContour, Stanz, White, Varnish, Foil and many more) and a cut line by its use.

You get back

technical_colours lists them; technical_knocks_out when one would cut a hole in the artwork. set_overprint fixes that.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'set_overprint']], $order);

Node.js

await seshat.fix(id, [{ fix: 'set_overprint' }], order);

Want a cut line around a sticker?

Live

You send

The file, and offset_mm (0 on the edge, more outside it). With die_cut in the order, or the preset stickers, the check asks for one.

You get back

A cut line around the shape of the artwork in the spot colour CutContour, overprinting, the number of shapes per page.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'add_cut_contour', 'offset_mm' => 2]], $order);

Node.js

await seshat.fix(id, [{ fix: 'add_cut_contour', offset_mm: 2 }], order);

Cut lines drawn twice or left open?

Live

You send

The file. The check finds cut lines drawn twice (the plotter would cut twice) and ones that do not close.

You get back

clean_cut_lines takes out the second copy and closes a line that stops less than 1 mm short of its start.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'clean_cut_lines']], $order);

Node.js

await seshat.fix(id, [{ fix: 'clean_cut_lines' }], order);

A banner with grommets?

Live

You send

grommets in the order (or the preset banner): true, or spacing_mm, offset_mm and diameter_mm.

You get back

Grommet marks in the spot colour Grommets at every corner and along every edge, at most spacing_mm apart; the check asks for them when they are missing.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'add_grommets', 'spacing_mm' => 500]], $order);

Node.js

await seshat.fix(id, [{ fix: 'add_grommets', spacing_mm: 500 }], order);

Letters that will not print, lines too thin?

Live

You send

Nothing extra.

You get back

letters_missing when text uses letters its font does not hold (an empty box on paper); shapes_thin and white_thin when parts of shapes, or white on a dark ground, are thinner than min_line_pt, measured on the page itself.

Laravel

$check = Rekhu::seshat()->check($path, $order);

Node.js

const check = await seshat.check(file, { name, order });

Good to know: Text and pictures are left out of the thin check: they have their own.

Hidden layers or hidden text?

Live

You send

Nothing extra.

You get back

The layers, which ones are hidden (clean_up removes them), text covered by a picture, and text the trim cuts through.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'clean_up', 'option' => 'remove']], $order);

Node.js

await seshat.fix(id, [{ fix: 'clean_up', option: 'remove' }], order);

Good to know: Every fix keeps the file's layers.

Will the barcode scan?

Live

You send

Nothing extra: barcodes and QR codes on the first pages are read.

You get back

What each code says, its size, and barcode_problem when it is too small, has too little white around it or is printed in colour inks.

Laravel

$check = Rekhu::seshat()->check($path, $order);

Node.js

const check = await seshat.check(file, { name, order });

Want a barcode or QR code?

Live

You send

type (qr, ean13 or code128), value, page, x_mm and y_mm from the bottom left of the trim, size_mm.

You get back

The code drawn as shapes in 100 % black. An EAN-13 of 12 digits gets its check digit.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'add_barcode', 'type' => 'qr', 'value' => 'https://example.com', 'x_mm' => 10, 'y_mm' => 10, 'size_mm' => 20]], $order);

Node.js

await seshat.fix(id, [{ fix: 'add_barcode', type: 'ean13', value: '871234567890', x_mm: 10, y_mm: 10 }], order);

See every plate?

Live

You send

A kept file, the page, dpi (36–300) and the profile.

You get back

Every plate (cyan, magenta, yellow, black and each spot colour) as a picture with its ink coverage, the highest total ink, and a proof of the page as printed, with overprint, through the profile (the file's own output intent when none is named). Send max_ink and you also get a heat map: the page in grey, amber where the total ink is over that limit, red where it is far over.

Laravel

Rekhu::seshat()->plates($id, page: 1);

Node.js

await seshat.plates(id, { page: 1 });

Good to know: Ink coverage per plate is also what a price per print run needs.

What changed since the last version?

Live

You send

Two kept files: the new one and the earlier one.

You get back

What changed in the file (sizes, colours, fonts), and per page the words added and removed and the areas that look different, with a picture of the page with the changes marked.

Laravel

Rekhu::seshat()->compareFiles($newId, $oldId);

Node.js

await seshat.compareFiles(newId, oldId);

Good to know: For reorders and approvals: the customer sees at once what they changed.

A report for the customer?

Live

You send

A kept file, the order or a recipe, the language (en, nl, de, fr) and, if you like, your own sentence per code.

You get back

A PDF: every page with a numbered mark where each problem is, and what was found, in plain words.

Laravel

Rekhu::seshat()->report($id, $order, language: 'nl');

Node.js

await seshat.report(id, { order, language: 'nl' });

The same checks for every product?

Live

You send

A recipe: a name, the order (on a preset: the GWG 2015 kinds of print gwg_sheet_cmyk, gwg_sheet_spot, gwg_web_cmyk, gwg_web_spot, gwg_magazine_ads, gwg_newspaper_ads, gwg_newsprint, each also with _rgb; or sheetfed_offset, sheetfed_uncoated, digital, newspaper, large_format, banner, stickers, pdfx4) and the fixes.

You get back

check, fix and report take recipe: the name. Order keys sent with the call win. With strict_colour, RGB is an error. Recipes are free.

Laravel

Rekhu::seshat()->saveRecipe('A5 flyer', ['preset' => 'sheetfed_offset', 'width_mm' => 148, 'height_mm' => 210], 'auto'); Rekhu::seshat()->fix($id, recipe: 'A5 flyer');

Node.js

await seshat.saveRecipe('A5 flyer', { order: { preset: 'sheetfed_offset', width_mm: 148, height_mm: 210 }, fixes: 'auto' }); await seshat.fix(id, null, {}, { recipe: 'A5 flyer' });

Size and bleed

The file is not the size of the order.

Want to resize?

Live

You send

The file and the ordered size. Option scale (same shape), fit (all of it, white edges) or fill (cropped, covering the bleed too).

You get back

The file at the size, with the size each page had before (from_mm) and the factor.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'scale_to_size', 'option' => 'fill']], $order);

Node.js

await seshat.fix(id, [{ fix: 'scale_to_size', option: 'fill' }], order);

Want bleed?

Live

You send

The file and bleed_mm in the order.

You get back

The page with its edges mirrored outwards, the trim and bleed boxes set. Bleed the file already has is kept as it was made; only the rest is mirrored.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'add_bleed']], $order);

Node.js

await seshat.fix(id, [{ fix: 'add_bleed' }], order);

Want crop marks?

Live

You send

The file. Option crop or crop_registration (also registration targets).

You get back

Marks outside the bleed in registration colour; the page made larger to hold them, the trim and bleed boxes in place.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'add_marks', 'option' => 'crop_registration']], $order);

Node.js

await seshat.fix(id, [{ fix: 'add_marks', option: 'crop' }], order);

Colour

The colours must print as the customer expects.

Want everything in CMYK?

Live

You send

The file.

You get back

RGB, Lab and spot colours converted to CMYK, printing exactly as the separations would (overprint kept, each object's rendering intent), for the file's own output intent; CMYK made for the same printing condition keeps its exact values.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'convert_cmyk']], $order);

Node.js

await seshat.fix(id, [{ fix: 'convert_cmyk' }], order);

Want a real print profile?

Live

You send

The file and the profile: fogra39, fogra39_300, fogra51, fogra52 (uncoated), gracol2013, swop2013, newspaper.

You get back

RGB, Lab and spot colours converted through the profile, as convert_cmyk does; CMYK of the same printing condition kept; the profile set as the file's output intent.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'convert_profile', 'option' => 'fogra51']], $order);

Node.js

await seshat.fix(id, [{ fix: 'convert_profile', option: 'fogra51' }], order);

Too much ink?

Live

You send

The file, and the limit in % (else the order's max_ink).

You get back

Colours and CMYK pictures under the limit: cyan, magenta and yellow lowered together, black kept. How many colours and pictures changed.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'reduce_ink', 'limit' => 300]], $order);

Node.js

await seshat.fix(id, [{ fix: 'reduce_ink', limit: 300 }], order);

Black text in four colours?

Live

You send

The file.

You get back

Text in rich black set in black only, so small type stays sharp; black areas keep their rich black.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'pure_black_text']], $order);

Node.js

await seshat.fix(id, [{ fix: 'pure_black_text' }], order);

White that would disappear?

Live

You send

The file. The check decides this fix on its own.

You get back

Overprint switched off for white and back on after, so black text keeps overprinting.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'white_knockout']], $order);

Node.js

await seshat.fix(id, [{ fix: 'white_knockout' }], order);

A spot colour spelt two ways?

Live

You send

The file, from and to, several in one call.

You get back

The spot colour renamed wherever the file defines it; spelling and spaces do not matter.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'rename_spot', 'from' => 'Pantone 286C', 'to' => 'PANTONE 286 C']], $order);

Node.js

await seshat.fix(id, [{ fix: 'rename_spot', from: 'Pantone 286C', to: 'PANTONE 286 C' }], order);

Print standard

The printer asks for PDF/X.

Want PDF/X?

Live

You send

The file, option x4 or x1a (transparency flattened), and a profile.

You get back

A file converted through the profile with its output intent, a trim box on every page and the PDF/X identification. When something stops it, such as a font that cannot be embedded, the answer names it.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'embed_fonts'], ['fix' => 'make_pdfx', 'option' => 'x4', 'profile' => 'fogra39']], $order);

Node.js

await seshat.fix(id, [{ fix: 'embed_fonts' }, { fix: 'make_pdfx', option: 'x4', profile: 'fogra39' }], order);

Good to know: Seshat makes the file to the rules of the standard; for a certified check, run it through your printer's validator.

Fonts and text

Fonts are missing, a word must change, or one template makes many copies.

Fonts missing in the file?

Live

You send

The file. Option lookalike for fonts the library does not have.

You get back

The real font from a library of 770 open-licence fonts, or a named look-alike that carries its own name inside the file. Per font: same, lookalike, not available or not possible.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'embed_fonts']], $order);

Node.js

await seshat.fix(id, [{ fix: 'embed_fonts' }], order);

Good to know: A font is never swapped without a word.

Want to change a word?

Live

You send

The file, find and replace, several in one call; optionally to, a library font.

You get back

The new text at the same place and size: in the file's own font when it has the letters, else the same font from the library, else to. What could not be set, with the missing letters.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'replace_text', 'find' => 'Summer sale', 'replace' => 'Winter sale']], $order);

Node.js

await seshat.fix(id, [{ fix: 'replace_text', find: 'Summer sale', replace: 'Winter sale' }], order);

Good to know: A PDF has no paragraphs: a longer text does not re-wrap. A new paragraph belongs in the design. A placeholder an editor split into pieces is found whole.

Want to delete a text?

Live

You send

The file, find, and replace left empty.

You get back

The text gone from the page; nothing is drawn in its place. Text after it on the same line closes up.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'replace_text', 'find' => 'DRAFT', 'replace' => '']], $order);

Node.js

await seshat.fix(id, [{ fix: 'replace_text', find: 'DRAFT', replace: '' }], order);

Many copies of one template?

Live

You send

A PDF template with placeholders such as [name] and [grade], and the rows: one per copy, as { "[name]": "Sara", "[grade]": "A" }. Options: output zip or merged, name_by (name each file by a placeholder's value, in plain Latin letters), align center on a centred certificate, webhook_url.

You get back

A job: poll or wait for it. Then the files, a ZIP of one PDF per row or one merged PDF, per 250 copies (a ZIP sooner when it reaches about 50 MB), and a report per row: done, partly (with what was not found), missing letters. A name is set in the template's own font when the font holds its letters, else in the same font from the library.

Laravel

$job = Rekhu::seshat()->fillTemplate($path, $rows, ['name_by' => '[name]', 'align' => 'center']); Rekhu::seshat()->waitFor($job['job_id']);

Node.js

const job = await seshat.fillTemplate(file, rows, { name: 'certificate.pdf', nameBy: '[name]', align: 'center' }); await seshat.waitFor(job.job_id);

Good to know: The template is uploaded once; up to 5,000 rows a job, sent in steps of 1,000 by the package. Charged per copy that came out right; a copy only partly set (a name with a letter the font lacks) is free up to a tenth of the job. Words after a filled text move along on their line; a copy whose line would run off the page is reported as overflow.

Where does a text sit?

Live

You send

The file and find: a text or a list.

You get back

Per match: the page, its box in points from the bottom left corner, the font and the size it prints at. To place your own layer next to it.

Laravel

Rekhu::seshat()->textPositions($fileId, ['[name]', '[grade]']);

Node.js

await seshat.textPositions(fileId, ['[name]', '[grade]']);

Want another font?

Live

You send

The file, from (a font in the file) and to (a library font).

You get back

All text of that font set in the new one; per font how many texts changed and what could not.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'replace_font', 'from' => 'ArialMT', 'to' => 'Montserrat-Bold']], $order);

Node.js

await seshat.fix(id, [{ fix: 'replace_font', from: 'ArialMT', to: 'Montserrat-Bold' }], order);

Good to know: A font that is not in the library is refused with the closest names.

Fonts for your own editor?

Live

You send

Nothing, or a font name.

You get back

The 70 families with their styles and licences; a font file to download. Free.

Laravel

Rekhu::seshat()->fonts(); Rekhu::seshat()->fontFile('Montserrat-Bold');

Node.js

await seshat.fonts(); await seshat.fontFile('Montserrat-Bold');

Pages

The pages are not in the right shape or order.

Pages turned, removed or reordered?

Live

You send

The file and order (the pages in their new order; one left out is removed), rotate and blank_after.

You get back

The file with its pages as asked, and which were removed.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'pages', 'order' => [2, 1, 3], 'rotate' => [3 => 90]]], $order);

Node.js

await seshat.fix(id, [{ fix: 'pages', order: [2, 1, 3], rotate: { 3: 90 } }], order);

Files merged into one?

Live

You send

Two or more kept files, in order.

You get back

One file with all pages, and the pages per file.

Laravel

Rekhu::seshat()->merge([$cover, $inside]);

Node.js

await seshat.merge([cover, inside]);

A file split?

Live

You send

The file and page ranges such as 1-2 and 3-end.

You get back

One file per range.

Laravel

Rekhu::seshat()->split($id, ['1-2', '3-end']);

Node.js

await seshat.split(id, ['1-2', '3-end']);

Every page as a picture?

Live

You send

The file, png or jpg, dpi (36–600) and pages.

You get back

A picture per page, each a file to download: for a shop, a mockup or an e-mail.

Laravel

Rekhu::seshat()->render($id, 'jpg', 150);

Node.js

await seshat.render(id, { format: 'jpg', dpi: 150 });

Good to know: Up to 50 pages per call.

Pictures

A picture is not yet a print file, or too small.

A photo instead of a PDF?

Live

You send

The picture and the order. Option fill or fit.

You get back

A print PDF at the ordered size with bleed.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'picture_to_pdf', 'option' => 'fill']], $order);

Node.js

await seshat.fix(id, [{ fix: 'picture_to_pdf', option: 'fill' }], order);

Pictures too small for their size?

Live

You send

The file, with ai_enhance on for the application.

You get back

The pictures upscaled in place, with how many and from which to which ppi.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'upscale_ai']], $order);

Node.js

await seshat.fix(id, [{ fix: 'upscale_ai' }], order);

Good to know: Inside a PDF the pictures are upscaled on the main servers. For the sharpest result, send the picture through enhance, which runs on the GPU.

One picture improved?

Live

You send

A picture and the modes: upscale, restore, denoise, sharpen, remove or replace the background (a picture, a colour or a description), extend, remove an object, vectorise.

You get back

The improved picture; a large one as a job with a webhook. Extend grows a side by up to its own length; an object can cover up to 60 % of the picture.

Laravel

Rekhu::seshat()->enhance($picture, ['upscale'], ['ppi' => 300]);

Node.js

await seshat.enhance(picture, ['upscale'], { ppi: 300 }, { name: 'photo.jpg' });

Good to know: Runs on Rekhu's own GPU server in the EU; nothing is kept after the answer.

Prepress

Lines, text, pictures and the file itself, ready for the press.

Lines too thin to print?

Live

You send

The file; min_pt, else the order's min_line_pt (0.25 pt).

You get back

Every thinner line, hairlines included, drawn at the minimum; how many changed. The check offers this fix itself.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'thicken_lines', 'min_pt' => 0.3]], $order);

Node.js

await seshat.fix(id, [{ fix: 'thicken_lines', min_pt: 0.3 }], order);

Text as outlines?

Live

You send

The file.

You get back

All text turned into shapes, so no font is needed to print it.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'outline_text']], $order);

Node.js

await seshat.fix(id, [{ fix: 'outline_text' }], order);

Good to know: Outlined text can no longer be edited or searched; keep the original.

Pictures far heavier than needed?

Live

You send

The file and ppi (else 300).

You get back

Pictures above one and a half times that resolution brought down to it; the size before and after.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'downsample', 'ppi' => 300]], $order);

Node.js

await seshat.fix(id, [{ fix: 'downsample', ppi: 300 }], order);

Good to know: No other fix changes a picture's resolution.

A smaller file?

Live

You send

The file.

You get back

The same file written compactly: unused objects dropped, streams compressed.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'make_smaller']], $order);

Node.js

await seshat.fix(id, [{ fix: 'make_smaller' }], order);

Forms, comments and hidden layers?

Live

You send

The file. Option flatten (default) or remove.

You get back

Form fields and comments drawn into the page as they show, or left out; hidden layers, scripts, attachments and links removed; what was found.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'clean_up']], $order);

Node.js

await seshat.fix(id, [{ fix: 'clean_up' }], order);

The press cannot take transparency?

Live

You send

The file.

You get back

Transparency flattened.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'flatten_transparency']], $order);

Node.js

await seshat.fix(id, [{ fix: 'flatten_transparency' }], order);

Imposition

The items must go on press sheets.

As many items on a sheet as fit?

Live

You send

The file with bleed, option nup, the sheet (sra4, sra3, sra2, sra1, a4–a1, b2, b1, 50x70, 70x100 or [width, height] in mm), gap_mm, margin_mm (5), and repeat (each sheet one page) or not (pages in sequence).

You get back

Press sheets with the items in a grid, turned when more fit that way; how many across, down and per sheet.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'impose', 'option' => 'nup', 'sheet' => 'sra3', 'gap_mm' => 2]], $order);

Node.js

await seshat.fix(id, [{ fix: 'impose', option: 'nup', sheet: 'sra3', gap_mm: 2 }], order);

A booklet?

Live

You send

The pages, option booklet.

You get back

Sheet sides of two pages in saddle-stitch order, padded with blank pages to a multiple of four.

Laravel

Rekhu::seshat()->fix($id, [['fix' => 'impose', 'option' => 'booklet']], $order);

Node.js

await seshat.fix(id, [{ fix: 'impose', option: 'booklet' }], order);

Coming

Decided, next.

Packaging?

Coming

You send

The file.

You get back

Cut lines and dielines found and checked.

Barcodes and QR codes?

Coming

You send

The file and the data.

You get back

Codes made and placed, checked for print.

A copy per record?

Coming

You send

The file and a list.

You get back

Variable data: names, numbers and pictures per copy.

What it costs

Per file and per fix. A file checked, up to 20 pages, is one line, with its explanation, report and proof included; each page beyond 20 is a small line of its own. Each fix made in the print-ready version is charged, at most 5 per file, and a fix that changed nothing is free. Plates, versions compared, pages as pictures, merge and split are extras. Listing codes and fonts, recipes, uploads and refused calls are free. The prices are in your account.