# Kontrollpunkte

A **Kontrollpunkt** bittet um Genehmigung einer Single Agent Action. Sie erstellen eine, bevor die Aktion ausgeführt wird; Maetra bewertet sie gegen Ihre aktive [Politik](https://maetra.io/de/docs/govern-api/policies) und gibt eine Entscheidung zurück - sofort für Fast-Path-Ergebnisse oder nachdem ein Mensch reagiert.

### Lebenszyklus

```
create ─▶ evaluate ─┬─▶ approved / rejected / blocked   (terminal, signed)
                    └─▶ pending ─▶ (human decides) ─▶ approved / rejected
                                └─▶ (timeout)      ─▶ expired
```

| Status | Bedeutung |
| ----------- | ------------------------------------------------ |
| `pending` | Warten auf eine menschliche Entscheidung. Umfrage für das Ergebnis. |
| `approved` | Zugelassen. A `decision_token` ausgestellt wird. |
| `rejected` | Ein Rezensent lehnte ab. |
| `blocked` | Eine Politik hat es automatisch blockiert (kein Mensch benötigt). |
| `expired` | Keine Entscheidung vor dem Timeout. |
| `cancelled` | Storniert vor Auflösung. |

Nur `approved` Entscheidungen können bis zur Einwegausführungsberechtigung fortgesetzt werden.

### Erstellen Sie einen Checkpoint

`POST /v1/checkpoints` — erfordert Anwendungsbereich `govern:checkpoints:write`.

Bewertet synchron: Eine Fast-Pfad-Politik kann eine Terminal-Entscheidung in der gleichen Antwort zurückgeben; Andernfalls erhalten Sie eine `pending` Checkpoint zum Pollen.

#### Exakte Richtlinien und Entscheidungsintelligenz

`/v1/checkpoints` verwendet die in Govern konfigurierten aktiven Richtlinien. Eine Richtlinie kann exakt gespeicherte Bedingungen verwenden, oder sie kann **Entscheidungsfindung von KI-Agenten** zur Bewertung des Laufzeitrisikos.

Sie tun dies **nicht** senden a `decision_intelligence` Markierung auf der Checkpoint-Anfrage. Aktivieren Sie Decision Intelligence für die Policy im Dashboard. Der API-Aufruf bleibt gleich; Maetra wendet den Richtlinienmodus an und gibt die gleiche Checkpoint-Entscheidungsform zurück.

**Anfordernde Stelle**

| Feld | Typ | erforderlich | Beschreibung |
| ------------------ | --------- | -------- | ------------------------------------------------------------ |
| `action` | Schnurschnur | ✓ | Der Aktionsname, z.B. `transfer_funds`. |
| `payload` | Objekt || Strukturierte Einzelheiten der Maßnahme. |
| `agent_name` | Schnurschnur || Menschenlesbarer anrufer (verwenden, wenn der agent nicht registriert ist). |
| `agent_id` | Schnurschnur || Registrierte Agent ID (siehe) [Agenten](https://maetra.io/de/docs/agents)). |
| `context` | Schnurschnur || Freitext-Kontext für Reviewer. |
| `reasoning` | Schnurschnur || Die Argumentation des Agenten. |
| `autonomy_level` | Schnurschnur || Ebene der Agentenautonomie, `L0`–`L5`. |
| `policy_ids` | string\[ || Beschränken Sie die Bewertung auf diese genauen oder Entscheidungs-Intelligenz-Richtlinien. |
| `policy_group_ids` | string\[ || Beschränken Sie die Bewertung auf diese Politikgruppen. |
| `timeout_seconds` | Ganzzahl || Wanduhr Decke für eine menschliche Entscheidung. |
| `target` | Objekt || Konto, Ressource oder Anbieter, die die Aktion beeinflussen wird. |
| `task_authorization` | Objekt || Aufgaben-, Revisions- und externe Aktions-IDs, die die Arbeit autorisiert haben. |
| `runtime` | Objekt || Werkzeug- und Modellnamen und Versionen, die für den Vorschlag der Aktion verwendet werden. |
| `executor_audience` | Schnurschnur || Service erlaubt, die zugelassene Fähigkeit zu nutzen. |

#### cURL

```bash
curl -X POST "https://api.maetra.io/v1/checkpoints" \
  -H "Authorization: Bearer $MAETRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "action": "delete_customer",
  "agent_name": "ops-agent",
  "payload": {
    "customer_id": "cus_41ab"
  },
  "reasoning": "GDPR erasure request #8821."
}'
```

#### JavaScript

```javascript
const res = await fetch("https://api.maetra.io/v1/checkpoints", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
      "action": "delete_customer",
      "agent_name": "ops-agent",
      "payload": {
          "customer_id": "cus_41ab"
      },
      "reasoning": "GDPR erasure request #8821."
  }),
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = await res.json();
console.log(data);
```

#### TypeScript

```typescript
interface CheckpointDecision {
  checkpoint_id: string;
  status: string;
  decision_token: string | null;
  expires_at: string | null;
  evals: unknown[];
}

const res = await fetch("https://api.maetra.io/v1/checkpoints", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
      "action": "delete_customer",
      "agent_name": "ops-agent",
      "payload": {
          "customer_id": "cus_41ab"
      },
      "reasoning": "GDPR erasure request #8821."
  }),
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = (await res.json()) as CheckpointDecision;
```

#### Python

```python
import os, requests

res = requests.post(
    "https://api.maetra.io/v1/checkpoints",
    headers={"Authorization": f"Bearer {os.environ['MAETRA_API_KEY']}"},
    json={
        "action": "delete_customer",
        "agent_name": "ops-agent",
        "payload": {
            "customer_id": "cus_41ab"
        },
        "reasoning": "GDPR erasure request #8821."
    },
)
res.raise_for_status()
print(res.json())
```

#### Rust

```rust
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("MAETRA_API_KEY")?;
    let client = reqwest::Client::new();
    let res = client
        .post("https://api.maetra.io/v1/checkpoints")
        .bearer_auth(&key)
        .json(&json!({
            "action": "delete_customer",
            "agent_name": "ops-agent",
            "payload": {
                "customer_id": "cus_41ab"
            },
            "reasoning": "GDPR erasure request #8821."
        }))
        .send()
        .await?;
    let data: serde_json::Value = res.json().await?;
    println!("{data:#}");
    Ok(())
}
```

#### C++

```cpp
#include <curl/curl.h>
#include <cstdlib>
#include <string>

int main() {
    CURL* curl = curl_easy_init();
    std::string auth = "Authorization: Bearer " + std::string(std::getenv("MAETRA_API_KEY"));
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, auth.c_str());
    headers = curl_slist_append(headers, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_URL, "https://api.maetra.io/v1/checkpoints");
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, R"({  "action": "delete_customer",  "agent_name": "ops-agent",  "payload": {    "customer_id": "cus_41ab"  },  "reasoning": "GDPR erasure request #8821."})");
    curl_easy_perform(curl);   // response is written to stdout by default
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}
```

#### Java

```java
import java.net.URI;
import java.net.http.*;

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.maetra.io/v1/checkpoints"))
    .header("Authorization", "Bearer " + System.getenv("MAETRA_API_KEY"))
    .header("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
{
  "action": "delete_customer",
  "agent_name": "ops-agent",
  "payload": {
    "customer_id": "cus_41ab"
  },
  "reasoning": "GDPR erasure request #8821."
}"""))
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```


#### Mit einem registrierten Agenten

Der obige Call verwendet `agent_name` weil der Agent nicht registriert ist - der gemeinsame Fall. Wenn der Agent **ist** [registriert](https://maetra.io/de/docs/agents)Übergeben Sie Ihre `agent_id` stattdessen (oder nebenbei) `agent_name`) so wird ihm der Checkpoint zugeschrieben:

```json
{
  "action": "delete_customer",
  "agent_id": "agt_5Ab2",
  "payload": { "customer_id": "cus_41ab" },
  "reasoning": "GDPR erasure request #8821."
}
```

#### Richtlinienumfang mit optionaler Agent-Identität

`agent_id` ist optional für `/v1/checkpoints`. Wenn Sie nur senden `agent_name`Govern bewertet immer noch die aktion.

Für die automatische aktive Politikauswertung:

| Name des Antrags | Berücksichtigte Strategien |
| ------------------------------------ | --------------------------------------------------------------------------------------------- |
| Registriert `agent_id` | Organisationsweite Richtlinien sowie Richtlinien, die diesem registrierten Agenten zugewiesen wurden. |
| `agent_name` Abgleich mit einem registrierten Agenten | Organisationsweite Richtlinien sowie Richtlinien, die diesem registrierten Agenten zugewiesen wurden. |
| Unbekannt oder nicht registriert `agent_name` | Nur organisationsweite Politik. Agentenspezifische Richtlinien laufen nicht versehentlich. |
| Keine Agentenidentität | Nur organisationsweite Politik. |

Verwendung `agent_id` für stabile Attribution. Verwendung `agent_name` nur für API-Agenten oder MCP-Agenten, die noch nicht registriert sind. Wenn Sie gehen `policy_ids` oder `policy_group_ids`Maetra bewertet diese explizite auswahl. Die Auswahl kann genaue Richtlinien oder Entscheidungsintelligenzrichtlinien umfassen.

#### Antwort

```json
{
  "checkpoint_id": "cp_7Yh2Qa",
  "agent_id": null,
  "agent_name": "ops-agent",
  "status": "pending",
  "reason": null,
  "decision_token": null,
  "expires_at": "2026-07-07T12:05:00.000Z",
  "evals": [
    { "policy_name": "Destructive actions", "status": "pending", "quorum_required": 2, "quorum_met": 0, "pool_size": 4 }
  ]
}
```

| Feld | Typ | Beschreibung |
| ------------------------- | -------------- | ----------------------------------------------------------------------------------------------- |
| `checkpoint_id` | Schnurschnur | Die ID des Checkpoints. |
| `agent_id` / `agent_name` | Schnurschnur \| Null | Die Anruferidentität, die Sie angegeben haben. |
| `status` | enum | `pending`, `approved`, `rejected`, `expired`, `blocked`, `cancelled`. |
| `reason` | Schnurschnur \| Null | Menschliche oder politische Gründe, sofern verfügbar. |
| `decision_token` | Schnurschnur \| Null | Unterzeichnetes JWT, das eine Terminalentscheidung belegt — siehe [Entscheidungsmarken](https://maetra.io/de/docs/govern-api/decision-tokens). |
| `action_envelope` / `action_envelope_hash` | Objekt / String | Genauer Vorschlag und kanonische SHA-256 Bindung. |
| `policy_versions` / `policy_digest` | Array / String | Genaue Richtlinienversionen, die für die Entscheidung verwendet wurden. |
| `decision_token_expires_at` | Schnurschnur \| Null | Ablauf der unterzeichneten One-Use-Entscheidungsfähigkeit. |
| `execution_expected_at` / `effect_expected_at` | Schnurschnur \| Null | Fristen, die verwendet wurden, um fehlende Lifecycle-Beweise aufzudecken. |
| `expires_at` | Schnurschnur \| Null | Ablaufdatum nach ISO 8601. |
| `evals` | Array | Detail der Bewertung nach Politik (unten). |

**Evales Objekt:** `policy_id`, `policy_name`, `applicability`, `status`, `quorum_required`, `quorum_met`, `pool_size`.

### Holen Sie sich einen Checkpoint (kalte Umfrage)

`GET /v1/checkpoints/{id}` — Anwendungsbereich `govern:checkpoints:read`. Gibt den aktuellen Zustand zurück, ohne zu warten. Halten Sie ≥ 1 Sekunde zwischen den Umfragen des gleichen Checkpoints; bevorzugen Sie die Long-Poll unten.

#### cURL

```bash
curl "https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa" \
  -H "Authorization: Bearer $MAETRA_API_KEY"
```

#### JavaScript

```javascript
const res = await fetch("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = await res.json();
console.log(data);
```

#### TypeScript

```typescript
const res = await fetch("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = (await res.json());
```

#### Python

```python
import os, requests

res = requests.get(
    "https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa",
    headers={"Authorization": f"Bearer {os.environ['MAETRA_API_KEY']}"},
)
res.raise_for_status()
print(res.json())
```

#### Rust

```rust
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("MAETRA_API_KEY")?;
    let client = reqwest::Client::new();
    let res = client
        .get("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa")
        .bearer_auth(&key)
        .send()
        .await?;
    let data: serde_json::Value = res.json().await?;
    println!("{data:#}");
    Ok(())
}
```

#### C++

```cpp
#include <curl/curl.h>
#include <cstdlib>
#include <string>

int main() {
    CURL* curl = curl_easy_init();
    std::string auth = "Authorization: Bearer " + std::string(std::getenv("MAETRA_API_KEY"));
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, auth.c_str());
    curl_easy_setopt(curl, CURLOPT_URL, "https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_perform(curl);   // response is written to stdout by default
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}
```

#### Java

```java
import java.net.URI;
import java.net.http.*;

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa"))
    .header("Authorization", "Bearer " + System.getenv("MAETRA_API_KEY"))
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```


### Warten auf eine Entscheidung (long-poll)

`GET /v1/checkpoints/{id}/wait` — Anwendungsbereich `govern:checkpoints:read`. Hält die Verbindung offen, bis der Checkpoint den Zustand ändert oder der Haltevorgang abgelaufen ist. Der effiziente Weg, auf einen Menschen zu warten.

* Abfrage `timeout`: Haltesekunden, `1`–`55` (Standard) `50`).
* `200` - verändert; Körper ist der neue Zustand. `202` Keine Änderung; Reconnect.

#### cURL

```bash
curl "https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50" \
  -H "Authorization: Bearer $MAETRA_API_KEY"
```

#### JavaScript

```javascript
const res = await fetch("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = await res.json();
console.log(data);
```

#### TypeScript

```typescript
const res = await fetch("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MAETRA_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Maetra API ${res.status}`);
const data = (await res.json());
```

#### Python

```python
import os, requests

res = requests.get(
    "https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50",
    headers={"Authorization": f"Bearer {os.environ['MAETRA_API_KEY']}"},
)
res.raise_for_status()
print(res.json())
```

#### Rust

```rust
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("MAETRA_API_KEY")?;
    let client = reqwest::Client::new();
    let res = client
        .get("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50")
        .bearer_auth(&key)
        .send()
        .await?;
    let data: serde_json::Value = res.json().await?;
    println!("{data:#}");
    Ok(())
}
```

#### C++

```cpp
#include <curl/curl.h>
#include <cstdlib>
#include <string>

int main() {
    CURL* curl = curl_easy_init();
    std::string auth = "Authorization: Bearer " + std::string(std::getenv("MAETRA_API_KEY"));
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, auth.c_str());
    curl_easy_setopt(curl, CURLOPT_URL, "https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_perform(curl);   // response is written to stdout by default
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}
```

#### Java

```java
import java.net.URI;
import java.net.http.*;

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.maetra.io/v1/checkpoints/cp_7Yh2Qa/wait?timeout=50"))
    .header("Authorization", "Bearer " + System.getenv("MAETRA_API_KEY"))
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```


### Empfohlener Fluss

1. `POST /v1/checkpoints`.
2. Wenn `status` ist bereits terminal, handeln Sie darauf (und überprüfen Sie das Token).
3. Wenn `pending`, Long-Poll `/wait` bis zum Terminal.
4. am `approved`, [Überprüfen Sie das Entscheidungs-Token](https://maetra.io/de/docs/govern-api/decision-tokens),
Dann konsumieren Sie es durch [Ausführungsberechtigung](https://maetra.io/de/docs/govern-api/execution-receipts) unmittelbar vor dem Handeln. Notieren Sie jeden Versuch und überprüfen Sie den Effekt. Auf irgendetwas anderes, handeln Sie nicht.