Schildwerk – Guide for AI agents
This page describes the Schildwerk website for agents. It is not a repository AGENTS.md.
Last updated
Content date 2026-10-07. Status stable. Profile creabyte-agents-v0.1. The same date is the Last-Modified value of this document.
Introduction
Schildwerk is a website that draws Tesla Paint Shop PNGs on the server. European plates are 50 country templates. The EU frame is 420 by 100 pixels. The NA frame is 420 by 200 pixels. Files stay under 500 KB. The audience is people who visualise a plate in the car, including a Tesla browser and a phone handoff. Schildwerk is not an official plate, not a print shop and not a vehicle registry.
Imprint
Operator: creabyte.com, Sole proprietorship (inactive), O. Meister, Patriotenweg 9, 4500 Solothurn, Switzerland. UID CHE-104.790.761. Source: https://creabyte.com/impressum, machine-readable at https://creabyte.com/imprint/v1.json. The imprint page is /imprint.
Contact
Phone +41 62 390 11 22, the contact form at https://creabyte.com/contact, the email address for legal matters shown on /imprint. No support promise is published.
How agents can act
- (a) Read and cite — available. Public pages, Markdown mirrors and this guide.
- (b) Prepare a request a person submits — available. Login, register, save, upload, USB ZIP, key management and confirmation links are browser forms. The person submits them.
- (c) Run a function via URL parameters — available for side-effect-free GET tools (render-png, countries). GET does not debit anything. There is no credit ledger.
- (d) Act for a person with an agent key, with a login — available, scoped to that person, audited. The key is narrower than or equal to the person. It is never an admin key.
Tooling
Five tools. Full descriptions stay on this page. There is no /tools.md.
render-png
- Name: render-png (Render a plate PNG)
- Purpose: Draw one Tesla-size plate PNG.
- Method: GET https://t9t.ch/demos/schildwerk/p.png?c={c}&t={t}&f={f}&m={m}&e={e}&s={s}&r={r}&d={d}&ff={ff}&x={x}
- Parameters:
cstring, unit country code, range AD, AL, AM, AT, AZ, BA, BE, BG, BY, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GE, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MC, MD, ME, MK, MT, NL, NO, PL, PT, RO, RS, RU, SE, SI, SK, SM, TR, UA, VA, XK, optional, default CH, example CHtstring, unit characters, range 0 to 32 after normalize. Empty (t=) draws the plate without characters: band, shields and colour only, required, default none, example ZH 123456fenum, unit frame, range eu, na, optional, default eu, example eumenum, unit mode, range complete, background, optional, default complete, example completeeenum, unit emblem, range flag, shield, none. Omitted: shield when c is CH, otherwise flag, optional, default shield for CH, flag otherwise, example shieldsenum, unit side, range front, rear, optional, default rear, example rearrstring, unit region, range 0 to 3 letters or digits, optional, default empty, example 75denum, unit separator, range on, off. Mid-height dot between canton and number (CH/LI). Default on, optional, default on, example onpenum, unit variant, range Colour or type variant of the country plate. CH: red, mil (military, text like M 56627). FR: yellow, black. GB: black. NL: blue. Omit for the standard plate. Other countries have none, optional, default empty (standard plate), example milffenum, unit face, range Face id for CH and Spass plates: creabyte-plate, d-din-condensed, alte-din, ibm-plex-condensed, tex-gyre-heros-cn, liberation-narrow, racing-sans, barlow-condensed, oswald, roboto-condensed, sofia-sans-condensed, archivo-narrow, overpass, big-shoulders, black-ops-one, bungee, press-start-2p, monoton, tilt-neon, russo-one, snv, penitentiary, arial-narrow, helvetica-neue-condensed, lineto. Optional (commercial/system) faces only when installed, optional, default d-din-condensed; with x the template face, example barlow-condensedxenum, unit Spass template, range Novelty plate, not official: herz, agent, kein-schild, spiegel, gold, carbon, neon, taxi. Omit for a country plate. With x, c/e/s/r/d are ignored and t may be omitted (template sample), optional, default empty (country plate), example neonformatenum, unit description, range md, optional, default omit for image/png, example md- Example request: GET /p.png?c=CH&t=ZH%20123456&f=eu&m=complete&e=shield&s=rear&d=on&ff=d-din-condensed
- Example response: Spass example: GET /p.png?x=neon&t=NEON. PNG image/png, 420×100, under 500 KB. A Markdown description (Accept: text/markdown or format=md) names the country, the text, fidelity (interim or font-exact) and the same URL. It is not the PNG bytes.
- Response formats: image/png for the picture. Markdown for the description and for errors, via Accept: text/markdown, /p.md or format=md.
- Auth: none
- Side effects: none. No credit is debited. Schildwerk has no credit ledger.
- Limits: About 90 PNG renders per minute per client IP. The published figure is soft. The hard counter uses REMOTE_ADDR and does not trust X-Forwarded-For until the host passes the client IP on a trusted hop.
countries
- Name: countries (List countries)
- Purpose: List the country codes the renderer accepts.
- Method: GET https://t9t.ch/demos/schildwerk/countries.md
- Parameters:
formatenum, unit body, range md, html, optional, default md on /countries.md, html on /countries, example md- Example request: GET /countries.md
- Example response: Markdown list of country codes and names, plus the sample plate text and fidelity (interim or font-exact). Count matches the catalog.
- Response formats: Markdown via /countries.md, Accept: text/markdown or format=md. HTML via /countries.
- Auth: none
- Side effects: none
- Limits: Read-only. Any query parameter other than format is rejected with 400.
save-plate
- Name: save-plate (Save a plate)
- Purpose: Save a plate on the key owner account.
- Method: POST https://t9t.ch/demos/schildwerk/api/plates with Authorization: Bearer
- Parameters:
cstring, unit country code, range catalog codes, required, default none, example CHtstring, unit characters, range 0 to 32 after normalize. Empty (t=) draws the plate without characters: band, shields and colour only, required, default none, example ZH 123456fenum, unit frame, range eu, na, optional, default eu, example eumenum, unit mode, range complete, background, optional, default complete, example completeeenum, unit emblem, range flag, shield, none. Omitted: shield when c is CH, otherwise flag, optional, default shield for CH, flag otherwise, example shieldsenum, unit side, range front, rear, optional, default rear, example rearrstring, unit region, range 0 to 3 letters or digits, optional, default empty, example ZHdenum, unit separator, range on, off. Mid-height dot between canton and number (CH/LI). Default on, optional, default on, example onpenum, unit variant, range Colour or type variant of the country plate. CH: red, mil (military, text like M 56627). FR: yellow, black. GB: black. NL: blue. Omit for the standard plate. Other countries have none, optional, default empty (standard plate), example milffenum, unit face, range Face id for CH and Spass plates: creabyte-plate, d-din-condensed, alte-din, ibm-plex-condensed, tex-gyre-heros-cn, liberation-narrow, racing-sans, barlow-condensed, oswald, roboto-condensed, sofia-sans-condensed, archivo-narrow, overpass, big-shoulders, black-ops-one, bungee, press-start-2p, monoton, tilt-neon, russo-one, snv, penitentiary, arial-narrow, helvetica-neue-condensed, lineto. Optional (commercial/system) faces only when installed, optional, default d-din-condensed; with x the template face, example barlow-condensedxenum, unit Spass template, range Novelty plate, not official: herz, agent, kein-schild, spiegel, gold, carbon, neon, taxi. Omit for a country plate. With x, c/e/s/r/d are ignored and t may be omitted (template sample), optional, default empty (country plate), example neontitlestring, unit characters, range 1 to 80, optional, default country plus text, example Zurich- Example request: POST /api/plates
Authorization: Bearer swk_…
Content-Type: application/x-www-form-urlencoded
c=CH&t=ZH%20123456&f=eu&title=Zurich
- Example response: Markdown (default for a key with no Accept header) with public_id, title and the audit phrase. Accept: application/json returns the same fields as JSON.
- Response formats: Markdown by default for agent-key calls. JSON when Accept is application/json. Errors are Markdown unless JSON was requested.
- Auth: Agent key, scope save_plate. Scope is at most the user rights. Never admin.
- Side effects: Inserts one library row. Audited as person <id> via agent key <name>.
- Limits: 40 saves per 10 minutes per account, same order as the human save limit.
usb-zip
- Name: usb-zip (Download a USB ZIP)
- Purpose: Download a ZIP of the owner plates with paths under LicensePlate/.
- Method: POST https://t9t.ch/demos/schildwerk/api/usb-zip with Authorization: Bearer
- Parameters:
plateslist of strings, unit public id, range 1 to 10 ULID public ids owned by the account, required, default none, example 01ARZ3NDEKTSV4RRFFQ69G5FAV- Example request: POST /api/usb-zip
Authorization: Bearer swk_…
plates[]=01ARZ3NDEKTSV4RRFFQ69G5FAV
- Example response: application/zip on success (max 10 PNGs, folder LicensePlate/). Errors are Markdown with 400 or 403.
- Response formats: application/zip for the file. Markdown for errors. The ZIP is not wrapped in Markdown.
- Auth: Agent key, scope usb_zip. A browser session with CSRF can still use POST /usb-set. The key does not use that form.
- Side effects: No library row is created. The download is audited as person <id> via agent key <name>.
- Limits: 10 ZIP downloads per 10 minutes per account. At most 10 plates.
handoff-draft
- Name: handoff-draft (Mint a phone handoff)
- Purpose: Mint a 20-minute link so a phone opens the same draft.
- Method: POST https://t9t.ch/demos/schildwerk/handoff (browser form, CSRF). Not GET.
- Parameters:
cstring, unit country code, range catalog codes, optional, default CH, example CHtstring, unit characters, range 1 to 32 after normalize, optional, default country sample, example ZH 123456fenum, unit frame, range eu, na, optional, default eu, example eumenum, unit mode, range complete, background, optional, default complete, example completeeenum, unit emblem, range flag, shield, none. Omitted: shield when c is CH, otherwise flag, optional, default shield for CH, flag otherwise, example shieldsenum, unit side, range front, rear, optional, default rear, example rearrstring, unit region, range 0 to 3 letters or digits, optional, default empty, example 75denum, unit separator, range on, off. Mid-height dot between canton and number (CH/LI). Default on, optional, default on, example onpenum, unit variant, range Colour or type variant of the country plate. CH: red, mil (military, text like M 56627). FR: yellow, black. GB: black. NL: blue. Omit for the standard plate. Other countries have none, optional, default empty (standard plate), example milffenum, unit face, range Face id for CH and Spass plates: creabyte-plate, d-din-condensed, alte-din, ibm-plex-condensed, tex-gyre-heros-cn, liberation-narrow, racing-sans, barlow-condensed, oswald, roboto-condensed, sofia-sans-condensed, archivo-narrow, overpass, big-shoulders, black-ops-one, bungee, press-start-2p, monoton, tilt-neon, russo-one, snv, penitentiary, arial-narrow, helvetica-neue-condensed, lineto. Optional (commercial/system) faces only when installed, optional, default d-din-condensed; with x the template face, example barlow-condensedxenum, unit Spass template, range Novelty plate, not official: herz, agent, kein-schild, spiegel, gold, carbon, neon, taxi. Omit for a country plate. With x, c/e/s/r/d are ignored and t may be omitted (template sample), optional, default empty (country plate), example neoncsrfstring, unit token, range current browser session, required, default none, example session token- Example request: POST /handoff (form fields above, same-origin, CSRF). An agent prepares the form. The person submits it.
- Example response: JSON {"ok":true,"url","qr"} for the browser. The URL is /h?t=… and expires after 20 minutes.
- Response formats: application/json for the browser. This tool has no Markdown success body in 0.4.
- Auth: Browser session. An agent key does not mint a handoff in 0.4.
- Side effects: Stores one draft. No plate is saved to the library.
- Limits: 20 mints per 10 minutes per IP.
Rules for agents
Desired
- Citation uses the canonical URL of the page.
- GET /p.png is free of charge. No credit is debited, because Schildwerk has no credit product.
- Spass plates (x=) are novelty images, never official and never a police or authority plate. Describe them as Spass / not official.
- A face, font or seal that is interim or stylized is described that way. CH rear shields are a visualisation (federal left, canton right) and they are the CH default. The square flag is e=flag. Front (s=front) has no shields.
- Account, contact, profile, key management, emptying trash, paying and making a plate public go through the owner's confirmation link.
Not desired
- An invented imprint, phone number or price.
- Mail sent by an agent, an account change, or a payment, outside the confirmation link.
- A key placed in a URL, a cookie or a log line.
- Traffic above the published rate limit.
- Admin or staff routes. None are granted to a key.
Rate limits are published as soft numbers and they are enforced. By default the limiter keys on REMOTE_ADDR (Klarspur pattern). X-Forwarded-For is used only when the immediate peer is listed in config trusted_proxies.
Unpublished topics
Legal entity, contact addresses, prices, credit products and staff tools are not on the site. The owner is the person to ask. Guessing is not a substitute. Country codes that are published: AD, AL, AM, AT, AZ, BA, BE, BG, BY, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GE, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MC, MD, ME, MK, MT, NL, NO, PL, PT, RO, RS, RU, SE, SI, SK, SM, TR, UA, VA, XK.
Limits
- PNG render: about 90 per minute per IP (GET /p.png).
- Handoff mint: 20 per 10 minutes per IP (browser only).
- Save: 40 per 10 minutes per account.
- USB ZIP: 10 per 10 minutes per account, max 10 plates, paths forced under LicensePlate/.
- Confirmation link TTL: 24 hours, which is also the maximum. Single use.
- Catalog size: 50 countries.
Authorization
A person creates a key in the browser at /account/keys. The secret is shown once and stored only as a hash. Fields kept: name, expiry, prefix, scope. Revocation is one click in that session.
The key travels as Authorization: Bearer. It is not a cookie and not a query parameter.
Default scope equals the person's plate rights: save_plate, usb_zip, trash, restore. Scope can be narrowed in the browser. Widening asks for the person's password. A key cannot create or widen keys. Those requests return a confirmation link.
Direct with a key, audited: save the person's own plate, download a USB ZIP of the person's own plates, soft-delete a plate, restore a plate from trash, render a PNG (also anonymous).
Confirmation link, even with scope equal to the person: profile name, contact email, password, account deletion, key create, key revoke, key update, emptying trash (hard delete), pay, make a plate public. The person opens the link while logged in. GET changes nothing. POST approves or rejects. The page shows the action and the key name.
Soft-delete is direct and restorable. Emptying trash is permanent and needs the link.
Audit phrase: person <id> via agent key <name>. Approvals and rejections use the same phrase. The person can read the log at /account/audit.
On text pages and text API responses, Markdown is the default body for a key request that sends no Accept header. An explicit Accept header wins. Image endpoints such as GET /p.png stay image/png even with a Bearer key and no Accept; Markdown for those is only via Accept: text/markdown, /p.md or format=md. ZIP downloads stay application/zip.
Languages
The product UI is de-CH. Agent-facing documents, including this page, are English. Plate images do not carry a locale.
Pricing
No public price list. PNG renders are not billed. There is no credit product to buy. A pay action still requires a confirmation link and, on approval, records that nothing was charged.
Known limitations
- Most country fonts are interim (Alte DIN), not the official plate face.
- Germany uses GL-Nummernschild. Seals stay stylized.
- The Netherlands use Kenteken (LeFly, CC BY-SA 3.0), marked as an interpretation.
- CH and GB stay on the interim face. CH rear default is the federal shield on the left and the cantonal shield on the right (public-domain Wikimedia visualisations, not official plate art). s=front omits both. e=flag keeps the square federal flag.
- GB and CY support a white front and a yellow rear.
- CH shields are visualisations from public-domain files, not a claim that the PNG is an official plate. No print, SVG or PDF export.
Canonical links
- https://t9t.ch/demos/schildwerk/
- https://t9t.ch/demos/schildwerk/generator
- https://t9t.ch/demos/schildwerk/guide
- https://t9t.ch/demos/schildwerk/credits
- https://t9t.ch/demos/schildwerk/library
- https://t9t.ch/demos/schildwerk/uploads
- https://t9t.ch/demos/schildwerk/countries
- https://t9t.ch/demos/schildwerk/agents
- https://t9t.ch/demos/schildwerk/imprint
- https://t9t.ch/demos/schildwerk/privacy
Machine-readable files
- https://t9t.ch/demos/schildwerk/agents.md
- https://t9t.ch/demos/schildwerk/llms.txt
- https://t9t.ch/demos/schildwerk/robots.txt
- https://t9t.ch/demos/schildwerk/sitemap.xml
No /tools.md. No OpenAPI file. No /agents.json.