# Step-Action ausführen

Eine konfigurierte Action mit validierten Eingaben ausführen.

`POST /v1/event/{eventId}/steps/{stepId}/actions/{actionIndex}/execute`

**Authentifizierung:** Benutzer-Access-JWT mit Projektzugriff. Ein API-Token reicht nicht aus.

## Parameter

Der Step muss freigegeben sein. Pro Step kann nur eine Action gleichzeitig laufen. Erfolg setzt den Step auf `success`, Fehler auf `failed`. Reine Links ändern keinen Stepstatus.

## Body

`inputs` enthält die konfigurierten Formularwerte. Wenn die Action eine `confirmation` definiert, ist `confirmed: true` erforderlich. Ein Button ohne Inputs kann `{}` senden, sofern keine Bestätigung verlangt wird. Eingaben werden vor der Ausführung validiert.

## Antwort und Fehler

HTTP `200` liefert das Ausführungsergebnis. Prüfe `success`, weil fehlgeschlagene Webhook-Erwartungen ebenfalls HTTP `200` zurückgeben können. `400`: Eingaben ungültig oder Bestätigung fehlt. `409`: Action abgelaufen, Limit erreicht oder Step gesperrt. Details unter [Actions und Formulare](/docs/guides/actions).


Das Antwortbeispiel zeigt einen Auszug. Die vollständige Antwort enthält außerdem `message` und `results`.


## SDK-Nutzung

Die SDK-Beispiele stehen neben den HTTP-Requests unter **SDKs**. Installation und Einrichtung: [JavaScript / TypeScript](/sdks/javascript), [Next.js](/sdks/nextjs) und [Swift](/sdks/swift). Projekt-Slugs werden vom Client ergänzt.

Diese Operation benötigt einen Benutzer-Access-JWT mit Projektzugriff. Der API-Token allein genügt nicht. Next.js-Beispiele gehören in eine Serverumgebung; Swift-Zugänge stammen aus deiner Laufzeitkonfiguration.

## Request

```bash
curl -X POST 'https://api.tracklytic.de/v1/event/EVENT_ID/steps/review/actions/0/execute' \
  -H "Authorization: Bearer $TRACKLYTIC_ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "inputs": {
    "comment": "Freigegeben"
  },
  "confirmed": true
}'
```

```js
const response = await fetch("https://api.tracklytic.de/v1/event/EVENT_ID/steps/review/actions/0/execute", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRACKLYTIC_ACCESS_TOKEN}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(
    {
      "inputs": {
        "comment": "Freigegeben"
      },
      "confirmed": true
    }
  )
});

if (!response.ok) throw new Error(await response.text());
const result = await response.json();
```

```python
import json
import os
from urllib.request import Request, urlopen

payload = {
  "inputs": {
    "comment": "Freigegeben"
  },
  "confirmed": True
}

request = Request(
    "https://api.tracklytic.de/v1/event/EVENT_ID/steps/review/actions/0/execute",
    method="POST",
    headers={
        "Authorization": "Bearer " + os.environ["TRACKLYTIC_ACCESS_TOKEN"],
        "Content-Type": "application/json"
    },
    data=json.dumps(payload).encode("utf-8")
)

with urlopen(request) as response:
    result = json.load(response)
```

## SDKs

### JavaScript / TypeScript

```ts
import Tracklytic from 'tracklytic';

const tracklytic = new Tracklytic({
  token: process.env.TRACKLYTIC_API_TOKEN!,
  project: "my-project",
  accessToken: process.env.TRACKLYTIC_ACCESS_TOKEN!,
});

const result = await tracklytic.pipeline.executeAction("EVENT_ID", "approval", 0, {
  inputs: { environment: "production" }, confirmed: true,
});
if (result && !result.success) console.error(result.results);
```

### Next.js

```ts
import { TracklyticServer } from 'tracklytic-next/server';

const tracklytic = new TracklyticServer({
  token: process.env.TRACKLYTIC_API_TOKEN!,
  project: "my-project",
  accessToken: process.env.TRACKLYTIC_ACCESS_TOKEN!,
});

const result = await tracklytic.pipeline.executeAction("EVENT_ID", "approval", 0, {
  inputs: { environment: "production" }, confirmed: true,
});
if (result && !result.success) console.error(result.results);
```

### Swift

```swift
import Foundation
import Tracklytic

let tracklytic = TracklyticClient(
    project: "my-project",
    token: apiToken,
    accessToken: userAccessToken
)

let result = try await tracklytic.executeStepAction(
    eventId: "EVENT_ID", stepId: "approval", actionIndex: 0,
    options: ActionInputs(
        inputs: ["environment": AnyCodable("production")], confirmed: true
    )
)
let succeeded = result["success"]?.value as? Bool == true
```

## Response (200)

```json
{
  "success": true,
  "eventStatus": "success"
}
```