StageApp API

Integriere Events, Tickets und Check-in in deine eigenen Anwendungen. Die API liefert JSON und nutzt REST-Konventionen.

Base URL https://api.stageapp.io/v1

Authentifizierung

Es gibt zwei Wege sich zu authentifizieren:

1. API-Key (Server-zu-Server)

Für serverseitige Integrationen. Du findest den Key im Dashboard unter API-Zugang.

Authorization: Bearer dein_api_key_64_zeichen

2. App-Token (Mobile Apps)

Für die iOS/Android Scanner-App. Token wird über POST /v1/auth/login erstellt.

Authorization: Bearer dein_app_token_128_zeichen
💡 API-Keys (64 Zeichen) sind an die Firma gebunden. App-Tokens (128 Zeichen) sind an einen Benutzer gebunden und 90 Tage gültig. Beide werden als Bearer-Token im Authorization-Header gesendet.

Fehlerbehandlung

Fehlerhafte Requests liefern einen passenden HTTP-Statuscode und ein JSON-Objekt:

Fehler Response
{
  "success": false,
  "error": "Fehlerbeschreibung"
}
StatusBedeutung
200Erfolg
400Ungültige Anfrage (fehlende Parameter, falsches Format)
401Ungültiger oder fehlender API-Key
404Ressource nicht gefunden
409Konflikt (z.B. gleichzeitiges Check-in)

App Login

Authentifiziert einen Dashboard-Benutzer und gibt ein langlebiges App-Token zurück. Dieses Token wird in der iOS/Android Scanner-App zur Authentifizierung verwendet.

POST /v1/auth/login
🔓 Dieser Endpoint benötigt keinen API-Key – die Authentifizierung erfolgt über E-Mail und Passwort.

Request Body

ParameterTypPflichtBeschreibung
emailstringJaE-Mail des Dashboard-Benutzers
passwordstringJaPasswort des Benutzers
device_namestringNeinGerätename (z.B. "iPhone 15 Pro")
Request
curl -X POST https://api.stageapp.io/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@meinefirma.de",
    "password": "mein_passwort",
    "device_name": "iPhone 15 Pro"
  }'
Response (Erfolg)
{
  "success": true,
  "token": "a1b2c3d4e5f6...128_zeichen_hex_token",
  "expires_at": "2026-09-15 14:30:00",
  "user": {
    "id": 1,
    "name": "Max Mustermann",
    "email": "admin@meinefirma.de",
    "role": "owner"
  },
  "company": {
    "id": 1,
    "name": "Meine Firma GmbH",
    "logo_url": "https://stageapp.io/cdn/...",
    "primary_color": "#CCFF00"
  }
}
Response (Fehler)
{
  "success": false,
  "error": "Ungültige E-Mail oder Passwort"
}
⏱️ App-Tokens sind 90 Tage gültig (128 Zeichen hex). Speichere das Token sicher (z.B. iOS Keychain). Bei 401-Antworten muss neu eingeloggt werden.

App Logout

Invalidiert das aktuelle App-Token und beendet die Sitzung auf dem Server.

POST /v1/auth/logout
Request
curl -X POST https://api.stageapp.io/v1/auth/logout \
  -H "Authorization: Bearer dein_app_token"
Response
{
  "success": true,
  "message": "Erfolgreich abgemeldet"
}

Aktueller User

Gibt die Informationen des aktuell eingeloggten Benutzers zurück. Nützlich zur Token-Validierung beim App-Start.

GET /v1/auth/me
Request
curl https://api.stageapp.io/v1/auth/me \
  -H "Authorization: Bearer dein_app_token"
Response
{
  "success": true,
  "user": {
    "id": 1,
    "name": "Max Mustermann",
    "email": "admin@meinefirma.de",
    "role": "owner"
  },
  "company": {
    "id": 1,
    "name": "Meine Firma GmbH",
    "logo_url": "https://stageapp.io/cdn/...",
    "primary_color": "#CCFF00"
  }
}

Alle Events abrufen

Gibt alle veröffentlichten Events deiner Firma zurück, inkl. Ticket-Typen mit Verfügbarkeit und Checkout-Links.

GET /v1/events
Response
{
  "success": true,
  "count": 2,
  "events": [
    {
      "id": 1,
      "title": "Sommerfest 2026",
      "description": "Das große Sommerfest im Park",
      "location": "Stadtpark Wien",
      "event_date": "2026-07-15",
      "event_time": "20:00:00",
      "end_date": "2026-07-16",
      "end_time": "04:00:00",
      "image_url": "https://...",
      "min_consumption": null,
      "age_restriction": "16+",
      "tickets": [
        {
          "id": 1,
          "name": "Early Bird",
          "price": 15.00,
          "quantity": 200,
          "sale_start": null,
          "sale_end": null,
          "description": "Frühbucher-Ticket",
          "sold": 47,
          "available": 153,
          "checkout_url": "https://stageapp.io/checkout?AbC12dEf"
        }
      ]
    }
  ]
}

Event Felder

FeldTypBeschreibung
idintEindeutige Event-ID
titlestringEvent-Name
descriptionstring|nullBeschreibung
locationstring|nullVeranstaltungsort
event_datestringDatum (YYYY-MM-DD)
event_timestring|nullUhrzeit (HH:MM:SS)
end_datestring|nullEnddatum
end_timestring|nullEndzeit
image_urlstring|nullEvent-Bild URL
min_consumptionfloat|nullMindestverzehr in €
age_restrictionstring|nullAltersbeschränkung
ticketsarrayTicket-Typen (siehe unten)

Ticket Felder

FeldTypBeschreibung
idintTicket-Typ-ID
namestringTicket-Name
pricefloatPreis in EUR
quantityint|nullKontingent (null = unbegrenzt)
soldintBereits verkaufte Menge
availableint|nullNoch verfügbar (null = unbegrenzt)
sale_startstring|nullVerkaufsstart (DATETIME)
sale_endstring|nullVerkaufsende (DATETIME)
checkout_urlstringDirekter Kauf-Link

Zukünftige Events

Wie /v1/events, aber nur Events deren Datum heute oder in der Zukunft liegt.

GET /v1/events/upcoming
Response
// Identisch mit /v1/events, gefiltert auf event_date ≥ heute
{
  "success": true,
  "count": 1,
  "events": [...]
}

Einzelnes Event

Gibt ein einzelnes Event mit seinen Tickets zurück.

GET /v1/events/:id
Response
{
  "success": true,
  "event": {
    "id": 1,
    "title": "Sommerfest 2026",
    // ... alle Event-Felder + tickets
  }
}

Parameter

ParameterTypBeschreibung
:id RequiredintEvent-ID

Fehler

StatusBedeutung
404Event nicht gefunden oder nicht veröffentlicht

Ticket Info

Gibt die Details eines ausgestellten Tickets zurück, ohne es zu entwerten. Nützlich zur Vorschau beim Scannen.

GET /v1/tickets/:code
Response
{
  "success": true,
  "ticket": {
    "ticket_code": "SA-AB3K-9FXZ",
    "status": "valid",
    "event_title": "Sommerfest 2026",
    "event_date": "2026-07-15",
    "event_time": "20:00:00",
    "location": "Stadtpark Wien",
    "ticket_name": "Early Bird",
    "ticket_price": 15.00,
    "customer_name": "Max Mustermann",
    "customer_email": "max@example.com",
    "order_number": "SA-20260315-A1B2",
    "used_at": null
  }
}

Parameter

ParameterTypBeschreibung
:code RequiredstringTicket-Code im Format SA-XXXX-XXXX

Ticket Status

StatusBedeutung
validGültig – kann eingecheckt werden
usedBereits verwendet
cancelledStorniert / ungültig

Ticket Check-in

Entwertet ein gültiges Ticket. Setzt den Status auf used und speichert den Zeitpunkt. Optimiert für Scanner-Apps.

POST /v1/tickets/:code/checkin
Erfolg – Ticket entwertet
{
  "success": true,
  "scan_result": "valid",
  "message": "Ticket successfully checked in.",
  "ticket": {
    "ticket_code": "SA-AB3K-9FXZ",
    "status": "used",
    "used_at": "2026-07-15 20:15:33",
    // ... alle Ticket-Felder
  }
}
Das scan_result-Feld ermöglicht schnelle UI-Entscheidungen: valid = grün, already_used = orange, cancelled = rot.

Mögliche Ergebnisse

scan_resultsuccessBedeutung
validtrueTicket wurde erfolgreich entwertet
already_usedfalseTicket wurde bereits verwendet – used_at zeigt wann
cancelledfalseTicket ist storniert und ungültig
invalidfalseTicket-Code existiert nicht

Beispiel: cURL

Request
curl -X POST https://api.stageapp.io/v1/tickets/SA-AB3K-9FXZ/checkin \
  -H "Authorization: Bearer YOUR_API_KEY"

Beispiel: Swift

Swift
let url = URL(string: "https://api.stageapp.io/v1/tickets/SA-AB3K-9FXZ/checkin")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")

let (data, _) = try await URLSession.shared.data(for: request)
let result = try JSONDecoder().decode(ScanResponse.self, from: data)

Beispiel: JavaScript

JavaScript
const res = await fetch('https://api.stageapp.io/v1/tickets/SA-AB3K-9FXZ/checkin', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` }
});
const data = await res.json();
console.log(data.scan_result); // 'valid', 'already_used', 'cancelled', 'invalid'

Firmen-Info

Gibt grundlegende Informationen zur authentifizierten Firma zurück. Nützlich zum Testen des API-Keys.

GET /v1/company
Response
{
  "success": true,
  "company": {
    "id": 1,
    "name": "Meine Firma GmbH",
    "event_count": 5
  }
}