Editing click paths through the API
The REST endpoints for click paths, sign-in flows and test runs, with examples, rights and error codes – for your own scripts without an AI assistant.
This article describes the endpoints through which your own scripts draft and try click paths and the steps of a multi-step sign-in. An AI assistant uses the same rules through the MCP server (Describing sign-in and click paths). The step language itself is described in Describing sign-in and click paths.
Token and rights
You need a token bound to the website that carries the right “Edit click paths”. How to create it is described in Describing sign-in and click paths. With this right the token gets two abilities: journeys:read for reading and checking, journeys:write for saving drafts and starting test runs.
Every request carries the token as a header; the base address is https://barrierepruefung.de/api/v1:
Authorization: Bearer YOUR_TOKEN
Accept: application/json
Accept-Language: en
{site} in the paths is the “Site ID” from the “Embedding” tab. For any other website the API answers 404. Texts in responses follow Accept-Language (de or en). Writing calls optionally take actor_name: the name under which your system knows the acting person. It is recorded on the draft as evidence; the responsible person remains whoever granted the right.
Endpoints
| Method | Path | Right | Purpose |
|---|---|---|---|
GET |
/sites/{site}/journeys |
read | all click paths with status, steps and draft |
GET |
/sites/{site}/journeys/{id} |
read | one click path |
POST |
/sites/{site}/journeys/pruefen |
read | check steps without saving |
POST |
/sites/{site}/journeys |
write | create a new click path as a draft |
PUT |
/sites/{site}/journeys/{id}/entwurf |
write | set the draft of an existing click path |
DELETE |
/sites/{site}/journeys/{id}/entwurf |
write | discard the draft; running steps stay |
GET |
/sites/{site}/anmeldung |
read | the sign-in steps, without credentials |
PUT |
/sites/{site}/anmeldung/entwurf |
write | propose the steps of a multi-step sign-in |
POST |
/sites/{site}/probelaeufe |
write | start a test run |
GET |
/sites/{site}/probelaeufe/{id} |
read | state and result of a test run |
The schema of the step language is available without a token at https://barrierepruefung.de/api/v1/schema/klickpfad.json and https://barrierepruefung.de/api/v1/schema/anmeldeablauf.json (JSON Schema 2020-12).
Approving and deleting are not available through the API. Neither are credentials: no user name, password or one-time code secret, no sign-in services and no confirmation for them are set or returned.
Checking steps
POST /sites/{site}/journeys/pruefen with steps and optionally stop_before saves nothing and always answers 200. An invalid path is the result here:
{
"gueltig": false,
"fehler": [
{
"code": "selektor_nicht_erlaubt",
"schritt": 2,
"feld": "selector",
"text": "Schritt 2: Der Selektor enthält unerlaubte Zeichen. Erlaubt sind CSS-Selektoren, role=… und text=…."
}
],
"bereinigt": [
{"action": "goto", "url": "/warenkorb"},
{"action": "click", "selector": "xpath=//button"}
]
}
The sentence in text is currently German only; use code, schritt and feld to react.
Saving a draft
POST /sites/{site}/journeys creates a new click path with name, steps and optionally stop_before. It then has no running steps, only a draft. PUT /sites/{site}/journeys/{id}/entwurf sets the draft of an existing path; its name stays, and so do its running steps.
{
"name": "Checkout",
"steps": [
{"action": "goto", "url": "/warenkorb"},
{"action": "click", "selector": "role=button[name=\"Zur Kasse\"]"}
],
"stop_before": "role=button[name=\"Zahlungspflichtig bestellen\"]",
"actor_name": "Build script"
}
The response (201 on creation, otherwise 200) describes the path:
{
"data": {
"id": 42,
"name": "Checkout",
"status": "entwurf",
"schritte": [],
"stop_before": null,
"entwurf": {
"schritte": [
{"action": "goto", "url": "/warenkorb"},
{"action": "click", "selector": "role=button[name=\"Zur Kasse\"]"}
],
"stop_before": "role=button[name=\"Zahlungspflichtig bestellen\"]",
"von": {"weg": "api", "name": "Build script", "token_name": "Build"},
"am": "2026-10-30T09:15:00+00:00"
},
"freigegeben": null,
"letzter_lauf": {
"status": "gescheitert",
"am": "2026-10-30T03:12:44+00:00",
"lauf_id": "01JBX0A2C4E6G8H1J3K5M7N9P0",
"seitdem_geaendert": false,
"grund": null,
"befund": {
"code": "element_versteckt",
"schritt": 2,
"schritte": 2,
"aktion": "click",
"selektor": "role=button[name=\"Zur Kasse\"]",
"viewport": "mobile",
"befund": {"treffer": 1, "sichtbar": 0},
"ueberschrift": "Schritt 2 von 2 gescheitert (click, Mobil, 390 px)",
"erklaerung": "Der Selektor trifft ein Element, es ist aber nicht sichtbar.",
"hinweis": "Wählen Sie ein Element, das in dieser Breite sichtbar ist, …"
}
},
"freigabe_url": "…/websites/…/pruefung"
}
}
status is entwurf (draft), freigegeben (approved) or freigegeben_mit_entwurf (approved, with a draft). letzter_lauf is null as long as the path has not appeared in a completed scan. Otherwise it holds the state in the last scan: status is erfolgreich (succeeded), gescheitert (failed) or nicht_geprueft (not checked; this is not a failure of the path: sign-in, throttling, deadline, budget or proxy prevented the check, the reason is in grund), am and lauf_id name the scan, seitdem_geaendert is true if the path was approved after it. Only for gescheitert is befund set: code is one of the codes in Describing sign-in and click paths, schritt, schritte, aktion, selektor and viewport say where, befund holds the measured values (treffer, sichtbar, erster_sichtbar, erster_bedienbar, abgeloest, navigiert, adresse; not all of them for every code), and ueberschrift, erklaerung and hinweis are texts in the language of the request. Branch on code, not on the texts.
At freigabe_url a person approves the draft (Describing sign-in and click paths).
For a multi-step sign-in, PUT /sites/{site}/anmeldung/entwurf with schritte proposes the steps, with placeholders instead of credentials (Describing sign-in and click paths). This works only if a credential of that kind already exists in the “Testing” tab; otherwise the API answers 404, and for a simple sign-in form kein_ablauf.
Test runs
POST /sites/{site}/probelaeufe starts a test run and answers 202 straight away. It needs exactly one source:
{"journey_id": 42, "quelle": "entwurf"}or"quelle": "freigegeben": a saved click path. If a credential is active, the test run signs in first, like a scan.{"anmeldung": "entwurf"}: only the draft of the sign-in.{"schritte": [...], "stop_before": "…"}: unsaved steps, without sign-in.
Poll the state with GET /sites/{site}/probelaeufe/{id} until status is no longer wartet or laeuft:
{
"data": {
"id": "01JBX3K7Q8M4V2N6P0R5S9T1W3",
"status": "fertig",
"quelle": "entwurf",
"journey_id": 42,
"mit_anmeldung": false,
"erfolgreich": false,
"grund": null,
"schritte": [
{"nr": 1, "viewport": "desktop", "action": "goto", "ok": true, "grund": null, "adresse": "https://www.example.org/warenkorb", "aria": "- main: …", "befund": null, "bild_url": "…"},
{"nr": 2, "viewport": "desktop", "action": "click", "ok": false, "grund": "klick_abgelehnt:nicht_gefunden", "adresse": "https://www.example.org/warenkorb", "aria": "- main: …", "befund": {"code": "klick_abgelehnt:nicht_gefunden", "schritt": 2, "schritte": 2, "aktion": "click", "selektor": "role=button[name=\"Zur Kasse\"]", "viewport": "desktop", "befund": {"treffer": 0, "sichtbar": 0}, "ueberschrift": "…", "erklaerung": "…", "hinweis": "…"}, "bild_url": "…"}
],
"anmeldung": null,
"dauer_ms": 5120,
"angelegt_am": "2026-10-30T09:16:00+00:00",
"fertig_am": "2026-10-30T09:16:07+00:00",
"loeschen_ab": "2026-10-31T09:16:00+00:00",
"freigabe_hinweis": "Before this path runs in scans, a person has to approve it in the ‘Testing’ tab: …"
}
}
status:wartet(waiting),laeuft(running),fertig(done),gescheitert(the test run failed as a whole, reason ingrund, for examplestart_fremder_host, a proxy error pageproxy_fehler:…,budget_ueberschritten,abgelaufenorscanner_veraltetduring an update) orabgelehnt(refused).erfolgreich:trueonly if the test run is done, no step failed and something actually succeeded (a step withok: trueor, for a sign-in-only test run, a successful sign-in);nullwhile it runs. Branch on this, not onstatus: afertigtest run can still have failed at a step.- A test run checks every width of the scan profile in turn and ends at the first failure.
schritteholds one entry per step and width;viewportisdesktop,mobileorreflow-320(older results without it count asdesktop). For a failed stepbefundhas the same shape as inletzter_lauf, includingselektor; otherwise it isnull. The image belongs to step and width. - Per step
ok:true,falseornullfor “not executed”. The test run ends at the first failure. The reasons are the same as in a scan (Describing sign-in and click paths);stop_beforemeans the path stopped before the stop target. bild_urlis a signed address valid for 10 minutes. Query the test run again to get a new one.- If a step lies outside your domain,
adresseholds only its origin, andariaandbild_urlare empty. - After
loeschen_abthe result and images are deleted.
The limits of test runs are described in Describing sign-in and click paths.
Errors
Errors come as application/problem+json with status, detail (a sentence in the language of the request) and, where there is one, a stable key reason. Branch on reason, not on the sentence.
| Status | reason |
Meaning |
|---|---|---|
| 401 | – | Token missing or invalid. |
| 403 | recht_fehlt |
The token lacks the right; url leads to the “Embedding” tab. |
| 403 | recht_erloschen |
The person who granted the right may no longer do so. Reading still works. |
| 403 | konto_geschlossen |
The organization’s account is closed. |
| 404 | – or nicht_gefunden |
Website, click path, credential or test run does not exist for this token. |
| 409 | probelauf_laeuft |
A test run is already in progress for this website. It is not queued. |
| 422 | schritte_ungueltig |
At least one step is invalid; fehler names code, step and field. |
| 422 | domain_nicht_bestaetigt |
The website’s domain is not verified. |
| 422 | plan |
The plan allows no (further) click paths. |
| 422 | kein_ablauf |
The credential is a simple sign-in form and has no steps. |
| 422 | anmeldung_pausiert |
Sign-in is paused; try a new sign-in flow first. |
| 422 | eingabe_ungueltig |
The test run’s input does not have the expected shape, for example two sources. |
| 422 | – | A field is missing or has the wrong shape; errors names it. |
| 429 | grenze_erreicht |
Too many test runs in the last hour; wieder_ab says when it is possible again. |
| 429 | anmeldung_gesperrt |
Test runs with sign-in are blocked after a failed sign-in; with wieder_ab. |
The codes in fehler[].code form a closed list:
| Code | Meaning |
|---|---|
aktion_unbekannt |
The action does not exist. |
feld_fehlt |
A required field of the action is missing. |
feld_kein_text |
A field is not text. |
adresse_unvollstaendig |
The address is incomplete. |
schema_nicht_erlaubt |
Only http and https are allowed. |
adresse_fremd |
The address is not on your domain. |
selektor_nicht_erlaubt |
The selector is not CSS, role=… or text=…. |
taste_nicht_erlaubt |
The key is not in the list. |
zu_viele_schritte |
More steps than allowed. |
keine_schritte |
The list is empty. |
stop_before_fehlt |
The path touches an order or payment and has no stop target. |
erster_schritt_nicht_eigen |
The first step of a sign-in is not a goto to your domain. |
platzhalter_falsch |
A placeholder is unknown or in the wrong place. |
platzhalter_fehlt |
User name or password do not occur in the sign-in. |
einmalcode_ohne_geheimnis |
The one-time code is used, but no secret is stored. |
schritt_ungueltig |
The step is not a valid object. |
anmeldehost_ungueltig |
A sign-in service is not a valid host. |
anmeldehost_eigen |
A sign-in service is on your own domain. |
zu_viele_anmeldehosts |
More sign-in services than allowed. |
anmeldehosts_unbestaetigt |
The sign-in services are not confirmed. |
Last checked against the product on November 3, 2026. As Markdown
Related articles
-
Describing sign-in and click paths
How to define sign-in and click paths as steps, approve drafts and work with an AI assistant; selectors, keys, failure reasons.
-
Scheduled scans, login areas and click paths
How to set up a recurring scan, have areas behind a login scanned and reach states through click paths.
-
Setting up webhooks and verifying signatures
How your system learns when a scan has finished or a statement is outdated – with events, payload, signature verification and retries.
Still have a question?
Tell us which question is still open. Questions we hear more than once become new help articles.